|
91 | 91 | // memory allocation macros |
92 | 92 | #define JM_MEMORY 1 |
93 | 93 | #if PY_VERSION_HEX < 0x03000000 |
| 94 | +#undef JM_MEMORY |
94 | 95 | #define JM_MEMORY 0 |
95 | 96 | #endif |
| 97 | + |
96 | 98 | #if JM_MEMORY == 1 |
97 | 99 | #define JM_Alloc(type, len) PyMem_New(type, len) |
98 | 100 | #define JM_Free(x) PyMem_Del(x) |
|
119 | 121 | #define JM_BinFromChar(x) PyByteArray_FromStringAndSize(x, (Py_ssize_t) strlen(x)) |
120 | 122 | #define JM_BinFromCharSize(x, y) PyByteArray_FromStringAndSize(x, (Py_ssize_t) y) |
121 | 123 | # endif |
| 124 | + |
122 | 125 | // define Python None object |
123 | 126 | #define NONE Py_BuildValue("s", NULL) |
| 127 | + |
124 | 128 | #include <fitz.h> |
125 | 129 | #include <pdf.h> |
126 | 130 | #include <zlib.h> |
@@ -235,22 +239,24 @@ struct fz_document_s |
235 | 239 |
|
236 | 240 | fz_document_s(const char *filename = NULL, PyObject *stream = NULL, |
237 | 241 | const char *filetype = NULL, struct fz_rect_s *rect = NULL, |
| 242 | + float width = 0, float height = 0, |
238 | 243 | float fontsize = 11) |
239 | 244 | { |
240 | 245 | gctx->error->errcode = 0; // reset any error code |
241 | 246 | gctx->error->message[0] = 0; // reset any error message |
242 | 247 | struct fz_document_s *doc = NULL; |
243 | 248 | fz_stream *data = NULL; |
244 | 249 | char *streamdata; |
| 250 | + float w = width, h = height; |
245 | 251 | size_t streamlen = JM_CharFromBytesOrArray(stream, &streamdata); |
246 | 252 | fz_try(gctx) |
247 | 253 | { |
248 | 254 | if (rect) |
249 | 255 | { |
250 | 256 | if (fz_is_empty_rect(rect) || fz_is_infinite_rect(rect)) |
251 | 257 | THROWMSG("rect must be finite and not empty"); |
252 | | - if (rect->x0 != 0.0f || rect->y0 != 0.0f) |
253 | | - THROWMSG("rect must start at (0,0)"); |
| 258 | + w = rect->x1 - rect->x0; |
| 259 | + h = rect->y1 - rect->y0; |
254 | 260 | } |
255 | 261 | if (streamlen > 0) |
256 | 262 | { |
@@ -282,8 +288,8 @@ struct fz_document_s |
282 | 288 | } |
283 | 289 | } |
284 | 290 | fz_catch(gctx) return NULL; |
285 | | - if (rect) |
286 | | - fz_layout_document(gctx, doc, rect->x1, rect->y1, fontsize); |
| 291 | + if (w > 0 && h > 0) |
| 292 | + fz_layout_document(gctx, doc, w, h, fontsize); |
287 | 293 | return doc; |
288 | 294 | } |
289 | 295 |
|
@@ -677,21 +683,48 @@ struct fz_document_s |
677 | 683 |
|
678 | 684 | FITZEXCEPTION(layout, !result) |
679 | 685 | CLOSECHECK(layout) |
680 | | - PyObject *layout(struct fz_rect_s *rect, float fontsize = 11) |
| 686 | + %pythonappend layout %{ |
| 687 | + self._reset_page_refs() |
| 688 | + self.initData()%} |
| 689 | + PyObject *layout(struct fz_rect_s *rect = NULL, float width = 0, float height = 0, float fontsize = 11) |
681 | 690 | { |
682 | 691 | if (!fz_is_document_reflowable(gctx, $self)) return NONE; |
683 | 692 | fz_try(gctx) |
684 | 693 | { |
685 | | - if (fz_is_empty_rect(rect) || fz_is_infinite_rect(rect)) |
686 | | - THROWMSG("rect must be finite and not empty"); |
687 | | - if (rect->x0 != 0.0 || rect->y0 != 0) |
688 | | - THROWMSG("rect must start at (0, 0)"); |
689 | | - fz_layout_document(gctx, $self, rect->x1, rect->y1, fontsize); |
| 694 | + float w = width, h = height; |
| 695 | + if (rect) |
| 696 | + { |
| 697 | + if (fz_is_empty_rect(rect) || fz_is_infinite_rect(rect)) |
| 698 | + THROWMSG("rect must be finite and not empty"); |
| 699 | + w = rect->x1 - rect->x0; |
| 700 | + h = rect->y1 - rect->y0; |
| 701 | + } |
| 702 | + if (w <= 0.0f || h <= 0.0f) |
| 703 | + THROWMSG("invalid page size"); |
| 704 | + fz_layout_document(gctx, $self, w, h, fontsize); |
690 | 705 | } |
691 | 706 | fz_catch(gctx) return NULL; |
692 | 707 | return NONE; |
693 | 708 | } |
694 | 709 |
|
| 710 | + CLOSECHECK(makeBookmark) |
| 711 | + PyObject *makeBookmark(int pno = 0) |
| 712 | + { |
| 713 | + if (!fz_is_document_reflowable(gctx, $self)) return NONE; |
| 714 | + int n = pno, cp = fz_count_pages(gctx, $self); |
| 715 | + while(n < 0) n += cp; |
| 716 | + long long mark = (long long) fz_make_bookmark(gctx, $self, n); |
| 717 | + return PyLong_FromLongLong(mark); |
| 718 | + } |
| 719 | +
|
| 720 | + CLOSECHECK(findBookmark) |
| 721 | + int findBookmark(long long bookmark) |
| 722 | + { |
| 723 | + if (!fz_is_document_reflowable(gctx, $self)) return -1; |
| 724 | + fz_bookmark m = (fz_bookmark) bookmark; |
| 725 | + return fz_lookup_bookmark(gctx, $self, m); |
| 726 | + } |
| 727 | +
|
695 | 728 | CLOSECHECK0(isReflowable) |
696 | 729 | %pythoncode%{@property%} |
697 | 730 | PyObject *isReflowable() |
@@ -2031,7 +2064,7 @@ struct fz_page_s { |
2031 | 2064 | pdf_page *page = pdf_page_from_fz_page(gctx, $self); |
2032 | 2065 | fz_annot *fzannot = NULL; |
2033 | 2066 | pdf_annot *annot = NULL; |
2034 | | - char *data = NULL, *uf, *d; |
| 2067 | + char *data = NULL, *uf = ufilename, *d = desc; |
2035 | 2068 | if (!ufilename) uf = filename; |
2036 | 2069 | if (!desc) d = filename; |
2037 | 2070 | size_t len = 0; |
|
0 commit comments