comparison src_classic/helper-geo-c.i @ 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 /*
3 # ------------------------------------------------------------------------
4 # Copyright 2020-2022, Harald Lieder, mailto:harald.lieder@outlook.com
5 # License: GNU AFFERO GPL 3.0, https://www.gnu.org/licenses/agpl-3.0.html
6 #
7 # Part of "PyMuPDF", a Python binding for "MuPDF" (http://mupdf.com), a
8 # lightweight PDF, XPS, and E-book viewer, renderer and toolkit which is
9 # maintained and developed by Artifex Software, Inc. https://artifex.com.
10 # ------------------------------------------------------------------------
11 */
12 //-----------------------------------------------------------------------------
13 // Functions converting betwenn PySequences and fitz geometry objects
14 //-----------------------------------------------------------------------------
15 static int
16 JM_INT_ITEM(PyObject *obj, Py_ssize_t idx, int *result)
17 {
18 PyObject *temp = PySequence_ITEM(obj, idx);
19 if (!temp) return 1;
20 if (PyLong_Check(temp)) {
21 *result = (int) PyLong_AsLong(temp);
22 Py_DECREF(temp);
23 } else if (PyFloat_Check(temp)) {
24 *result = (int) PyFloat_AsDouble(temp);
25 Py_DECREF(temp);
26 } else {
27 Py_DECREF(temp);
28 return 1;
29 }
30 if (PyErr_Occurred()) {
31 PyErr_Clear();
32 return 1;
33 }
34 return 0;
35 }
36
37 static int
38 JM_FLOAT_ITEM(PyObject *obj, Py_ssize_t idx, double *result)
39 {
40 PyObject *temp = PySequence_ITEM(obj, idx);
41 if (!temp) return 1;
42 *result = PyFloat_AsDouble(temp);
43 Py_DECREF(temp);
44 if (PyErr_Occurred()) {
45 PyErr_Clear();
46 return 1;
47 }
48 return 0;
49 }
50
51
52 static fz_point
53 JM_normalize_vector(float x, float y)
54 {
55 double px = x, py = y, len = (double) (x * x + y * y);
56
57 if (len != 0) {
58 len = sqrt(len);
59 px /= len;
60 py /= len;
61 }
62 return fz_make_point((float) px, (float) py);
63 }
64
65
66 //-----------------------------------------------------------------------------
67 // PySequence to fz_rect. Default: infinite rect
68 //-----------------------------------------------------------------------------
69 static fz_rect
70 JM_rect_from_py(PyObject *r)
71 {
72 if (!r || !PySequence_Check(r) || PySequence_Size(r) != 4)
73 return fz_infinite_rect;
74 Py_ssize_t i;
75 double f[4];
76
77 for (i = 0; i < 4; i++) {
78 if (JM_FLOAT_ITEM(r, i, &f[i]) == 1) return fz_infinite_rect;
79 if (f[i] < FZ_MIN_INF_RECT) f[i] = FZ_MIN_INF_RECT;
80 if (f[i] > FZ_MAX_INF_RECT) f[i] = FZ_MAX_INF_RECT;
81 }
82
83 return fz_make_rect((float) f[0], (float) f[1], (float) f[2], (float) f[3]);
84 }
85
86 //-----------------------------------------------------------------------------
87 // PySequence from fz_rect
88 //-----------------------------------------------------------------------------
89 static PyObject *
90 JM_py_from_rect(fz_rect r)
91 {
92 return Py_BuildValue("ffff", r.x0, r.y0, r.x1, r.y1);
93 }
94
95 //-----------------------------------------------------------------------------
96 // PySequence to fz_irect. Default: infinite irect
97 //-----------------------------------------------------------------------------
98 static fz_irect
99 JM_irect_from_py(PyObject *r)
100 {
101 if (!r || !PySequence_Check(r) || PySequence_Size(r) != 4)
102 return fz_infinite_irect;
103 int x[4];
104 Py_ssize_t i;
105
106 for (i = 0; i < 4; i++) {
107 if (JM_INT_ITEM(r, i, &x[i]) == 1) return fz_infinite_irect;
108 if (x[i] < FZ_MIN_INF_RECT) x[i] = FZ_MIN_INF_RECT;
109 if (x[i] > FZ_MAX_INF_RECT) x[i] = FZ_MAX_INF_RECT;
110 }
111
112 return fz_make_irect(x[0], x[1], x[2], x[3]);
113 }
114
115 //-----------------------------------------------------------------------------
116 // PySequence from fz_irect
117 //-----------------------------------------------------------------------------
118 static PyObject *
119 JM_py_from_irect(fz_irect r)
120 {
121 return Py_BuildValue("iiii", r.x0, r.y0, r.x1, r.y1);
122 }
123
124
125 //-----------------------------------------------------------------------------
126 // PySequence to fz_point. Default: (FZ_MIN_INF_RECT, FZ_MIN_INF_RECT)
127 //-----------------------------------------------------------------------------
128 static fz_point
129 JM_point_from_py(PyObject *p)
130 {
131 fz_point p0 = fz_make_point(FZ_MIN_INF_RECT, FZ_MIN_INF_RECT);
132 double x, y;
133
134 if (!p || !PySequence_Check(p) || PySequence_Size(p) != 2)
135 return p0;
136
137 if (JM_FLOAT_ITEM(p, 0, &x) == 1) return p0;
138 if (JM_FLOAT_ITEM(p, 1, &y) == 1) return p0;
139 if (x < FZ_MIN_INF_RECT) x = FZ_MIN_INF_RECT;
140 if (y < FZ_MIN_INF_RECT) y = FZ_MIN_INF_RECT;
141 if (x > FZ_MAX_INF_RECT) x = FZ_MAX_INF_RECT;
142 if (y > FZ_MAX_INF_RECT) y = FZ_MAX_INF_RECT;
143
144 return fz_make_point((float) x, (float) y);
145 }
146
147 //-----------------------------------------------------------------------------
148 // PySequence from fz_point
149 //-----------------------------------------------------------------------------
150 static PyObject *
151 JM_py_from_point(fz_point p)
152 {
153 return Py_BuildValue("ff", p.x, p.y);
154 }
155
156
157 //-----------------------------------------------------------------------------
158 // PySequence to fz_matrix. Default: fz_identity
159 //-----------------------------------------------------------------------------
160 static fz_matrix
161 JM_matrix_from_py(PyObject *m)
162 {
163 Py_ssize_t i;
164 double a[6];
165
166 if (!m || !PySequence_Check(m) || PySequence_Size(m) != 6)
167 return fz_identity;
168
169 for (i = 0; i < 6; i++)
170 if (JM_FLOAT_ITEM(m, i, &a[i]) == 1) return fz_identity;
171
172 return fz_make_matrix((float) a[0], (float) a[1], (float) a[2], (float) a[3], (float) a[4], (float) a[5]);
173 }
174
175 //-----------------------------------------------------------------------------
176 // PySequence from fz_matrix
177 //-----------------------------------------------------------------------------
178 static PyObject *
179 JM_py_from_matrix(fz_matrix m)
180 {
181 return Py_BuildValue("ffffff", m.a, m.b, m.c, m.d, m.e, m.f);
182 }
183
184 //-----------------------------------------------------------------------------
185 // fz_quad from PySequence. Four floats are treated as rect.
186 // Else must be four pairs of floats.
187 //-----------------------------------------------------------------------------
188 static fz_quad
189 JM_quad_from_py(PyObject *r)
190 {
191 fz_quad q = fz_make_quad(FZ_MIN_INF_RECT, FZ_MIN_INF_RECT,
192 FZ_MAX_INF_RECT, FZ_MIN_INF_RECT,
193 FZ_MIN_INF_RECT, FZ_MAX_INF_RECT,
194 FZ_MAX_INF_RECT, FZ_MAX_INF_RECT);
195 fz_point p[4];
196 double test, x, y;
197 Py_ssize_t i;
198 PyObject *obj = NULL;
199
200 if (!r || !PySequence_Check(r) || PySequence_Size(r) != 4)
201 return q;
202
203 if (JM_FLOAT_ITEM(r, 0, &test) == 0)
204 return fz_quad_from_rect(JM_rect_from_py(r));
205
206 for (i = 0; i < 4; i++) {
207 obj = PySequence_ITEM(r, i); // next point item
208 if (!obj || !PySequence_Check(obj) || PySequence_Size(obj) != 2)
209 goto exit_result; // invalid: cancel the rest
210
211 if (JM_FLOAT_ITEM(obj, 0, &x) == 1) goto exit_result;
212 if (JM_FLOAT_ITEM(obj, 1, &y) == 1) goto exit_result;
213 if (x < FZ_MIN_INF_RECT) x = FZ_MIN_INF_RECT;
214 if (y < FZ_MIN_INF_RECT) y = FZ_MIN_INF_RECT;
215 if (x > FZ_MAX_INF_RECT) x = FZ_MAX_INF_RECT;
216 if (y > FZ_MAX_INF_RECT) y = FZ_MAX_INF_RECT;
217 p[i] = fz_make_point((float) x, (float) y);
218
219 Py_CLEAR(obj);
220 }
221 q.ul = p[0];
222 q.ur = p[1];
223 q.ll = p[2];
224 q.lr = p[3];
225 return q;
226
227 exit_result:;
228 Py_CLEAR(obj);
229 return q;
230 }
231
232 //-----------------------------------------------------------------------------
233 // PySequence from fz_quad.
234 //-----------------------------------------------------------------------------
235 static PyObject *
236 JM_py_from_quad(fz_quad q)
237 {
238 return Py_BuildValue("((f,f),(f,f),(f,f),(f,f))",
239 q.ul.x, q.ul.y, q.ur.x, q.ur.y,
240 q.ll.x, q.ll.y, q.lr.x, q.lr.y);
241 }
242
243 %}