diff --git a/doc/PyMuPDF.pdf b/doc/PyMuPDF.pdf index 3a8a3cc3a..c947e1718 100644 Binary files a/doc/PyMuPDF.pdf and b/doc/PyMuPDF.pdf differ diff --git a/doc/html.zip b/doc/html.zip index b575292a9..e5af216f4 100644 Binary files a/doc/html.zip and b/doc/html.zip differ diff --git a/fitz/__init__.py b/fitz/__init__.py index 21680e9d7..7418399ce 100644 --- a/fitz/__init__.py +++ b/fitz/__init__.py @@ -13,6 +13,9 @@ TOOLS = fitz.Tools() fitz.TOOLS = TOOLS +if fitz.VersionFitz != fitz.TOOLS.mupdf_version(): + raise ValueError("MuPDF library mismatch %s <> %s" % (fitz.VersionFitz, fitz.TOOLS.mupdf_version())) + import fitz.utils # copy functions to their respective fitz classes diff --git a/fitz/fitz.i b/fitz/fitz.i index 94a50447e..6a222b78e 100644 --- a/fitz/fitz.i +++ b/fitz/fitz.i @@ -145,10 +145,10 @@ fz_set_stderr(gctx, JM_fitz_stderr); if (JM_fitz_stderr && JM_fitz_stdout) {;} else - PySys_WriteStdout("error redirecting stdout/stderr!\n"); + PySys_WriteStderr("error redirecting stdout/stderr!\n"); -JM_error_log = PyList_New(0); -JM_output_log = PyList_New(0); +JM_error_log = PyByteArray_FromStringAndSize("", 0); +JM_output_log = PyByteArray_FromStringAndSize("", 0); //----------------------------------------------------------------------------- // STOP redirect stdout/stderr @@ -172,6 +172,7 @@ struct DeviceWrapper { // include version information and several other helpers //----------------------------------------------------------------------------- %pythoncode %{ +import os import weakref from binascii import hexlify import math @@ -211,18 +212,27 @@ struct fz_document_s FITZEXCEPTION(fz_document_s, !result) %pythonprepend fz_document_s %{ - if not filename or type(filename) == str: + if not filename or type(filename) is str: pass - elif type(filename) == unicode: - filename = filename.encode('utf8') else: - raise TypeError("filename must be string or None") - self.name = filename if filename else "" + if str is bytes: # Python 2 + if type(filename) is unicode: + filename = filename.encode("utf8") + else: + filename = str(filename) # should take care of pathlib + self.streamlen = len(stream) if stream else 0 - if stream and not (filename or filetype): - raise ValueError("filetype missing with stream specified") - if stream and type(stream) not in (bytes, bytearray): - raise ValueError("stream must be bytes or bytearray") + + self.name = "" + if filename and self.streamlen == 0: + self.name = filename + + if self.streamlen > 0: + if not (filename or filetype): + raise ValueError("filetype missing with stream specified") + if type(stream) not in (bytes, bytearray): + raise ValueError("stream must be bytes or bytearray") + self.isClosed = False self.isEncrypted = 0 self.metadata = None @@ -2102,18 +2112,18 @@ struct fz_page_s { inklist = pdf_new_array(gctx, annot->page->doc, n0); for (j = 0; j < n0; j++) { - sublist = PySequence_GetItem(list, j); + sublist = PySequence_ITEM(list, j); n1 = PySequence_Size(sublist); stroke = pdf_new_array(gctx, annot->page->doc, 2 * n1); for (i = 0; i < n1; i++) { - p = PySequence_GetItem(sublist, i); + p = PySequence_ITEM(sublist, i); if (!PySequence_Check(p) || PySequence_Size(p) != 2) THROWMSG("3rd level entries must be pairs of floats"); - x = PyFloat_AsDouble(PySequence_GetItem(p, 0)); + x = PyFloat_AsDouble(PySequence_ITEM(p, 0)); if (PyErr_Occurred()) THROWMSG("invalid point coordinate"); - y = PyFloat_AsDouble(PySequence_GetItem(p, 1)); + y = PyFloat_AsDouble(PySequence_ITEM(p, 1)); if (PyErr_Occurred()) THROWMSG("invalid point coordinate"); Py_CLEAR(p); @@ -4559,7 +4569,7 @@ struct fz_annot_s if (n>0) { for (i=0; i Document""" - if not filename or type(filename) == str: + if not filename or type(filename) is str: pass - elif type(filename) == unicode: - filename = filename.encode('utf8') else: - raise TypeError("filename must be string or None") - self.name = filename if filename else "" + if str is bytes: # Python 2 + if type(filename) is unicode: + filename = filename.encode("utf8") + else: + filename = str(filename) # should take care of pathlib + self.streamlen = len(stream) if stream else 0 - if stream and not (filename or filetype): - raise ValueError("filetype missing with stream specified") - if stream and type(stream) not in (bytes, bytearray): - raise ValueError("stream must be bytes or bytearray") + + self.name = "" + if filename and self.streamlen == 0: + self.name = filename + + if self.streamlen > 0: + if not (filename or filetype): + raise ValueError("filetype missing with stream specified") + if type(stream) not in (bytes, bytearray): + raise ValueError("stream must be bytes or bytearray") + self.isClosed = False self.isEncrypted = 0 self.metadata = None @@ -4095,8 +4105,19 @@ def glyph_cache_empty(self): @property + def fitz_stdout(self): + """fitz_stdout(self) -> char *""" + return _fitz.Tools_fitz_stdout(self) + + + def fitz_stdout_reset(self): + """fitz_stdout_reset(self)""" + return _fitz.Tools_fitz_stdout_reset(self) + + @property + def fitz_stderr(self): - """fitz_stderr(self) -> PyObject *""" + """fitz_stderr(self) -> char *""" return _fitz.Tools_fitz_stderr(self) @@ -4105,6 +4126,11 @@ def fitz_stderr_reset(self): return _fitz.Tools_fitz_stderr_reset(self) + def mupdf_version(self): + """mupdf_version(self) -> char *""" + return _fitz.Tools_mupdf_version(self) + + def transform_rect(self, rect, matrix): """transform_rect(self, rect, matrix) -> PyObject *""" return _fitz.Tools_transform_rect(self, rect, matrix) diff --git a/fitz/fitz_wrap.c b/fitz/fitz_wrap.c index 15d6c3216..ac35342a9 100644 --- a/fitz/fitz_wrap.c +++ b/fitz/fitz_wrap.c @@ -3141,16 +3141,16 @@ fz_quad JM_quad_from_py(PyObject *r) if (!r || !PySequence_Check(r) || PySequence_Size(r) != 4) return q; - double x0 = PyFloat_AsDouble(PySequence_GetItem(r, 0)); + double x0 = PyFloat_AsDouble(PySequence_ITEM(r, 0)); if (!PyErr_Occurred()) // assume case 1: a rect is given { - double y0 = PyFloat_AsDouble(PySequence_GetItem(r, 1)); + double y0 = PyFloat_AsDouble(PySequence_ITEM(r, 1)); if (PyErr_Occurred()) goto return_simple; - double x1 = PyFloat_AsDouble(PySequence_GetItem(r, 2)); + double x1 = PyFloat_AsDouble(PySequence_ITEM(r, 2)); if (PyErr_Occurred()) goto return_simple; - double y1 = PyFloat_AsDouble(PySequence_GetItem(r, 3)); + double y1 = PyFloat_AsDouble(PySequence_ITEM(r, 3)); if (PyErr_Occurred()) goto return_simple; q.ul = fz_make_point(x0, y0); @@ -3166,16 +3166,16 @@ fz_quad JM_quad_from_py(PyObject *r) PyErr_Clear(); for (i = 0; i < 4; i++) { - PyObject *o = PySequence_GetItem(r, i); + PyObject *o = PySequence_ITEM(r, i); p[i].x = p[i].y = 0; if (!PySequence_Check(o) || PySequence_Size(o) != 2) goto weiter; - p[i].x = PyFloat_AsDouble(PySequence_GetItem(o, 0)); + p[i].x = PyFloat_AsDouble(PySequence_ITEM(o, 0)); if (PyErr_Occurred()) p[i].x = 0; - p[i].y = PyFloat_AsDouble(PySequence_GetItem(o, 1)); + p[i].y = PyFloat_AsDouble(PySequence_ITEM(o, 1)); if (PyErr_Occurred()) p[i].y = 0; @@ -3198,16 +3198,16 @@ fz_rect JM_rect_from_py(PyObject *r) if (!r || !PySequence_Check(r) || PySequence_Size(r) != 4) return fz_infinite_rect; - double x0 = PyFloat_AsDouble(PySequence_GetItem(r, 0)); + double x0 = PyFloat_AsDouble(PySequence_ITEM(r, 0)); if (PyErr_Occurred()) goto return_empty; - double y0 = PyFloat_AsDouble(PySequence_GetItem(r, 1)); + double y0 = PyFloat_AsDouble(PySequence_ITEM(r, 1)); if (PyErr_Occurred()) goto return_empty; - double x1 = PyFloat_AsDouble(PySequence_GetItem(r, 2)); + double x1 = PyFloat_AsDouble(PySequence_ITEM(r, 2)); if (PyErr_Occurred()) goto return_empty; - double y1 = PyFloat_AsDouble(PySequence_GetItem(r, 3)); + double y1 = PyFloat_AsDouble(PySequence_ITEM(r, 3)); if (PyErr_Occurred()) goto return_empty; return fz_make_rect((float) x0, (float) y0, (float) x1, (float) y1); @@ -3233,16 +3233,16 @@ fz_irect JM_irect_from_py(PyObject *r) if (!r || !PySequence_Check(r) || PySequence_Size(r) != 4) return fz_infinite_irect; - long x0 = PyLong_AsLong(PySequence_GetItem(r, 0)); + long x0 = PyLong_AsLong(PySequence_ITEM(r, 0)); if (PyErr_Occurred()) goto return_empty; - long y0 = PyLong_AsLong(PySequence_GetItem(r, 1)); + long y0 = PyLong_AsLong(PySequence_ITEM(r, 1)); if (PyErr_Occurred()) goto return_empty; - long x1 = PyLong_AsLong(PySequence_GetItem(r, 2)); + long x1 = PyLong_AsLong(PySequence_ITEM(r, 2)); if (PyErr_Occurred()) goto return_empty; - long y1 = PyLong_AsLong(PySequence_GetItem(r, 3)); + long y1 = PyLong_AsLong(PySequence_ITEM(r, 3)); if (PyErr_Occurred()) goto return_empty; return fz_make_irect((int) x0, (int) y0, (int) x1, (int) y1); @@ -3270,10 +3270,10 @@ fz_point JM_point_from_py(PyObject *p) if (!p || !PySequence_Check(p) || PySequence_Size(p) != 2) return p0; - double x = PyFloat_AsDouble(PySequence_GetItem(p, 0)); + double x = PyFloat_AsDouble(PySequence_ITEM(p, 0)); if (PyErr_Occurred()) goto zero_point; - double y = PyFloat_AsDouble(PySequence_GetItem(p, 1)); + double y = PyFloat_AsDouble(PySequence_ITEM(p, 1)); if (PyErr_Occurred()) goto zero_point; return fz_make_point((float) x, (float) y); @@ -3301,22 +3301,22 @@ fz_matrix JM_matrix_from_py(PyObject *m) if (!m || !PySequence_Check(m) || PySequence_Size(m) != 6) return m0; - double a = PyFloat_AsDouble(PySequence_GetItem(m, 0)); + double a = PyFloat_AsDouble(PySequence_ITEM(m, 0)); if (PyErr_Occurred()) goto fertig; - double b = PyFloat_AsDouble(PySequence_GetItem(m, 1)); + double b = PyFloat_AsDouble(PySequence_ITEM(m, 1)); if (PyErr_Occurred()) goto fertig; - double c = PyFloat_AsDouble(PySequence_GetItem(m, 2)); + double c = PyFloat_AsDouble(PySequence_ITEM(m, 2)); if (PyErr_Occurred()) goto fertig; - double d = PyFloat_AsDouble(PySequence_GetItem(m, 3)); + double d = PyFloat_AsDouble(PySequence_ITEM(m, 3)); if (PyErr_Occurred()) goto fertig; - double e = PyFloat_AsDouble(PySequence_GetItem(m, 4)); + double e = PyFloat_AsDouble(PySequence_ITEM(m, 4)); if (PyErr_Occurred()) goto fertig; - double f = PyFloat_AsDouble(PySequence_GetItem(m, 5)); + double f = PyFloat_AsDouble(PySequence_ITEM(m, 5)); if (PyErr_Occurred()) goto fertig; m0.a = a; @@ -3494,7 +3494,7 @@ void JM_color_FromSequence(PyObject *color, int *n, float col[4]) float mcol[4] = {0,0,0,0}; // local color storage for (i = 0; i < len; i++) { - mcol[i] = (float) PyFloat_AsDouble(PySequence_GetItem(color, i)); + mcol[i] = (float) PyFloat_AsDouble(PySequence_ITEM(color, i)); if (PyErr_Occurred()) { PyErr_Clear(); // reset Py error indicator @@ -4093,9 +4093,9 @@ static void JM_write_stdout(fz_context *ctx, void *opaque, const void *buffer, size_t count) { if (!buffer || !count) return; - PyObject *c = Py_BuildValue("s#", (const char *) buffer, (Py_ssize_t) count); + PyObject *c = PyByteArray_FromStringAndSize((const char *)buffer, (Py_ssize_t) count); if (!c || c == NONE) return; - PyList_Append(JM_output_log, c); + JM_output_log = PySequence_InPlaceConcat(JM_output_log, c); Py_CLEAR(c); return; } @@ -4104,9 +4104,9 @@ static void JM_write_stderr(fz_context *ctx, void *opaque, const void *buffer, size_t count) { if (!buffer || !count) return; - PyObject *c = Py_BuildValue("s#", (const char *) buffer, (Py_ssize_t) count); + PyObject *c = PyByteArray_FromStringAndSize((const char *)buffer, (Py_ssize_t) count); if (!c || c == NONE) return; - PyList_Append(JM_error_log, c); + JM_error_log = PySequence_InPlaceConcat(JM_error_log, c); Py_CLEAR(c); return; } @@ -7377,8 +7377,8 @@ struct fz_annot_s *JM_AnnotMultiline(fz_context *ctx, pdf_page *page, PyObject * PyObject *p = PySequence_ITEM(points, i); if (!PySequence_Check(p) || PySequence_Size(p) != 2) THROWMSG("invalid points list"); - point.x = (float) PyFloat_AsDouble(PySequence_GetItem(p, 0)); - point.y = (float) PyFloat_AsDouble(PySequence_GetItem(p, 1)); + point.x = (float) PyFloat_AsDouble(PySequence_ITEM(p, 0)); + point.y = (float) PyFloat_AsDouble(PySequence_ITEM(p, 1)); Py_CLEAR(p); pdf_add_annot_vertex(ctx, annot, point); if (i == 0) @@ -7508,7 +7508,7 @@ PyObject *JM_annot_set_border(fz_context *ctx, PyObject *border, pdf_document *d pdf_obj *darr = pdf_new_array(ctx, doc, n); for (i = 0; i < n; i++) { - d = (int) PyInt_AsLong(PySequence_GetItem(ndashes, i)); + d = (int) PyInt_AsLong(PySequence_ITEM(ndashes, i)); pdf_array_push_int(ctx, darr, (int64_t) d); } pdf_dict_putl_drop(ctx, annot_obj, darr, PDF_NAME(BS), PDF_NAME(D), NULL); @@ -8022,7 +8022,7 @@ void JM_set_choice_options(fz_context *ctx, pdf_annot *annot, PyObject *liste) pdf_obj *optarr = pdf_new_array(ctx, pdf, n); for (i = 0; i < n; i++) { - opt = JM_Python_str_AsChar(PySequence_GetItem(liste, i)); + opt = JM_Python_str_AsChar(PySequence_ITEM(liste, i)); pdf_array_push_text_string(ctx, optarr, (const char *) opt); JM_Python_str_DelForPy3(opt); } @@ -8043,7 +8043,7 @@ void JM_set_widget_properties(fz_context *ctx, pdf_annot *annot, PyObject *Widge { pdf_document *pdf = annot->page->doc; pdf_page *page = annot->page; - fz_rect rect = {0,0,0,0}; + fz_rect rect; pdf_obj *fill_col = NULL, *text_col = NULL, *border_col = NULL; pdf_obj *dashes = NULL; Py_ssize_t i, n = 0; @@ -8068,12 +8068,8 @@ void JM_set_widget_properties(fz_context *ctx, pdf_annot *annot, PyObject *Widge // rectangle -------------------------------------------------------------- value = PyObject_GetAttrString(Widget, "rect"); - rect.x0 = (float) PyFloat_AsDouble(PySequence_GetItem(value, 0)); - rect.y0 = (float) PyFloat_AsDouble(PySequence_GetItem(value, 1)); - rect.x1 = (float) PyFloat_AsDouble(PySequence_GetItem(value, 2)); - rect.y1 = (float) PyFloat_AsDouble(PySequence_GetItem(value, 3)); + rect = JM_rect_from_py(value); Py_CLEAR(value); - JM_PyErr_Clear; pdf_set_annot_rect(ctx, annot, rect); // set the rect // fill color ------------------------------------------------------------- @@ -8084,7 +8080,7 @@ void JM_set_widget_properties(fz_context *ctx, pdf_annot *annot, PyObject *Widge fill_col = pdf_new_array(ctx, pdf, n); for (i = 0; i < n; i++) pdf_array_push_real(ctx, fill_col, - PyFloat_AsDouble(PySequence_GetItem(value, i))); + PyFloat_AsDouble(PySequence_ITEM(value, i))); pdf_field_set_fill_color(ctx, pdf, annot->obj, fill_col); pdf_drop_obj(ctx, fill_col); } @@ -8099,7 +8095,7 @@ void JM_set_widget_properties(fz_context *ctx, pdf_annot *annot, PyObject *Widge dashes = pdf_new_array(ctx, pdf, n); for (i = 0; i < n; i++) pdf_array_push_int(ctx, dashes, - PyInt_AsLong(PySequence_GetItem(value, i))); + PyInt_AsLong(PySequence_ITEM(value, i))); pdf_dict_putl_drop(ctx, annot->obj, dashes, PDF_NAME(BS), PDF_NAME(D), NULL); } @@ -8114,7 +8110,7 @@ void JM_set_widget_properties(fz_context *ctx, pdf_annot *annot, PyObject *Widge border_col = pdf_new_array(ctx, pdf, n); for (i = 0; i < n; i++) pdf_array_push_real(ctx, border_col, - PyFloat_AsDouble(PySequence_GetItem(value, i))); + PyFloat_AsDouble(PySequence_ITEM(value, i))); pdf_dict_putl_drop(ctx, annot->obj, border_col, PDF_NAME(MK), PDF_NAME(BC), NULL); } @@ -8615,7 +8611,7 @@ void retainpages(fz_context *ctx, globals *glo, PyObject *liste) { for (page = 0; page < argc; page++) { - i = (int) PyInt_AsLong(PySequence_GetItem(liste, page)); + i = (int) PyInt_AsLong(PySequence_ITEM(liste, page)); if (i < 0 || i >= pagecount) THROWMSG("invalid page number(s)"); retainpage(ctx, doc, pages, kids, i); @@ -10911,18 +10907,18 @@ SWIGINTERN struct fz_annot_s *fz_page_s_addInkAnnot(struct fz_page_s *self,PyObj inklist = pdf_new_array(gctx, annot->page->doc, n0); for (j = 0; j < n0; j++) { - sublist = PySequence_GetItem(list, j); + sublist = PySequence_ITEM(list, j); n1 = PySequence_Size(sublist); stroke = pdf_new_array(gctx, annot->page->doc, 2 * n1); for (i = 0; i < n1; i++) { - p = PySequence_GetItem(sublist, i); + p = PySequence_ITEM(sublist, i); if (!PySequence_Check(p) || PySequence_Size(p) != 2) THROWMSG("3rd level entries must be pairs of floats"); - x = PyFloat_AsDouble(PySequence_GetItem(p, 0)); + x = PyFloat_AsDouble(PySequence_ITEM(p, 0)); if (PyErr_Occurred()) THROWMSG("invalid point coordinate"); - y = PyFloat_AsDouble(PySequence_GetItem(p, 1)); + y = PyFloat_AsDouble(PySequence_ITEM(p, 1)); if (PyErr_Occurred()) THROWMSG("invalid point coordinate"); Py_CLEAR(p); @@ -12332,7 +12328,7 @@ SWIGINTERN void fz_annot_s_setColors(struct fz_annot_s *self,PyObject *colors){ if (n>0) { for (i=0; i PyObject *"}, + { (char *)"Tools_fitz_stdout", _wrap_Tools_fitz_stdout, METH_VARARGS, (char *)"Tools_fitz_stdout(self) -> char *"}, + { (char *)"Tools_fitz_stdout_reset", _wrap_Tools_fitz_stdout_reset, METH_VARARGS, (char *)"Tools_fitz_stdout_reset(self)"}, + { (char *)"Tools_fitz_stderr", _wrap_Tools_fitz_stderr, METH_VARARGS, (char *)"Tools_fitz_stderr(self) -> char *"}, { (char *)"Tools_fitz_stderr_reset", _wrap_Tools_fitz_stderr_reset, METH_VARARGS, (char *)"Tools_fitz_stderr_reset(self)"}, + { (char *)"Tools_mupdf_version", _wrap_Tools_mupdf_version, METH_VARARGS, (char *)"Tools_mupdf_version(self) -> char *"}, { (char *)"Tools_transform_rect", _wrap_Tools_transform_rect, METH_VARARGS, (char *)"Tools_transform_rect(self, rect, matrix) -> PyObject *"}, { (char *)"Tools_invert_matrix", _wrap_Tools_invert_matrix, METH_VARARGS, (char *)"Tools_invert_matrix(self, matrix) -> PyObject *"}, { (char *)"new_Tools", _wrap_new_Tools, METH_VARARGS, (char *)"new_Tools() -> Tools"}, @@ -22148,10 +22222,10 @@ SWIG_init(void) { ; } else - PySys_WriteStdout("error redirecting stdout/stderr!\n"); + PySys_WriteStderr("error redirecting stdout/stderr!\n"); - JM_error_log = PyList_New(0); - JM_output_log = PyList_New(0); + JM_error_log = PyByteArray_FromStringAndSize("", 0); + JM_output_log = PyByteArray_FromStringAndSize("", 0); //----------------------------------------------------------------------------- // STOP redirect stdout/stderr diff --git a/fitz/helper-annot.i b/fitz/helper-annot.i index 372fb2e4a..0a9ed571f 100644 --- a/fitz/helper-annot.i +++ b/fitz/helper-annot.i @@ -276,8 +276,8 @@ struct fz_annot_s *JM_AnnotMultiline(fz_context *ctx, pdf_page *page, PyObject * PyObject *p = PySequence_ITEM(points, i); if (!PySequence_Check(p) || PySequence_Size(p) != 2) THROWMSG("invalid points list"); - point.x = (float) PyFloat_AsDouble(PySequence_GetItem(p, 0)); - point.y = (float) PyFloat_AsDouble(PySequence_GetItem(p, 1)); + point.x = (float) PyFloat_AsDouble(PySequence_ITEM(p, 0)); + point.y = (float) PyFloat_AsDouble(PySequence_ITEM(p, 1)); Py_CLEAR(p); pdf_add_annot_vertex(ctx, annot, point); if (i == 0) @@ -407,7 +407,7 @@ PyObject *JM_annot_set_border(fz_context *ctx, PyObject *border, pdf_document *d pdf_obj *darr = pdf_new_array(ctx, doc, n); for (i = 0; i < n; i++) { - d = (int) PyInt_AsLong(PySequence_GetItem(ndashes, i)); + d = (int) PyInt_AsLong(PySequence_ITEM(ndashes, i)); pdf_array_push_int(ctx, darr, (int64_t) d); } pdf_dict_putl_drop(ctx, annot_obj, darr, PDF_NAME(BS), PDF_NAME(D), NULL); diff --git a/fitz/helper-fields.i b/fitz/helper-fields.i index 38f535bfb..bf6f1488a 100644 --- a/fitz/helper-fields.i +++ b/fitz/helper-fields.i @@ -127,7 +127,7 @@ void JM_set_choice_options(fz_context *ctx, pdf_annot *annot, PyObject *liste) pdf_obj *optarr = pdf_new_array(ctx, pdf, n); for (i = 0; i < n; i++) { - opt = JM_Python_str_AsChar(PySequence_GetItem(liste, i)); + opt = JM_Python_str_AsChar(PySequence_ITEM(liste, i)); pdf_array_push_text_string(ctx, optarr, (const char *) opt); JM_Python_str_DelForPy3(opt); } @@ -148,7 +148,7 @@ void JM_set_widget_properties(fz_context *ctx, pdf_annot *annot, PyObject *Widge { pdf_document *pdf = annot->page->doc; pdf_page *page = annot->page; - fz_rect rect = {0,0,0,0}; + fz_rect rect; pdf_obj *fill_col = NULL, *text_col = NULL, *border_col = NULL; pdf_obj *dashes = NULL; Py_ssize_t i, n = 0; @@ -173,12 +173,8 @@ void JM_set_widget_properties(fz_context *ctx, pdf_annot *annot, PyObject *Widge // rectangle -------------------------------------------------------------- value = PyObject_GetAttrString(Widget, "rect"); - rect.x0 = (float) PyFloat_AsDouble(PySequence_GetItem(value, 0)); - rect.y0 = (float) PyFloat_AsDouble(PySequence_GetItem(value, 1)); - rect.x1 = (float) PyFloat_AsDouble(PySequence_GetItem(value, 2)); - rect.y1 = (float) PyFloat_AsDouble(PySequence_GetItem(value, 3)); + rect = JM_rect_from_py(value); Py_CLEAR(value); - JM_PyErr_Clear; pdf_set_annot_rect(ctx, annot, rect); // set the rect // fill color ------------------------------------------------------------- @@ -189,7 +185,7 @@ void JM_set_widget_properties(fz_context *ctx, pdf_annot *annot, PyObject *Widge fill_col = pdf_new_array(ctx, pdf, n); for (i = 0; i < n; i++) pdf_array_push_real(ctx, fill_col, - PyFloat_AsDouble(PySequence_GetItem(value, i))); + PyFloat_AsDouble(PySequence_ITEM(value, i))); pdf_field_set_fill_color(ctx, pdf, annot->obj, fill_col); pdf_drop_obj(ctx, fill_col); } @@ -204,7 +200,7 @@ void JM_set_widget_properties(fz_context *ctx, pdf_annot *annot, PyObject *Widge dashes = pdf_new_array(ctx, pdf, n); for (i = 0; i < n; i++) pdf_array_push_int(ctx, dashes, - PyInt_AsLong(PySequence_GetItem(value, i))); + PyInt_AsLong(PySequence_ITEM(value, i))); pdf_dict_putl_drop(ctx, annot->obj, dashes, PDF_NAME(BS), PDF_NAME(D), NULL); } @@ -219,7 +215,7 @@ void JM_set_widget_properties(fz_context *ctx, pdf_annot *annot, PyObject *Widge border_col = pdf_new_array(ctx, pdf, n); for (i = 0; i < n; i++) pdf_array_push_real(ctx, border_col, - PyFloat_AsDouble(PySequence_GetItem(value, i))); + PyFloat_AsDouble(PySequence_ITEM(value, i))); pdf_dict_putl_drop(ctx, annot->obj, border_col, PDF_NAME(MK), PDF_NAME(BC), NULL); } diff --git a/fitz/helper-geo-c.i b/fitz/helper-geo-c.i index 5f647d038..063e16822 100644 --- a/fitz/helper-geo-c.i +++ b/fitz/helper-geo-c.i @@ -46,16 +46,16 @@ fz_quad JM_quad_from_py(PyObject *r) if (!r || !PySequence_Check(r) || PySequence_Size(r) != 4) return q; - double x0 = PyFloat_AsDouble(PySequence_GetItem(r, 0)); + double x0 = PyFloat_AsDouble(PySequence_ITEM(r, 0)); if (!PyErr_Occurred()) // assume case 1: a rect is given { - double y0 = PyFloat_AsDouble(PySequence_GetItem(r, 1)); + double y0 = PyFloat_AsDouble(PySequence_ITEM(r, 1)); if (PyErr_Occurred()) goto return_simple; - double x1 = PyFloat_AsDouble(PySequence_GetItem(r, 2)); + double x1 = PyFloat_AsDouble(PySequence_ITEM(r, 2)); if (PyErr_Occurred()) goto return_simple; - double y1 = PyFloat_AsDouble(PySequence_GetItem(r, 3)); + double y1 = PyFloat_AsDouble(PySequence_ITEM(r, 3)); if (PyErr_Occurred()) goto return_simple; q.ul = fz_make_point(x0, y0); @@ -71,16 +71,16 @@ fz_quad JM_quad_from_py(PyObject *r) PyErr_Clear(); for (i = 0; i < 4; i++) { - PyObject *o = PySequence_GetItem(r, i); + PyObject *o = PySequence_ITEM(r, i); p[i].x = p[i].y = 0; if (!PySequence_Check(o) || PySequence_Size(o) != 2) goto weiter; - p[i].x = PyFloat_AsDouble(PySequence_GetItem(o, 0)); + p[i].x = PyFloat_AsDouble(PySequence_ITEM(o, 0)); if (PyErr_Occurred()) p[i].x = 0; - p[i].y = PyFloat_AsDouble(PySequence_GetItem(o, 1)); + p[i].y = PyFloat_AsDouble(PySequence_ITEM(o, 1)); if (PyErr_Occurred()) p[i].y = 0; @@ -103,16 +103,16 @@ fz_rect JM_rect_from_py(PyObject *r) if (!r || !PySequence_Check(r) || PySequence_Size(r) != 4) return fz_infinite_rect; - double x0 = PyFloat_AsDouble(PySequence_GetItem(r, 0)); + double x0 = PyFloat_AsDouble(PySequence_ITEM(r, 0)); if (PyErr_Occurred()) goto return_empty; - double y0 = PyFloat_AsDouble(PySequence_GetItem(r, 1)); + double y0 = PyFloat_AsDouble(PySequence_ITEM(r, 1)); if (PyErr_Occurred()) goto return_empty; - double x1 = PyFloat_AsDouble(PySequence_GetItem(r, 2)); + double x1 = PyFloat_AsDouble(PySequence_ITEM(r, 2)); if (PyErr_Occurred()) goto return_empty; - double y1 = PyFloat_AsDouble(PySequence_GetItem(r, 3)); + double y1 = PyFloat_AsDouble(PySequence_ITEM(r, 3)); if (PyErr_Occurred()) goto return_empty; return fz_make_rect((float) x0, (float) y0, (float) x1, (float) y1); @@ -138,16 +138,16 @@ fz_irect JM_irect_from_py(PyObject *r) if (!r || !PySequence_Check(r) || PySequence_Size(r) != 4) return fz_infinite_irect; - long x0 = PyLong_AsLong(PySequence_GetItem(r, 0)); + long x0 = PyLong_AsLong(PySequence_ITEM(r, 0)); if (PyErr_Occurred()) goto return_empty; - long y0 = PyLong_AsLong(PySequence_GetItem(r, 1)); + long y0 = PyLong_AsLong(PySequence_ITEM(r, 1)); if (PyErr_Occurred()) goto return_empty; - long x1 = PyLong_AsLong(PySequence_GetItem(r, 2)); + long x1 = PyLong_AsLong(PySequence_ITEM(r, 2)); if (PyErr_Occurred()) goto return_empty; - long y1 = PyLong_AsLong(PySequence_GetItem(r, 3)); + long y1 = PyLong_AsLong(PySequence_ITEM(r, 3)); if (PyErr_Occurred()) goto return_empty; return fz_make_irect((int) x0, (int) y0, (int) x1, (int) y1); @@ -175,10 +175,10 @@ fz_point JM_point_from_py(PyObject *p) if (!p || !PySequence_Check(p) || PySequence_Size(p) != 2) return p0; - double x = PyFloat_AsDouble(PySequence_GetItem(p, 0)); + double x = PyFloat_AsDouble(PySequence_ITEM(p, 0)); if (PyErr_Occurred()) goto zero_point; - double y = PyFloat_AsDouble(PySequence_GetItem(p, 1)); + double y = PyFloat_AsDouble(PySequence_ITEM(p, 1)); if (PyErr_Occurred()) goto zero_point; return fz_make_point((float) x, (float) y); @@ -206,22 +206,22 @@ fz_matrix JM_matrix_from_py(PyObject *m) if (!m || !PySequence_Check(m) || PySequence_Size(m) != 6) return m0; - double a = PyFloat_AsDouble(PySequence_GetItem(m, 0)); + double a = PyFloat_AsDouble(PySequence_ITEM(m, 0)); if (PyErr_Occurred()) goto fertig; - double b = PyFloat_AsDouble(PySequence_GetItem(m, 1)); + double b = PyFloat_AsDouble(PySequence_ITEM(m, 1)); if (PyErr_Occurred()) goto fertig; - double c = PyFloat_AsDouble(PySequence_GetItem(m, 2)); + double c = PyFloat_AsDouble(PySequence_ITEM(m, 2)); if (PyErr_Occurred()) goto fertig; - double d = PyFloat_AsDouble(PySequence_GetItem(m, 3)); + double d = PyFloat_AsDouble(PySequence_ITEM(m, 3)); if (PyErr_Occurred()) goto fertig; - double e = PyFloat_AsDouble(PySequence_GetItem(m, 4)); + double e = PyFloat_AsDouble(PySequence_ITEM(m, 4)); if (PyErr_Occurred()) goto fertig; - double f = PyFloat_AsDouble(PySequence_GetItem(m, 5)); + double f = PyFloat_AsDouble(PySequence_ITEM(m, 5)); if (PyErr_Occurred()) goto fertig; m0.a = a; diff --git a/fitz/helper-other.i b/fitz/helper-other.i index d1cce1451..167641842 100644 --- a/fitz/helper-other.i +++ b/fitz/helper-other.i @@ -152,7 +152,7 @@ void JM_color_FromSequence(PyObject *color, int *n, float col[4]) float mcol[4] = {0,0,0,0}; // local color storage for (i = 0; i < len; i++) { - mcol[i] = (float) PyFloat_AsDouble(PySequence_GetItem(color, i)); + mcol[i] = (float) PyFloat_AsDouble(PySequence_ITEM(color, i)); if (PyErr_Occurred()) { PyErr_Clear(); // reset Py error indicator @@ -751,9 +751,9 @@ static void JM_write_stdout(fz_context *ctx, void *opaque, const void *buffer, size_t count) { if (!buffer || !count) return; - PyObject *c = Py_BuildValue("s#", (const char *) buffer, (Py_ssize_t) count); + PyObject *c = PyByteArray_FromStringAndSize((const char *)buffer, (Py_ssize_t) count); if (!c || c == NONE) return; - PyList_Append(JM_output_log, c); + JM_output_log = PySequence_InPlaceConcat(JM_output_log, c); Py_CLEAR(c); return; } @@ -762,9 +762,9 @@ static void JM_write_stderr(fz_context *ctx, void *opaque, const void *buffer, size_t count) { if (!buffer || !count) return; - PyObject *c = Py_BuildValue("s#", (const char *) buffer, (Py_ssize_t) count); + PyObject *c = PyByteArray_FromStringAndSize((const char *)buffer, (Py_ssize_t) count); if (!c || c == NONE) return; - PyList_Append(JM_error_log, c); + JM_error_log = PySequence_InPlaceConcat(JM_error_log, c); Py_CLEAR(c); return; } diff --git a/fitz/helper-select.i b/fitz/helper-select.i index 3c01bfeb5..48a8c9569 100644 --- a/fitz/helper-select.i +++ b/fitz/helper-select.i @@ -224,7 +224,7 @@ void retainpages(fz_context *ctx, globals *glo, PyObject *liste) { for (page = 0; page < argc; page++) { - i = (int) PyInt_AsLong(PySequence_GetItem(liste, page)); + i = (int) PyInt_AsLong(PySequence_ITEM(liste, page)); if (i < 0 || i >= pagecount) THROWMSG("invalid page number(s)"); retainpage(ctx, doc, pages, kids, i); diff --git a/fitz/utils.py b/fitz/utils.py index 0265129a4..d74bc206d 100644 --- a/fitz/utils.py +++ b/fitz/utils.py @@ -170,10 +170,10 @@ def getPixmap(page, matrix = None, colorspace = csRGB, clip = None, assert cs.n in (1,3,4), "unsupported colorspace" dl = page.getDisplayList() # create DisplayList - if type(clip) is IRect: - scissor = clip.rect + if clip: + scissor = Rect(clip) else: - scissor = clip + scissor = None pix = dl.getPixmap(matrix = matrix, colorspace = cs, alpha = alpha, @@ -877,12 +877,12 @@ def drawLine(page, p1, p2, color = (0, 0, 0), dashes = None, """Draw a line from point p1 to point p2. """ img = page.newShape() - img.drawLine(p1, p2) + img.drawLine(Point(p1), Point(p2)) img.finish(color = color, dashes = dashes, width = width, closePath = False, roundCap = roundCap, morph = morph) img.commit(overlay) - return p2 + return Point(p2) #------------------------------------------------------------------------------- # Page.drawSquiggle @@ -892,12 +892,12 @@ def drawSquiggle(page, p1, p2, breadth = 2, color = (0, 0, 0), dashes = None, """Draw a squiggly line from point p1 to point p2. """ img = page.newShape() - img.drawSquiggle(p1, p2, breadth = breadth) + img.drawSquiggle(Point(p1), Point(p2), breadth = breadth) img.finish(color = color, dashes = dashes, width = width, closePath = False, roundCap = roundCap, morph = morph) img.commit(overlay) - return p2 + return point(p2) #------------------------------------------------------------------------------- # Page.drawZigzag @@ -907,12 +907,12 @@ def drawZigzag(page, p1, p2, breadth = 2, color = (0, 0, 0), dashes = None, """Draw a zigzag line from point p1 to point p2. """ img = page.newShape() - img.drawZigzag(p1, p2, breadth = breadth) + img.drawZigzag(Point(p1), Point(p2), breadth = breadth) img.finish(color = color, dashes = dashes, width = width, closePath = False, roundCap = roundCap, morph = morph) img.commit(overlay) - return p2 + return Point(p2) #------------------------------------------------------------------------------- # Page.drawRect @@ -922,7 +922,7 @@ def drawRect(page, rect, color = (0, 0, 0), fill = None, dashes = None, """Draw a rectangle. """ img = page.newShape() - Q = img.drawRect(rect) + Q = img.drawRect(Rect(rect)) img.finish(color = color, fill = fill, dashes = dashes, width = width, roundCap = roundCap, morph = morph) img.commit(overlay) @@ -954,7 +954,7 @@ def drawCircle(page, center, radius, color = (0, 0, 0), fill = None, """Draw a circle given its center and radius. """ img = page.newShape() - Q = img.drawCircle(center, radius) + Q = img.drawCircle(Point(center), radius) img.finish(color = color, fill = fill, dashes = dashes, width = width, roundCap = roundCap, morph = morph) img.commit(overlay) @@ -969,7 +969,7 @@ def drawOval(page, rect, color = (0, 0, 0), fill = None, dashes = None, """Draw an oval given its containing rectangle. """ img = page.newShape() - Q = img.drawOval(rect) + Q = img.drawOval(Rect(rect)) img.finish(color = color, fill = fill, dashes = dashes, width = width, roundCap = roundCap, morph = morph) img.commit(overlay) @@ -985,7 +985,7 @@ def drawCurve(page, p1, p2, p3, color = (0, 0, 0), fill = None, dashes = None, """Draw a special Bezier curve from p1 to p3, generating control points on lines p1 to p2 and p2 to p3. """ img = page.newShape() - Q = img.drawCurve(p1, p2, p3) + Q = img.drawCurve(Point(p1), Point(p2), Point(p3)) img.finish(color = color, fill = fill, dashes = dashes, width = width, roundCap = roundCap, morph = morph, closePath = closePath) img.commit(overlay) @@ -1002,7 +1002,7 @@ def drawBezier(page, p1, p2, p3, p4, color = (0, 0, 0), fill = None, """Draw a general cubic Bezier curve from p1 to p4 using control points p2 and p3. """ img = page.newShape() - Q = img.drawBezier(p1, p2, p3, p4) + Q = img.drawBezier(Point(p1), Point(p2), Point(p3), Point(p4)) img.finish(color = color, fill = fill, dashes = dashes, width = width, roundCap = roundCap, morph = morph, closePath = closePath) img.commit(overlay) @@ -1022,7 +1022,7 @@ def drawSector(page, center, point, beta, color = (0, 0, 0), fill = None, fullSector - connect arc ends with center """ img = page.newShape() - Q = img.drawSector(center, point, beta, fullSector = fullSector) + Q = img.drawSector(Point(center), Point(point), beta, fullSector = fullSector) img.finish(color = color, fill = fill, dashes = dashes, width = width, roundCap = roundCap, morph = morph, closePath = closePath) img.commit(overlay) @@ -1707,9 +1707,8 @@ def horizontal_angle(C, P): This uses the arcus sine function and resolves its inherent ambiguity by looking up in which quadrant vector S = P - C is located. """ - S = P - C # vector 'C' -> 'P' - rad = abs(S) # distance of C to P - alfa = math.asin(abs(S.y) / rad) # absolute angle from horizontal + S = Point(P - C).unit # unit vector 'C' -> 'P' + alfa = math.asin(abs(S.y)) # absolute angle from horizontal if S.x < 0: # make arcsin result unique if S.y <= 0: # bottom-left alfa = -(math.pi - alfa) @@ -1739,13 +1738,13 @@ def __init__(self, page): def updateRect(self, x): if self.rect is None: - if type(x) is Point: + if len(x) == 2: self.rect = Rect(x, x) else: - self.rect = x + self.rect = Rect(x) else: - if type(x) is Point: + if len(x) == 2: self.rect.x0 = min(self.rect.x0, x.x) self.rect.y0 = min(self.rect.y0, x.y) self.rect.x1 = max(self.rect.x1, x.x) @@ -1776,39 +1775,41 @@ def drawPolyline(self, points): """ for i, p in enumerate(points): if i == 0: - if not (self.lastPoint == p): - self.contents += "%g %g m\n" % (p.x + self.x, - self.height - p.y - self.y) - self.lastPoint = p + if not (self.lastPoint == Point(p)): + self.contents += "%g %g m\n" % (p[0] + self.x, + self.height - p[1] - self.y) + self.lastPoint = Point(p) else: - self.contents += "%g %g l\n" % (p.x + self.x, - self.height - p.y - self.y) + self.contents += "%g %g l\n" % (p[0] + self.x, + self.height - p[1] - self.y) self.updateRect(p) - self.lastPoint = points[-1] + self.lastPoint = Point(points[-1]) return self.lastPoint def drawBezier(self, p1, p2, p3, p4): """Draw a standard cubic Bezier curve. """ - if not (self.lastPoint == p1): - self.contents += "%g %g m\n" % (p1.x + self.x, - self.height - p1.y - self.y) - self.contents += "%g %g %g %g %g %g c\n" % (p2.x + self.x, - self.height - p2.y - self.y, - p3.x + self.x, - self.height - p3.y - self.y, - p4.x + self.x, - self.height - p4.y - self.y) + if not (self.lastPoint == Point(p1)): + self.contents += "%g %g m\n" % (p1[0] + self.x, + self.height - p1[1] - self.y) + self.contents += "%g %g %g %g %g %g c\n" % (p2[0] + self.x, + self.height - p2[1] - self.y, + p3[0] + self.x, + self.height - p3[1] - self.y, + p4[0] + self.x, + self.height - p4[1] - self.y) self.updateRect(p1) self.updateRect(p2) self.updateRect(p3) self.updateRect(p4) - self.lastPoint = p4 + self.lastPoint = Point(p4) return self.lastPoint def drawOval(self, rect): """Draw an ellipse inside a rectangle. """ + if type(rect) is not Rect: + rect = Rect(rect) if rect.isEmpty or rect.isInfinite: raise ValueError("rectangle must be finite and not empty") mt = rect.tl + (rect.tr - rect.tl)*0.5 @@ -1830,6 +1831,8 @@ def drawCircle(self, center, radius): """Draw a circle given its center and radius. """ assert radius > 1e-5, "radius must be postive" + if type(center) is not Point: + center = Point(center) p1 = center - (radius, 0) return self.drawSector(center, p1, 360, fullSector = False) @@ -1837,6 +1840,9 @@ def drawCurve(self, p1, p2, p3): """Draw a curve between points using one control point. """ kappa = 0.55228474983 + if type(p1) is not Point: p1 = Point(p1) + if type(p2) is not Point: p2 = Point(p2) + if type(p3) is not Point: p3 = Point(p3) k1 = p1 + (p2 - p1) * kappa k2 = p3 + (p2 - p3) * kappa return self.drawBezier(p1, k1, k2, p3) @@ -1844,6 +1850,8 @@ def drawCurve(self, p1, p2, p3): def drawSector(self, center, point, beta, fullSector = True): """Draw a circle sector. """ + if type(center) is not Point: center = Point(center) + if type(point) is not Point: point = Point(point) h = self.height l3 = "%g %g m\n" l4 = "%g %g %g %g %g %g c\n" @@ -1908,7 +1916,7 @@ def drawSector(self, center, point, beta, fullSector = True): def drawRect(self, rect): """Draw a rectangle. """ - r = +rect + r = Rect(rect) self.contents += "%g %g %g %g re\n" % (r.x0 + self.x, self.height - r.y1 - self.y, r.width, r.height) @@ -1919,6 +1927,8 @@ def drawRect(self, rect): def drawZigzag(self, p1, p2, breadth = 2): """Draw a zig-zagged line from p1 to p2. """ + p1 = Point(p1) + p2 = Point(p2) S = p2 - p1 # vector start - end rad = abs(S) # distance of points cnt = 4 * int(round(rad / (4 * breadth), 0)) # always take full phases @@ -1948,6 +1958,8 @@ def drawZigzag(self, p1, p2, breadth = 2): def drawSquiggle(self, p1, p2, breadth = 2): """Draw a squiggly line from p1 to p2. """ + p1 = Point(p1) + p2 = Point(p2) S = p2 - p1 # vector start - end rad = abs(S) # distance of points cnt = 4 * int(round(rad / (4 * breadth), 0)) # always take full phases @@ -2000,10 +2012,11 @@ def insertText(self, point, buffer, text = buffer.splitlines() else: text = buffer - + if not len(text) > 0: return 0 - + + point = Point(point) maxcode = max([ord(c) for c in "\n".join(text)]) # ensure valid 'fontname' xref = 0 # xref of font object @@ -2135,6 +2148,7 @@ def insertTextbox(self, rect, buffer, fontname = "Helvetica", fontfile = None, morph - morph box with a matrix and a pivotal point Returns: unused or deficit rectangle area (float) """ + rect = Rect(rect) if rect.isEmpty or rect.isInfinite: raise ValueError("text box must be finite and not empty") CheckColor(color) diff --git a/fitz/version.i b/fitz/version.i index 325c0d6b0..e53552207 100644 --- a/fitz/version.i +++ b/fitz/version.i @@ -1,6 +1,6 @@ %pythoncode %{ VersionFitz = "1.14.0" -VersionBind = "1.14.0" -VersionDate = "2018-11-16 05:14:22" -version = (VersionBind, VersionFitz, "20181116051422") +VersionBind = "1.14.1" +VersionDate = "2018-11-18 17:07:00" +version = (VersionBind, VersionFitz, "20181118170700") %} \ No newline at end of file