PyMuPDF icon indicating copy to clipboard operation
PyMuPDF copied to clipboard

Incorrect links to points on pages having different heights

Open ikseek opened this issue 1 year ago • 2 comments

Description of the bug

Having a document with pages of a different height I try to create a link from a rectangle on one page to a rectangle on another. When links are created to places on pages of equal heights, all works fine. When links are created to places on pages of different heights, viewers jump to an offset position on that page. Empirically I found that this offset is the difference of source and destination page heights.

Is that intended? In the example I'm attaching, I added a convert function, but why do I need it, shouldn't insert_link calculate it automatically?

To reproduce the problem open the document with higher zoom level (300%) and click rectangles, notice that following links do not bring next rectangle into top-level corner of the viewport. Replace target point (to_rect.top_left) with commented out convert call to see workaround that fixes it. Tested in Mac OS Preview, Chrome PDF and https://mozilla.github.io/pdf.js/web/viewer.html viewers.

How to reproduce the bug

import os

import fitz


def convert(link_page_size, target_page_size, point):
    return fitz.Point(point.x, point.y + link_page_size.y - target_page_size.y)


doc = fitz.open()
doc.new_page(width=500, height=800)
doc.new_page(width=800, height=500)
rects = [
    (0, fitz.Rect(10, 20, 50, 40), fitz.utils.getColor('red')),
    (0, fitz.Rect(300, 350, 400, 450), fitz.utils.getColor('green')),
    (1, fitz.Rect(20, 30, 40, 50), fitz.utils.getColor('blue')),
    (1, fitz.Rect(350, 300, 450, 400), fitz.utils.getColor('black'))
]

for page, rect, color in rects:
    doc[page].draw_rect(rect, color=color)

for (from_page, from_rect, _), (to_page, to_rect, _) in zip(rects, rects[1:] + rects[:1]):
    doc[from_page].insert_link({
        'kind': 1,
        'from': from_rect,
        'page': to_page,
        'to': to_rect.top_left,
        # 'to': convert(doc[from_page].mediabox_size, doc[to_page].mediabox_size, to_rect.top_left),
    })

doc.save("out.pdf")
os.system("open out.pdf")

PyMuPDF version

1.24.1

Operating system

MacOS

Python version

3.12

ikseek avatar Apr 05 '24 20:04 ikseek

You did not provide a reproducer file. The referenced file seems to have all equal page heights.

JorjMcKie avatar Apr 06 '24 10:04 JorjMcKie

Actually I did, the code generates pdf from scratch and page heights are different

ikseek avatar Apr 06 '24 17:04 ikseek

Thanks for submitting this bug, and for the reproducing code. I've just pushed a fix so this will be fixed in our next release.

Fixed in 1.24.6.