Skip to content

Address 4520 #4523

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/page.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://github.com/pymupdf/PyMuPDF-Utilities/blob/master/examples/combine-pages/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 <https://github.com/pymupdf/PyMuPDF-Utilities/blob/master/examples/posterize-document/posterize.py>`_),
* include PDF-based vector images like company logos, watermarks, etc., see `svg-logo.py <https://github.com/pymupdf/PyMuPDF-Utilities/tree/master/examples/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 <https://github.com/pymupdf/PyMuPDF-Utilities/tree/master/examples/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.
Expand All @@ -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:

Expand Down
2 changes: 1 addition & 1 deletion src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
2 changes: 0 additions & 2 deletions src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
19 changes: 19 additions & 0 deletions tests/test_4520.py
Original file line number Diff line number Diff line change
@@ -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