@@ -157,3 +157,120 @@ def get(doc):
157
157
with pymupdf .open (file_out ) as doc :
158
158
print (f'4: { get (doc )} ' )
159
159
pymupdf ._log_items_clear ()
160
+
161
+
162
+ def test_3347 ():
163
+ '''
164
+ Check fix for #3347 - link destination rectangles when source/destination
165
+ pages have different sizes.
166
+ '''
167
+ doc = pymupdf .open ()
168
+ doc .new_page (width = 500 , height = 800 )
169
+ doc .new_page (width = 800 , height = 500 )
170
+ rects = [
171
+ (0 , pymupdf .Rect (10 , 20 , 50 , 40 ), pymupdf .utils .getColor ('red' )),
172
+ (0 , pymupdf .Rect (300 , 350 , 400 , 450 ), pymupdf .utils .getColor ('green' )),
173
+ (1 , pymupdf .Rect (20 , 30 , 40 , 50 ), pymupdf .utils .getColor ('blue' )),
174
+ (1 , pymupdf .Rect (350 , 300 , 450 , 400 ), pymupdf .utils .getColor ('black' ))
175
+ ]
176
+
177
+ for page , rect , color in rects :
178
+ doc [page ].draw_rect (rect , color = color )
179
+
180
+ for (from_page , from_rect , _ ), (to_page , to_rect , _ ) in zip (rects , rects [1 :] + rects [:1 ]):
181
+ doc [from_page ].insert_link ({
182
+ 'kind' : 1 ,
183
+ 'from' : from_rect ,
184
+ 'page' : to_page ,
185
+ 'to' : to_rect .top_left ,
186
+ })
187
+
188
+ links_expected = [
189
+ (0 , {'kind' : 1 , 'xref' : 11 , 'from' : pymupdf .Rect (10.0 , 20.0 , 50.0 , 40.0 ), 'page' : 0 , 'to' : pymupdf .Point (300.0 , 350.0 ), 'zoom' : 0.0 , 'id' : 'jorj-L0' }),
190
+ (0 , {'kind' : 1 , 'xref' : 12 , 'from' : pymupdf .Rect (300.0 , 350.0 , 400.0 , 450.0 ), 'page' : 1 , 'to' : pymupdf .Point (20.0 , 30.0 ), 'zoom' : 0.0 , 'id' : 'jorj-L1' }),
191
+ (1 , {'kind' : 1 , 'xref' : 13 , 'from' : pymupdf .Rect (20.0 , 30.0 , 40.0 , 50.0 ), 'page' : 1 , 'to' : pymupdf .Point (350.0 , 300.0 ), 'zoom' : 0.0 , 'id' : 'jorj-L0' }),
192
+ (1 , {'kind' : 1 , 'xref' : 14 , 'from' : pymupdf .Rect (350.0 , 300.0 , 450.0 , 400.0 ), 'page' : 0 , 'to' : pymupdf .Point (10.0 , 20.0 ), 'zoom' : 0.0 , 'id' : 'jorj-L1' }),
193
+ ]
194
+
195
+ path = os .path .normpath (f'{ __file__ } /../../tests/test_3347_out.pdf' )
196
+ doc .save (path )
197
+ print (f'Have saved to { path = } .' )
198
+
199
+ links_actual = list ()
200
+ for page_i , page in enumerate (doc ):
201
+ links = page .get_links ()
202
+ for link_i , link in enumerate (links ):
203
+ print (f'{ page_i = } { link_i = } : { link !r} ' )
204
+ links_actual .append ( (page_i , link ) )
205
+
206
+ assert links_actual == links_expected
207
+
208
+
209
+ def test_3400 ():
210
+ '''
211
+ Check fix for #3400 - link destination rectangles when source/destination
212
+ pages have different rotations.
213
+ '''
214
+ width = 750
215
+ height = 1110
216
+ circle_middle_point = pymupdf .Point (height / 4 , width / 4 )
217
+ print (f'{ circle_middle_point = } ' )
218
+ with pymupdf .open () as doc :
219
+
220
+ page = doc .new_page (width = width , height = height )
221
+ page .set_rotation (270 )
222
+ # draw a circle at the middle point to facilitate debugging
223
+ page .draw_circle (circle_middle_point , color = (0 , 0 , 1 ), radius = 5 , width = 2 )
224
+
225
+ for i in range (10 ):
226
+ for j in range (10 ):
227
+ x = i / 10 * width
228
+ y = j / 10 * height
229
+ page .draw_circle (pymupdf .Point (x , y ), color = (0 ,0 ,0 ), radius = 0.2 , width = 0.1 )
230
+ page .insert_htmlbox (pymupdf .Rect (x , y , x + width / 10 , y + height / 20 ), f'<small><small><small><small>({ x = :.1f} ,{ y = :.1f} )</small></small></small></small>' , )
231
+
232
+ # rotate the middle point by the page rotation for the new toc entry
233
+ toc_link_coords = circle_middle_point
234
+ print (f'{ toc_link_coords = } ' )
235
+
236
+ toc = [
237
+ (
238
+ 1 ,
239
+ "Link to circle" ,
240
+ 1 ,
241
+ {
242
+ "kind" : pymupdf .LINK_GOTO ,
243
+ "page" : 1 ,
244
+ "to" : toc_link_coords ,
245
+ "from" : pymupdf .Rect (0 , 0 , height / 4 , width / 4 ),
246
+ },
247
+ )
248
+ ]
249
+ doc .set_toc (toc , 0 ) # set the toc
250
+
251
+ page = doc .new_page (width = 200 , height = 300 )
252
+ from_rect = pymupdf .Rect (10 , 10 , 100 , 50 )
253
+ page .insert_htmlbox (from_rect , 'link' )
254
+ link = dict ()
255
+ link ['from' ] = from_rect
256
+ link ['kind' ] = pymupdf .LINK_GOTO
257
+ link ['to' ] = toc_link_coords
258
+ link ['page' ] = 0
259
+ page .insert_link (link )
260
+
261
+ path = os .path .normpath (f'{ __file__ } /../../tests/test_3400.pdf' )
262
+ doc .save (path )
263
+ print (f'Saved to { path = } .' )
264
+
265
+ links_expected = [
266
+ (1 , {'kind' : 1 , 'xref' : 1120 , 'from' : pymupdf .Rect (10.0 , 10.0 , 100.0 , 50.0 ), 'page' : 0 , 'to' : pymupdf .Point (187.5 , 472.5 ), 'zoom' : 0.0 , 'id' : 'jorj-L0' })
267
+ ]
268
+
269
+ links_actual = list ()
270
+ for page_i , page in enumerate (doc ):
271
+ links = page .get_links ()
272
+ for link_i , link in enumerate (links ):
273
+ print (f'({ page_i } , { link !r} )' )
274
+ links_actual .append ( (page_i , link ) )
275
+
276
+ assert links_actual == links_expected
0 commit comments