diff --git a/src/__init__.py b/src/__init__.py index 97890ed45..9372fadc7 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -7291,14 +7291,14 @@ def set_toc( title = get_pdf_str(o[1]) # title pno = min(doc.page_count - 1, max(0, o[2] - 1)) # page number page_xref = doc.page_xref(pno) - page_height = doc.page_cropbox(pno).height - top = Point(72, page_height - 36) + cropbox = doc.page_cropbox(pno) + top = Point(72, cropbox.y1 - 36) dest_dict = {"to": top, "kind": LINK_GOTO} # fall back target if o[2] < 0: dest_dict["kind"] = LINK_NONE if len(o) > 3: # some target is specified if type(o[3]) in (int, float): # convert a number to a point - dest_dict["to"] = Point(72, page_height - o[3]) + dest_dict["to"] = Point(72, cropbox.y1 - o[3]) else: # if something else, make sure we have a dict # We make a copy of o[3] to avoid modifying our caller's data. dest_dict = o[3].copy() if type(o[3]) is dict else dest_dict @@ -7307,7 +7307,7 @@ def set_toc( else: # transform target to PDF coordinates page = doc[pno] point = Point(dest_dict["to"]) - point.y = page.cropbox.height - point.y + point.y = page.cropbox.y1 - point.y point = point * page.rotation_matrix dest_dict["to"] = (point.x, point.y) d = {} @@ -7460,9 +7460,9 @@ def set_toc_item( if dest_dict["kind"] == LINK_GOTO: pno = dest_dict["page"] page_xref = doc.page_xref(pno) - page_height = doc.page_cropbox(pno).height + cropbox = doc.page_cropbox(pno) to = dest_dict.get('to', Point(72, 36)) - to.y = page_height - to.y + to.y = cropbox.y1 - to.y dest_dict["to"] = to action = utils.getDestStr(page_xref, dest_dict) if not action.startswith("/A"): @@ -7496,12 +7496,12 @@ def set_toc_item( if pno is None or pno not in range(1, doc.page_count + 1): raise ValueError("bad page number") page_xref = doc.page_xref(pno - 1) - page_height = doc.page_cropbox(pno - 1).height + cropbox = doc.page_cropbox(pno - 1) if to is None: - to = Point(72, page_height - 36) + to = Point(72, cropbox.y1 - 36) else: to = Point(to) - to.y = page_height - to.y + to.y = cropbox.y1 - to.y ddict = { "kind": kind, diff --git a/tests/test_toc.py b/tests/test_toc.py index 8975011f4..3bfb540c6 100644 --- a/tests/test_toc.py +++ b/tests/test_toc.py @@ -315,3 +315,16 @@ def test_3820(): assert epage == dest["page"] + 1 +def test_set_toc_y_with_shifted_cropbox(): + """TOC y is in page space. Destinations are in PDF user space (MediaBox).""" + doc = pymupdf.open() + page = doc.new_page(width=612, height=792) + page.set_cropbox(pymupdf.Rect(108, 90, 504, 702)) + y = 304.6222839355469 + doc.set_toc([[1, "title", 1, y]]) + toc = doc.get_toc(simple=False) + actual_y = toc[0][3]["to"][1] + assert abs(actual_y - y) < 0.05, (y, actual_y) + doc.close() + +