diff options
author | Sam James <sam@gentoo.org> | 2022-09-21 14:18:08 +0100 |
---|---|---|
committer | Sam James <sam@gentoo.org> | 2022-10-02 04:31:25 +0100 |
commit | a529111f77ff46f4836fe7312e70953bc16587cf (patch) | |
tree | 9dc3924cb1a6ef3ef853b7bb45f735365e0b4e6d /psi/zpdfops.c | |
parent | Import Ghostscript 9.56.1 (diff) | |
download | ghostscript-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.c | 605 |
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 |