Mercurial > hgrepos > Python2 > PyMuPDF
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src_classic/helper-defines.i Mon Sep 15 11:37:51 2025 +0200 @@ -0,0 +1,817 @@ +%inline %{ +/* +# ------------------------------------------------------------------------ +# Copyright 2020-2022, Harald Lieder, mailto:harald.lieder@outlook.com +# License: GNU AFFERO GPL 3.0, https://www.gnu.org/licenses/agpl-3.0.html +# +# Part of "PyMuPDF", a Python binding for "MuPDF" (http://mupdf.com), a +# lightweight PDF, XPS, and E-book viewer, renderer and toolkit which is +# maintained and developed by Artifex Software, Inc. https://artifex.com. +# ------------------------------------------------------------------------ +*/ +//---------------------------------------------------------------------------- +// general +//---------------------------------------------------------------------------- +#define EPSILON 1e-5 + +//---------------------------------------------------------------------------- +// annotation types +//---------------------------------------------------------------------------- +#define PDF_ANNOT_TEXT 0 +#define PDF_ANNOT_LINK 1 +#define PDF_ANNOT_FREE_TEXT 2 +#define PDF_ANNOT_LINE 3 +#define PDF_ANNOT_SQUARE 4 +#define PDF_ANNOT_CIRCLE 5 +#define PDF_ANNOT_POLYGON 6 +#define PDF_ANNOT_POLY_LINE 7 +#define PDF_ANNOT_HIGHLIGHT 8 +#define PDF_ANNOT_UNDERLINE 9 +#define PDF_ANNOT_SQUIGGLY 10 +#define PDF_ANNOT_STRIKE_OUT 11 +#define PDF_ANNOT_REDACT 12 +#define PDF_ANNOT_STAMP 13 +#define PDF_ANNOT_CARET 14 +#define PDF_ANNOT_INK 15 +#define PDF_ANNOT_POPUP 16 +#define PDF_ANNOT_FILE_ATTACHMENT 17 +#define PDF_ANNOT_SOUND 18 +#define PDF_ANNOT_MOVIE 19 +#define PDF_ANNOT_RICH_MEDIA 20 +#define PDF_ANNOT_WIDGET 21 +#define PDF_ANNOT_SCREEN 22 +#define PDF_ANNOT_PRINTER_MARK 23 +#define PDF_ANNOT_TRAP_NET 24 +#define PDF_ANNOT_WATERMARK 25 +#define PDF_ANNOT_3D 26 +#define PDF_ANNOT_PROJECTION 27 +#define PDF_ANNOT_UNKNOWN -1 + +//------------------------ +// redaction annot options +//------------------------ +#define PDF_REDACT_IMAGE_NONE 0 +#define PDF_REDACT_IMAGE_REMOVE 1 +#define PDF_REDACT_IMAGE_PIXELS 2 + +//---------------------------------------------------------------------------- +// annotation flag bits +//---------------------------------------------------------------------------- +#define PDF_ANNOT_IS_INVISIBLE 1 << (1-1) +#define PDF_ANNOT_IS_HIDDEN 1 << (2-1) +#define PDF_ANNOT_IS_PRINT 1 << (3-1) +#define PDF_ANNOT_IS_NO_ZOOM 1 << (4-1) +#define PDF_ANNOT_IS_NO_ROTATE 1 << (5-1) +#define PDF_ANNOT_IS_NO_VIEW 1 << (6-1) +#define PDF_ANNOT_IS_READ_ONLY 1 << (7-1) +#define PDF_ANNOT_IS_LOCKED 1 << (8-1) +#define PDF_ANNOT_IS_TOGGLE_NO_VIEW 1 << (9-1) +#define PDF_ANNOT_IS_LOCKED_CONTENTS 1 << (10-1) + + +//---------------------------------------------------------------------------- +// annotation line ending styles +//---------------------------------------------------------------------------- +#define PDF_ANNOT_LE_NONE 0 +#define PDF_ANNOT_LE_SQUARE 1 +#define PDF_ANNOT_LE_CIRCLE 2 +#define PDF_ANNOT_LE_DIAMOND 3 +#define PDF_ANNOT_LE_OPEN_ARROW 4 +#define PDF_ANNOT_LE_CLOSED_ARROW 5 +#define PDF_ANNOT_LE_BUTT 6 +#define PDF_ANNOT_LE_R_OPEN_ARROW 7 +#define PDF_ANNOT_LE_R_CLOSED_ARROW 8 +#define PDF_ANNOT_LE_SLASH 9 + + +//---------------------------------------------------------------------------- +// annotation field (widget) types +//---------------------------------------------------------------------------- +#define PDF_WIDGET_TYPE_UNKNOWN 0 +#define PDF_WIDGET_TYPE_BUTTON 1 +#define PDF_WIDGET_TYPE_CHECKBOX 2 +#define PDF_WIDGET_TYPE_COMBOBOX 3 +#define PDF_WIDGET_TYPE_LISTBOX 4 +#define PDF_WIDGET_TYPE_RADIOBUTTON 5 +#define PDF_WIDGET_TYPE_SIGNATURE 6 +#define PDF_WIDGET_TYPE_TEXT 7 + + +//---------------------------------------------------------------------------- +// annotation text widget subtypes +//---------------------------------------------------------------------------- +#define PDF_WIDGET_TX_FORMAT_NONE 0 +#define PDF_WIDGET_TX_FORMAT_NUMBER 1 +#define PDF_WIDGET_TX_FORMAT_SPECIAL 2 +#define PDF_WIDGET_TX_FORMAT_DATE 3 +#define PDF_WIDGET_TX_FORMAT_TIME 4 + + +//---------------------------------------------------------------------------- +// annotation widget flags +//---------------------------------------------------------------------------- +// Common to all field types +#define PDF_FIELD_IS_READ_ONLY 1 +#define PDF_FIELD_IS_REQUIRED 1 << 1 +#define PDF_FIELD_IS_NO_EXPORT 1 << 2 + + +// Text fields +#define PDF_TX_FIELD_IS_MULTILINE 1 << 12 +#define PDF_TX_FIELD_IS_PASSWORD 1 << 13 +#define PDF_TX_FIELD_IS_FILE_SELECT 1 << 20 +#define PDF_TX_FIELD_IS_DO_NOT_SPELL_CHECK 1 << 22 +#define PDF_TX_FIELD_IS_DO_NOT_SCROLL 1 << 23 +#define PDF_TX_FIELD_IS_COMB 1 << 24 +#define PDF_TX_FIELD_IS_RICH_TEXT 1 << 25 + + +// Button fields +#define PDF_BTN_FIELD_IS_NO_TOGGLE_TO_OFF 1 << 14 +#define PDF_BTN_FIELD_IS_RADIO 1 << 15 +#define PDF_BTN_FIELD_IS_PUSHBUTTON 1 << 16 +#define PDF_BTN_FIELD_IS_RADIOS_IN_UNISON 1 << 25 + + +// Choice fields +#define PDF_CH_FIELD_IS_COMBO 1 << 17 +#define PDF_CH_FIELD_IS_EDIT 1 << 18 +#define PDF_CH_FIELD_IS_SORT 1 << 19 +#define PDF_CH_FIELD_IS_MULTI_SELECT 1 << 21 +#define PDF_CH_FIELD_IS_DO_NOT_SPELL_CHECK 1 << 22 +#define PDF_CH_FIELD_IS_COMMIT_ON_SEL_CHANGE 1 << 25 + + +// Signature fields errors +#define PDF_SIGNATURE_ERROR_OKAY 0 +#define PDF_SIGNATURE_ERROR_NO_SIGNATURES 1 +#define PDF_SIGNATURE_ERROR_NO_CERTIFICATE 2 +#define PDF_SIGNATURE_ERROR_DIGEST_FAILURE 3 +#define PDF_SIGNATURE_ERROR_SELF_SIGNED 4 +#define PDF_SIGNATURE_ERROR_SELF_SIGNED_IN_CHAIN 5 +#define PDF_SIGNATURE_ERROR_NOT_TRUSTED 6 +#define PDF_SIGNATURE_ERROR_UNKNOWN 7 + +// Signature appearances + +#define PDF_SIGNATURE_SHOW_LABELS 1 +#define PDF_SIGNATURE_SHOW_DN 2 +#define PDF_SIGNATURE_SHOW_DATE 4 +#define PDF_SIGNATURE_SHOW_TEXT_NAME 8 +#define PDF_SIGNATURE_SHOW_GRAPHIC_NAME 16 +#define PDF_SIGNATURE_SHOW_LOGO 32 +#define PDF_SIGNATURE_DEFAULT_APPEARANCE ( \ + PDF_SIGNATURE_SHOW_LABELS | \ + PDF_SIGNATURE_SHOW_DN | \ + PDF_SIGNATURE_SHOW_DATE | \ + PDF_SIGNATURE_SHOW_TEXT_NAME | \ + PDF_SIGNATURE_SHOW_GRAPHIC_NAME | \ + PDF_SIGNATURE_SHOW_LOGO ) + +//---------------------------------------------------------------------------- +// colorspace identifiers +//---------------------------------------------------------------------------- +#define CS_RGB 1 +#define CS_GRAY 2 +#define CS_CMYK 3 + +//---------------------------------------------------------------------------- +// PDF encryption algorithms +//---------------------------------------------------------------------------- +#define PDF_ENCRYPT_KEEP 0 +#define PDF_ENCRYPT_NONE 1 +#define PDF_ENCRYPT_RC4_40 2 +#define PDF_ENCRYPT_RC4_128 3 +#define PDF_ENCRYPT_AES_128 4 +#define PDF_ENCRYPT_AES_256 5 +#define PDF_ENCRYPT_UNKNOWN 6 + +//---------------------------------------------------------------------------- +// PDF permission codes +//---------------------------------------------------------------------------- +#define PDF_PERM_PRINT 1 << 2 +#define PDF_PERM_MODIFY 1 << 3 +#define PDF_PERM_COPY 1 << 4 +#define PDF_PERM_ANNOTATE 1 << 5 +#define PDF_PERM_FORM 1 << 8 +#define PDF_PERM_ACCESSIBILITY 1 << 9 +#define PDF_PERM_ASSEMBLE 1 << 10 +#define PDF_PERM_PRINT_HQ 1 << 11 + +//---------------------------------------------------------------------------- +// PDF Blend Modes +//---------------------------------------------------------------------------- +#define PDF_BM_Color "Color" +#define PDF_BM_ColorBurn "ColorBurn" +#define PDF_BM_ColorDodge "ColorDodge" +#define PDF_BM_Darken "Darken" +#define PDF_BM_Difference "Difference" +#define PDF_BM_Exclusion "Exclusion" +#define PDF_BM_HardLight "HardLight" +#define PDF_BM_Hue "Hue" +#define PDF_BM_Lighten "Lighten" +#define PDF_BM_Luminosity "Luminosity" +#define PDF_BM_Multiply "Multiply" +#define PDF_BM_Normal "Normal" +#define PDF_BM_Overlay "Overlay" +#define PDF_BM_Saturation "Saturation" +#define PDF_BM_Screen "Screen" +#define PDF_BM_SoftLight "Softlight" + + +// General text flags +#define TEXT_FONT_SUPERSCRIPT 1 +#define TEXT_FONT_ITALIC 2 +#define TEXT_FONT_SERIFED 4 +#define TEXT_FONT_MONOSPACED 8 +#define TEXT_FONT_BOLD 16 + +// UCDN Script codes +#define UCDN_SCRIPT_COMMON 0 +#define UCDN_SCRIPT_LATIN 1 +#define UCDN_SCRIPT_GREEK 2 +#define UCDN_SCRIPT_CYRILLIC 3 +#define UCDN_SCRIPT_ARMENIAN 4 +#define UCDN_SCRIPT_HEBREW 5 +#define UCDN_SCRIPT_ARABIC 6 +#define UCDN_SCRIPT_SYRIAC 7 +#define UCDN_SCRIPT_THAANA 8 +#define UCDN_SCRIPT_DEVANAGARI 9 +#define UCDN_SCRIPT_BENGALI 10 +#define UCDN_SCRIPT_GURMUKHI 11 +#define UCDN_SCRIPT_GUJARATI 12 +#define UCDN_SCRIPT_ORIYA 13 +#define UCDN_SCRIPT_TAMIL 14 +#define UCDN_SCRIPT_TELUGU 15 +#define UCDN_SCRIPT_KANNADA 16 +#define UCDN_SCRIPT_MALAYALAM 17 +#define UCDN_SCRIPT_SINHALA 18 +#define UCDN_SCRIPT_THAI 19 +#define UCDN_SCRIPT_LAO 20 +#define UCDN_SCRIPT_TIBETAN 21 +#define UCDN_SCRIPT_MYANMAR 22 +#define UCDN_SCRIPT_GEORGIAN 23 +#define UCDN_SCRIPT_HANGUL 24 +#define UCDN_SCRIPT_ETHIOPIC 25 +#define UCDN_SCRIPT_CHEROKEE 26 +#define UCDN_SCRIPT_CANADIAN_ABORIGINAL 27 +#define UCDN_SCRIPT_OGHAM 28 +#define UCDN_SCRIPT_RUNIC 29 +#define UCDN_SCRIPT_KHMER 30 +#define UCDN_SCRIPT_MONGOLIAN 31 +#define UCDN_SCRIPT_HIRAGANA 32 +#define UCDN_SCRIPT_KATAKANA 33 +#define UCDN_SCRIPT_BOPOMOFO 34 +#define UCDN_SCRIPT_HAN 35 +#define UCDN_SCRIPT_YI 36 +#define UCDN_SCRIPT_OLD_ITALIC 37 +#define UCDN_SCRIPT_GOTHIC 38 +#define UCDN_SCRIPT_DESERET 39 +#define UCDN_SCRIPT_INHERITED 40 +#define UCDN_SCRIPT_TAGALOG 41 +#define UCDN_SCRIPT_HANUNOO 42 +#define UCDN_SCRIPT_BUHID 43 +#define UCDN_SCRIPT_TAGBANWA 44 +#define UCDN_SCRIPT_LIMBU 45 +#define UCDN_SCRIPT_TAI_LE 46 +#define UCDN_SCRIPT_LINEAR_B 47 +#define UCDN_SCRIPT_UGARITIC 48 +#define UCDN_SCRIPT_SHAVIAN 49 +#define UCDN_SCRIPT_OSMANYA 50 +#define UCDN_SCRIPT_CYPRIOT 51 +#define UCDN_SCRIPT_BRAILLE 52 +#define UCDN_SCRIPT_BUGINESE 53 +#define UCDN_SCRIPT_COPTIC 54 +#define UCDN_SCRIPT_NEW_TAI_LUE 55 +#define UCDN_SCRIPT_GLAGOLITIC 56 +#define UCDN_SCRIPT_TIFINAGH 57 +#define UCDN_SCRIPT_SYLOTI_NAGRI 58 +#define UCDN_SCRIPT_OLD_PERSIAN 59 +#define UCDN_SCRIPT_KHAROSHTHI 60 +#define UCDN_SCRIPT_BALINESE 61 +#define UCDN_SCRIPT_CUNEIFORM 62 +#define UCDN_SCRIPT_PHOENICIAN 63 +#define UCDN_SCRIPT_PHAGS_PA 64 +#define UCDN_SCRIPT_NKO 65 +#define UCDN_SCRIPT_SUNDANESE 66 +#define UCDN_SCRIPT_LEPCHA 67 +#define UCDN_SCRIPT_OL_CHIKI 68 +#define UCDN_SCRIPT_VAI 69 +#define UCDN_SCRIPT_SAURASHTRA 70 +#define UCDN_SCRIPT_KAYAH_LI 71 +#define UCDN_SCRIPT_REJANG 72 +#define UCDN_SCRIPT_LYCIAN 73 +#define UCDN_SCRIPT_CARIAN 74 +#define UCDN_SCRIPT_LYDIAN 75 +#define UCDN_SCRIPT_CHAM 76 +#define UCDN_SCRIPT_TAI_THAM 77 +#define UCDN_SCRIPT_TAI_VIET 78 +#define UCDN_SCRIPT_AVESTAN 79 +#define UCDN_SCRIPT_EGYPTIAN_HIEROGLYPHS 80 +#define UCDN_SCRIPT_SAMARITAN 81 +#define UCDN_SCRIPT_LISU 82 +#define UCDN_SCRIPT_BAMUM 83 +#define UCDN_SCRIPT_JAVANESE 84 +#define UCDN_SCRIPT_MEETEI_MAYEK 85 +#define UCDN_SCRIPT_IMPERIAL_ARAMAIC 86 +#define UCDN_SCRIPT_OLD_SOUTH_ARABIAN 87 +#define UCDN_SCRIPT_INSCRIPTIONAL_PARTHIAN 88 +#define UCDN_SCRIPT_INSCRIPTIONAL_PAHLAVI 89 +#define UCDN_SCRIPT_OLD_TURKIC 90 +#define UCDN_SCRIPT_KAITHI 91 +#define UCDN_SCRIPT_BATAK 92 +#define UCDN_SCRIPT_BRAHMI 93 +#define UCDN_SCRIPT_MANDAIC 94 +#define UCDN_SCRIPT_CHAKMA 95 +#define UCDN_SCRIPT_MEROITIC_CURSIVE 96 +#define UCDN_SCRIPT_MEROITIC_HIEROGLYPHS 97 +#define UCDN_SCRIPT_MIAO 98 +#define UCDN_SCRIPT_SHARADA 99 +#define UCDN_SCRIPT_SORA_SOMPENG 100 +#define UCDN_SCRIPT_TAKRI 101 +#define UCDN_SCRIPT_UNKNOWN 102 +#define UCDN_SCRIPT_BASSA_VAH 103 +#define UCDN_SCRIPT_CAUCASIAN_ALBANIAN 104 +#define UCDN_SCRIPT_DUPLOYAN 105 +#define UCDN_SCRIPT_ELBASAN 106 +#define UCDN_SCRIPT_GRANTHA 107 +#define UCDN_SCRIPT_KHOJKI 108 +#define UCDN_SCRIPT_KHUDAWADI 109 +#define UCDN_SCRIPT_LINEAR_A 110 +#define UCDN_SCRIPT_MAHAJANI 111 +#define UCDN_SCRIPT_MANICHAEAN 112 +#define UCDN_SCRIPT_MENDE_KIKAKUI 113 +#define UCDN_SCRIPT_MODI 114 +#define UCDN_SCRIPT_MRO 115 +#define UCDN_SCRIPT_NABATAEAN 116 +#define UCDN_SCRIPT_OLD_NORTH_ARABIAN 117 +#define UCDN_SCRIPT_OLD_PERMIC 118 +#define UCDN_SCRIPT_PAHAWH_HMONG 119 +#define UCDN_SCRIPT_PALMYRENE 120 +#define UCDN_SCRIPT_PAU_CIN_HAU 121 +#define UCDN_SCRIPT_PSALTER_PAHLAVI 122 +#define UCDN_SCRIPT_SIDDHAM 123 +#define UCDN_SCRIPT_TIRHUTA 124 +#define UCDN_SCRIPT_WARANG_CITI 125 +#define UCDN_SCRIPT_AHOM 126 +#define UCDN_SCRIPT_ANATOLIAN_HIEROGLYPHS 127 +#define UCDN_SCRIPT_HATRAN 128 +#define UCDN_SCRIPT_MULTANI 129 +#define UCDN_SCRIPT_OLD_HUNGARIAN 130 +#define UCDN_SCRIPT_SIGNWRITING 131 +#define UCDN_SCRIPT_ADLAM 132 +#define UCDN_SCRIPT_BHAIKSUKI 133 +#define UCDN_SCRIPT_MARCHEN 134 +#define UCDN_SCRIPT_NEWA 135 +#define UCDN_SCRIPT_OSAGE 136 +#define UCDN_SCRIPT_TANGUT 137 +#define UCDN_SCRIPT_MASARAM_GONDI 138 +#define UCDN_SCRIPT_NUSHU 139 +#define UCDN_SCRIPT_SOYOMBO 140 +#define UCDN_SCRIPT_ZANABAZAR_SQUARE 141 +#define UCDN_SCRIPT_DOGRA 142 +#define UCDN_SCRIPT_GUNJALA_GONDI 143 +#define UCDN_SCRIPT_HANIFI_ROHINGYA 144 +#define UCDN_SCRIPT_MAKASAR 145 +#define UCDN_SCRIPT_MEDEFAIDRIN 146 +#define UCDN_SCRIPT_OLD_SOGDIAN 147 +#define UCDN_SCRIPT_SOGDIAN 148 +#define UCDN_SCRIPT_ELYMAIC 149 +#define UCDN_SCRIPT_NANDINAGARI 150 +#define UCDN_SCRIPT_NYIAKENG_PUACHUE_HMONG 151 +#define UCDN_SCRIPT_WANCHO 152 + + +// exceptions +PyObject *_set_FileDataError(PyObject *value) +{ + if (!value) { + Py_RETURN_FALSE; + } + JM_Exc_FileDataError = value; + Py_RETURN_TRUE; +} + +//------------------------------------------------------------------- +// minor tools +//------------------------------------------------------------------- +PyObject *util_sine_between(PyObject *C, PyObject *P, PyObject *Q) +{ + // for points C, P, Q compute the sine between lines CP and QP + fz_point c = JM_point_from_py(C); + fz_point p = JM_point_from_py(P); + fz_point q = JM_point_from_py(Q); + fz_point s = JM_normalize_vector(q.x - p.x, q.y - p.y); + fz_matrix m1 = fz_make_matrix(1, 0, 0, 1, -p.x, -p.y); + fz_matrix m2 = fz_make_matrix(s.x, -s.y, s.y, s.x, 0, 0); + m1 = fz_concat(m1, m2); + c = fz_transform_point(c, m1); + c = JM_normalize_vector(c.x, c.y); + return Py_BuildValue("f", c.y); +} + + +// Return the matrix that maps two points C, P to the x-axis such that +// C -> (0,0) and the image of P have the same distance. +PyObject *util_hor_matrix(PyObject *C, PyObject *P) +{ + fz_point c = JM_point_from_py(C); + fz_point p = JM_point_from_py(P); + + // compute (cosine, sine) of vector P-C with double precision: + fz_point s = JM_normalize_vector(p.x - c.x, p.y - c.y); + + fz_matrix m1 = fz_make_matrix(1, 0, 0, 1, -c.x, -c.y); + fz_matrix m2 = fz_make_matrix(s.x, -s.y, s.y, s.x, 0, 0); + return JM_py_from_matrix(fz_concat(m1, m2)); +} + +struct Annot; + +// Ensure that widgets with /AA/C JavaScript are in array AcroForm/CO +struct Annot; +PyObject *util_ensure_widget_calc(struct Annot *annot) +{ + pdf_obj *PDFNAME_CO=NULL; + fz_try(gctx) { + pdf_obj *annot_obj = pdf_annot_obj(gctx, (pdf_annot *) annot); + pdf_document *pdf = pdf_get_bound_document(gctx, annot_obj); + PDFNAME_CO = pdf_new_name(gctx, "CO"); // = PDF_NAME(CO) + pdf_obj *acro = pdf_dict_getl(gctx, // get AcroForm dict + pdf_trailer(gctx, pdf), + PDF_NAME(Root), + PDF_NAME(AcroForm), + NULL); + + pdf_obj *CO = pdf_dict_get(gctx, acro, PDFNAME_CO); // = AcroForm/CO + if (!CO) { + CO = pdf_dict_put_array(gctx, acro, PDFNAME_CO, 2); + } + int i, n = pdf_array_len(gctx, CO); + int xref, nxref, found = 0; + xref = pdf_to_num(gctx, annot_obj); + for (i = 0; i < n; i++) { + nxref = pdf_to_num(gctx, pdf_array_get(gctx, CO, i)); + if (xref == nxref) { + found = 1; + break; + } + } + if (!found) { + pdf_array_push_drop(gctx, CO, pdf_new_indirect(gctx, pdf, xref, 0)); + } + } + fz_always(gctx) { + pdf_drop_obj(gctx, PDFNAME_CO); + } + fz_catch(gctx) { + PyErr_SetString(PyExc_RuntimeError, fz_caught_message(gctx)); + return NULL; + } + Py_RETURN_NONE; +} + + +//----------------------------------------------------------- +// Compute Rect coordinates using different alternatives +//----------------------------------------------------------- +PyObject *util_make_rect(PyObject *a) +{ + Py_ssize_t i, n = PyTuple_GET_SIZE(a); + PyObject *p1, *p2, *l = a; + char *msg = "Rect: bad args"; + double c[4] = { 0, 0, 0, 0 }; + switch (n) { + case 0: goto exit_normal; + case 1: goto size1; + case 2: goto size2; + case 3: goto size31; + case 4: goto size4; + default: + msg = "Rect: bad seq len"; + goto exit_error; + } + + size4:; + for (i = 0; i < 4; i++) { + if (JM_FLOAT_ITEM(l, i, &c[i]) == 1) { + goto exit_error; + } + } + goto exit_normal; + + size1:; + l = PyTuple_GET_ITEM(a, 0); + if (!PySequence_Check(l) || PySequence_Size(l) != 4) { + msg = "Rect: bad seq len"; + goto exit_error; + } + goto size4; + + size2:; + msg = "Rect: bad args"; + p1 = PyTuple_GET_ITEM(a, 0); + p2 = PyTuple_GET_ITEM(a, 1); + if (!PySequence_Check(p1) || PySequence_Size(p1) != 2) { + goto exit_error; + } + if (!PySequence_Check(p2) || PySequence_Size(p2) != 2) { + goto exit_error; + } + if (JM_FLOAT_ITEM(p1, 0, &c[0]) == 1) goto exit_error; + if (JM_FLOAT_ITEM(p1, 1, &c[1]) == 1) goto exit_error; + if (JM_FLOAT_ITEM(p2, 0, &c[2]) == 1) goto exit_error; + if (JM_FLOAT_ITEM(p2, 1, &c[3]) == 1) goto exit_error; + goto exit_normal; + + size31:; + p1 = PyTuple_GET_ITEM(a, 0); + if (PySequence_Check(p1)) goto size32; + if (JM_FLOAT_ITEM(a, 0, &c[0]) == 1) goto exit_error; + if (JM_FLOAT_ITEM(a, 1, &c[1]) == 1) goto exit_error; + p2 = PyTuple_GET_ITEM(a, 2); + if (!PySequence_Check(p2) || PySequence_Size(p2) != 2) { + goto exit_error; + } + if (JM_FLOAT_ITEM(p2, 0, &c[2]) == 1) goto exit_error; + if (JM_FLOAT_ITEM(p2, 1, &c[3]) == 1) goto exit_error; + goto exit_normal; + + size32:; + if (PySequence_Size(p1) != 2) goto exit_error; + if (JM_FLOAT_ITEM(p1, 0, &c[0]) == 1) goto exit_error; + if (JM_FLOAT_ITEM(p1, 1, &c[1]) == 1) goto exit_error; + if (JM_FLOAT_ITEM(a, 1, &c[2]) == 1) goto exit_error; + if (JM_FLOAT_ITEM(a, 2, &c[3]) == 1) goto exit_error; + goto exit_normal; + + exit_normal:; + for (i = 0; i < 4; i++) { + if (c[i] < FZ_MIN_INF_RECT) c[i] = FZ_MIN_INF_RECT; + if (c[i] > FZ_MAX_INF_RECT) c[i] = FZ_MAX_INF_RECT; + } + return Py_BuildValue("dddd", c[0], c[1], c[2], c[3]); + + exit_error:; + PyErr_SetString(PyExc_ValueError, msg); + return NULL; +} + + +//----------------------------------------------------------- +// Compute IRect coordinates using different alternatives +//----------------------------------------------------------- +PyObject *util_make_irect(PyObject *a) +{ + Py_ssize_t i, n = PyTuple_GET_SIZE(a); + PyObject *p1, *p2, *l = a; + char *msg = "IRect: bad args"; + int c[4] = { 0, 0, 0, 0 }; + switch (n) { + case 0: goto exit_normal; + case 1: goto size1; + case 2: goto size2; + case 3: goto size31; + case 4: goto size4; + default: + msg = "IRect: bad seq len"; + goto exit_error; + } + + size4:; + for (i = 0; i < 4; i++) { + if (JM_INT_ITEM(l, i, &c[i]) == 1) { + goto exit_error; + } + } + goto exit_normal; + + size1:; + l = PyTuple_GET_ITEM(a, 0); + if (!PySequence_Check(l) || PySequence_Size(l) != 4) { + msg = "IRect: bad seq len"; + goto exit_error; + } + goto size4; + + size2:; + p1 = PyTuple_GET_ITEM(a, 0); + p2 = PyTuple_GET_ITEM(a, 1); + if (!PySequence_Check(p1) || PySequence_Size(p1) != 2) { + goto exit_error; + } + if (!PySequence_Check(p2) || PySequence_Size(p2) != 2) { + goto exit_error; + } + msg = "IRect: bad int values"; + if (JM_INT_ITEM(p1, 0, &c[0]) == 1) goto exit_error; + if (JM_INT_ITEM(p1, 1, &c[1]) == 1) goto exit_error; + if (JM_INT_ITEM(p2, 0, &c[2]) == 1) goto exit_error; + if (JM_INT_ITEM(p2, 1, &c[3]) == 1) goto exit_error; + goto exit_normal; + + size31:; + p1 = PyTuple_GET_ITEM(a, 0); + if (PySequence_Check(p1)) goto size32; + if (JM_INT_ITEM(a, 0, &c[0]) == 1) goto exit_error; + if (JM_INT_ITEM(a, 1, &c[1]) == 1) goto exit_error; + p2 = PyTuple_GET_ITEM(a, 2); + if (!PySequence_Check(p2) || PySequence_Size(p2) != 2) { + goto exit_error; + } + if (JM_INT_ITEM(p2, 0, &c[2]) == 1) goto exit_error; + if (JM_INT_ITEM(p2, 1, &c[3]) == 1) goto exit_error; + goto exit_normal; + + size32:; + if (PySequence_Size(p1) != 2) goto exit_error; + if (JM_INT_ITEM(p1, 0, &c[0]) == 1) goto exit_error; + if (JM_INT_ITEM(p1, 1, &c[1]) == 1) goto exit_error; + if (JM_INT_ITEM(a, 1, &c[2]) == 1) goto exit_error; + if (JM_INT_ITEM(a, 2, &c[3]) == 1) goto exit_error; + goto exit_normal; + + exit_normal:; + for (i = 0; i < 4; i++) { + if (c[i] < FZ_MIN_INF_RECT) c[i] = FZ_MIN_INF_RECT; + if (c[i] > FZ_MAX_INF_RECT) c[i] = FZ_MAX_INF_RECT; + } + return Py_BuildValue("iiii", c[0], c[1], c[2], c[3]); + + exit_error:; + PyErr_SetString(PyExc_ValueError, msg); + return NULL; +} + + +PyObject *util_round_rect(PyObject *rect) +{ + return JM_py_from_irect(fz_round_rect(JM_rect_from_py(rect))); +} + + +PyObject *util_transform_rect(PyObject *rect, PyObject *matrix) +{ + return JM_py_from_rect(fz_transform_rect(JM_rect_from_py(rect), JM_matrix_from_py(matrix))); +} + + +PyObject *util_intersect_rect(PyObject *r1, PyObject *r2) +{ + return JM_py_from_rect(fz_intersect_rect(JM_rect_from_py(r1), + JM_rect_from_py(r2))); +} + + +PyObject *util_is_point_in_rect(PyObject *p, PyObject *r) +{ + return JM_BOOL(fz_is_point_inside_rect(JM_point_from_py(p), JM_rect_from_py(r))); +} + + +PyObject *util_include_point_in_rect(PyObject *r, PyObject *p) +{ + return JM_py_from_rect(fz_include_point_in_rect(JM_rect_from_py(r), + JM_point_from_py(p))); +} + + +PyObject *util_point_in_quad(PyObject *P, PyObject *Q) +{ + fz_point p = JM_point_from_py(P); + fz_quad q = JM_quad_from_py(Q); + return JM_BOOL(fz_is_point_inside_quad(p, q)); +} + + +PyObject *util_transform_point(PyObject *point, PyObject *matrix) +{ + return JM_py_from_point(fz_transform_point(JM_point_from_py(point), JM_matrix_from_py(matrix))); +} + + +PyObject *util_union_rect(PyObject *r1, PyObject *r2) +{ + return JM_py_from_rect(fz_union_rect(JM_rect_from_py(r1), + JM_rect_from_py(r2))); +} + + +PyObject *util_concat_matrix(PyObject *m1, PyObject *m2) +{ + return JM_py_from_matrix(fz_concat(JM_matrix_from_py(m1), + JM_matrix_from_py(m2))); +} + + +PyObject *util_invert_matrix(PyObject *matrix) +{ + fz_matrix src = JM_matrix_from_py(matrix); + float a = src.a; + float det = a * src.d - src.b * src.c; + if (det < -FLT_EPSILON || det > FLT_EPSILON) + { + fz_matrix dst; + float rdet = 1 / det; + dst.a = src.d * rdet; + dst.b = -src.b * rdet; + dst.c = -src.c * rdet; + dst.d = a * rdet; + a = -src.e * dst.a - src.f * dst.c; + dst.f = -src.e * dst.b - src.f * dst.d; + dst.e = a; + return Py_BuildValue("iN", 0, JM_py_from_matrix(dst)); + } + return Py_BuildValue("(i, ())", 1); +} + + +PyObject *util_measure_string(const char *text, const char *fontname, double fontsize, int encoding) +{ + double w = 0; + fz_font *font = NULL; + fz_try(gctx) { + font = fz_new_base14_font(gctx, fontname); + while (*text) + { + int c, g; + text += fz_chartorune(&c, text); + switch (encoding) + { + case PDF_SIMPLE_ENCODING_GREEK: + c = fz_iso8859_7_from_unicode(c); break; + case PDF_SIMPLE_ENCODING_CYRILLIC: + c = fz_windows_1251_from_unicode(c); break; + default: + c = fz_windows_1252_from_unicode(c); break; + } + if (c < 0) c = 0xB7; + g = fz_encode_character(gctx, font, c); + w += (double) fz_advance_glyph(gctx, font, g, 0); + } + } + fz_always(gctx) { + fz_drop_font(gctx, font); + } + fz_catch(gctx) { + return PyFloat_FromDouble(0); + } + return PyFloat_FromDouble(w * fontsize); +} + +%} + +%{ +// Global Constants - Python dictionary keys +PyObject *dictkey_align; +PyObject *dictkey_ascender; +PyObject *dictkey_bbox; +PyObject *dictkey_blocks; +PyObject *dictkey_bpc; +PyObject *dictkey_c; +PyObject *dictkey_chars; +PyObject *dictkey_color; +PyObject *dictkey_colorspace; +PyObject *dictkey_content; +PyObject *dictkey_creationDate; +PyObject *dictkey_cs_name; +PyObject *dictkey_da; +PyObject *dictkey_dashes; +PyObject *dictkey_desc; +PyObject *dictkey_descender; +PyObject *dictkey_dir; +PyObject *dictkey_effect; +PyObject *dictkey_ext; +PyObject *dictkey_filename; +PyObject *dictkey_fill; +PyObject *dictkey_flags; +PyObject *dictkey_font; +PyObject *dictkey_glyph; +PyObject *dictkey_height; +PyObject *dictkey_id; +PyObject *dictkey_image; +PyObject *dictkey_items; +PyObject *dictkey_length; +PyObject *dictkey_lines; +PyObject *dictkey_matrix; +PyObject *dictkey_modDate; +PyObject *dictkey_name; +PyObject *dictkey_number; +PyObject *dictkey_origin; +PyObject *dictkey_rect; +PyObject *dictkey_size; +PyObject *dictkey_smask; +PyObject *dictkey_spans; +PyObject *dictkey_stroke; +PyObject *dictkey_style; +PyObject *dictkey_subject; +PyObject *dictkey_text; +PyObject *dictkey_title; +PyObject *dictkey_type; +PyObject *dictkey_ufilename; +PyObject *dictkey_width; +PyObject *dictkey_wmode; +PyObject *dictkey_xref; +PyObject *dictkey_xres; +PyObject *dictkey_yres; +%}
