diff options
author | Ray Johnston <ray.johnston@pobox.com> | 2022-05-31 10:19:01 -0700 |
---|---|---|
committer | Ray Johnston <ray.johnston@pobox.com> | 2022-07-30 10:26:52 -0700 |
commit | af3fa99aece39bfb83583d28e817c630c269bfea (patch) | |
tree | def55ccc2d61266142c574a249a0db9a26bc7da4 /psi | |
parent | b097603e36106f26550f85eadc124efba9e6d39b (diff) | |
download | ghostpdl-af3fa99aece39bfb83583d28e817c630c269bfea.tar.gz |
New PageList processing, supporting PDF and XPS random order.
Supports out-of-order ranges (if the parser allows it and disables the
PageHandler, i.e., flp device). Also adds support for ranges appended
to the "even" and "odd" keyword following a ":".
As before a trailing "-" in a range implies the last page, and as was
supported by the previous 'gxps' code, a leading "-" also is the last page.
For example, with XPS or PDF: -sPageList=odd:3-7,even:4-8,1-,-1,9
prints pages: 3, 5, 7, 4, 6, 8, 1, 2, ..., last, last, last-1, ..., 1, 9
The PageList string is parsed using C code into an array that consists of
an initial int that is > 0 if the list is ordered, followed by sets of
3 integers per range, even/odd flag (odd=1, even=2), start, end. The
final 3 ints are 0,0,0 as a marker.
The initial int is used by 'pagelist_test_printed' as an index to the next
range to be processed when the PageList is used for languages that can only
be processed sequentially (e.g. PS and PCL) and is updated when the page
passes the end of the current range. A value of -1 means the ranges are
not ordered (not strctly increasing).
The flp_fillpage is changed to ignore errors from processing the PageList
performed by ParsePageList (called from SkipPage) when PageCount is 0
so that parsers that support out of order processing (PDF and XPS) can
continue until later. This should have little or no performance impact
since it is limited to PageCount == 0.
Note that the new PDF parser also uses the C code parser and then uses
the array of ranges returned by ".PDFparsePageList". The old PostScript
based parser has not been updated, although it is easy to do so.
Diffstat (limited to 'psi')
-rw-r--r-- | psi/zpdfops.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/psi/zpdfops.c b/psi/zpdfops.c index 7023592b0..50b8b1b5a 100644 --- a/psi/zpdfops.c +++ b/psi/zpdfops.c @@ -30,6 +30,7 @@ #include "iminst.h" #include "dstack.h" #include "gsicc_profilecache.h" +#include "pagelist.h" #endif #include "ghost.h" @@ -1453,6 +1454,36 @@ error: } return code; } + +/* <Pagelist_string> num_pages .PDFparsePageList even/odd, start, end ... range_count */ +/* PostScript will create an array of 3 integers per range */ +static int zPDFparsePageList(i_ctx_t *i_ctx_p) +{ + int code = 0, size = 0, i; + os_ptr op = osp; + int *page_range_array; + int num_pages = op->value.intval; + + code = pagelist_parse_to_array((char *)((op - 1)->value.const_bytes), imemory, num_pages, &page_range_array); + make_int(op, 0); /* default return 0 */ + if (code < 0) { + return code; + } + /* code returned is the number of ranges */ + size = 3 * (code - 1); /* runpdfpagerange doesn't use 0, 0, 0 marker at end */ + code = ref_stack_push(&o_stack, size - 1); + if (code < 0) { + return code; + } + /* push the even/odd, start, end triples on the stack */ + for (i=0; i < size; i++) { + /* skip the initial "ordered" flag */ + make_int(ref_stack_index(&o_stack, size - i), page_range_array[i+1]); + } + make_int(ref_stack_index(&o_stack, 0), size); + pagelist_free_range_array(imemory, page_range_array); /* all done with C array */ + return 0; +} #else static int zPDFfile(i_ctx_t *i_ctx_p) @@ -1499,6 +1530,11 @@ static int zPDFInit(i_ctx_t *i_ctx_p) { return_error(gs_error_undefined); } + +static int zPDFparsePageList(i_ctx_t *i_ctx_p) +{ + return_error(gs_error_undefined); +} #endif /* ------ Initialization procedure ------ */ @@ -1518,6 +1554,7 @@ const op_def zpdfops_op_defs[] = {"1.PDFDrawPage", zPDFdrawpage}, {"1.PDFDrawAnnots", zPDFdrawannots}, {"1.PDFInit", zPDFInit}, + {"1.PDFparsePageList", zPDFparsePageList}, #ifdef HAVE_LIBIDN {"1.saslprep", zsaslprep}, #endif |