summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam James <sam@gentoo.org>2022-09-21 14:18:08 +0100
committerSam James <sam@gentoo.org>2022-10-02 04:31:25 +0100
commita529111f77ff46f4836fe7312e70953bc16587cf (patch)
tree9dc3924cb1a6ef3ef853b7bb45f735365e0b4e6d /psi/zpdfops.c
parentImport Ghostscript 9.56.1 (diff)
downloadghostscript-gpl-patches-a529111f77ff46f4836fe7312e70953bc16587cf.tar.gz
ghostscript-gpl-patches-a529111f77ff46f4836fe7312e70953bc16587cf.tar.bz2
ghostscript-gpl-patches-a529111f77ff46f4836fe7312e70953bc16587cf.zip
Import Ghostscript 10.0ghostscript-10.0ghostscript-10
Signed-off-by: Sam James <sam@gentoo.org>
Diffstat (limited to 'psi/zpdfops.c')
-rw-r--r--psi/zpdfops.c605
1 files changed, 466 insertions, 139 deletions
diff --git a/psi/zpdfops.c b/psi/zpdfops.c
index 45bd7803..e5526772 100644
--- a/psi/zpdfops.c
+++ b/psi/zpdfops.c
@@ -22,10 +22,15 @@
#include "gzht.h"
#include "gsrefct.h"
#include "pdf_misc.h"
+#include "pdf_stack.h"
+#include "pdf_dict.h"
+#include "pdf_array.h"
+#include "pdf_loop_detect.h"
#include "iminst.h"
#include "dstack.h"
#include "gsicc_profilecache.h"
+#include "pagelist.h"
#endif
#include "ghost.h"
@@ -402,6 +407,7 @@ typedef struct pdfctx_s {
gs_memory_t *pdf_memory; /* The 'wrapped' memory allocator used by the PDF interpreter. Not exposed to garbager */
gs_memory_t *pdf_stream_memory; /* The memory allocator used to copy the PostScript stream to pdf_stream. Not exposed to garbager */
stream *pdf_stream;
+ bool UsingPDFFile;
gsicc_profile_cache_t *profile_cache;
gs_memory_t *cache_memory; /* The memory allocator used to allocate the working (GC'ed) profile cache */
} pdfctx_t;
@@ -508,13 +514,13 @@ static int zPDFstream(i_ctx_t *i_ctx_p)
pdfctx = r_ptr(op, pdfctx_t);
/* If the supplied context already has a file open, signal an error */
- if (pdfctx->ps_stream != NULL)
+ if (pdfctx->ps_stream != NULL || pdfctx->UsingPDFFile)
return_error(gs_error_ioerror);
s->close_at_eod = false;
pdfctx->ps_stream = s;
- pdfctx->pdf_stream = s_alloc_immovable(imemory, "PDFstream copy of PS stream");
- pdfctx->pdf_stream_memory = imemory;
+ pdfctx->pdf_stream = s_alloc_immovable(imemory->stable_memory, "PDFstream copy of PS stream");
+ pdfctx->pdf_stream_memory = imemory->stable_memory;
if (pdfctx->pdf_stream == NULL)
return_error(gs_error_VMerror);
@@ -580,6 +586,7 @@ static int zPDFfile(i_ctx_t *i_ctx_p)
if (code < 0)
return code;
+ pdfctx->UsingPDFFile = true;
pdfctx->ctx->finish_page = NULL;
pop(2);
@@ -622,6 +629,283 @@ static int zPDFclose(i_ctx_t *i_ctx_p)
return code;
}
+static int PDFobj_to_PSobj(i_ctx_t *i_ctx_p, pdfctx_t *pdfctx, pdf_obj *PDFobj, ref *PSobj);
+
+#define DEBUG_INFO_DICT 0
+
+static void debug_printmark(int type)
+{
+#if DEBUG_INFO_DICT
+ switch(type) {
+ case 0:
+ dbgprintf("<<\n");
+ break;
+ case 1:
+ dbgprintf(">>\n");
+ break;
+ case 2:
+ dbgprintf("[");
+ break;
+ case 3:
+ dbgprintf("]\n");
+ break;
+ }
+#endif
+}
+
+static void debug_pdfobj(i_ctx_t *i_ctx_p, pdfctx_t *pdfctx, pdf_obj *PDFobj)
+{
+#if DEBUG_INFO_DICT
+ char *str = NULL;
+ int code = 0, len = 0;
+
+ switch(pdfi_type_of(PDFobj)) {
+ case PDF_NAME:
+ code = pdfi_string_from_name(pdfctx->ctx, (pdf_name *)PDFobj, &str, &len);
+ if (code < 0)
+ return;
+ dbgprintf1("/%s ", str);
+ (void)pdfi_free_string_from_name(pdfctx->ctx, str);
+ break;
+ case PDF_STRING:
+ str = (char *)gs_alloc_bytes(pdfctx->ctx->memory, ((pdf_string *)PDFobj)->length + 1, "");
+ if (str == NULL)
+ return;
+ memset(str, 0x00, ((pdf_string *)PDFobj)->length + 1);
+ memcpy(str, ((pdf_string *)PDFobj)->data, ((pdf_string *)PDFobj)->length);
+ dbgprintf1("/%s ", str);
+ gs_free_object(pdfctx->ctx->memory, str, "");
+ break;
+ case PDF_INT:
+ dbgprintf1("/%d ", ((pdf_num *)PDFobj)->value.i);
+ break;
+ case PDF_REAL:
+ dbgprintf1("/%f ", ((pdf_num *)PDFobj)->value.d);
+ break;
+ break;
+ case PDF_BOOL:
+ if (PDFobj == PDF_TRUE_OBJ)
+ dbgprintf("true ");
+ else
+ dbgprintf("false ");
+ break;
+ default:
+ break;
+ }
+#endif
+}
+
+static int PDFdict_to_PSdict(i_ctx_t *i_ctx_p, pdfctx_t *pdfctx, pdf_dict *PDFdict, ref *PSdict)
+{
+ int code = 0;
+ uint64_t index = 0;
+ pdf_name *Key = NULL;
+ pdf_obj *Value = NULL;
+ ref nameref, valueref;
+ char *str = NULL;
+ int len = 0;
+
+ code = dict_create(pdfi_dict_entries(PDFdict), PSdict);
+ if (code < 0)
+ return code;
+
+ code = pdfi_loop_detector_mark(pdfctx->ctx);
+ if (code < 0)
+ goto error;
+
+ code = pdfi_dict_first(pdfctx->ctx, PDFdict, (pdf_obj **)&Key, &Value, &index);
+ if (code == gs_error_undefined) {
+ code = 0;
+ goto error;
+ }
+
+ while (code >= 0) {
+ code = pdfi_string_from_name(pdfctx->ctx, Key, &str, &len);
+ if (code < 0)
+ goto error;
+
+ debug_pdfobj(i_ctx_p, pdfctx, (pdf_obj *)Key);
+
+ code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)str, len, &nameref, 1);
+ if (code < 0)
+ goto error;
+
+ code = PDFobj_to_PSobj(i_ctx_p, pdfctx, Value, &valueref);
+ if (code < 0)
+ goto error;
+
+ code = dict_put(PSdict, &nameref, &valueref, &i_ctx_p->dict_stack);
+ if (code < 0)
+ goto error;
+
+ pdfi_countdown(Key);
+ pdfi_countdown(Value);
+ Key = NULL;
+ Value = NULL;
+
+ code = pdfi_loop_detector_cleartomark(pdfctx->ctx);
+ if (code < 0)
+ goto error;
+
+ code = pdfi_loop_detector_mark(pdfctx->ctx);
+ if (code < 0)
+ goto error;
+
+ (void)pdfi_free_string_from_name(pdfctx->ctx, str);
+ str = NULL;
+ code = pdfi_dict_next(pdfctx->ctx, PDFdict, (pdf_obj **)&Key, &Value, &index);
+ if (code == gs_error_undefined) {
+ code = 0;
+ break;
+ }
+ }
+error:
+ (void)pdfi_free_string_from_name(pdfctx->ctx, str);
+ pdfi_countdown(Key);
+ pdfi_countdown(Value);
+
+ if (code < 0)
+ (void)pdfi_loop_detector_cleartomark(pdfctx->ctx);
+ else
+ code = pdfi_loop_detector_cleartomark(pdfctx->ctx);
+ return code;
+}
+
+static int PDFarray_to_PSarray(i_ctx_t *i_ctx_p, pdfctx_t *pdfctx, pdf_array *PDFarray, ref *PSarray)
+{
+ int code = 0, i = 0;
+ ref PS_ref;
+ pdf_obj *array_obj = NULL;
+ ref *eltp = NULL;
+
+ code = pdfi_loop_detector_mark(pdfctx->ctx);
+ if (code < 0)
+ goto error;
+
+ code = ialloc_ref_array(PSarray, a_all, pdfi_array_size(PDFarray), "zPDFInfo");
+ if (code < 0)
+ goto error;
+
+ for (i = 0;i < pdfi_array_size(PDFarray); i++) {
+ code = pdfi_array_fetch_recursing(pdfctx->ctx, PDFarray, i, &array_obj, true, true);
+ if (code < 0)
+ goto error;
+ code = PDFobj_to_PSobj(i_ctx_p, pdfctx, array_obj, &PS_ref);
+ if (code < 0) {
+ pdfi_countdown(array_obj);
+ goto error;
+ }
+
+ eltp = PSarray->value.refs + i;
+ ref_assign_old((const ref *)PSarray, eltp, &PS_ref, "zPDFInfo");
+
+ pdfi_countdown(array_obj);
+ array_obj = NULL;
+ }
+error:
+ if (code < 0)
+ (void)pdfi_loop_detector_cleartomark(pdfctx->ctx);
+ else
+ code = pdfi_loop_detector_cleartomark(pdfctx->ctx);
+ return code;
+}
+
+static int PDFobj_to_PSobj(i_ctx_t *i_ctx_p, pdfctx_t *pdfctx, pdf_obj *PDFobj, ref *PSobj)
+{
+ int code = 0;
+
+ code = pdfi_loop_detector_mark(pdfctx->ctx);
+ if (code < 0)
+ goto error;
+
+ debug_pdfobj(i_ctx_p, pdfctx, PDFobj);
+
+ switch(pdfi_type_of(PDFobj)) {
+ case PDF_NAME:
+ {
+ char *str = NULL;
+ int len;
+
+ code = pdfi_string_from_name(pdfctx->ctx, (pdf_name *)PDFobj, &str, &len);
+ if (code < 0)
+ goto error;
+ code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)str, len, PSobj, 1);
+ (void)pdfi_free_string_from_name(pdfctx->ctx, str);
+ }
+ break;
+ case PDF_STRING:
+ {
+ byte *sbody;
+ uint size = ((pdf_name *)PDFobj)->length;
+
+ sbody = ialloc_string(size, "string");
+ if (sbody == 0) {
+ code = gs_note_error(gs_error_VMerror);
+ } else {
+ make_string(PSobj, a_all | icurrent_space, size, sbody);
+ memcpy(sbody, ((pdf_name *)PDFobj)->data, size);
+ }
+ }
+ break;
+ case PDF_INT:
+ {
+ int64_t i;
+
+ code = pdfi_obj_to_int(pdfctx->ctx, PDFobj, &i);
+ if (code < 0)
+ goto error;
+ make_int(PSobj, i);
+ }
+ break;
+ case PDF_BOOL:
+ if (PDFobj == PDF_TRUE_OBJ)
+ make_bool(PSobj, 1);
+ else
+ make_bool(PSobj, 0);
+ break;
+ case PDF_REAL:
+ {
+ double d;
+
+ code = pdfi_obj_to_real(pdfctx->ctx, PDFobj, &d);
+ if (code < 0)
+ goto error;
+ make_real(PSobj, d);
+ }
+ break;
+ case PDF_DICT:
+ if (PDFobj->object_num != 0) {
+ code = pdfi_loop_detector_add_object(pdfctx->ctx, PDFobj->object_num);
+ if (code < 0)
+ goto error;
+ }
+ debug_printmark(0);
+ code = PDFdict_to_PSdict(i_ctx_p, pdfctx, (pdf_dict *)PDFobj, PSobj);
+ debug_printmark(1);
+ break;
+ case PDF_ARRAY:
+ if (PDFobj->object_num != 0) {
+ code = pdfi_loop_detector_add_object(pdfctx->ctx, PDFobj->object_num);
+ if (code < 0)
+ goto error;
+ }
+ debug_printmark(2);
+ code = PDFarray_to_PSarray(i_ctx_p, pdfctx, (pdf_array *)PDFobj, PSobj);
+ debug_printmark(3);
+ break;
+ default:
+ make_null(PSobj);
+ break;
+ }
+
+error:
+ if (code < 0)
+ (void)pdfi_loop_detector_cleartomark(pdfctx->ctx);
+ else
+ code = pdfi_loop_detector_cleartomark(pdfctx->ctx);
+ return code;
+}
+
static int zPDFinfo(i_ctx_t *i_ctx_p)
{
os_ptr op = osp;
@@ -634,7 +918,7 @@ static int zPDFinfo(i_ctx_t *i_ctx_p)
check_type(*(op), t_pdfctx);
pdfctx = r_ptr(op, pdfctx_t);
- if (pdfctx->pdf_stream != NULL) {
+ if (pdfctx->pdf_stream != NULL || pdfctx->UsingPDFFile) {
code = dict_create(4, op);
if (code < 0)
return code;
@@ -702,6 +986,36 @@ static int zPDFinfo(i_ctx_t *i_ctx_p)
}
gs_free_object(pdfctx->ctx->memory, names_array, "free collection temporary filenames");
code = 0;
+ } else {
+ if (pdfctx->ctx->Info != NULL) {
+ code = PDFobj_to_PSobj(i_ctx_p, pdfctx, (pdf_obj *)pdfctx->ctx->Info, (ref *)op);
+ if (code < 0)
+ return code;
+
+ code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"NumPages", 8, &nameref, 1);
+ if (code < 0)
+ return code;
+
+ make_int(&intref, pdfctx->ctx->num_pages);
+
+ code = dict_put(op, &nameref, &intref, &i_ctx_p->dict_stack);
+ if (code < 0)
+ return code;
+ } else {
+ code = dict_create(1, op);
+ if (code < 0)
+ return code;
+
+ code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"NumPages", 8, &nameref, 1);
+ if (code < 0)
+ return code;
+
+ make_int(&intref, pdfctx->ctx->num_pages);
+
+ code = dict_put(op, &nameref, &intref, &i_ctx_p->dict_stack);
+ if (code < 0)
+ return code;
+ }
}
}
else {
@@ -719,10 +1033,9 @@ error:
static int zPDFpageinfo(i_ctx_t *i_ctx_p)
{
os_ptr op = osp;
- ref aref, boolref, nameref, numref, *eltp;
- int page = 0, code = 0, i;
+ int page = 0, code = 0;
pdfctx_t *pdfctx;
- pdf_info_t info;
+ pdf_dict *InfoDict = NULL;
pdfi_switch_t i_switch;
check_op(2);
@@ -733,11 +1046,11 @@ static int zPDFpageinfo(i_ctx_t *i_ctx_p)
check_type(*(op - 1), t_pdfctx);
pdfctx = r_ptr(op - 1, pdfctx_t);
- if (pdfctx->pdf_stream != NULL) {
+ if (pdfctx->pdf_stream != NULL || pdfctx->UsingPDFFile) {
code = pdfi_gstate_from_PS(pdfctx->ctx, igs, &i_switch, pdfctx->profile_cache);
if (code >= 0) {
- code = pdfi_page_info(pdfctx->ctx, (uint64_t)page, &info);
+ code = pdfi_page_info(pdfctx->ctx, (uint64_t)page, &InfoDict, false);
pdfi_gstate_to_PS(pdfctx->ctx, igs, &i_switch);
}
@@ -748,141 +1061,52 @@ static int zPDFpageinfo(i_ctx_t *i_ctx_p)
pop(1);
op = osp;
- code = dict_create(4, op);
- if (code < 0)
- return code;
-
- code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"HasAnnots", 9, &nameref, 1);
- if (code < 0)
- return code;
- make_bool(&boolref, false);
- code = dict_put(op, &nameref, &boolref, &i_ctx_p->dict_stack);
+ code = PDFobj_to_PSobj(i_ctx_p, pdfctx, (pdf_obj *)InfoDict, op);
+ pdfi_countdown(InfoDict);
if (code < 0)
return code;
+ }
+ else {
+ return_error(gs_error_ioerror);
+ }
+ return 0;
+}
- code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"UsesTransparency", 16, &nameref, 1);
- if (code < 0)
- return code;
- make_bool(&boolref, info.HasTransparency);
- code = dict_put(op, &nameref, &boolref, &i_ctx_p->dict_stack);
- if (code < 0)
- return code;
+static int zPDFpageinfoExt(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ int page = 0, code = 0;
+ pdfctx_t *pdfctx;
+ pdf_dict *InfoDict = NULL;
+ pdfi_switch_t i_switch;
- code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"NumSpots", 8, &nameref, 1);
- if (code < 0)
- return code;
- make_int(&numref, info.NumSpots);
- code = dict_put(op, &nameref, &numref, &i_ctx_p->dict_stack);
- if (code < 0)
- return code;
+ check_op(2);
- if (info.boxes & MEDIA_BOX) {
- code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"MediaBox", 8, &nameref, 1);
- if (code < 0)
- return code;
- code = ialloc_ref_array(&aref, a_all, 4, "array");
- if (code < 0)
- return code;
- refset_null(aref.value.refs, 4);
- for (i=0;i < 4;i++) {
- make_real(&numref, info.MediaBox[i]);
- eltp = aref.value.refs + i;
- ref_assign_old(&aref, eltp, &numref, "put");
- }
- code = dict_put(op, &nameref, &aref, &i_ctx_p->dict_stack);
- if (code < 0)
- return code;
- }
+ check_type(*op, t_integer);
+ page = op->value.intval;
- if (info.boxes & CROP_BOX) {
- code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"CropBox", 7, &nameref, 1);
- if (code < 0)
- return code;
- code = ialloc_ref_array(&aref, a_all, 4, "array");
- if (code < 0)
- return code;
- refset_null(aref.value.refs, 4);
- for (i=0;i < 4;i++) {
- make_real(&numref, info.CropBox[i]);
- eltp = aref.value.refs + i;
- ref_assign_old(&aref, eltp, &numref, "put");
- }
- code = dict_put(op, &nameref, &aref, &i_ctx_p->dict_stack);
- if (code < 0)
- return code;
- }
+ check_type(*(op - 1), t_pdfctx);
+ pdfctx = r_ptr(op - 1, pdfctx_t);
- if (info.boxes & TRIM_BOX) {
- code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"TrimBox", 7, &nameref, 1);
- if (code < 0)
- return code;
- code = ialloc_ref_array(&aref, a_all, 4, "array");
- if (code < 0)
- return code;
- refset_null(aref.value.refs, 4);
- for (i=0;i < 4;i++) {
- make_real(&numref, info.TrimBox[i]);
- eltp = aref.value.refs + i;
- ref_assign_old(&aref, eltp, &numref, "put");
- }
- code = dict_put(op, &nameref, &aref, &i_ctx_p->dict_stack);
- if (code < 0)
- return code;
- }
+ if (pdfctx->pdf_stream != NULL || pdfctx->UsingPDFFile) {
+ code = pdfi_gstate_from_PS(pdfctx->ctx, igs, &i_switch, pdfctx->profile_cache);
- if (info.boxes & ART_BOX) {
- code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"ArtBox", 6, &nameref, 1);
- if (code < 0)
- return code;
- code = ialloc_ref_array(&aref, a_all, 4, "array");
- if (code < 0)
- return code;
- refset_null(aref.value.refs, 4);
- for (i=0;i < 4;i++) {
- make_real(&numref, info.ArtBox[i]);
- eltp = aref.value.refs + i;
- ref_assign_old(&aref, eltp, &numref, "put");
- }
- code = dict_put(op, &nameref, &aref, &i_ctx_p->dict_stack);
- if (code < 0)
- return code;
- }
+ if (code >= 0) {
+ code = pdfi_page_info(pdfctx->ctx, (uint64_t)page, &InfoDict, true);
- if (info.boxes & BLEED_BOX) {
- code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"BleedBox", 8, &nameref, 1);
- if (code < 0)
- return code;
- code = ialloc_ref_array(&aref, a_all, 4, "array");
- if (code < 0)
- return code;
- refset_null(aref.value.refs, 4);
- for (i=0;i < 4;i++) {
- make_real(&numref, info.BleedBox[i]);
- eltp = aref.value.refs + i;
- ref_assign_old(&aref, eltp, &numref, "put");
- }
- code = dict_put(op, &nameref, &aref, &i_ctx_p->dict_stack);
- if (code < 0)
- return code;
+ pdfi_gstate_to_PS(pdfctx->ctx, igs, &i_switch);
}
- code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"Rotate", 6, &nameref, 1);
if (code < 0)
return code;
- make_real(&numref, info.Rotate);
- code = dict_put(op, &nameref, &numref, &i_ctx_p->dict_stack);
+
+ pop(1);
+ op = osp;
+
+ code = PDFobj_to_PSobj(i_ctx_p, pdfctx, (pdf_obj *)InfoDict, op);
+ pdfi_countdown(InfoDict);
if (code < 0)
return code;
-
- if (info.UserUnit != 1) {
- code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"UserUnit", 8, &nameref, 1);
- if (code < 0)
- return code;
- make_real(&numref, info.UserUnit);
- code = dict_put(op, &nameref, &numref, &i_ctx_p->dict_stack);
- if (code < 0)
- return code;
- }
}
else {
return_error(gs_error_ioerror);
@@ -919,7 +1143,7 @@ static int zPDFdrawpage(i_ctx_t *i_ctx_p)
check_type(*(op - 1), t_pdfctx);
pdfctx = r_ptr(op - 1, pdfctx_t);
- if (pdfctx->pdf_stream != NULL) {
+ if (pdfctx->pdf_stream != NULL || pdfctx->UsingPDFFile) {
code = gs_gsave(igs);
if (code < 0)
return code;
@@ -927,7 +1151,10 @@ static int zPDFdrawpage(i_ctx_t *i_ctx_p)
code = pdfi_gstate_from_PS(pdfctx->ctx, igs, &i_switch, pdfctx->profile_cache);
if (code >= 0) {
- code = pdfi_page_render(pdfctx->ctx, page, false);
+ if (pdfctx->ctx->args.pdfinfo)
+ code = pdfi_output_page_info(pdfctx->ctx, page);
+ else
+ code = pdfi_page_render(pdfctx->ctx, page, false);
if (code >= 0)
pop(2);
@@ -1004,6 +1231,7 @@ static int zPDFInit(i_ctx_t *i_ctx_p)
pdfctx->ctx = NULL;
pdfctx->ps_stream = NULL;
pdfctx->pdf_stream = NULL;
+ pdfctx->UsingPDFFile = false;
pdfctx->pdf_stream_memory = NULL;
pdfctx->profile_cache = gsicc_profilecache_new(imemory);
if (pdfctx->profile_cache == NULL) {
@@ -1217,19 +1445,49 @@ static int zPDFInit(i_ctx_t *i_ctx_p)
if (code < 0)
goto error;
}
- if (dict_find_string(pdictref, "CIDSubstPath", &pvalueref) > 0) {
+ if (dict_find_string(pdictref, "CIDFSubstPath", &pvalueref) > 0) {
if (!r_has_type(pvalueref, t_string))
goto error;
- pdfctx->ctx->args.cidsubstpath.data = (byte *)gs_alloc_bytes(pdfctx->ctx->memory, r_size(pvalueref) + 1, "PDF CIDSubstPath from zpdfops");
- memcpy(pdfctx->ctx->args.cidsubstpath.data, pvalueref->value.const_bytes, r_size(pvalueref));
- pdfctx->ctx->args.cidsubstpath.size = r_size(pvalueref);
+ pdfctx->ctx->args.cidfsubstpath.data = (byte *)gs_alloc_bytes(pdfctx->ctx->memory, r_size(pvalueref) + 1, "PDF cidfsubstpath from zpdfops");
+ if (pdfctx->ctx->args.cidfsubstpath.data == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto error;
+ }
+ memcpy(pdfctx->ctx->args.cidfsubstpath.data, pvalueref->value.const_bytes, r_size(pvalueref));
+ pdfctx->ctx->args.cidfsubstpath.size = r_size(pvalueref);
}
- if (dict_find_string(pdictref, "CIDSubstFont", &pvalueref) > 0) {
+ if (dict_find_string(pdictref, "CIDFSubstFont", &pvalueref) > 0) {
if (!r_has_type(pvalueref, t_string))
goto error;
- pdfctx->ctx->args.cidsubstfont.data = (byte *)gs_alloc_bytes(pdfctx->ctx->memory, r_size(pvalueref) + 1, "PDF CIDSubstPath from zpdfops");
- memcpy(pdfctx->ctx->args.cidsubstfont.data, pvalueref->value.const_bytes, r_size(pvalueref));
- pdfctx->ctx->args.cidsubstfont.size = r_size(pvalueref);
+ pdfctx->ctx->args.cidfsubstfont.data = (byte *)gs_alloc_bytes(pdfctx->ctx->memory, r_size(pvalueref) + 1, "PDF cidfsubstfont from zpdfops");
+ if (pdfctx->ctx->args.cidfsubstfont.data == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto error;
+ }
+ memcpy(pdfctx->ctx->args.cidfsubstfont.data, pvalueref->value.const_bytes, r_size(pvalueref));
+ pdfctx->ctx->args.cidfsubstfont.size = r_size(pvalueref);
+ }
+ if (dict_find_string(pdictref, "SUBSTFONT", &pvalueref) > 0) {
+ ref nmstr, *namstrp;
+ if (r_has_type(pvalueref, t_string)) {
+ namstrp = pvalueref;
+ pdfctx->ctx->args.defaultfont_is_name = false;
+ } else if (r_has_type(pvalueref, t_name)) {
+ name_string_ref(imemory, pvalueref, &nmstr);
+ namstrp = &nmstr;
+ pdfctx->ctx->args.defaultfont_is_name = true;
+ }
+ else {
+ code = gs_note_error(gs_error_typecheck);
+ goto error;
+ }
+ pdfctx->ctx->args.defaultfont.data = (byte *)gs_alloc_bytes(pdfctx->ctx->memory, r_size(namstrp) + 1, "PDF defaultfontname from zpdfops");
+ if (pdfctx->ctx->args.defaultfont.data == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto error;
+ }
+ memcpy(pdfctx->ctx->args.defaultfont.data, pvalueref->value.const_bytes, r_size(namstrp));
+ pdfctx->ctx->args.defaultfont.size = r_size(namstrp);
}
if (dict_find_string(pdictref, "IgnoreToUnicode", &pvalueref) > 0) {
if (!r_has_type(pvalueref, t_boolean))
@@ -1241,6 +1499,11 @@ static int zPDFInit(i_ctx_t *i_ctx_p)
goto error;
pdfctx->ctx->args.nonativefontmap = pvalueref->value.boolval;
}
+ if (dict_find_string(pdictref, "PageCount", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_integer))
+ goto error;
+ pdfctx->ctx->Pdfmark_InitialPage = pvalueref->value.intval;
+ }
code = 0;
pop(1);
}
@@ -1273,6 +1536,44 @@ 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;
+
+ check_op(2);
+
+ code = int_param(op, max_int, &num_pages);
+ if (code < 0)
+ return code;
+
+ check_type_only(*(op - 1), t_string);
+
+ 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)
@@ -1300,6 +1601,11 @@ static int zPDFpageinfo(i_ctx_t *i_ctx_p)
return_error(gs_error_undefined);
}
+static int zPDFpageinfoExt(i_ctx_t *i_ctx_p)
+{
+ return_error(gs_error_undefined);
+}
+
static int zPDFmetadata(i_ctx_t *i_ctx_p)
{
return_error(gs_error_undefined);
@@ -1319,8 +1625,26 @@ 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
+static int zPDFAvailable(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+
+ push(1);
+#if defined(BUILD_PDF) && BUILD_PDF == 1
+ make_bool(op, true);
+#else
+ make_bool(op, false);
+#endif
+ return 0;
+}
+
/* ------ Initialization procedure ------ */
const op_def zpdfops_op_defs[] =
@@ -1333,10 +1657,13 @@ const op_def zpdfops_op_defs[] =
{"1.PDFClose", zPDFclose},
{"1.PDFInfo", zPDFinfo},
{"1.PDFPageInfo", zPDFpageinfo},
+ {"1.PDFPageInfoExt", zPDFpageinfoExt},
{"1.PDFMetadata", zPDFmetadata},
{"1.PDFDrawPage", zPDFdrawpage},
{"1.PDFDrawAnnots", zPDFdrawannots},
{"1.PDFInit", zPDFInit},
+ {"1.PDFparsePageList", zPDFparsePageList},
+ {"0.PDFAvailable", zPDFAvailable},
#ifdef HAVE_LIBIDN
{"1.saslprep", zsaslprep},
#endif