Mercurial > hgrepos > Python2 > PyMuPDF
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 %} |
