comparison tests/test_geometry.py @ 1:1d09e1dec1d9 upstream

ADD: PyMuPDF v1.26.4: the original sdist. It does not yet contain MuPDF. This normally will be downloaded when building PyMuPDF.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:37:51 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 1:1d09e1dec1d9
1 """
2 * Check various construction methods of rects, points, matrices
3 * Check matrix inversions in variations
4 * Check algebra constructs
5 """
6 import os
7
8 import pymupdf
9
10
11 def test_rect():
12 assert tuple(pymupdf.Rect()) == (0, 0, 0, 0)
13 if hasattr(pymupdf, 'mupdf'):
14 assert tuple(pymupdf.Rect(y0=12)) == (0, 12, 0, 0)
15 assert tuple(pymupdf.Rect(10, 20, 100, 200, x1=12)) == (10, 20, 12, 200)
16 p1 = pymupdf.Point(10, 20)
17 p2 = pymupdf.Point(100, 200)
18 p3 = pymupdf.Point(150, 250)
19 r = pymupdf.Rect(10, 20, 100, 200)
20 r_tuple = tuple(r)
21 assert tuple(pymupdf.Rect(p1, p2)) == r_tuple
22 assert tuple(pymupdf.Rect(p1, 100, 200)) == r_tuple
23 assert tuple(pymupdf.Rect(10, 20, p2)) == r_tuple
24 assert tuple(r.include_point(p3)) == (10, 20, 150, 250)
25 r = pymupdf.Rect(10, 20, 100, 200)
26 assert tuple(r.include_rect((100, 200, 110, 220))) == (10, 20, 110, 220)
27 r = pymupdf.Rect(10, 20, 100, 200)
28 # include empty rect makes no change
29 assert tuple(r.include_rect((0, 0, 0, 0))) == r_tuple
30 # include invalid rect makes no change
31 assert tuple(r.include_rect((1, 1, -1, -1))) == r_tuple
32 r = pymupdf.Rect()
33 for i in range(4):
34 r[i] = i + 1
35 assert r == pymupdf.Rect(1, 2, 3, 4)
36 assert pymupdf.Rect() / 5 == pymupdf.Rect()
37 assert pymupdf.Rect(1, 1, 2, 2) / pymupdf.Identity == pymupdf.Rect(1, 1, 2, 2)
38 failed = False
39 try:
40 r = pymupdf.Rect(1)
41 except:
42 failed = True
43 assert failed
44 failed = False
45 try:
46 r = pymupdf.Rect(1, 2, 3, 4, 5)
47 except:
48 failed = True
49 assert failed
50 failed = False
51 try:
52 r = pymupdf.Rect((1, 2, 3, 4, 5))
53 except:
54 failed = True
55 assert failed
56 failed = False
57 try:
58 r = pymupdf.Rect(1, 2, 3, "x")
59 except:
60 failed = True
61 assert failed
62 failed = False
63 try:
64 r = pymupdf.Rect()
65 r[5] = 1
66 except:
67 failed = True
68 assert failed
69
70
71 def test_irect():
72 p1 = pymupdf.Point(10, 20)
73 p2 = pymupdf.Point(100, 200)
74 p3 = pymupdf.Point(150, 250)
75 r = pymupdf.IRect(10, 20, 100, 200)
76 r_tuple = tuple(r)
77 assert tuple(pymupdf.IRect(p1, p2)) == r_tuple
78 assert tuple(pymupdf.IRect(p1, 100, 200)) == r_tuple
79 assert tuple(pymupdf.IRect(10, 20, p2)) == r_tuple
80 assert tuple(r.include_point(p3)) == (10, 20, 150, 250)
81 r = pymupdf.IRect(10, 20, 100, 200)
82 assert tuple(r.include_rect((100, 200, 110, 220))) == (10, 20, 110, 220)
83 r = pymupdf.IRect(10, 20, 100, 200)
84 # include empty rect makes no change
85 assert tuple(r.include_rect((0, 0, 0, 0))) == r_tuple
86 r = pymupdf.IRect()
87 for i in range(4):
88 r[i] = i + 1
89 assert r == pymupdf.IRect(1, 2, 3, 4)
90
91 failed = False
92 try:
93 r = pymupdf.IRect(1)
94 except:
95 failed = True
96 assert failed
97 failed = False
98 try:
99 r = pymupdf.IRect(1, 2, 3, 4, 5)
100 except:
101 failed = True
102 assert failed
103 failed = False
104 try:
105 r = pymupdf.IRect((1, 2, 3, 4, 5))
106 except:
107 failed = True
108 assert failed
109 failed = False
110 try:
111 r = pymupdf.IRect(1, 2, 3, "x")
112 except:
113 failed = True
114 assert failed
115 failed = False
116 try:
117 r = pymupdf.IRect()
118 r[5] = 1
119 except:
120 failed = True
121 assert failed
122
123
124 def test_inversion():
125 alpha = 255
126 m1 = pymupdf.Matrix(alpha)
127 m2 = pymupdf.Matrix(-alpha)
128 m3 = m1 * m2 # should equal identity matrix
129 assert abs(m3 - pymupdf.Identity) < pymupdf.EPSILON
130 m = pymupdf.Matrix(1, 0, 1, 0, 1, 0) # not invertible!
131 # inverted matrix must be zero
132 assert ~m == pymupdf.Matrix()
133
134
135 def test_matrix():
136 assert tuple(pymupdf.Matrix()) == (0, 0, 0, 0, 0, 0)
137 assert tuple(pymupdf.Matrix(90)) == (0, 1, -1, 0, 0, 0)
138 if hasattr(pymupdf, 'mupdf'):
139 assert tuple(pymupdf.Matrix(c=1)) == (0, 0, 1, 0, 0, 0)
140 assert tuple(pymupdf.Matrix(90, e=5)) == (0, 1, -1, 0, 5, 0)
141 m45p = pymupdf.Matrix(45)
142 m45m = pymupdf.Matrix(-45)
143 m90 = pymupdf.Matrix(90)
144 assert abs(m90 - m45p * m45p) < pymupdf.EPSILON
145 assert abs(pymupdf.Identity - m45p * m45m) < pymupdf.EPSILON
146 assert abs(m45p - ~m45m) < pymupdf.EPSILON
147 assert pymupdf.Matrix(2, 3, 1) == pymupdf.Matrix(1, 3, 2, 1, 0, 0)
148 m = pymupdf.Matrix(2, 3, 1)
149 m.invert()
150 assert abs(m * pymupdf.Matrix(2, 3, 1) - pymupdf.Identity) < pymupdf.EPSILON
151 assert pymupdf.Matrix(1, 1).pretranslate(2, 3) == pymupdf.Matrix(1, 0, 0, 1, 2, 3)
152 assert pymupdf.Matrix(1, 1).prescale(2, 3) == pymupdf.Matrix(2, 0, 0, 3, 0, 0)
153 assert pymupdf.Matrix(1, 1).preshear(2, 3) == pymupdf.Matrix(1, 3, 2, 1, 0, 0)
154 assert abs(pymupdf.Matrix(1, 1).prerotate(30) - pymupdf.Matrix(30)) < pymupdf.EPSILON
155 small = 1e-6
156 assert pymupdf.Matrix(1, 1).prerotate(90 + small) == pymupdf.Matrix(90)
157 assert pymupdf.Matrix(1, 1).prerotate(180 + small) == pymupdf.Matrix(180)
158 assert pymupdf.Matrix(1, 1).prerotate(270 + small) == pymupdf.Matrix(270)
159 assert pymupdf.Matrix(1, 1).prerotate(small) == pymupdf.Matrix(0)
160 assert pymupdf.Matrix(1, 1).concat(
161 pymupdf.Matrix(1, 2), pymupdf.Matrix(3, 4)
162 ) == pymupdf.Matrix(3, 0, 0, 8, 0, 0)
163 assert pymupdf.Matrix(1, 2, 3, 4, 5, 6) / 1 == pymupdf.Matrix(1, 2, 3, 4, 5, 6)
164 assert m[0] == m.a
165 assert m[1] == m.b
166 assert m[2] == m.c
167 assert m[3] == m.d
168 assert m[4] == m.e
169 assert m[5] == m.f
170 m = pymupdf.Matrix()
171 for i in range(6):
172 m[i] = i + 1
173 assert m == pymupdf.Matrix(1, 2, 3, 4, 5, 6)
174 failed = False
175 try:
176 m = pymupdf.Matrix(1, 2, 3)
177 except:
178 failed = True
179 assert failed
180 failed = False
181 try:
182 m = pymupdf.Matrix(1, 2, 3, 4, 5, 6, 7)
183 except:
184 failed = True
185 assert failed
186
187 failed = False
188 try:
189 m = pymupdf.Matrix((1, 2, 3, 4, 5, 6, 7))
190 except:
191 failed = True
192 assert failed
193
194 failed = False
195 try:
196 m = pymupdf.Matrix(1, 2, 3, 4, 5, "x")
197 except:
198 failed = True
199 assert failed
200
201 failed = False
202 try:
203 m = pymupdf.Matrix(1, 0, 1, 0, 1, 0)
204 n = pymupdf.Matrix(1, 1) / m
205 except:
206 failed = True
207 assert failed
208
209
210 def test_point():
211 assert tuple(pymupdf.Point()) == (0, 0)
212 assert pymupdf.Point(1, -1).unit == pymupdf.Point(5, -5).unit
213 assert pymupdf.Point(-1, -1).abs_unit == pymupdf.Point(1, 1).unit
214 assert pymupdf.Point(1, 1).distance_to(pymupdf.Point(1, 1)) == 0
215 assert pymupdf.Point(1, 1).distance_to(pymupdf.Rect(1, 1, 2, 2)) == 0
216 assert pymupdf.Point().distance_to((1, 1, 2, 2)) > 0
217 failed = False
218 try:
219 p = pymupdf.Point(1, 2, 3)
220 except:
221 failed = True
222 assert failed
223
224 failed = False
225 try:
226 p = pymupdf.Point((1, 2, 3))
227 except:
228 failed = True
229 assert failed
230
231 failed = False
232 try:
233 p = pymupdf.Point(1, "x")
234 except:
235 failed = True
236 assert failed
237
238 failed = False
239 try:
240 p = pymupdf.Point()
241 p[3] = 1
242 except:
243 failed = True
244 assert failed
245
246
247 def test_algebra():
248 p = pymupdf.Point(1, 2)
249 m = pymupdf.Matrix(1, 2, 3, 4, 5, 6)
250 r = pymupdf.Rect(1, 1, 2, 2)
251 assert p + p == p * 2
252 assert p - p == pymupdf.Point()
253 assert m + m == m * 2
254 assert m - m == pymupdf.Matrix()
255 assert r + r == r * 2
256 assert r - r == pymupdf.Rect()
257 assert p + 5 == pymupdf.Point(6, 7)
258 assert m + 5 == pymupdf.Matrix(6, 7, 8, 9, 10, 11)
259 assert r.tl in r
260 assert r.tr not in r
261 assert r.br not in r
262 assert r.bl not in r
263 assert p * m == pymupdf.Point(12, 16)
264 assert r * m == pymupdf.Rect(9, 12, 13, 18)
265 assert (pymupdf.Rect(1, 1, 2, 2) & pymupdf.Rect(2, 2, 3, 3)).is_empty
266 assert not pymupdf.Rect(1, 1, 2, 2).intersects((2, 2, 4, 4))
267 failed = False
268 try:
269 x = m + p
270 except:
271 failed = True
272 assert failed
273 failed = False
274 try:
275 x = m + r
276 except:
277 failed = True
278 assert failed
279 failed = False
280 try:
281 x = p + r
282 except:
283 failed = True
284 assert failed
285 failed = False
286 try:
287 x = r + m
288 except:
289 failed = True
290 assert failed
291 assert m not in r
292
293
294 def test_quad():
295 r = pymupdf.Rect(10, 10, 20, 20)
296 q = r.quad
297 assert q.is_rectangular
298 assert not q.is_empty
299 assert q.is_convex
300 q *= pymupdf.Matrix(1, 1).preshear(2, 3)
301 assert not q.is_rectangular
302 assert not q.is_empty
303 assert q.is_convex
304 assert r.tl not in q
305 assert r not in q
306 assert r.quad not in q
307 failed = False
308 try:
309 q[5] = pymupdf.Point()
310 except:
311 failed = True
312 assert failed
313
314 failed = False
315 try:
316 q /= (1, 0, 1, 0, 1, 0)
317 except:
318 failed = True
319 assert failed
320
321
322 def test_pageboxes():
323 """Tests concerning ArtBox, TrimBox, BleedBox."""
324 doc = pymupdf.open()
325 page = doc.new_page()
326 assert page.cropbox == page.artbox == page.bleedbox == page.trimbox
327 rect_methods = (
328 page.set_cropbox,
329 page.set_artbox,
330 page.set_bleedbox,
331 page.set_trimbox,
332 )
333 keys = ("CropBox", "ArtBox", "BleedBox", "TrimBox")
334 rect = pymupdf.Rect(100, 200, 400, 700)
335 for f in rect_methods:
336 f(rect)
337 for key in keys:
338 assert doc.xref_get_key(page.xref, key) == ("array", "[100 142 400 642]")
339 assert page.cropbox == page.artbox == page.bleedbox == page.trimbox
340
341 def test_3163():
342 b = {'number': 0, 'type': 0, 'bbox': (403.3577880859375, 330.8871765136719, 541.2731323242188, 349.5766296386719), 'lines': [{'spans': [{'size': 14.0, 'flags': 4, 'font': 'SFHello-Medium', 'color': 1907995, 'ascender': 1.07373046875, 'descender': -0.26123046875, 'text': 'Inclusion and diversity', 'origin': (403.3577880859375, 345.9194030761719), 'bbox': (403.3577880859375, 330.8871765136719, 541.2731323242188, 349.5766296386719)}], 'wmode': 0, 'dir': (1.0, 0.0), 'bbox': (403.3577880859375, 330.8871765136719, 541.2731323242188, 349.5766296386719)}]}
343 bbox = pymupdf.IRect(b["bbox"])
344
345 def test_3182():
346 pix = pymupdf.Pixmap(os.path.abspath(f'{__file__}/../../tests/resources/img-transparent.png'))
347 rect = pymupdf.Rect(0, 0, 100, 100)
348 pix.invert_irect(rect)