summaryrefslogtreecommitdiff
path: root/psi
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2021-08-12 12:00:25 +0100
committerRobin Watts <Robin.Watts@artifex.com>2021-08-12 12:25:53 +0100
commit316c3a08269212f1005709da64efcb383f8f5ce0 (patch)
treef159677a5685a79e9a735f6cbf375f85dbab4adc /psi
parent0a0c521d85d0275c0d207a35bd27f0a31d54012b (diff)
downloadghostpdl-316c3a08269212f1005709da64efcb383f8f5ce0.tar.gz
Commit pdfi to master.
This is a commit of the pdfi branch to master, eliminating the traditional merge step. The full history of the pdfi branch can be seen in the repo, and that branch is effectively frozen from this point onwards. This commit actually differs from pdfi in a small number of whitespace changes (trailing spaces etc).
Diffstat (limited to 'psi')
-rw-r--r--psi/bfont.h1
-rw-r--r--psi/idebug.c1
-rw-r--r--psi/igc.c1
-rw-r--r--psi/igcref.c1
-rw-r--r--psi/int.mak3
-rw-r--r--psi/interp.c3
-rw-r--r--psi/iref.h10
-rw-r--r--psi/iutil.c4
-rw-r--r--psi/msvc.mak152
-rw-r--r--psi/zbfont.c8
-rw-r--r--psi/zpdfops.c867
-rw-r--r--psi/zvmem.c1
12 files changed, 1039 insertions, 13 deletions
diff --git a/psi/bfont.h b/psi/bfont.h
index 06110f47d..184c11f76 100644
--- a/psi/bfont.h
+++ b/psi/bfont.h
@@ -85,5 +85,6 @@ gs_glyph zfont_encode_char(gs_font *pfont, gs_char chr, gs_glyph_space_t ignored
int gs_font_map_glyph_to_unicode(gs_font *font, gs_glyph glyph, int ch, unsigned short *unicode_return, unsigned int length);
const ref *zfont_get_to_unicode_map(gs_font_dir *dir);
void get_GlyphNames2Unicode(i_ctx_t *i_ctx_p, gs_font *pfont, ref *pdref);
+void get_zfont_glyph_name( void **proc);
#endif /* bfont_INCLUDED */
diff --git a/psi/idebug.c b/psi/idebug.c
index fb6ce0c70..796b53712 100644
--- a/psi/idebug.c
+++ b/psi/idebug.c
@@ -132,6 +132,7 @@ debug_print_full_ref(const gs_memory_t *mem, const ref * pref)
case t_string:
dmprintf2(mem, "string(%u)"PRI_INTPTR"", size, (intptr_t)pref->value.bytes);
break;
+ case t_pdfctx:
case t_struct:
strct:{
obj_header_t *obj = (obj_header_t *) pref->value.pstruct;
diff --git a/psi/igc.c b/psi/igc.c
index 5a841ebd5..420a013a0 100644
--- a/psi/igc.c
+++ b/psi/igc.c
@@ -958,6 +958,7 @@ gc_trace(gs_gc_root_t * rp, gc_state_t * pstate, gc_mark_stack * pmstack)
case t_fontID:
case t_struct:
case t_astruct:
+ case t_pdfctx:
nptr = rptr->value.pstruct;
goto rs;
/* Non-trivial non-struct cases */
diff --git a/psi/igcref.c b/psi/igcref.c
index 35fdc7580..a18bcfb79 100644
--- a/psi/igcref.c
+++ b/psi/igcref.c
@@ -431,6 +431,7 @@ igc_reloc_refs(ref_packed * from, ref_packed * to, gc_state_t * gcst)
case t_fontID:
case t_struct:
case t_astruct:
+ case t_pdfctx:
DO_RELOC(pref->value.pstruct,
RELOC_VAR(pref->value.pstruct));
break;
diff --git a/psi/int.mak b/psi/int.mak
index 4efdc768a..6499f5d9a 100644
--- a/psi/int.mak
+++ b/psi/int.mak
@@ -542,7 +542,7 @@ INT2=$(PSOBJ)idict.$(OBJ) $(PSOBJ)idparam.$(OBJ) $(PSOBJ)idstack.$(OBJ)
INT3=$(PSOBJ)iinit.$(OBJ) $(PSOBJ)interp.$(OBJ)
INT4=$(PSOBJ)iparam.$(OBJ) $(PSOBJ)ireclaim.$(OBJ) $(PSOBJ)iplugin.$(OBJ)
INT5=$(PSOBJ)iscan.$(OBJ) $(PSOBJ)iscannum.$(OBJ) $(PSOBJ)istack.$(OBJ)
-INT6=$(PSOBJ)iutil.$(OBJ) $(GLOBJ)sa85d.$(OBJ) $(GLOBJ)scantab.$(OBJ)
+INT6=$(PSOBJ)iutil.$(OBJ) $(GLOBJ)scantab.$(OBJ)
INT7=$(GLOBJ)sstring.$(OBJ) $(GLOBJ)stream.$(OBJ)
Z1=$(PSOBJ)zarith.$(OBJ) $(PSOBJ)zarray.$(OBJ) $(PSOBJ)zcontrol.$(OBJ)
Z2=$(PSOBJ)zdict.$(OBJ) $(PSOBJ)zfile.$(OBJ) $(PSOBJ)zfile1.$(OBJ) $(PSOBJ)zfileio.$(OBJ)
@@ -1810,6 +1810,7 @@ $(PSD)pdfops.dev : $(ECHOGS_XE) $(zpdfops_) $(INT_MAK) $(MAKEDIRS)
$(ADDMOD) $(PSD)pdfops -oper zpdfops
$(PSOBJ)zpdfops.$(OBJ) : $(PSSRC)zpdfops.c $(OP) $(MAKEFILE)\
+ $(ghost_h) $(gsmchunk_h) $(oper_h) \
$(igstate_h) $(istack_h) $(iutil_h) $(gspath_h) $(math__h) $(ialloc_h)\
$(string__h) $(store_h) $(INT_MAK) $(MAKEDIRS)
$(PSCC) $(PSO_)zpdfops.$(OBJ) $(C_) $(PSSRC)zpdfops.c
diff --git a/psi/interp.c b/psi/interp.c
index 40f94fe9a..2cf9d4a61 100644
--- a/psi/interp.c
+++ b/psi/interp.c
@@ -1158,7 +1158,8 @@ interp(i_ctx_t **pi_ctx_p /* context for execution, updated if resched */,
case lit(t_shortarray): case nox(t_shortarray):\
case plain(t_device): case plain_exec(t_device):\
case plain(t_struct): case plain_exec(t_struct):\
- case plain(t_astruct): case plain_exec(t_astruct)
+ case plain(t_astruct): case plain_exec(t_astruct):\
+ case plain(t_pdfctx): case plain_exec(t_pdfctx)
/* Executable arrays are treated as literals in direct execution. */
#define cases_lit_array()\
case exec(t_array): case exec(t_mixedarray): case exec(t_shortarray)
diff --git a/psi/iref.h b/psi/iref.h
index 955cff318..099ff93ba 100644
--- a/psi/iref.h
+++ b/psi/iref.h
@@ -204,6 +204,7 @@ typedef enum {
t_device, /* @ + value.pdevice */
t_oparray, /* @! # value.const_refs, uses size */
/* for index */
+ t_pdfctx, /* @ value.pstruct */
t_next_index /*** first available index ***/
} ref_type;
@@ -247,11 +248,12 @@ extern const byte ref_type_properties[1 << 6]; /* r_type_bits */
_REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* t_string */\
_REF_TYPE_USES_ACCESS, /* t_device */\
_REF_TYPE_USES_SIZE, /* t_oparray */\
+ 0, /* t_pdfctx */\
/*\
* The remaining types are the extended pseudo-types used by the\
* interpreter for operators. We need to fill up the table.\
*/\
- _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*24*/\
+ _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*24*/\
_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*28*/\
_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*32*/\
_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*36*/\
@@ -280,7 +282,7 @@ extern const byte ref_type_properties[1 << 6]; /* r_type_bits */
"STRC","ASTR",\
"int ","real","font","mark","name","null",\
"oper","save","str ",\
- "devc","opry"
+ "devc","opry","pdfctx"
/*
* Define the type names for the type operator.
*/
@@ -290,7 +292,7 @@ extern const byte ref_type_properties[1 << 6]; /* r_type_bits */
0,0,\
"integertype","realtype","fonttype","marktype","nametype","nulltype",\
"operatortype","savetype","stringtype",\
- "devicetype","operatortype"
+ "devicetype","operatortype","pdfctxtype"
/*
* Define the type names for obj_cvp (the == operator). We only need these
* for types that obj_cvp and obj_cvs don't handle specially.
@@ -301,7 +303,7 @@ extern const byte ref_type_properties[1 << 6]; /* r_type_bits */
0,0,0,0,\
"-fontID-","-mark-",0,\
0,0,"-save-","-string-",\
- "-device-",0
+ "-device-",0,"-pdfcontext-"
/*
* The following factors affect the encoding of attributes:
diff --git a/psi/iutil.c b/psi/iutil.c
index b51abbc92..ea582e6e2 100644
--- a/psi/iutil.c
+++ b/psi/iutil.c
@@ -179,6 +179,7 @@ obj_eq(const gs_memory_t *mem, const ref * pref1, const ref * pref2)
return (pref1->value.pdevice == pref2->value.pdevice);
case t_struct:
case t_astruct:
+ case t_pdfctx:
return (pref1->value.pstruct == pref2->value.pstruct);
case t_fontID:
/* This is complicated enough to deserve a separate procedure. */
@@ -478,6 +479,9 @@ obj_cvp(const ref * op, byte * str, uint len, uint * prlen,
size += 2;
data = (const byte *)buf;
goto nl;
+ case t_pdfctx:
+ data = (const byte *)"-pdfcontext-";
+ goto rs;
default:
other:
{
diff --git a/psi/msvc.mak b/psi/msvc.mak
index 3037c4445..5952a20d4 100644
--- a/psi/msvc.mak
+++ b/psi/msvc.mak
@@ -236,6 +236,18 @@ XPSGENDIR=$(GLGENDIR)
XPSOBJDIR=$(GLOBJDIR)
!endif
+!ifndef PDFSRCDIR
+PDFSRCDIR=.\pdf
+!endif
+
+!ifndef PDFGENDIR
+PDFGENDIR=$(GLGENDIR)
+!endif
+
+!ifndef PDFOBJDIR
+PDFOBJDIR=$(GLOBJDIR)
+!endif
+
!ifndef GPDLSRCDIR
GPDLSRCDIR=.\gpdl
!endif
@@ -268,7 +280,7 @@ IMGOBJDIR=$(GLOBJDIR)
CONTRIBDIR=.\contrib
-# Can we build PCL and XPS
+# Can we build PCL and XPS and PDF
!ifndef BUILD_PCL
BUILD_PCL=0
!if exist ("$(PLSRCDIR)\pl.mak")
@@ -283,6 +295,15 @@ BUILD_XPS=1
!endif
!endif
+!ifndef BUILD_PDF
+BUILD_PDF=0
+GPDF_DEV=
+!if exist ("$(PDFSRCDIR)\pdf.mak")
+BUILD_PDF=1
+GPDF_DEV=$(PDFOBJDIR)\pdfi.dev
+!endif
+!endif
+
!ifndef BUILD_GPDL
BUILD_GPDL=0
!if exist ("$(GPDLSRCDIR)\gpdl.mak")
@@ -292,6 +313,7 @@ BUILD_GPDL=1
PCL_TARGET=
XPS_TARGET=
+PDF_TARGET=
!if $(BUILD_PCL)
PCL_TARGET=gpcl6
@@ -301,11 +323,15 @@ PCL_TARGET=gpcl6
XPS_TARGET=gxps
!endif
+!if $(BUILD_PDF)
+PDF_TARGET=gpdf
+!endif
+
!if $(BUILD_GPDL)
GPDL_TARGET=gpdl
!endif
-PCL_XPS_PDL_TARGETS=$(PCL_TARGET) $(XPS_TARGET) $(GPDL_TARGET)
+PCL_XPS_PDL_TARGETS=$(PCL_TARGET) $(XPS_TARGET) $(GPDL_TARGET) $(PDF_TARGET)
# Define the root directory for Ghostscript installation.
@@ -471,17 +497,20 @@ GS=gswin64
PCL=gpcl6win64
XPS=gxpswin64
GPDL=gpdlwin64
+PDF=gpdfwin64
!else
!ifdef ARM
GS=gswinARM
PCL=gpcl6winARM
XPS=gxpswinARM
GPDL=gpdlwinARM
+PDF=gpdfwinARM
!else
GS=gswin32
PCL=gpcl6win32
XPS=gxpswin32
GPDL=gpdlwin32
+PDF=gpdfwin32
!endif
!endif
!endif
@@ -549,6 +578,26 @@ GXPSDLL=gxpsdll32
!endif
!endif
+!ifndef GPDFDLL
+!ifdef METRO
+!ifdef WIN64
+GPDFDLL=gpdfdll64metro
+!else
+!ifdef ARM
+GPDFDLL=gpfddllARM32metro
+!else
+GPDFDLL=gpdfdll32metro
+!endif
+!endif
+!else
+!ifdef WIN64
+GPDFDLL=gpdfdll64
+!else
+GPDFDLL=gpdfdll32
+!endif
+!endif
+!endif
+
!ifndef GPDLDLL
!ifdef METRO
!ifdef WIN64
@@ -739,6 +788,8 @@ EXTRACT_DIR=extract
! error Cannot find extract directory: $(EXTRACT_DIR)
! endif
EXTRACT_DEVS=$(DD)docxwrite.dev
+!else
+! message Not building with extract: $(EXTRACT_DIR)
!endif
# Alternatively, you can build a separate DLL
@@ -850,6 +901,10 @@ CFLAGS=$(CFLAGS) -DMETRO -DWINAPI_FAMILY=WINAPI_PARTITION_APP -DTIF_PLATFORM_CON
PNG_CFLAGS=/DExitProcess=exit
!endif
+!if $(BUILD_PDF)
+CFLAGS=/DBUILD_PDF=1 /I$(PDFSRCDIR) /I$(ZSRCDIR) $(CFLAGS)
+!endif
+
CFLAGS=$(CFLAGS) $(XCFLAGS)
# 1 --> Use 64 bits for gx_color_index. This is required only for
@@ -1623,7 +1678,7 @@ JPX_CFLAGS = $JPX_CFLAGS -DUSE_JPIP -DUSE_OPENJPEG_JP2 -DOPJ_STATIC
# Choose the language feature(s) to include. See gs.mak for details.
# if it's included, $(PSD)gs_pdfwr.dev should always be one of the last in the list
-PSI_FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)epsf.dev $(PSD)ttfont.dev \
+PSI_FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(GPDF_DEV) $(PSD)epsf.dev $(PSD)ttfont.dev \
$(PSD)jbig2.dev $(PSD)jpx.dev $(PSD)fapi_ps.dev $(GLD)winutf8.dev $(PSD)gs_pdfwr.dev
@@ -1632,6 +1687,8 @@ PCL_FEATURE_DEVS=$(PLOBJDIR)/pl.dev $(PLOBJDIR)/pjl.dev $(PXLOBJDIR)/pxl.dev $(P
XPS_FEATURE_DEVS=$(XPSOBJDIR)/pl.dev $(XPSOBJDIR)/xps.dev
+PDF_FEATURE_DEVS=$(PDFOBJDIR)/pl.dev $(PDFOBJDIR)/gpdf.dev
+
FEATURE_DEVS=$(GLD)pipe.dev $(GLD)gsnogc.dev $(GLD)htxlib.dev $(GLD)psl3lib.dev $(GLD)psl2lib.dev \
$(GLD)dps2lib.dev $(GLD)path1lib.dev $(GLD)patlib.dev $(GLD)psl2cs.dev $(GLD)rld.dev $(GLD)gxfapiu$(UFST_BRIDGE).dev\
$(GLD)ttflib.dev $(GLD)cielib.dev $(GLD)pipe.dev $(GLD)htxlib.dev $(GLD)sdct.dev $(GLD)libpng.dev\
@@ -1757,6 +1814,10 @@ BEGINFILES2=$(BEGINFILES2) $(BSCFILE)
!include $(XPSSRCDIR)\xpsromfs.mak
!endif
+!if $(BUILD_PDF)
+!include $(PDFSRCDIR)\pdfromfs.mak
+!endif
+
!include $(GLSRCDIR)\winlib.mak
!if $(BUILD_PCL)
@@ -1770,6 +1831,10 @@ BEGINFILES2=$(BEGINFILES2) $(BSCFILE)
!include $(XPSSRCDIR)\xps.mak
!endif
+!if $(BUILD_PDF)
+!include $(PDFSRCDIR)\pdf.mak
+!endif
+
!if $(BUILD_GPDL)
!include $(GPDLSRCDIR)\gpdl.mak
!endif
@@ -1785,6 +1850,7 @@ GSDLL_OBJS=$(PSOBJ)gsdll.$(OBJ) $(GLOBJ)gp_msdll.$(OBJ)
GPCL6DLL_DLL=$(BINDIR)\$(GPCL6DLL).dll
GXPSDLL_DLL=$(BINDIR)\$(GXPSDLL).dll
+GPDFDLL_DLL=$(BINDIR)\$(GPDFDLL).dll
GPDLDLL_DLL=$(BINDIR)\$(GPDLDLL).dll
INT_ARCHIVE_SOME=$(GLOBJ)gconfig.$(OBJ) $(GLOBJ)gscdefs.$(OBJ)
@@ -1855,6 +1921,27 @@ $(XPSGEN)xpslib.rsp: $(TOP_MAKEFILES)
!if $(TDEBUG) != 0
+$(PDFGEN)pdflib.rsp: $(TOP_MAKEFILES)
+ echo /NODEFAULTLIB:LIBC.lib > $(PDFGEN)pdflib.rsp
+ echo /NODEFAULTLIB:LIBCMT.lib >> $(PDFGEN)pdflib.rsp
+!ifdef METRO
+ echo kernel32.lib runtimeobject.lib rpcrt4.lib >> $(PDFGEN)pdflib.rsp
+!else
+ echo LIBCMTD.lib >> $(PDFGEN)pdflib.rsp
+!endif
+!else
+$(PDFGEN)pdflib.rsp: $(TOP_MAKEFILES)
+ echo /NODEFAULTLIB:LIBC.lib > $(PDFGEN)pdflib.rsp
+ echo /NODEFAULTLIB:LIBCMTD.lib >> $(PDFGEN)pdflib.rsp
+!ifdef METRO
+ echo kernel32.lib runtimeobject.lib rpcrt4.lib >> $(PDFGEN)pdflib.rsp
+!else
+ echo LIBCMT.lib >> $(PDFGEN)pdflib.rsp
+!endif
+!endif
+
+!if $(TDEBUG) != 0
+
$(GPDLGEN)gpdllib.rsp: $(TOP_MAKEFILES)
echo /NODEFAULTLIB:LIBC.lib > $(XPSGEN)gpdllib.rsp
echo /NODEFAULTLIB:LIBCMT.lib >> $(XPSGEN)gpdllib.rsp
@@ -2000,6 +2087,32 @@ $(GXPS_XE): $(GXPSDLL_DLL) $(DWMAINOBJS) $(GS_OBJ).res $(TOP_MAKEFILES)
$(LINK) $(LCT) @$(XPSGEN)gxpswin.rsp $(DWMAINOBJS) $(BINDIR)\$(GXPSDLL).lib $(LINKLIBPATH) @$(LIBCTR) $(GS_OBJ).res
del $(XPSGEN)gxpswin.rsp
+$(GPDFDLL_DLL): $(ECHOGS_XE) $(GSDLL_OBJ).res $(LIBCTR) $(LIB_ALL) $(PDF_DEVS_ALL) $(PDFGEN)pdflib.rsp \
+ $(PDFOBJ)pdfromfs$(COMPILE_INITS).$(OBJ) $(ld_tr) $(pdf_tr) $(MAIN_OBJ) $(PDF_TOP_OBJS) \
+ $(XOBJS) $(INT_ARCHIVE_SOME) $(TOP_MAKEFILES)
+ echo Linking $(GPDFDLL) $(GPDFDLL_DLL) $(METRO)
+ copy $(pdfld_tr) $(PDFGEN)gpdfwin.tr
+ echo $(MAIN_OBJ) $(PDF_TOP_OBJS) $(INT_ARCHIVE_SOME) $(XOBJS) >> $(PDFGEN)gpdfwin.tr
+ echo $(PCLOBJ)pdfromfs$(COMPILE_INITS).$(OBJ) >> $(PDFGEN)gpdfwin.tr
+ echo /DLL /DEF:$(PLSRCDIR)\$(GPDFDLL).def /OUT:$(GPDFDLL_DLL) > $(PDFGEN)gpdfwin.rsp
+!if "$(PROFILE)"=="1"
+ echo /PROFILE >> $(PDFGEN)gpdfwin.rsp
+!endif
+ $(LINK) $(LCT) @$(PDFGEN)gpdfwin.rsp $(GPDFDLL_OBJS) @$(PDFGEN)gpdfwin.tr @$(PDFGEN)pdflib.rsp $(LINKLIBPATH) @$(LIBCTR) $(GSDLL_OBJ).res
+ del $(PCLGEN)gpdfwin.rsp
+
+$(GPDF_XE): $(GPDFDLL_DLL) $(DWMAINOBJS) $(GS_OBJ).res $(TOP_MAKEFILES)
+ echo /SUBSYSTEM:CONSOLE > $(PDFGEN)gpdfwin.rsp
+!if "$(PROFILE)"=="1"
+ echo /PROFILE >> $(PDFGEN)gpdfwin.rsp
+!endif
+!ifdef WIN64
+ echo /OUT:$(GPDF_XE) >> $(PDFGEN)gpdfwin.rsp
+!else
+ echo /OUT:$(GPDF_XE) >> $(PDFGEN)gpdfwin.rsp
+!endif
+ $(LINK) $(LCT) @$(PDFGEN)gpdfwin.rsp $(DWMAINOBJS) $(BINDIR)\$(GPDFDLL).lib $(LINKLIBPATH) @$(LIBCTR) $(GS_OBJ).res
+ del $(PDFGEN)gpdfwin.rsp
$(GPDLDLL_DLL): $(ECHOGS_XE) $(GSDLL_OBJ).res $(LIBCTR) $(LIB_ALL) $(PCL_DEVS_ALL) $(XPS_DEVS_ALL) $(GS_ALL) \
@@ -2132,6 +2245,19 @@ $(GXPS_XE): $(ECHOGS_XE) $(LIBCTR) $(LIB_ALL) $(WINMAINOBJS) $(XPS_DEVS_ALL) $(X
del $(XPSGEN)xpswin.rsp
del $(XPSGEN)gxpswin.tr
+$(GPDF_XE): $(ECHOGS_XE) $(LIBCTR) $(LIB_ALL) $(WINMAINOBJS) $(PDF_DEVS_ALL) $(PDFGEN)pdflib.rsp \
+ $(PDF_TOP_OBJS) $(PDFOBJ)pdfromfs$(COMPILE_INITS).$(OBJ) \
+ $(ld_tr) $(pdf_tr) $(MAIN_OBJ) $(XOBJS) $(INT_ARCHIVE_SOME) \
+ $(TOP_MAKEFILES)
+ copy $(pdfld_tr) $(PDFGEN)gpdfwin.tr
+ echo $(WINMAINOBJS) $(MAIN_OBJ) $(PDF_TOP_OBJS) $(INT_ARCHIVE_SOME) $(XOBJS) >> $(PDFGEN)gpdfwin.tr
+ echo $(PCLOBJ)pdfromfs$(COMPILE_INITS).$(OBJ) >> $(PDFGEN)gpdfwin.tr
+ echo /SUBSYSTEM:CONSOLE > $(PDFGEN)pdfwin.rsp
+ echo /OUT:$(GPDF_XE) >> $(XPSGEN)pdfwin.rsp
+ $(LINK) $(LCT) @$(PDFGEN)pdfwin.rsp @$(PDFGEN)gpdfwin.tr $(LINKLIBPATH) @$(LIBCTR) @$(PDFGEN)pdflib.rsp
+ del $(XPSGEN)pdfwin.rsp
+ del $(XPSGEN)gpdfwin.tr
+
$(GPDL_XE): $(ECHOGS_XE) $(ld_tr) $(gpdl_tr) $(LIBCTR) $(LIB_ALL) $(WINMAINOBJS) $(XPS_DEVS_ALL) $(PCL_DEVS_ALL) $(GS_ALL) \
$(GPDLGEN)gpdllib.rsp $(GPDLOBJ)pdlromfs$(COMPILE_INITS).$(OBJ) \
$(GPDL_PSI_TOP_OBJS) $(PCL_PXL_TOP_OBJS) $(PSI_TOP_OBJ) $(XPS_TOP_OBJ) \
@@ -2185,6 +2311,9 @@ gpcl6debug:
gxpsdebug:
nmake -f $(MAKEFILE) $(DEBUGDEFS) FT_BRIDGE=$(FT_BRIDGE) gxps
+gpdfdebug:
+ nmake -f $(MAKEFILE) DEVSTUDIO="$(DEVSTUDIO)" FT_BRIDGE=$(FT_BRIDGE) $(DEBUGDEFS) $(WINDEFS) gpdf
+
gpdldebug:
nmake -f $(MAKEFILE) $(DEBUGDEFS) FT_BRIDGE=$(FT_BRIDGE) gpdl
@@ -2211,6 +2340,9 @@ gpcl6memento:
gxpsmemento:
nmake -f $(MAKEFILE) $(MEMENTODEFS) FT_BRIDGE=$(FT_BRIDGE) gxps
+gpdfmemento:
+ nmake -f $(MAKEFILE) DEVSTUDIO="$(DEVSTUDIO)" FT_BRIDGE=$(FT_BRIDGE) $(MEMENTODEFS) $(WINDEFS) gpdf
+
gpdlmemento:
nmake -f $(MAKEFILE) $(MEMENTODEFS) FT_BRIDGE=$(FT_BRIDGE) gpdl
@@ -2238,6 +2370,9 @@ gpcl6profile:
gxpsprofile:
nmake -f $(MAKEFILE) $(PROFILEDEFS) FT_BRIDGE=$(FT_BRIDGE) gxps
+gpdfprofile:
+ nmake -f $(MAKEFILE) DEVSTUDIO="$(DEVSTUDIO)" FT_BRIDGE=$(FT_BRIDGE) $(PROFILEDEFS) $(WINDEFS) gpdf
+
gpdlprofile:
nmake -f $(MAKEFILE) $(PROFILEDEFS) FT_BRIDGE=$(FT_BRIDGE) gpdl
@@ -2310,8 +2445,8 @@ ufst-lib:
ufst-debug: ufst-lib
nmake -f $(MAKEFILE) $(RECURSIVEDEFS) $(UFSTBASEDEFS) $(UFSTDEBUGDEFS) UFST_CFLAGS="$(UFST_CFLAGS)"
-gpcl6-ufst-debug: ufst-lib
- nmake -f $(MAKEFILE) $(RECURSIVEDEFS) $(UFSTBASEDEFS) $(UFSTDEBUGDEFS) UFST_CFLAGS="$(UFST_CFLAGS)" gpcl6
+ufst-debug-pcl: ufst-lib
+ nmake -f $(MAKEFILE) $(RECURSIVEDEFS) $(UFSTBASEDEFS) $(UFSTDEBUGDEFS) UFST_CFLAGS="$(UFST_CFLAGS)" pcl
ufst-debugclean: ufst-lib
nmake -f $(MAKEFILE) $(RECURSIVEDEFS) $(UFSTBASEDEFS) $(UFSTDEBUGDEFS) UFST_CFLAGS="$(UFST_CFLAGS)" clean
@@ -2322,8 +2457,8 @@ ufst-debugbsc: ufst-lib
ufst: ufst-lib
nmake -f $(MAKEFILE) $(RECURSIVEDEFS) $(UFSTBASEDEFS) $(UFSTDEFS) UFST_CFLAGS="$(UFST_CFLAGS)"
-gpcl6-ufst: ufst-lib
- nmake -f $(MAKEFILE) $(RECURSIVEDEFS) $(UFSTBASEDEFS) $(UFSTDEFS) UFST_CFLAGS="$(UFST_CFLAGS)" gpcl6
+ufst-pcl: ufst-lib
+ nmake -f $(MAKEFILE) $(RECURSIVEDEFS) $(UFSTBASEDEFS) $(UFSTDEFS) UFST_CFLAGS="$(UFST_CFLAGS)" pcl
ufst-clean: ufst-lib
nmake -f $(MAKEFILE) $(RECURSIVEDEFS) $(UFSTBASEDEFS) $(UFSTDEFS) UFST_CFLAGS="$(UFST_CFLAGS)" clean
@@ -2341,6 +2476,9 @@ gpcl6:$(GPCL_XE)
gxps:$(GXPS_XE)
$(NO_OP)
+gpdf:$(GPDF_XE)
+ $(NO_OP)
+
gpdl:$(GPDL_XE)
$(NO_OP)
diff --git a/psi/zbfont.c b/psi/zbfont.c
index fa2597d71..09589159b 100644
--- a/psi/zbfont.c
+++ b/psi/zbfont.c
@@ -144,6 +144,14 @@ zfont_glyph_name(gs_font *font, gs_glyph index, gs_const_string *pstr)
return 0;
}
+#define font_proc_glyph_name1\
+ int (gs_font *font, gs_glyph glyph, gs_const_string *pstr)
+
+void get_zfont_glyph_name( void **proc)
+{
+ *proc = zfont_glyph_name;
+}
+
static gs_char
gs_font_map_glyph_by_dict(const gs_memory_t *mem, const ref *map, gs_glyph glyph, ushort *u, unsigned int length)
{
diff --git a/psi/zpdfops.c b/psi/zpdfops.c
index 2539c275c..8386acbdf 100644
--- a/psi/zpdfops.c
+++ b/psi/zpdfops.c
@@ -16,7 +16,16 @@
/* Custom operators for PDF interpreter */
+#if defined(BUILD_PDF) && BUILD_PDF == 1
+#include "ghostpdf.h"
+#include "pdf_page.h"
+#include "gzht.h"
+#include "gsrefct.h"
+#include "pdf_misc.h"
+#endif
+
#include "ghost.h"
+#include "gsmchunk.h"
#include "oper.h"
#include "igstate.h"
#include "istack.h"
@@ -29,6 +38,9 @@
#include "store.h"
#include "gxgstate.h"
#include "gxdevsop.h"
+#include "idict.h"
+#include "iname.h"
+#include "bfont.h"
#ifdef HAVE_LIBIDN
# include <stringprep.h>
@@ -255,6 +267,851 @@ zsaslprep(i_ctx_t *i_ctx_p)
}
#endif
+#if defined(BUILD_PDF) && BUILD_PDF == 1
+static int
+psi_pdf_finish_page(pdf_context *ctx)
+{
+ return 0;
+}
+
+static int zdopdffile(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ pdf_context *ctx = NULL;
+ char pdffilename[gp_file_name_sizeof];
+ int code = 0, code2 = 0;
+ gs_memory_t *cmem;
+
+ check_read_type(*op, t_string);
+ if (r_size(op) > gp_file_name_sizeof - 2)
+ return_error(gs_error_limitcheck);
+
+ code = gs_memory_chunk_wrap(&cmem, imemory->non_gc_memory);
+ if (code < 0)
+ return_error(gs_error_VMerror);
+
+ ctx = pdfi_create_context(cmem);
+ if (ctx == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto done;
+ }
+
+ code = gs_gsave(ctx->pgs);
+ if (code < 0)
+ goto done;
+ code = gs_setdevice_no_erase(ctx->pgs, igs->device);
+ if (code < 0)
+ goto done;
+
+
+ ctx->finish_page = psi_pdf_finish_page;
+ memcpy(pdffilename, op->value.bytes, r_size(op));
+ pdffilename[r_size(op)] = 0;
+ code = pdfi_process_pdf_file(ctx, pdffilename);
+ code = gs_grestore(ctx->pgs);
+done:
+ if (ctx)
+ code2 = pdfi_free_context(ctx);
+ /* gs_memory_chunk_unwrap() returns the "wrapped" allocator, which we don't need */
+ (void)gs_memory_chunk_unwrap(cmem);
+
+ if (code == 0)
+ code = code2;
+ if (code >= 0) pop(1);
+ return code;
+}
+
+/*
+ * Declare the structure we use to represent an instance of the PDF parser
+ * as a t_struct.
+ */
+typedef struct pdfctx_s {
+ pdf_context *ctx; /* Not exposed to garbager */
+ stream *ps_stream;
+ 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;
+} pdfctx_t;
+
+/* Structure descriptors */
+static void pdfctx_finalize(const gs_memory_t *cmem, void *vptr);
+
+gs_private_st_composite_final(st_pdfctx_t, pdfctx_t, "pdfctx_struct",\
+ pdfctx_enum_ptrs, pdfctx_reloc_ptrs, pdfctx_finalize);
+
+static
+ENUM_PTRS_BEGIN(pdfctx_enum_ptrs) return 0;
+ENUM_PTR2(0, pdfctx_t, ps_stream, pdf_stream);
+ENUM_PTRS_END
+
+static RELOC_PTRS_BEGIN(pdfctx_reloc_ptrs);
+RELOC_PTR2(pdfctx_t, ps_stream, pdf_stream);
+RELOC_PTRS_END
+
+static void
+pdfctx_finalize(const gs_memory_t *cmem, void *vptr)
+{
+ pdfctx_t *pdfctx = vptr;
+ /* Finalize methods have to cope with the possibility of being called multiple times
+ * on the same object - hence we null the entries.
+ */
+
+ if (cmem != NULL) {
+ if (pdfctx->ctx != NULL) {
+ if (pdfctx->pdf_stream) {
+ memset(pdfctx->pdf_stream, 0x00, sizeof(stream));
+ gs_free_object(pdfctx->pdf_stream_memory, pdfctx->pdf_stream, "free PDF copy of stream");
+ pdfctx->pdf_stream = NULL;
+ }
+
+ if (pdfctx->ps_stream) {
+ /* Detach the PostScript stream from the PDF context, otherwise the
+ * free_context code will close the main stream.
+ */
+ pdfctx->ctx->main_stream = NULL;
+ }
+ (void)pdfi_free_context(pdfctx->ctx);
+ pdfctx->ctx = NULL;
+ }
+ if (pdfctx->pdf_memory != NULL) {
+ /* gs_memory_chunk_unwrap() returns the "wrapped" allocator, which we don't need */
+ (void)gs_memory_chunk_unwrap(pdfctx->pdf_memory);
+ pdfctx->pdf_memory = NULL;
+ }
+ }
+}
+
+static int zPDFstream(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ int code = 0;
+ stream *s;
+ pdfctx_t *pdfctx;
+
+ check_op(2);
+
+ check_read_file(i_ctx_p, s, op - 1);
+
+ check_type(*op, t_pdfctx);
+ pdfctx = r_ptr(op, pdfctx_t);
+
+ /* If the supplied context already has a file open, signal an error */
+ if (pdfctx->ps_stream != NULL)
+ 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;
+ if (pdfctx->pdf_stream == NULL)
+ return_error(gs_error_VMerror);
+
+ *(pdfctx->pdf_stream) = *(pdfctx->ps_stream);
+
+ code = pdfi_set_input_stream(pdfctx->ctx, pdfctx->pdf_stream);
+ if (code < 0) {
+ memset(pdfctx->pdf_stream, 0x00, sizeof(stream));
+ gs_free_object(imemory, pdfctx->pdf_stream, "PDFstream copy of PS stream");
+ pdfctx->pdf_stream = NULL;
+ pdfctx->ps_stream = NULL;
+ return code;
+ }
+
+ pdfctx->ctx->finish_page = NULL;
+ make_tav(op, t_pdfctx, icurrent_space | a_all, pstruct, (obj_header_t *)(pdfctx));
+
+ pop(2);
+ return 0;
+}
+
+static int zPDFfile(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ pdfctx_t *pdfctx;
+ char pdffilename[gp_file_name_sizeof];
+ int code = 0;
+
+ check_op(2);
+
+ check_type(*op, t_pdfctx);
+ pdfctx = r_ptr(op, pdfctx_t);
+
+ check_read_type(*(op - 1), t_string);
+ if (r_size(op - 1) > gp_file_name_sizeof - 2)
+ return_error(gs_error_limitcheck);
+
+ /* If the supplied context already has a file open, signal an error */
+ if (pdfctx->ps_stream != NULL)
+ return_error(gs_error_ioerror);
+
+ pdfctx->ps_stream = NULL;
+
+ memcpy(pdffilename, (op - 1)->value.bytes, r_size(op - 1));
+ pdffilename[r_size(op - 1)] = 0;
+ code = pdfi_open_pdf_file(pdfctx->ctx, pdffilename);
+ if (code < 0)
+ return code;
+
+ pdfctx->ctx->finish_page = NULL;
+
+ pop(2);
+ return 0;
+}
+
+static int zPDFclose(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ int code = 0;
+ pdfctx_t *pdfctx;
+
+ check_type(*op, t_pdfctx);
+ pdfctx = r_ptr(op, pdfctx_t);
+
+ if (pdfctx->ctx != NULL) {
+ if (pdfctx->ps_stream) {
+ /* Detach the PostScript stream from the PDF context, otherwise the
+ * close code will close the main stream
+ */
+ pdfctx->ctx->main_stream = NULL;
+ }
+ code = pdfi_free_context(pdfctx->ctx);
+ pdfctx->ctx = NULL;
+ }
+ if (pdfctx->pdf_stream) {
+ memset(pdfctx->pdf_stream, 0x00, sizeof(stream));
+ gs_free_object(imemory, pdfctx->pdf_stream, "free copy of PostScript stream");
+ pdfctx->pdf_stream = NULL;
+ }
+ if (pdfctx->ps_stream)
+ pdfctx->ps_stream = NULL;
+ pop(1);
+ return code;
+}
+
+static int zPDFinfo(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ pdfctx_t *pdfctx;
+ int code = 0;
+ ref intref, nameref;
+ uint64_t TotalFiles = 0, ix = 0;
+ char **names_array = NULL;
+
+ check_type(*(op), t_pdfctx);
+ pdfctx = r_ptr(op, pdfctx_t);
+
+ code = dict_create(4, 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;
+
+ /* Code to process Collections. The pdfi_prep_collection() function returns an
+ * array of descriptions and filenames. Because the descriptions can contain
+ * UTF16-BE encoded data we can't sue a NULL terminated string, so the description
+ * strings are terminated with a triple-NULL sequence of bytes.
+ * We copy the contents into a PostScript array, which we store in the info
+ * dictionary using the /Collection key.
+ */
+ if (pdfctx->ctx->Collection != NULL) {
+ code = pdfi_prep_collection(pdfctx->ctx, &TotalFiles, &names_array);
+ if (code >= 0 && TotalFiles > 0) {
+ uint size;
+ ref collection, stringref;
+
+ code = ialloc_ref_array(&collection, a_all, TotalFiles * 2, "names array");
+ if (code < 0)
+ goto error;
+
+ code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)"Collection", 10, &nameref, 1);
+ if (code < 0)
+ goto error;
+
+ code = dict_put(op, &nameref, &collection, &i_ctx_p->dict_stack);
+ if (code < 0)
+ goto error;
+
+ for (ix=0; ix < TotalFiles * 2; ix++) {
+ char *ptr = names_array[ix];
+ byte *sbody;
+ ref *pelement;
+
+ size = 0;
+ do {
+ if (ptr[0] == 0x00 && ptr[1] == 0x00 && ptr[2] == 0x00)
+ break;
+ ptr++;
+ size++;
+ } while (1);
+ sbody = ialloc_string(size, "string");
+ if (sbody == 0) {
+ code = gs_error_VMerror;
+ goto error;
+ }
+ make_string(&stringref, a_all | icurrent_space, size, sbody);
+ memset(sbody, 0x00, size);
+ memcpy(sbody, names_array[ix], size);
+ gs_free_object(pdfctx->ctx->memory, names_array[ix], "free collection temporary filenames");
+ names_array[ix] = NULL;
+ pelement = collection.value.refs + ix;
+ ref_assign_old(&collection, pelement, &stringref, "put names string");
+ }
+ }
+ gs_free_object(pdfctx->ctx->memory, names_array, "free collection temporary filenames");
+ code = 0;
+ }
+
+ return code;
+
+error:
+ for (ix=0; ix < TotalFiles * 2; ix++)
+ gs_free_object(pdfctx->ctx->memory, names_array[ix], "free collection temporary filenames");
+ gs_free_object(pdfctx->ctx->memory, names_array, "free collection temporary filenames");
+ return code;
+}
+
+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;
+ pdfctx_t *pdfctx;
+ pdf_info_t info;
+
+ check_op(2);
+
+ check_type(*op, t_integer);
+ page = op->value.intval;
+
+ check_type(*(op - 1), t_pdfctx);
+ pdfctx = r_ptr(op - 1, pdfctx_t);
+
+ code = pdfi_page_info(pdfctx->ctx, (uint64_t)page, &info);
+ if (code < 0)
+ return code;
+
+ 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);
+ if (code < 0)
+ return code;
+
+ 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;
+
+ 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;
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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 (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 (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;
+ }
+
+ 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);
+ 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;
+ }
+
+ return 0;
+}
+
+static int zPDFmetadata(i_ctx_t *i_ctx_p)
+{
+#if 0
+ os_ptr op = osp;
+ pdfctx_t *pdfctx;
+
+ check_type(*op, t_pdfctx);
+ pdfctx = r_ptr(op, pdfctx_t);
+#endif
+
+ return_error(gs_error_undefined);
+}
+
+static int zPDFdrawpage(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ int code = 0;
+ uint64_t page = 0;
+ pdfctx_t *pdfctx;
+ gs_gstate *pgs = NULL;
+ gs_gstate_client_procs procs;
+ void *client_data;
+
+ check_op(2);
+
+ check_type(*op, t_integer);
+ page = op->value.intval;
+
+ check_type(*(op - 1), t_pdfctx);
+ pdfctx = r_ptr(op - 1, pdfctx_t);
+
+ code = gs_gsave(igs);
+ if (code < 0)
+ return code;
+
+ pgs = pdfctx->ctx->pgs;
+ procs = igs->client_procs;
+ client_data = igs->client_data;
+ pdfi_gstate_from_PS(pdfctx->ctx, igs, &client_data, &procs);
+ pdfctx->ctx->pgs = igs;
+
+ code = pdfi_page_render(pdfctx->ctx, page, false);
+ if (code >= 0)
+ pop(2);
+
+ pdfi_gstate_to_PS(pdfctx->ctx, igs, client_data, &procs);
+ if (code == 0)
+ code = gs_grestore(igs);
+ else
+ (void)gs_grestore(igs);
+ pdfctx->ctx->pgs = pgs;
+
+ return code;
+}
+
+static int zPDFdrawannots(i_ctx_t *i_ctx_p)
+{
+#if 0
+ os_ptr op = osp;
+ pdfctx_t *pdfctx;
+
+ check_type(*op, t_pdfctx);
+ pdfctx = r_ptr(op, pdfctx_t);
+#endif
+
+ return_error(gs_error_undefined);
+}
+
+static int zpdfi_glyph_index(gs_font *pfont, byte *str, uint size, uint *glyph)
+{
+ int code = 0;
+ ref nref;
+ code = name_ref(pfont->memory, str, size, &nref, true);
+ if (code < 0)
+ return code;
+ *glyph = name_index(pfont->memory, &nref);
+ return 0;
+}
+
+static int param_value_get_namelist(pdf_context *ctx, ref *pvalueref, char ***pstrlist)
+{
+ char *data;
+ uint size;
+
+ if (!r_has_type(pvalueref, t_string))
+ return_error(gs_error_typecheck);
+
+ data = (char *)pvalueref->value.bytes;
+ size = pvalueref->tas.rsize;
+
+ return pdfi_parse_name_cstring_array(ctx, data, size, pstrlist);
+}
+
+static int zPDFInit(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ ref *pdictref = NULL, *pvalueref;
+ pdfctx_t *pdfctx = NULL;
+ pdf_context *ctx = NULL;
+ int code = 0;
+ gs_memory_t *cmem;
+
+ code = gs_memory_chunk_wrap(&cmem, imemory->non_gc_memory);
+ if (code < 0)
+ return_error(gs_error_VMerror);
+
+ pdfctx = gs_alloc_struct(imemory, pdfctx_t, &st_pdfctx_t, "PDFcontext");
+ if (!pdfctx) {
+ code = gs_note_error(gs_error_VMerror);
+ goto error;
+ }
+ pdfctx->pdf_memory = cmem;
+ pdfctx->ctx = NULL;
+ pdfctx->ps_stream = NULL;
+ pdfctx->pdf_stream = NULL;
+ pdfctx->pdf_stream_memory = NULL;
+
+ ctx = pdfi_create_context(cmem);
+ if (ctx == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto error;
+ }
+
+ pdfctx->ctx = ctx;
+ get_zfont_glyph_name((void **)&pdfctx->ctx->get_glyph_name);
+ pdfctx->ctx->get_glyph_index = zpdfi_glyph_index;
+
+ if (ref_stack_count(&o_stack) > 0 && r_has_type(op, t_dictionary)) {
+ pdictref = op;
+
+ code = gs_error_typecheck;
+ if (dict_find_string(pdictref, "PDFDEBUG", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.pdfdebug = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "PDFSTOPONERROR", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.pdfstoponerror = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "PDFSTOPONWARNING", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.pdfstoponwarning = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "NOTRANSPARENCY", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.notransparency = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "QUIET", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.QUIET = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "VerboseErrors", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.verbose_errors = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "VerboseWarnings", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.verbose_warnings = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "PDFPassword", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_string))
+ goto error;
+ pdfctx->ctx->encryption.Password = (char *)gs_alloc_bytes(pdfctx->ctx->memory, r_size(pvalueref) + 1, "PDF Password from zpdfops");
+ memset(pdfctx->ctx->encryption.Password, 0x00, r_size(pvalueref) + 1);
+ memcpy(pdfctx->ctx->encryption.Password, pvalueref->value.const_bytes, r_size(pvalueref));
+ pdfctx->ctx->encryption.PasswordLen = r_size(pvalueref);
+ }
+
+ if (dict_find_string(pdictref, "FirstPage", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_integer))
+ goto error;
+ pdfctx->ctx->args.first_page = pvalueref->value.intval;
+ }
+
+ if (dict_find_string(pdictref, "LastPage", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_integer))
+ goto error;
+ pdfctx->ctx->args.last_page = pvalueref->value.intval;
+ }
+
+ if (dict_find_string(pdictref, "NOCIDFALLBACK", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.nocidfallback = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "NO_PDFMARK_OUTLINES", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.no_pdfmark_outlines = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "NO_PDFMARK_DESTS", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.no_pdfmark_dests = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "PDFFitPage", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.pdffitpage = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "Printed", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.printed = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "UseBleedBox", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.usebleedbox = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "UseCropBox", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.usecropbox = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "UseArtBox", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.useartbox = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "UseTrimBox", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.usetrimbox = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "ShowAcroForm", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.showacroform = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "ShowAnnots", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.showannots = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "PreserveAnnots", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.preserveannots = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "NoUserUnit", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.nouserunit = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "RENDERTTNOTDEF", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.renderttnotdef = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "DOPDFMARKS", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.dopdfmarks = pvalueref->value.boolval;
+ }
+
+ if (dict_find_string(pdictref, "PDFINFO", &pvalueref) > 0) {
+ if (!r_has_type(pvalueref, t_boolean))
+ goto error;
+ pdfctx->ctx->args.pdfinfo = pvalueref->value.boolval;
+ }
+ if (dict_find_string(pdictref, "SHOWANNOTTYPES", &pvalueref) > 0) {
+ code = param_value_get_namelist(pdfctx->ctx, pvalueref,
+ &pdfctx->ctx->args.showannottypes);
+ if (code < 0)
+ goto error;
+ }
+ if (dict_find_string(pdictref, "PRESERVEANNOTTYPES", &pvalueref) > 0) {
+ code = param_value_get_namelist(pdfctx->ctx, pvalueref,
+ &pdfctx->ctx->args.preserveannottypes);
+ if (code < 0)
+ goto error;
+ }
+ code = 0;
+ pop(1);
+ }
+ op = osp;
+ push(1);
+ make_tav(op, t_pdfctx, icurrent_space | a_all, pstruct, (obj_header_t *)(pdfctx));
+ return 0;
+
+error:
+ if (ctx)
+ pdfi_free_context(ctx);
+ /* gs_memory_chunk_unwrap() returns the "wrapped" allocator, which we don't need */
+ (void)gs_memory_chunk_unwrap(cmem);
+ if (pdfctx) {
+ pdfctx->pdf_memory = NULL;
+ gs_free_object(imemory, pdfctx, "PDFcontext");
+ }
+ return code;
+}
+#else
+static int zdopdffile(i_ctx_t *i_ctx_p)
+{
+ return_error(gs_error_invalidaccess);
+}
+
+static int zPDFfile(i_ctx_t *i_ctx_p)
+{
+ return_error(gs_error_undefined);
+}
+
+static int zPDFstream(i_ctx_t *i_ctx_p)
+{
+ return_error(gs_error_undefined);
+}
+
+static int zPDFclose(i_ctx_t *i_ctx_p)
+{
+ return_error(gs_error_undefined);
+}
+
+static int zPDFinfo(i_ctx_t *i_ctx_p)
+{
+ return_error(gs_error_undefined);
+}
+
+static int zPDFpageinfo(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);
+}
+
+static int zPDFdrawpage(i_ctx_t *i_ctx_p)
+{
+ return_error(gs_error_undefined);
+}
+
+static int zPDFdrawannots(i_ctx_t *i_ctx_p)
+{
+ return_error(gs_error_undefined);
+}
+
+static int zPDFInit(i_ctx_t *i_ctx_p)
+{
+ return_error(gs_error_undefined);
+}
+#endif
+
/* ------ Initialization procedure ------ */
const op_def zpdfops_op_defs[] =
@@ -262,6 +1119,16 @@ const op_def zpdfops_op_defs[] =
{"0.pdfinkpath", zpdfinkpath},
{"1.pdfFormName", zpdfFormName},
{"3.setscreenphase", zsetscreenphase},
+ {"1.dopdffile", zdopdffile},
+ {"0.PDFFile", zPDFfile},
+ {"1.PDFStream", zPDFstream},
+ {"1.PDFClose", zPDFclose},
+ {"1.PDFInfo", zPDFinfo},
+ {"1.PDFPageInfo", zPDFpageinfo},
+ {"1.PDFMetadata", zPDFmetadata},
+ {"1.PDFDrawPage", zPDFdrawpage},
+ {"1.PDFDrawAnnots", zPDFdrawannots},
+ {"1.PDFInit", zPDFInit},
#ifdef HAVE_LIBIDN
{"1.saslprep", zsaslprep},
#endif
diff --git a/psi/zvmem.c b/psi/zvmem.c
index 0a1f5bdfb..637ac46cd 100644
--- a/psi/zvmem.c
+++ b/psi/zvmem.c
@@ -324,6 +324,7 @@ restore_check_stack(const i_ctx_t *i_ctx_p, const ref_stack_t * pstack,
case t_fontID:
case t_struct:
case t_astruct:
+ case t_pdfctx:
ptr = stkp->value.pstruct;
break;
case t_save: