comparison src_classic/helper-defines.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 %inline %{
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 // general
14 //----------------------------------------------------------------------------
15 #define EPSILON 1e-5
16
17 //----------------------------------------------------------------------------
18 // annotation types
19 //----------------------------------------------------------------------------
20 #define PDF_ANNOT_TEXT 0
21 #define PDF_ANNOT_LINK 1
22 #define PDF_ANNOT_FREE_TEXT 2
23 #define PDF_ANNOT_LINE 3
24 #define PDF_ANNOT_SQUARE 4
25 #define PDF_ANNOT_CIRCLE 5
26 #define PDF_ANNOT_POLYGON 6
27 #define PDF_ANNOT_POLY_LINE 7
28 #define PDF_ANNOT_HIGHLIGHT 8
29 #define PDF_ANNOT_UNDERLINE 9
30 #define PDF_ANNOT_SQUIGGLY 10
31 #define PDF_ANNOT_STRIKE_OUT 11
32 #define PDF_ANNOT_REDACT 12
33 #define PDF_ANNOT_STAMP 13
34 #define PDF_ANNOT_CARET 14
35 #define PDF_ANNOT_INK 15
36 #define PDF_ANNOT_POPUP 16
37 #define PDF_ANNOT_FILE_ATTACHMENT 17
38 #define PDF_ANNOT_SOUND 18
39 #define PDF_ANNOT_MOVIE 19
40 #define PDF_ANNOT_RICH_MEDIA 20
41 #define PDF_ANNOT_WIDGET 21
42 #define PDF_ANNOT_SCREEN 22
43 #define PDF_ANNOT_PRINTER_MARK 23
44 #define PDF_ANNOT_TRAP_NET 24
45 #define PDF_ANNOT_WATERMARK 25
46 #define PDF_ANNOT_3D 26
47 #define PDF_ANNOT_PROJECTION 27
48 #define PDF_ANNOT_UNKNOWN -1
49
50 //------------------------
51 // redaction annot options
52 //------------------------
53 #define PDF_REDACT_IMAGE_NONE 0
54 #define PDF_REDACT_IMAGE_REMOVE 1
55 #define PDF_REDACT_IMAGE_PIXELS 2
56
57 //----------------------------------------------------------------------------
58 // annotation flag bits
59 //----------------------------------------------------------------------------
60 #define PDF_ANNOT_IS_INVISIBLE 1 << (1-1)
61 #define PDF_ANNOT_IS_HIDDEN 1 << (2-1)
62 #define PDF_ANNOT_IS_PRINT 1 << (3-1)
63 #define PDF_ANNOT_IS_NO_ZOOM 1 << (4-1)
64 #define PDF_ANNOT_IS_NO_ROTATE 1 << (5-1)
65 #define PDF_ANNOT_IS_NO_VIEW 1 << (6-1)
66 #define PDF_ANNOT_IS_READ_ONLY 1 << (7-1)
67 #define PDF_ANNOT_IS_LOCKED 1 << (8-1)
68 #define PDF_ANNOT_IS_TOGGLE_NO_VIEW 1 << (9-1)
69 #define PDF_ANNOT_IS_LOCKED_CONTENTS 1 << (10-1)
70
71
72 //----------------------------------------------------------------------------
73 // annotation line ending styles
74 //----------------------------------------------------------------------------
75 #define PDF_ANNOT_LE_NONE 0
76 #define PDF_ANNOT_LE_SQUARE 1
77 #define PDF_ANNOT_LE_CIRCLE 2
78 #define PDF_ANNOT_LE_DIAMOND 3
79 #define PDF_ANNOT_LE_OPEN_ARROW 4
80 #define PDF_ANNOT_LE_CLOSED_ARROW 5
81 #define PDF_ANNOT_LE_BUTT 6
82 #define PDF_ANNOT_LE_R_OPEN_ARROW 7
83 #define PDF_ANNOT_LE_R_CLOSED_ARROW 8
84 #define PDF_ANNOT_LE_SLASH 9
85
86
87 //----------------------------------------------------------------------------
88 // annotation field (widget) types
89 //----------------------------------------------------------------------------
90 #define PDF_WIDGET_TYPE_UNKNOWN 0
91 #define PDF_WIDGET_TYPE_BUTTON 1
92 #define PDF_WIDGET_TYPE_CHECKBOX 2
93 #define PDF_WIDGET_TYPE_COMBOBOX 3
94 #define PDF_WIDGET_TYPE_LISTBOX 4
95 #define PDF_WIDGET_TYPE_RADIOBUTTON 5
96 #define PDF_WIDGET_TYPE_SIGNATURE 6
97 #define PDF_WIDGET_TYPE_TEXT 7
98
99
100 //----------------------------------------------------------------------------
101 // annotation text widget subtypes
102 //----------------------------------------------------------------------------
103 #define PDF_WIDGET_TX_FORMAT_NONE 0
104 #define PDF_WIDGET_TX_FORMAT_NUMBER 1
105 #define PDF_WIDGET_TX_FORMAT_SPECIAL 2
106 #define PDF_WIDGET_TX_FORMAT_DATE 3
107 #define PDF_WIDGET_TX_FORMAT_TIME 4
108
109
110 //----------------------------------------------------------------------------
111 // annotation widget flags
112 //----------------------------------------------------------------------------
113 // Common to all field types
114 #define PDF_FIELD_IS_READ_ONLY 1
115 #define PDF_FIELD_IS_REQUIRED 1 << 1
116 #define PDF_FIELD_IS_NO_EXPORT 1 << 2
117
118
119 // Text fields
120 #define PDF_TX_FIELD_IS_MULTILINE 1 << 12
121 #define PDF_TX_FIELD_IS_PASSWORD 1 << 13
122 #define PDF_TX_FIELD_IS_FILE_SELECT 1 << 20
123 #define PDF_TX_FIELD_IS_DO_NOT_SPELL_CHECK 1 << 22
124 #define PDF_TX_FIELD_IS_DO_NOT_SCROLL 1 << 23
125 #define PDF_TX_FIELD_IS_COMB 1 << 24
126 #define PDF_TX_FIELD_IS_RICH_TEXT 1 << 25
127
128
129 // Button fields
130 #define PDF_BTN_FIELD_IS_NO_TOGGLE_TO_OFF 1 << 14
131 #define PDF_BTN_FIELD_IS_RADIO 1 << 15
132 #define PDF_BTN_FIELD_IS_PUSHBUTTON 1 << 16
133 #define PDF_BTN_FIELD_IS_RADIOS_IN_UNISON 1 << 25
134
135
136 // Choice fields
137 #define PDF_CH_FIELD_IS_COMBO 1 << 17
138 #define PDF_CH_FIELD_IS_EDIT 1 << 18
139 #define PDF_CH_FIELD_IS_SORT 1 << 19
140 #define PDF_CH_FIELD_IS_MULTI_SELECT 1 << 21
141 #define PDF_CH_FIELD_IS_DO_NOT_SPELL_CHECK 1 << 22
142 #define PDF_CH_FIELD_IS_COMMIT_ON_SEL_CHANGE 1 << 25
143
144
145 // Signature fields errors
146 #define PDF_SIGNATURE_ERROR_OKAY 0
147 #define PDF_SIGNATURE_ERROR_NO_SIGNATURES 1
148 #define PDF_SIGNATURE_ERROR_NO_CERTIFICATE 2
149 #define PDF_SIGNATURE_ERROR_DIGEST_FAILURE 3
150 #define PDF_SIGNATURE_ERROR_SELF_SIGNED 4
151 #define PDF_SIGNATURE_ERROR_SELF_SIGNED_IN_CHAIN 5
152 #define PDF_SIGNATURE_ERROR_NOT_TRUSTED 6
153 #define PDF_SIGNATURE_ERROR_UNKNOWN 7
154
155 // Signature appearances
156
157 #define PDF_SIGNATURE_SHOW_LABELS 1
158 #define PDF_SIGNATURE_SHOW_DN 2
159 #define PDF_SIGNATURE_SHOW_DATE 4
160 #define PDF_SIGNATURE_SHOW_TEXT_NAME 8
161 #define PDF_SIGNATURE_SHOW_GRAPHIC_NAME 16
162 #define PDF_SIGNATURE_SHOW_LOGO 32
163 #define PDF_SIGNATURE_DEFAULT_APPEARANCE ( \
164 PDF_SIGNATURE_SHOW_LABELS | \
165 PDF_SIGNATURE_SHOW_DN | \
166 PDF_SIGNATURE_SHOW_DATE | \
167 PDF_SIGNATURE_SHOW_TEXT_NAME | \
168 PDF_SIGNATURE_SHOW_GRAPHIC_NAME | \
169 PDF_SIGNATURE_SHOW_LOGO )
170
171 //----------------------------------------------------------------------------
172 // colorspace identifiers
173 //----------------------------------------------------------------------------
174 #define CS_RGB 1
175 #define CS_GRAY 2
176 #define CS_CMYK 3
177
178 //----------------------------------------------------------------------------
179 // PDF encryption algorithms
180 //----------------------------------------------------------------------------
181 #define PDF_ENCRYPT_KEEP 0
182 #define PDF_ENCRYPT_NONE 1
183 #define PDF_ENCRYPT_RC4_40 2
184 #define PDF_ENCRYPT_RC4_128 3
185 #define PDF_ENCRYPT_AES_128 4
186 #define PDF_ENCRYPT_AES_256 5
187 #define PDF_ENCRYPT_UNKNOWN 6
188
189 //----------------------------------------------------------------------------
190 // PDF permission codes
191 //----------------------------------------------------------------------------
192 #define PDF_PERM_PRINT 1 << 2
193 #define PDF_PERM_MODIFY 1 << 3
194 #define PDF_PERM_COPY 1 << 4
195 #define PDF_PERM_ANNOTATE 1 << 5
196 #define PDF_PERM_FORM 1 << 8
197 #define PDF_PERM_ACCESSIBILITY 1 << 9
198 #define PDF_PERM_ASSEMBLE 1 << 10
199 #define PDF_PERM_PRINT_HQ 1 << 11
200
201 //----------------------------------------------------------------------------
202 // PDF Blend Modes
203 //----------------------------------------------------------------------------
204 #define PDF_BM_Color "Color"
205 #define PDF_BM_ColorBurn "ColorBurn"
206 #define PDF_BM_ColorDodge "ColorDodge"
207 #define PDF_BM_Darken "Darken"
208 #define PDF_BM_Difference "Difference"
209 #define PDF_BM_Exclusion "Exclusion"
210 #define PDF_BM_HardLight "HardLight"
211 #define PDF_BM_Hue "Hue"
212 #define PDF_BM_Lighten "Lighten"
213 #define PDF_BM_Luminosity "Luminosity"
214 #define PDF_BM_Multiply "Multiply"
215 #define PDF_BM_Normal "Normal"
216 #define PDF_BM_Overlay "Overlay"
217 #define PDF_BM_Saturation "Saturation"
218 #define PDF_BM_Screen "Screen"
219 #define PDF_BM_SoftLight "Softlight"
220
221
222 // General text flags
223 #define TEXT_FONT_SUPERSCRIPT 1
224 #define TEXT_FONT_ITALIC 2
225 #define TEXT_FONT_SERIFED 4
226 #define TEXT_FONT_MONOSPACED 8
227 #define TEXT_FONT_BOLD 16
228
229 // UCDN Script codes
230 #define UCDN_SCRIPT_COMMON 0
231 #define UCDN_SCRIPT_LATIN 1
232 #define UCDN_SCRIPT_GREEK 2
233 #define UCDN_SCRIPT_CYRILLIC 3
234 #define UCDN_SCRIPT_ARMENIAN 4
235 #define UCDN_SCRIPT_HEBREW 5
236 #define UCDN_SCRIPT_ARABIC 6
237 #define UCDN_SCRIPT_SYRIAC 7
238 #define UCDN_SCRIPT_THAANA 8
239 #define UCDN_SCRIPT_DEVANAGARI 9
240 #define UCDN_SCRIPT_BENGALI 10
241 #define UCDN_SCRIPT_GURMUKHI 11
242 #define UCDN_SCRIPT_GUJARATI 12
243 #define UCDN_SCRIPT_ORIYA 13
244 #define UCDN_SCRIPT_TAMIL 14
245 #define UCDN_SCRIPT_TELUGU 15
246 #define UCDN_SCRIPT_KANNADA 16
247 #define UCDN_SCRIPT_MALAYALAM 17
248 #define UCDN_SCRIPT_SINHALA 18
249 #define UCDN_SCRIPT_THAI 19
250 #define UCDN_SCRIPT_LAO 20
251 #define UCDN_SCRIPT_TIBETAN 21
252 #define UCDN_SCRIPT_MYANMAR 22
253 #define UCDN_SCRIPT_GEORGIAN 23
254 #define UCDN_SCRIPT_HANGUL 24
255 #define UCDN_SCRIPT_ETHIOPIC 25
256 #define UCDN_SCRIPT_CHEROKEE 26
257 #define UCDN_SCRIPT_CANADIAN_ABORIGINAL 27
258 #define UCDN_SCRIPT_OGHAM 28
259 #define UCDN_SCRIPT_RUNIC 29
260 #define UCDN_SCRIPT_KHMER 30
261 #define UCDN_SCRIPT_MONGOLIAN 31
262 #define UCDN_SCRIPT_HIRAGANA 32
263 #define UCDN_SCRIPT_KATAKANA 33
264 #define UCDN_SCRIPT_BOPOMOFO 34
265 #define UCDN_SCRIPT_HAN 35
266 #define UCDN_SCRIPT_YI 36
267 #define UCDN_SCRIPT_OLD_ITALIC 37
268 #define UCDN_SCRIPT_GOTHIC 38
269 #define UCDN_SCRIPT_DESERET 39
270 #define UCDN_SCRIPT_INHERITED 40
271 #define UCDN_SCRIPT_TAGALOG 41
272 #define UCDN_SCRIPT_HANUNOO 42
273 #define UCDN_SCRIPT_BUHID 43
274 #define UCDN_SCRIPT_TAGBANWA 44
275 #define UCDN_SCRIPT_LIMBU 45
276 #define UCDN_SCRIPT_TAI_LE 46
277 #define UCDN_SCRIPT_LINEAR_B 47
278 #define UCDN_SCRIPT_UGARITIC 48
279 #define UCDN_SCRIPT_SHAVIAN 49
280 #define UCDN_SCRIPT_OSMANYA 50
281 #define UCDN_SCRIPT_CYPRIOT 51
282 #define UCDN_SCRIPT_BRAILLE 52
283 #define UCDN_SCRIPT_BUGINESE 53
284 #define UCDN_SCRIPT_COPTIC 54
285 #define UCDN_SCRIPT_NEW_TAI_LUE 55
286 #define UCDN_SCRIPT_GLAGOLITIC 56
287 #define UCDN_SCRIPT_TIFINAGH 57
288 #define UCDN_SCRIPT_SYLOTI_NAGRI 58
289 #define UCDN_SCRIPT_OLD_PERSIAN 59
290 #define UCDN_SCRIPT_KHAROSHTHI 60
291 #define UCDN_SCRIPT_BALINESE 61
292 #define UCDN_SCRIPT_CUNEIFORM 62
293 #define UCDN_SCRIPT_PHOENICIAN 63
294 #define UCDN_SCRIPT_PHAGS_PA 64
295 #define UCDN_SCRIPT_NKO 65
296 #define UCDN_SCRIPT_SUNDANESE 66
297 #define UCDN_SCRIPT_LEPCHA 67
298 #define UCDN_SCRIPT_OL_CHIKI 68
299 #define UCDN_SCRIPT_VAI 69
300 #define UCDN_SCRIPT_SAURASHTRA 70
301 #define UCDN_SCRIPT_KAYAH_LI 71
302 #define UCDN_SCRIPT_REJANG 72
303 #define UCDN_SCRIPT_LYCIAN 73
304 #define UCDN_SCRIPT_CARIAN 74
305 #define UCDN_SCRIPT_LYDIAN 75
306 #define UCDN_SCRIPT_CHAM 76
307 #define UCDN_SCRIPT_TAI_THAM 77
308 #define UCDN_SCRIPT_TAI_VIET 78
309 #define UCDN_SCRIPT_AVESTAN 79
310 #define UCDN_SCRIPT_EGYPTIAN_HIEROGLYPHS 80
311 #define UCDN_SCRIPT_SAMARITAN 81
312 #define UCDN_SCRIPT_LISU 82
313 #define UCDN_SCRIPT_BAMUM 83
314 #define UCDN_SCRIPT_JAVANESE 84
315 #define UCDN_SCRIPT_MEETEI_MAYEK 85
316 #define UCDN_SCRIPT_IMPERIAL_ARAMAIC 86
317 #define UCDN_SCRIPT_OLD_SOUTH_ARABIAN 87
318 #define UCDN_SCRIPT_INSCRIPTIONAL_PARTHIAN 88
319 #define UCDN_SCRIPT_INSCRIPTIONAL_PAHLAVI 89
320 #define UCDN_SCRIPT_OLD_TURKIC 90
321 #define UCDN_SCRIPT_KAITHI 91
322 #define UCDN_SCRIPT_BATAK 92
323 #define UCDN_SCRIPT_BRAHMI 93
324 #define UCDN_SCRIPT_MANDAIC 94
325 #define UCDN_SCRIPT_CHAKMA 95
326 #define UCDN_SCRIPT_MEROITIC_CURSIVE 96
327 #define UCDN_SCRIPT_MEROITIC_HIEROGLYPHS 97
328 #define UCDN_SCRIPT_MIAO 98
329 #define UCDN_SCRIPT_SHARADA 99
330 #define UCDN_SCRIPT_SORA_SOMPENG 100
331 #define UCDN_SCRIPT_TAKRI 101
332 #define UCDN_SCRIPT_UNKNOWN 102
333 #define UCDN_SCRIPT_BASSA_VAH 103
334 #define UCDN_SCRIPT_CAUCASIAN_ALBANIAN 104
335 #define UCDN_SCRIPT_DUPLOYAN 105
336 #define UCDN_SCRIPT_ELBASAN 106
337 #define UCDN_SCRIPT_GRANTHA 107
338 #define UCDN_SCRIPT_KHOJKI 108
339 #define UCDN_SCRIPT_KHUDAWADI 109
340 #define UCDN_SCRIPT_LINEAR_A 110
341 #define UCDN_SCRIPT_MAHAJANI 111
342 #define UCDN_SCRIPT_MANICHAEAN 112
343 #define UCDN_SCRIPT_MENDE_KIKAKUI 113
344 #define UCDN_SCRIPT_MODI 114
345 #define UCDN_SCRIPT_MRO 115
346 #define UCDN_SCRIPT_NABATAEAN 116
347 #define UCDN_SCRIPT_OLD_NORTH_ARABIAN 117
348 #define UCDN_SCRIPT_OLD_PERMIC 118
349 #define UCDN_SCRIPT_PAHAWH_HMONG 119
350 #define UCDN_SCRIPT_PALMYRENE 120
351 #define UCDN_SCRIPT_PAU_CIN_HAU 121
352 #define UCDN_SCRIPT_PSALTER_PAHLAVI 122
353 #define UCDN_SCRIPT_SIDDHAM 123
354 #define UCDN_SCRIPT_TIRHUTA 124
355 #define UCDN_SCRIPT_WARANG_CITI 125
356 #define UCDN_SCRIPT_AHOM 126
357 #define UCDN_SCRIPT_ANATOLIAN_HIEROGLYPHS 127
358 #define UCDN_SCRIPT_HATRAN 128
359 #define UCDN_SCRIPT_MULTANI 129
360 #define UCDN_SCRIPT_OLD_HUNGARIAN 130
361 #define UCDN_SCRIPT_SIGNWRITING 131
362 #define UCDN_SCRIPT_ADLAM 132
363 #define UCDN_SCRIPT_BHAIKSUKI 133
364 #define UCDN_SCRIPT_MARCHEN 134
365 #define UCDN_SCRIPT_NEWA 135
366 #define UCDN_SCRIPT_OSAGE 136
367 #define UCDN_SCRIPT_TANGUT 137
368 #define UCDN_SCRIPT_MASARAM_GONDI 138
369 #define UCDN_SCRIPT_NUSHU 139
370 #define UCDN_SCRIPT_SOYOMBO 140
371 #define UCDN_SCRIPT_ZANABAZAR_SQUARE 141
372 #define UCDN_SCRIPT_DOGRA 142
373 #define UCDN_SCRIPT_GUNJALA_GONDI 143
374 #define UCDN_SCRIPT_HANIFI_ROHINGYA 144
375 #define UCDN_SCRIPT_MAKASAR 145
376 #define UCDN_SCRIPT_MEDEFAIDRIN 146
377 #define UCDN_SCRIPT_OLD_SOGDIAN 147
378 #define UCDN_SCRIPT_SOGDIAN 148
379 #define UCDN_SCRIPT_ELYMAIC 149
380 #define UCDN_SCRIPT_NANDINAGARI 150
381 #define UCDN_SCRIPT_NYIAKENG_PUACHUE_HMONG 151
382 #define UCDN_SCRIPT_WANCHO 152
383
384
385 // exceptions
386 PyObject *_set_FileDataError(PyObject *value)
387 {
388 if (!value) {
389 Py_RETURN_FALSE;
390 }
391 JM_Exc_FileDataError = value;
392 Py_RETURN_TRUE;
393 }
394
395 //-------------------------------------------------------------------
396 // minor tools
397 //-------------------------------------------------------------------
398 PyObject *util_sine_between(PyObject *C, PyObject *P, PyObject *Q)
399 {
400 // for points C, P, Q compute the sine between lines CP and QP
401 fz_point c = JM_point_from_py(C);
402 fz_point p = JM_point_from_py(P);
403 fz_point q = JM_point_from_py(Q);
404 fz_point s = JM_normalize_vector(q.x - p.x, q.y - p.y);
405 fz_matrix m1 = fz_make_matrix(1, 0, 0, 1, -p.x, -p.y);
406 fz_matrix m2 = fz_make_matrix(s.x, -s.y, s.y, s.x, 0, 0);
407 m1 = fz_concat(m1, m2);
408 c = fz_transform_point(c, m1);
409 c = JM_normalize_vector(c.x, c.y);
410 return Py_BuildValue("f", c.y);
411 }
412
413
414 // Return the matrix that maps two points C, P to the x-axis such that
415 // C -> (0,0) and the image of P have the same distance.
416 PyObject *util_hor_matrix(PyObject *C, PyObject *P)
417 {
418 fz_point c = JM_point_from_py(C);
419 fz_point p = JM_point_from_py(P);
420
421 // compute (cosine, sine) of vector P-C with double precision:
422 fz_point s = JM_normalize_vector(p.x - c.x, p.y - c.y);
423
424 fz_matrix m1 = fz_make_matrix(1, 0, 0, 1, -c.x, -c.y);
425 fz_matrix m2 = fz_make_matrix(s.x, -s.y, s.y, s.x, 0, 0);
426 return JM_py_from_matrix(fz_concat(m1, m2));
427 }
428
429 struct Annot;
430
431 // Ensure that widgets with /AA/C JavaScript are in array AcroForm/CO
432 struct Annot;
433 PyObject *util_ensure_widget_calc(struct Annot *annot)
434 {
435 pdf_obj *PDFNAME_CO=NULL;
436 fz_try(gctx) {
437 pdf_obj *annot_obj = pdf_annot_obj(gctx, (pdf_annot *) annot);
438 pdf_document *pdf = pdf_get_bound_document(gctx, annot_obj);
439 PDFNAME_CO = pdf_new_name(gctx, "CO"); // = PDF_NAME(CO)
440 pdf_obj *acro = pdf_dict_getl(gctx, // get AcroForm dict
441 pdf_trailer(gctx, pdf),
442 PDF_NAME(Root),
443 PDF_NAME(AcroForm),
444 NULL);
445
446 pdf_obj *CO = pdf_dict_get(gctx, acro, PDFNAME_CO); // = AcroForm/CO
447 if (!CO) {
448 CO = pdf_dict_put_array(gctx, acro, PDFNAME_CO, 2);
449 }
450 int i, n = pdf_array_len(gctx, CO);
451 int xref, nxref, found = 0;
452 xref = pdf_to_num(gctx, annot_obj);
453 for (i = 0; i < n; i++) {
454 nxref = pdf_to_num(gctx, pdf_array_get(gctx, CO, i));
455 if (xref == nxref) {
456 found = 1;
457 break;
458 }
459 }
460 if (!found) {
461 pdf_array_push_drop(gctx, CO, pdf_new_indirect(gctx, pdf, xref, 0));
462 }
463 }
464 fz_always(gctx) {
465 pdf_drop_obj(gctx, PDFNAME_CO);
466 }
467 fz_catch(gctx) {
468 PyErr_SetString(PyExc_RuntimeError, fz_caught_message(gctx));
469 return NULL;
470 }
471 Py_RETURN_NONE;
472 }
473
474
475 //-----------------------------------------------------------
476 // Compute Rect coordinates using different alternatives
477 //-----------------------------------------------------------
478 PyObject *util_make_rect(PyObject *a)
479 {
480 Py_ssize_t i, n = PyTuple_GET_SIZE(a);
481 PyObject *p1, *p2, *l = a;
482 char *msg = "Rect: bad args";
483 double c[4] = { 0, 0, 0, 0 };
484 switch (n) {
485 case 0: goto exit_normal;
486 case 1: goto size1;
487 case 2: goto size2;
488 case 3: goto size31;
489 case 4: goto size4;
490 default:
491 msg = "Rect: bad seq len";
492 goto exit_error;
493 }
494
495 size4:;
496 for (i = 0; i < 4; i++) {
497 if (JM_FLOAT_ITEM(l, i, &c[i]) == 1) {
498 goto exit_error;
499 }
500 }
501 goto exit_normal;
502
503 size1:;
504 l = PyTuple_GET_ITEM(a, 0);
505 if (!PySequence_Check(l) || PySequence_Size(l) != 4) {
506 msg = "Rect: bad seq len";
507 goto exit_error;
508 }
509 goto size4;
510
511 size2:;
512 msg = "Rect: bad args";
513 p1 = PyTuple_GET_ITEM(a, 0);
514 p2 = PyTuple_GET_ITEM(a, 1);
515 if (!PySequence_Check(p1) || PySequence_Size(p1) != 2) {
516 goto exit_error;
517 }
518 if (!PySequence_Check(p2) || PySequence_Size(p2) != 2) {
519 goto exit_error;
520 }
521 if (JM_FLOAT_ITEM(p1, 0, &c[0]) == 1) goto exit_error;
522 if (JM_FLOAT_ITEM(p1, 1, &c[1]) == 1) goto exit_error;
523 if (JM_FLOAT_ITEM(p2, 0, &c[2]) == 1) goto exit_error;
524 if (JM_FLOAT_ITEM(p2, 1, &c[3]) == 1) goto exit_error;
525 goto exit_normal;
526
527 size31:;
528 p1 = PyTuple_GET_ITEM(a, 0);
529 if (PySequence_Check(p1)) goto size32;
530 if (JM_FLOAT_ITEM(a, 0, &c[0]) == 1) goto exit_error;
531 if (JM_FLOAT_ITEM(a, 1, &c[1]) == 1) goto exit_error;
532 p2 = PyTuple_GET_ITEM(a, 2);
533 if (!PySequence_Check(p2) || PySequence_Size(p2) != 2) {
534 goto exit_error;
535 }
536 if (JM_FLOAT_ITEM(p2, 0, &c[2]) == 1) goto exit_error;
537 if (JM_FLOAT_ITEM(p2, 1, &c[3]) == 1) goto exit_error;
538 goto exit_normal;
539
540 size32:;
541 if (PySequence_Size(p1) != 2) goto exit_error;
542 if (JM_FLOAT_ITEM(p1, 0, &c[0]) == 1) goto exit_error;
543 if (JM_FLOAT_ITEM(p1, 1, &c[1]) == 1) goto exit_error;
544 if (JM_FLOAT_ITEM(a, 1, &c[2]) == 1) goto exit_error;
545 if (JM_FLOAT_ITEM(a, 2, &c[3]) == 1) goto exit_error;
546 goto exit_normal;
547
548 exit_normal:;
549 for (i = 0; i < 4; i++) {
550 if (c[i] < FZ_MIN_INF_RECT) c[i] = FZ_MIN_INF_RECT;
551 if (c[i] > FZ_MAX_INF_RECT) c[i] = FZ_MAX_INF_RECT;
552 }
553 return Py_BuildValue("dddd", c[0], c[1], c[2], c[3]);
554
555 exit_error:;
556 PyErr_SetString(PyExc_ValueError, msg);
557 return NULL;
558 }
559
560
561 //-----------------------------------------------------------
562 // Compute IRect coordinates using different alternatives
563 //-----------------------------------------------------------
564 PyObject *util_make_irect(PyObject *a)
565 {
566 Py_ssize_t i, n = PyTuple_GET_SIZE(a);
567 PyObject *p1, *p2, *l = a;
568 char *msg = "IRect: bad args";
569 int c[4] = { 0, 0, 0, 0 };
570 switch (n) {
571 case 0: goto exit_normal;
572 case 1: goto size1;
573 case 2: goto size2;
574 case 3: goto size31;
575 case 4: goto size4;
576 default:
577 msg = "IRect: bad seq len";
578 goto exit_error;
579 }
580
581 size4:;
582 for (i = 0; i < 4; i++) {
583 if (JM_INT_ITEM(l, i, &c[i]) == 1) {
584 goto exit_error;
585 }
586 }
587 goto exit_normal;
588
589 size1:;
590 l = PyTuple_GET_ITEM(a, 0);
591 if (!PySequence_Check(l) || PySequence_Size(l) != 4) {
592 msg = "IRect: bad seq len";
593 goto exit_error;
594 }
595 goto size4;
596
597 size2:;
598 p1 = PyTuple_GET_ITEM(a, 0);
599 p2 = PyTuple_GET_ITEM(a, 1);
600 if (!PySequence_Check(p1) || PySequence_Size(p1) != 2) {
601 goto exit_error;
602 }
603 if (!PySequence_Check(p2) || PySequence_Size(p2) != 2) {
604 goto exit_error;
605 }
606 msg = "IRect: bad int values";
607 if (JM_INT_ITEM(p1, 0, &c[0]) == 1) goto exit_error;
608 if (JM_INT_ITEM(p1, 1, &c[1]) == 1) goto exit_error;
609 if (JM_INT_ITEM(p2, 0, &c[2]) == 1) goto exit_error;
610 if (JM_INT_ITEM(p2, 1, &c[3]) == 1) goto exit_error;
611 goto exit_normal;
612
613 size31:;
614 p1 = PyTuple_GET_ITEM(a, 0);
615 if (PySequence_Check(p1)) goto size32;
616 if (JM_INT_ITEM(a, 0, &c[0]) == 1) goto exit_error;
617 if (JM_INT_ITEM(a, 1, &c[1]) == 1) goto exit_error;
618 p2 = PyTuple_GET_ITEM(a, 2);
619 if (!PySequence_Check(p2) || PySequence_Size(p2) != 2) {
620 goto exit_error;
621 }
622 if (JM_INT_ITEM(p2, 0, &c[2]) == 1) goto exit_error;
623 if (JM_INT_ITEM(p2, 1, &c[3]) == 1) goto exit_error;
624 goto exit_normal;
625
626 size32:;
627 if (PySequence_Size(p1) != 2) goto exit_error;
628 if (JM_INT_ITEM(p1, 0, &c[0]) == 1) goto exit_error;
629 if (JM_INT_ITEM(p1, 1, &c[1]) == 1) goto exit_error;
630 if (JM_INT_ITEM(a, 1, &c[2]) == 1) goto exit_error;
631 if (JM_INT_ITEM(a, 2, &c[3]) == 1) goto exit_error;
632 goto exit_normal;
633
634 exit_normal:;
635 for (i = 0; i < 4; i++) {
636 if (c[i] < FZ_MIN_INF_RECT) c[i] = FZ_MIN_INF_RECT;
637 if (c[i] > FZ_MAX_INF_RECT) c[i] = FZ_MAX_INF_RECT;
638 }
639 return Py_BuildValue("iiii", c[0], c[1], c[2], c[3]);
640
641 exit_error:;
642 PyErr_SetString(PyExc_ValueError, msg);
643 return NULL;
644 }
645
646
647 PyObject *util_round_rect(PyObject *rect)
648 {
649 return JM_py_from_irect(fz_round_rect(JM_rect_from_py(rect)));
650 }
651
652
653 PyObject *util_transform_rect(PyObject *rect, PyObject *matrix)
654 {
655 return JM_py_from_rect(fz_transform_rect(JM_rect_from_py(rect), JM_matrix_from_py(matrix)));
656 }
657
658
659 PyObject *util_intersect_rect(PyObject *r1, PyObject *r2)
660 {
661 return JM_py_from_rect(fz_intersect_rect(JM_rect_from_py(r1),
662 JM_rect_from_py(r2)));
663 }
664
665
666 PyObject *util_is_point_in_rect(PyObject *p, PyObject *r)
667 {
668 return JM_BOOL(fz_is_point_inside_rect(JM_point_from_py(p), JM_rect_from_py(r)));
669 }
670
671
672 PyObject *util_include_point_in_rect(PyObject *r, PyObject *p)
673 {
674 return JM_py_from_rect(fz_include_point_in_rect(JM_rect_from_py(r),
675 JM_point_from_py(p)));
676 }
677
678
679 PyObject *util_point_in_quad(PyObject *P, PyObject *Q)
680 {
681 fz_point p = JM_point_from_py(P);
682 fz_quad q = JM_quad_from_py(Q);
683 return JM_BOOL(fz_is_point_inside_quad(p, q));
684 }
685
686
687 PyObject *util_transform_point(PyObject *point, PyObject *matrix)
688 {
689 return JM_py_from_point(fz_transform_point(JM_point_from_py(point), JM_matrix_from_py(matrix)));
690 }
691
692
693 PyObject *util_union_rect(PyObject *r1, PyObject *r2)
694 {
695 return JM_py_from_rect(fz_union_rect(JM_rect_from_py(r1),
696 JM_rect_from_py(r2)));
697 }
698
699
700 PyObject *util_concat_matrix(PyObject *m1, PyObject *m2)
701 {
702 return JM_py_from_matrix(fz_concat(JM_matrix_from_py(m1),
703 JM_matrix_from_py(m2)));
704 }
705
706
707 PyObject *util_invert_matrix(PyObject *matrix)
708 {
709 fz_matrix src = JM_matrix_from_py(matrix);
710 float a = src.a;
711 float det = a * src.d - src.b * src.c;
712 if (det < -FLT_EPSILON || det > FLT_EPSILON)
713 {
714 fz_matrix dst;
715 float rdet = 1 / det;
716 dst.a = src.d * rdet;
717 dst.b = -src.b * rdet;
718 dst.c = -src.c * rdet;
719 dst.d = a * rdet;
720 a = -src.e * dst.a - src.f * dst.c;
721 dst.f = -src.e * dst.b - src.f * dst.d;
722 dst.e = a;
723 return Py_BuildValue("iN", 0, JM_py_from_matrix(dst));
724 }
725 return Py_BuildValue("(i, ())", 1);
726 }
727
728
729 PyObject *util_measure_string(const char *text, const char *fontname, double fontsize, int encoding)
730 {
731 double w = 0;
732 fz_font *font = NULL;
733 fz_try(gctx) {
734 font = fz_new_base14_font(gctx, fontname);
735 while (*text)
736 {
737 int c, g;
738 text += fz_chartorune(&c, text);
739 switch (encoding)
740 {
741 case PDF_SIMPLE_ENCODING_GREEK:
742 c = fz_iso8859_7_from_unicode(c); break;
743 case PDF_SIMPLE_ENCODING_CYRILLIC:
744 c = fz_windows_1251_from_unicode(c); break;
745 default:
746 c = fz_windows_1252_from_unicode(c); break;
747 }
748 if (c < 0) c = 0xB7;
749 g = fz_encode_character(gctx, font, c);
750 w += (double) fz_advance_glyph(gctx, font, g, 0);
751 }
752 }
753 fz_always(gctx) {
754 fz_drop_font(gctx, font);
755 }
756 fz_catch(gctx) {
757 return PyFloat_FromDouble(0);
758 }
759 return PyFloat_FromDouble(w * fontsize);
760 }
761
762 %}
763
764 %{
765 // Global Constants - Python dictionary keys
766 PyObject *dictkey_align;
767 PyObject *dictkey_ascender;
768 PyObject *dictkey_bbox;
769 PyObject *dictkey_blocks;
770 PyObject *dictkey_bpc;
771 PyObject *dictkey_c;
772 PyObject *dictkey_chars;
773 PyObject *dictkey_color;
774 PyObject *dictkey_colorspace;
775 PyObject *dictkey_content;
776 PyObject *dictkey_creationDate;
777 PyObject *dictkey_cs_name;
778 PyObject *dictkey_da;
779 PyObject *dictkey_dashes;
780 PyObject *dictkey_desc;
781 PyObject *dictkey_descender;
782 PyObject *dictkey_dir;
783 PyObject *dictkey_effect;
784 PyObject *dictkey_ext;
785 PyObject *dictkey_filename;
786 PyObject *dictkey_fill;
787 PyObject *dictkey_flags;
788 PyObject *dictkey_font;
789 PyObject *dictkey_glyph;
790 PyObject *dictkey_height;
791 PyObject *dictkey_id;
792 PyObject *dictkey_image;
793 PyObject *dictkey_items;
794 PyObject *dictkey_length;
795 PyObject *dictkey_lines;
796 PyObject *dictkey_matrix;
797 PyObject *dictkey_modDate;
798 PyObject *dictkey_name;
799 PyObject *dictkey_number;
800 PyObject *dictkey_origin;
801 PyObject *dictkey_rect;
802 PyObject *dictkey_size;
803 PyObject *dictkey_smask;
804 PyObject *dictkey_spans;
805 PyObject *dictkey_stroke;
806 PyObject *dictkey_style;
807 PyObject *dictkey_subject;
808 PyObject *dictkey_text;
809 PyObject *dictkey_title;
810 PyObject *dictkey_type;
811 PyObject *dictkey_ufilename;
812 PyObject *dictkey_width;
813 PyObject *dictkey_wmode;
814 PyObject *dictkey_xref;
815 PyObject *dictkey_xres;
816 PyObject *dictkey_yres;
817 %}