diff --git a/docs/page.rst b/docs/page.rst index 852539aab..4d3fffcc1 100644 --- a/docs/page.rst +++ b/docs/page.rst @@ -1977,11 +1977,11 @@ In a nutshell, this is what you can do with PyMuPDF: .. method:: show_pdf_page(rect, docsrc, pno=0, keep_proportion=True, overlay=True, oc=0, rotate=0, clip=None) - PDF only: Display a page of another PDF as a **vector image** (otherwise similar to :meth:`Page.insert_image`). This is a multi-purpose method. For example, you can use it to: + PDF only: Display a page of another PDF. This is similar to :meth:`Page.insert_image` but the source page will appear like a copy of itself and will not be rasterized. This is a multi-purpose method. For example, you can use it to: * create "n-up" versions of existing PDF files, combining several input pages into **one output page** (see example `combine.py `_), * create "posterized" PDF files, i.e. every input page is split up in parts which each create a separate output page (see `posterize.py `_), - * include PDF-based vector images like company logos, watermarks, etc., see `svg-logo.py `_, which puts an SVG-based logo on each page (requires additional packages to deal with SVG-to-PDF conversions). + * include PDF-based vector images like company logos, watermarks, etc., see `svg-logo.py `_, which puts an SVG-based logo on each page. :arg rect_like rect: where to place the image on current page. Must be finite and its intersection with the page must not be empty. :arg docsrc: source PDF document containing the page. Must be a different document object, but may be the same file. @@ -1998,7 +1998,7 @@ In a nutshell, this is what you can do with PyMuPDF: :arg rect_like clip: choose which part of the source page to show. Default is the full page, else must be finite and its intersection with the source page must not be empty. - .. note:: In contrast to method :meth:`Document.insert_pdf`, this method does not copy annotations, widgets or links, so these are not included in the target [#f6]_. But all its **other resources (text, images, fonts, etc.)** will be imported into the current PDF. They will therefore appear in text extractions and in :meth:`get_fonts` and :meth:`get_images` lists -- even if they are not contained in the visible area given by *clip*. + .. note:: In contrast to method :meth:`Document.insert_pdf`, this method does not copy annotations, widgets or links, so these objects are not included in the target [#f6]_. But all its **other resources (text, images, fonts, etc.)** will be imported into the current PDF. They will therefore appear in text extractions and in :meth:`get_fonts` and :meth:`get_images` lists -- even if they are not contained in the visible area given by *clip*. Example: Show the same source page, rotated by 90 and by -90 degrees: diff --git a/src/__init__.py b/src/__init__.py index 1c7791534..4f0c82513 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -17240,7 +17240,7 @@ def JM_read_contents(pageref): elif contents.m_internal: res = mupdf.pdf_load_stream(contents) else: - res = b"" + res = mupdf.FzBuffer(0) return res diff --git a/src/utils.py b/src/utils.py index 882aa05ff..8a7272b41 100644 --- a/src/utils.py +++ b/src/utils.py @@ -174,8 +174,6 @@ def calc_matrix(sr, tr, keep=True, rotate=0): while pno < 0: # support negative page numbers pno += docsrc.page_count src_page = docsrc[pno] # load source page - if src_page.get_contents() == []: - raise ValueError("nothing to show - source page empty") tar_rect = rect * ~page.transformation_matrix # target rect in PDF coordinates diff --git a/tests/test_4520.py b/tests/test_4520.py new file mode 100644 index 000000000..388ffde2f --- /dev/null +++ b/tests/test_4520.py @@ -0,0 +1,19 @@ +import pymupdf + + +def test_4520(): + """Accept source pages without /Contents object in show_pdf_page.""" + vsn_tuple = tuple(map(int, pymupdf.__version__.split("."))) + tar = pymupdf.open() + src = pymupdf.open() + src.new_page() + page = tar.new_page() + try: + assert page.show_pdf_page(page.rect, src, 0) + rc = True + except Exception as e: + rc = False + if vsn_tuple < (1, 26, 0): + assert rc is False + else: + assert rc is True