From a529111f77ff46f4836fe7312e70953bc16587cf Mon Sep 17 00:00:00 2001 From: Sam James Date: Wed, 21 Sep 2022 14:18:08 +0100 Subject: Import Ghostscript 10.0 Signed-off-by: Sam James --- psi/dwmain.rc | 6 +- psi/gsdll32.rc | 6 +- psi/idstack.c | 5 +- psi/ierrors.h | 7 +- psi/iinit.c | 4 +- psi/mkfilelt.cpp | 368 --------------------------------- psi/msvc.mak | 26 ++- psi/nsisinst.nsi | 34 +++- psi/winint.mak | 12 +- psi/zbfont.c | 5 +- psi/zchar.c | 4 +- psi/zcharout.c | 18 +- psi/zcie.c | 10 +- psi/zcolor.c | 3 + psi/zdevice.c | 7 +- psi/zfapi.c | 17 +- psi/zfile.c | 15 +- psi/zfont2.c | 18 +- psi/zfsample.c | 7 +- psi/zpdfops.c | 605 ++++++++++++++++++++++++++++++++++++++++++------------- 20 files changed, 622 insertions(+), 555 deletions(-) delete mode 100644 psi/mkfilelt.cpp (limited to 'psi') diff --git a/psi/dwmain.rc b/psi/dwmain.rc index 3e81c9d2..a96d0eac 100644 --- a/psi/dwmain.rc +++ b/psi/dwmain.rc @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -35,8 +35,8 @@ GSIMAGE_ICON ICON gsgraph_ico #endif VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,GS_VERSION_MAJOR,GS_VERSION_MINOR - PRODUCTVERSION 0,0,GS_VERSION_MAJOR,GS_VERSION_MINOR + FILEVERSION GS_VERSION_MAJOR,GS_VERSION_MINOR,GS_VERSION_PATCH,0 + PRODUCTVERSION GS_VERSION_MAJOR,GS_VERSION_MINOR,GS_VERSION_PATCH,0 BEGIN BLOCK "StringFileInfo" BEGIN diff --git a/psi/gsdll32.rc b/psi/gsdll32.rc index a03540ac..6bbf6d03 100644 --- a/psi/gsdll32.rc +++ b/psi/gsdll32.rc @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -51,8 +51,8 @@ BEGIN END VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,GS_VERSION_MAJOR,GS_VERSION_MINOR - PRODUCTVERSION 0,0,GS_VERSION_MAJOR,GS_VERSION_MINOR + FILEVERSION GS_VERSION_MAJOR,GS_VERSION_MINOR,GS_VERSION_PATCH,0 + PRODUCTVERSION GS_VERSION_MAJOR,GS_VERSION_MINOR,GS_VERSION_PATCH,0 BEGIN BLOCK "StringFileInfo" BEGIN diff --git a/psi/idstack.c b/psi/idstack.c index 701cd8d0..6342c6ad 100644 --- a/psi/idstack.c +++ b/psi/idstack.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -24,6 +24,8 @@ #include "ipacked.h" #include "iutil.h" #include "ivmspace.h" +#include "idebug.h" /* for debug_print_name */ + /* #include "idicttpl.h" - Do not remove this comment. "idicttpl.h" is included below. @@ -33,7 +35,6 @@ /* #define COLLECT_STATS_IDSTACK */ #ifdef COLLECT_STATS_IDSTACK -#include "idebug.h" #define MAX_STATS_DEPTH 6 struct stats_dstack_s { long lookups; /* total lookups */ diff --git a/psi/ierrors.h b/psi/ierrors.h index 50f32128..15abaa0f 100644 --- a/psi/ierrors.h +++ b/psi/ierrors.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -57,8 +57,11 @@ extern const char *const gs_error_names[]; #define DPS_ERROR_NAMES\ "invalidcontext", "invalidid" +#define PDF_ERROR_NAMES\ + "pdf_stackoverflow", "pdf_circular_reference" + #define ERROR_NAMES\ - LEVEL1_ERROR_NAMES, LEVEL2_ERROR_NAMES, DPS_ERROR_NAMES + LEVEL1_ERROR_NAMES, LEVEL2_ERROR_NAMES, DPS_ERROR_NAMES, PDF_ERROR_NAMES /* * Define which error codes require re-executing the current object. diff --git a/psi/iinit.c b/psi/iinit.c index e3471292..2d8bfe99 100644 --- a/psi/iinit.c +++ b/psi/iinit.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -363,7 +363,7 @@ obj_init(i_ctx_t **pi_ctx_p, gs_dual_memory_t *idmem) /* Create the error name table */ { - int n = countof(gs_error_names) - 1; + int n = countof(gs_error_names); int i; ref era; diff --git a/psi/mkfilelt.cpp b/psi/mkfilelt.cpp deleted file mode 100644 index 8647fbb3..00000000 --- a/psi/mkfilelt.cpp +++ /dev/null @@ -1,368 +0,0 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, - CA 94945, U.S.A., +1(415)492-9861, for further information. -*/ - -// -// -// This is the setup program for Win32 GPL Ghostscript -// -// The starting point is a self extracting zip archive -// with the following contents: -// setupgs.exe -// uninstgs.exe -// filelist.txt (contains list of program files) -// gs#.##\* (files listed in filelist.txt) -// This is the same as the zip file created by Aladdin Enterprises, -// with the addition of setupgs.exe, uninstgs.exe, and filelist.txt -// -// The first line of the file filelist.txt -// contains the uninstall name to be used. -// The second line contains name of the main directory where -// uninstall log files are to be placed. -// Subsequent lines contain files to be copied (but not directories). -// For example, filelist.txt might contain: -// GPL Ghostscript 8.55 -// gs8.55 -// gs8.55\bin\gsdll32.dll -// gs8.55\lib\gs_init.ps -// -// The default install directory is c:\gs. -// The default Start Menu Folder is Ghostscript. -// These are set in the resources. -// The setup program will create the following uninstall log files -// c:\gs\gs#.##\uninstal.txt -// The uninstall program (accessed through control panel) will not -// remove directories nor will it remove itself. -// -// If the install directory is the same as the current file -// location, no files will be copied, but the existence of each file -// will be checked. This allows the archive to be unzipped, then -// configured in its current location. Running the uninstall will not -// remove uninstgs.exe, setupgs.exe, or filelist.txt. - - -#define STRICT -#include -#include -#include -#include -#include -#include -#include - -#pragma comment(lib,"user32.lib") - -#ifdef MAX_PATH -#define MAXSTR MAX_PATH -#else -#define MAXSTR 256 -#endif - -CHAR g_szAppName[MAXSTR]; - -// Prototypes -BOOL init(); -BOOL make_filelist(int argc, char *argv[]); - - -////////////////////////////////////////////////////////////////////// -// Entry point -////////////////////////////////////////////////////////////////////// - -int APIENTRY WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) -{ - strcpy(g_szAppName, "make_filelist"); - if (!init()) { - MessageBox(HWND_DESKTOP, "Initialisation failed", - g_szAppName, MB_OK); - return 1; - } - - return 0; -} - - - - -////////////////////////////////////////////////////////////////////// -// Initialisation and Main dialog box -////////////////////////////////////////////////////////////////////// - -void -message_box(const char *str) -{ - MessageBox(HWND_DESKTOP, str, g_szAppName, MB_OK); -} - - -BOOL -init() -{ - DWORD dwVersion = GetVersion(); - // get source directory - - - if (LOBYTE(LOWORD(dwVersion)) < 4) { - MessageBox(HWND_DESKTOP, - "This install program needs Windows 4.0 or later", - g_szAppName, MB_OK); - return FALSE; - } - - -#define MAXCMDTOKENS 128 - - int argc; - LPSTR argv[MAXCMDTOKENS]; - LPSTR p; - char *args; - char *d, *e; - - p = GetCommandLine(); - - argc = 0; - args = (char *)malloc(lstrlen(p)+1); - if (args == (char *)NULL) - return 1; - - // Parse command line handling quotes. - d = args; - while (*p) { - // for each argument - - if (argc >= MAXCMDTOKENS - 1) - break; - - e = d; - while ((*p) && (*p != ' ')) { - if (*p == '\042') { - // Remove quotes, skipping over embedded spaces. - // Doesn't handle embedded quotes. - p++; - while ((*p) && (*p != '\042')) - *d++ =*p++; - } - else - *d++ = *p; - if (*p) - p++; - } - *d++ = '\0'; - argv[argc++] = e; - - while ((*p) && (*p == ' ')) - p++; // Skip over trailing spaces - } - argv[argc] = NULL; - - if (argc > 2) { - // Probably creating filelist.txt - return make_filelist(argc, argv); - } - return 0; -} - - -////////////////////////////////////////////////////////////////////// -// Create file list -////////////////////////////////////////////////////////////////////// - -FILE *fList; - -typedef int (*PFN_dodir)(const char *name); - -/* Called once for each directory */ -int -dodir(const char *filename) -{ - return 0; -} - -/* Called once for each file */ -int -dofile(const char *filename) -{ - if (fList != (FILE *)NULL) { - fputs(filename, fList); - fputs("\n", fList); - } - - return 0; -} - - -/* Walk through directory 'path', calling dodir() for given directory - * and dofile() for each file. - * If recurse=1, recurse into subdirectories, calling dodir() for - * each directory. - */ -int -dirwalk(char *path, int recurse, PFN_dodir dodir, PFN_dodir dofile) -{ - WIN32_FIND_DATA find_data; - HANDLE find_handle; - char pattern[MAXSTR]; /* orig pattern + modified pattern */ - char base[MAXSTR]; - char name[MAXSTR]; - BOOL bMore = TRUE; - char *p; - - - if (path) { - strcpy(pattern, path); - if (strlen(pattern) != 0) { - p = pattern + strlen(pattern) -1; - if (*p == '\\') - *p = '\0'; // truncate trailing backslash - } - - strcpy(base, pattern); - if (strchr(base, '*') != NULL) { - // wildcard already included - // truncate it from the base path - if ( (p = strrchr(base, '\\')) != NULL ) - *(++p) = '\0'; - } - else if (isalpha(pattern[0]) && - pattern[1]==':' && pattern[2]=='\0') { - strcat(pattern, "\\*"); // search entire disk - strcat(base, "\\"); - } - else { - // wildcard NOT included - // check to see if path is a directory - find_handle = FindFirstFile(pattern, &find_data); - if (find_handle != INVALID_HANDLE_VALUE) { - FindClose(find_handle); - if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - strcat(pattern, "\\*"); // yes, search files - strcat(base, "\\"); - } - else { - dofile(path); // no, return just this file - return 0; - } - } - else - return 1; // path invalid - } - } - else { - base[0] = '\0'; - strcpy(pattern, "*"); - } - - find_handle = FindFirstFile(pattern, &find_data); - if (find_handle == INVALID_HANDLE_VALUE) - return 1; - - while (bMore) { - strcpy(name, base); - strcat(name, find_data.cFileName); - if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - if ( strcmp(find_data.cFileName, ".") && - strcmp(find_data.cFileName, "..") ) { - dodir(name); - if (recurse) - dirwalk(name, recurse, dodir, dofile); - } - } - else { - dofile(name); - } - bMore = FindNextFile(find_handle, &find_data); - } - FindClose(find_handle); - - return 0; -} - - - -// This is used when creating a file list. - -BOOL make_filelist(int argc, char *argv[]) -{ - char *title = NULL; - char *dir = NULL; - char *list = NULL; - int i; - - for (i=1; i= 0) && - ((buf[j] == '\n') || (buf[j] == ' ')) ) - buf[j] = '\0'; - dirwalk(buf, TRUE, &dodir, &dofile); - } - fclose(f); - } - else { - wsprintf(buf, "Can't open @ file \042%s\042", - &argv[i][1]); - message_box(buf); - } - } - else - dirwalk(argv[i], TRUE, &dodir, &dofile); - } - } - - if (fList != (FILE *)NULL) { - fclose(fList); - fList = NULL; - } - return TRUE; -} - diff --git a/psi/msvc.mak b/psi/msvc.mak index cb74a2b6..c8fd659e 100644 --- a/psi/msvc.mak +++ b/psi/msvc.mak @@ -278,6 +278,15 @@ IMGGENDIR=$(GLGENDIR) IMGOBJDIR=$(GLOBJDIR) !endif +# CAL detects the presence of SSE/AVX2 at runtime. We assume +# modern windows compilers can build for both, and they will +# just be disabled automatically if not present. If the compiler +# can't cope with this, then define CAL_CFLAGS to be empty +# in the makefile invocation. +!ifndef CAL_CFLAGS +CAL_CFLAGS=/DHAVE_SSE4_2 /DHAVE_AVX2 +!endif + CONTRIBDIR=.\contrib # Can we build PCL and XPS and PDF @@ -730,7 +739,7 @@ TIFFSRCDIR=tiff$(D) TIFFCONFDIR=$(TIFFSRCDIR) TIFFCONFIG_SUFFIX=.vc TIFFPLATFORM=win32 -TIFF_CFLAGS=-DJPEG_SUPPORT -DOJPEG_SUPPORT -DJPEG_LIB_MK1_OR_12BIT=0 +TIFF_CFLAGS=-DJPEG_SUPPORT -DOJPEG_SUPPORT -DJPEG_LIB_MK1_OR_12BIT=0 -DTIFF_DISABLE_DEPRECATED ENABLE_TIFF=$(D_)TIFF_INCLUDED$(_D) !endif @@ -1155,6 +1164,21 @@ MS_TOOLSET_VERSION=14.29.30133 MSVC_VERSION=16 MS_TOOLSET_VERSION=14.29.30133 !endif +!if "$(_NMAKE_VER)" == "14.29.30142.1" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.29.30133 +!endif +!if "$(_NMAKE_VER)" == "14.29.30145.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.29.30133 +!endif +!if "$(_NMAKE_VER)" == "14.29.30146.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.29.30133 +!endif !endif !ifndef MSVC_VERSION diff --git a/psi/nsisinst.nsi b/psi/nsisinst.nsi index 404747b5..3c141da3 100644 --- a/psi/nsisinst.nsi +++ b/psi/nsisinst.nsi @@ -1,4 +1,4 @@ -; Copyright (C) 2001-2021 Artifex Software, Inc. +; Copyright (C) 2001-2022 Artifex Software, Inc. ; All Rights Reserved. ; ; This software is provided AS-IS with no warranty, either express or @@ -43,6 +43,8 @@ SetCompressor /SOLID /FINAL lzma XPStyle on CRCCheck on +Var RebootRequired + ; the following is from: http://nsis.sourceforge.net/StrRep !define StrRep "!insertmacro StrRep" !macro StrRep output string old new @@ -141,7 +143,7 @@ FunctionEnd !define MUI_FINISHPAGE_RUN_TEXT "Generate cidfmap for Windows CJK TrueType fonts" !define MUI_FINISHPAGE_RUN_FUNCTION CJKGen ; !define MUI_FINISHPAGE_RUN_NOTCHECKED -!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\doc\Readme.htm" +; !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\doc\Readme.htm" ; MUI_FINISHPAGE_SHOWREADME_NOTCHECKED !define MUI_FINISHPAGE_LINK "Visit the Ghostscript web site" !define MUI_FINISHPAGE_LINK_LOCATION http://www.ghostscript.com/ @@ -159,7 +161,6 @@ Page custom OldVersionsPageCreate Function OldVersionsPageCreate !insertmacro MUI_HEADER_TEXT "Previous Ghostscript Installations" "Optionally run the uninstallers for previous Ghostscript installations$\nClick $\"Cancel$\" to stop uninstalling previous installs" - StrCpy $0 0 loop: EnumRegKey $1 HKLM "Software\Artifex\GPL Ghostscript" $0 @@ -174,6 +175,13 @@ Function OldVersionsPageCreate FunctionEnd +Function RedistInstCreate + ExecWait '"$INSTDIR\${VCREDIST}" /norestart /install /quiet' $0 + ${If} $0 == 3010 + StrCpy $RebootRequired "yes" + ${EndIf} +FunctionEnd + !searchparse /ignorecase /noerrors "${TARGET}" w WINTYPE !echo "Building ${WINTYPE}-bit installer" @@ -230,6 +238,8 @@ File /oname=bin\gsdll${WINTYPE}.lib .\bin\gsdll${WINTYPE}.lib File /oname=bin\gswin${WINTYPE}.exe .\bin\gswin${WINTYPE}.exe File /oname=bin\gswin${WINTYPE}c.exe .\bin\gswin${WINTYPE}c.exe +File /oname=${VCREDIST} .\${VCREDIST} + !if "${WINTYPE}" == "64" SetRegView 64 !endif @@ -254,6 +264,9 @@ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GPL Ghos ; write out uninstaller WriteUninstaller "$INSTDIR\uninstgs.exe" + +Call RedistInstCreate + SectionEnd ; end of default section Function .onInstSuccess @@ -261,10 +274,19 @@ Function .onInstSuccess SetShellVarContext all CreateDirectory "$SMPROGRAMS\Ghostscript" CreateShortCut "$SMPROGRAMS\Ghostscript\Ghostscript ${VERSION}.LNK" "$INSTDIR\bin\gswin${WINTYPE}.exe" '"-I$INSTDIR\lib;$INSTDIR\..\fonts"' - CreateShortCut "$SMPROGRAMS\Ghostscript\Ghostscript Readme ${VERSION}.LNK" "$INSTDIR\doc\Readme.htm" +; CreateShortCut "$SMPROGRAMS\Ghostscript\Ghostscript Readme ${VERSION}.LNK" "$INSTDIR\doc\Readme.htm" CreateShortCut "$SMPROGRAMS\Ghostscript\Uninstall Ghostscript ${VERSION}.LNK" "$INSTDIR\uninstgs.exe" FunctionEnd +Function .onGUIEnd + StrCmp $RebootRequired "yes" doit + Goto done + doit: + MessageBox MB_YESNO|MB_ICONQUESTION "Do you wish to reboot the system?" IDNO +2 + Reboot + done: +FunctionEnd + Function CJKGen ${StrRep} $0 "$FONTS" "\" "/" ${StrRep} $1 "$INSTDIR\lib\cidfmap" "\" "/" @@ -273,6 +295,7 @@ Function CJKGen FunctionEnd Function .onInit + StrCpy $RebootRequired "no" !if "${WINTYPE}" == "64" SetRegView 64 ${IfNot} ${RunningX64} @@ -301,7 +324,7 @@ Section Uninstall ; add delete commands to delete whatever files/registry keys/etc you installed here. SetShellVarContext all Delete "$SMPROGRAMS\Ghostscript\Ghostscript ${VERSION}.LNK" -Delete "$SMPROGRAMS\Ghostscript\Ghostscript Readme ${VERSION}.LNK" +; Delete "$SMPROGRAMS\Ghostscript\Ghostscript Readme ${VERSION}.LNK" Delete "$SMPROGRAMS\Ghostscript\Uninstall Ghostscript ${VERSION}.LNK" RMDir "$SMPROGRAMS\Ghostscript" Delete "$INSTDIR\uninstgs.exe" @@ -320,6 +343,7 @@ Delete "$INSTDIR\bin\gsdll${WINTYPE}.dll" Delete "$INSTDIR\bin\gsdll${WINTYPE}.lib" Delete "$INSTDIR\bin\gswin${WINTYPE}.exe" Delete "$INSTDIR\bin\gswin${WINTYPE}c.exe" +Delete "$INSTDIR\${VCREDIST}" RMDir "$INSTDIR\bin" RMDir "$INSTDIR" !if "${WINTYPE}" == "64" diff --git a/psi/winint.mak b/psi/winint.mak index d6234089..d604d024 100644 --- a/psi/winint.mak +++ b/psi/winint.mak @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2021 Artifex Software, Inc. +# Copyright (C) 2001-2022 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -34,8 +34,10 @@ MAKENSIS_XE="C:\Program Files\NSIS-3.0\makensis.exe" !ifdef WIN64 NSISTARGET=gs$(GS_VERSION)w64 +VCREDIST=vcredist_x64.exe !else NSISTARGET=gs$(GS_VERSION)w32 +VCREDIST=vcredist_x86.exe !endif # Define the C++ compiler invocation for library modules. @@ -83,7 +85,7 @@ $(GS_OBJ).res: $(PSSRC)dwmain.rc $(dwres_h) $(ICONS) $(WININT_MAK) $(ECHOGS_XE) -w $(PSGEN)_exe.rc -x 23 define -s gstext_ico $(GLGENDIR)\gswin.ico $(ECHOGS_XE) -a $(PSGEN)_exe.rc -x 23 define -s gsgraph_ico $(GLGENDIR)\gswin.ico $(ECHOGS_XE) -a $(PSGEN)_exe.rc -R $(PSSRC)dwmain.rc - $(RCOMP) -dGS_DOT_VERSION=$(GS_DOT_VERSION) -dGS_VERSION_MAJOR=$(GS_VERSION_MAJOR) -dGS_VERSION_MINOR=$(GS_VERSION_MINOR) -i$(PSSRCDIR) -i$(PSGENDIR) -i$(GLSRCDIR) $(i_INCDIR) -r $(RO_)$(GS_OBJ).res $(PSGEN)_exe.rc + $(RCOMP) -dGS_DOT_VERSION=$(GS_DOT_VERSION) -dGS_VERSION_MAJOR=$(GS_VERSION_MAJOR) -dGS_VERSION_MINOR=$(GS_VERSION_MINOR) -dGS_VERSION_PATCH=$(GS_VERSION_PATCH) -i$(PSSRCDIR) -i$(PSGENDIR) -i$(GLSRCDIR) $(i_INCDIR) -r $(RO_)$(GS_OBJ).res $(PSGEN)_exe.rc del $(PSGEN)_exe.rc # resources for main program (includes dialogs) @@ -91,7 +93,7 @@ $(GSDLL_OBJ).res: $(PSSRC)gsdll32.rc $(gp_mswin_h) $(ICONS) $(WININT_MAK) $(ECHOGS_XE) -w $(PSGEN)_dll.rc -x 23 define -s gstext_ico $(GLGENDIR)\gswin.ico $(ECHOGS_XE) -a $(PSGEN)_dll.rc -x 23 define -s gsgraph_ico $(GLGENDIR)\gswin.ico $(ECHOGS_XE) -a $(PSGEN)_dll.rc -R $(PSSRC)gsdll32.rc - $(RCOMP) -dGS_DOT_VERSION=$(GS_DOT_VERSION) -dGS_VERSION_MAJOR=$(GS_VERSION_MAJOR) -dGS_VERSION_MINOR=$(GS_VERSION_MINOR) -i$(PSSRCDIR) -i$(PSGENDIR) -i$(GLSRCDIR) $(i_INCDIR) -r $(RO_)$(GSDLL_OBJ).res $(PSGEN)_dll.rc + $(RCOMP) -dGS_DOT_VERSION=$(GS_DOT_VERSION) -dGS_VERSION_MAJOR=$(GS_VERSION_MAJOR) -dGS_VERSION_MINOR=$(GS_VERSION_MINOR) -dGS_VERSION_PATCH=$(GS_VERSION_PATCH) -i$(PSSRCDIR) -i$(PSGENDIR) -i$(GLSRCDIR) $(i_INCDIR) -r $(RO_)$(GSDLL_OBJ).res $(PSGEN)_dll.rc del $(PSGEN)_dll.rc @@ -185,8 +187,10 @@ $(PSOBJ)zwinutf8.$(OBJ) : $(PSSRC)zwinutf8.c $(OP)\ # -------------------- NSIS Installer -------------------------------- # nsis: $(PSSRC)nsisinst.nsi $(GSCONSOLE_XE) $(GS_ALL) $(GS_XE) $(GSDLL_DLL) $(BINDIR)\$(GSDLL).lib \ + "$(VCINSTALLDIR)Redist\MSVC\$(MS_TOOLSET_VERSION)\$(VCREDIST)" \ $(WININT_MAK) - $(MAKENSIS_XE) -NOCD -DTARGET=$(NSISTARGET) -DVERSION=$(GS_DOT_VERSION) -DCOMPILE_INITS=$(COMPILE_INITS) $(PSSRC)nsisinst.nsi + $(CP_) "$(VCINSTALLDIR)Redist\MSVC\$(MS_TOOLSET_VERSION)\$(VCREDIST)" . + $(MAKENSIS_XE) -NOCD -DVCREDIST=$(VCREDIST) -DTARGET=$(NSISTARGET) -DVERSION=$(GS_DOT_VERSION) -DCOMPILE_INITS=$(COMPILE_INITS) $(PSSRC)nsisinst.nsi !if defined(KEYFILE) && defined(KEYPWORD) && defined(TIMESTAMP) signtool sign -f $(KEYFILE) /p $(KEYPWORD) /t $(TIMESTAMP) $(NSISTARGET)$(XE) !endif diff --git a/psi/zbfont.c b/psi/zbfont.c index 044f58a1..bcf38ace 100644 --- a/psi/zbfont.c +++ b/psi/zbfont.c @@ -136,8 +136,11 @@ zfont_glyph_name(gs_font *font, gs_glyph index, gs_const_string *pstr) &nref, 1); if (code < 0) return code; - } else + } else { name_index_ref(font->memory, index, &nref); + if (nref.value.pname == NULL) + return_error(gs_error_unknownerror); + } name_string_ref(font->memory, &nref, &sref); pstr->data = sref.value.const_bytes; pstr->size = r_size(&sref); diff --git a/psi/zchar.c b/psi/zchar.c index 55af9f59..d4527db0 100644 --- a/psi/zchar.c +++ b/psi/zchar.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -1020,7 +1020,7 @@ op_show_restore(i_ctx_t *i_ctx_p, bool for_error) If we are going to be doing the stroke operation through zstroke then we do not want to restore yet. */ if (penum->k_text_release) { - gsicc_restore_black_text(igs); + gsicc_restore_blacktextvec(igs, true); } gs_text_release(NULL, penum, "op_show_restore"); diff --git a/psi/zcharout.c b/psi/zcharout.c index c204a956..96e1d355 100644 --- a/psi/zcharout.c +++ b/psi/zcharout.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -309,9 +309,25 @@ int zchar_charstring_data(gs_font *font, const ref *pgref, gs_glyph_data_t *pgd) { ref *pcstr; + ref *cffcstr; + ref *pdr = pfont_dict(font); if (dict_find(&pfont_data(font)->CharStrings, pgref, &pcstr) <= 0) return_error(gs_error_undefined); + + if (r_has_type(pcstr, t_integer) + && dict_find_string(pdr, "CFFCharStrings", &cffcstr) > 0) { + ref *pcstr2; + if (dict_find(cffcstr, pcstr, &pcstr2) <= 0) { + ref nd; + make_int(&nd, 0); + if (dict_find(cffcstr, &nd, &pcstr2) <= 0) { + return_error(gs_error_undefined); + } + } + pcstr = pcstr2; + } + if (!r_has_type(pcstr, t_string)) { /* * The ADOBEPS4 Windows driver replaces the .notdef entry of diff --git a/psi/zcie.c b/psi/zcie.c index 93284186..ea95dcfc 100644 --- a/psi/zcie.c +++ b/psi/zcie.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -467,8 +467,8 @@ ciedefgspace(i_ctx_t *i_ctx_p, ref *CIEDict, uint64_t dictkey) check_read_type(*ptref, t_array); if (r_size(ptref) != 5) return_error(gs_error_rangecheck); - /* Stable memory due to current caching of color space */ - code = gs_cspace_build_CIEDEFG(&pcs, NULL, mem->stable_memory); + /* Stable memory due to current caching of color space */ + code = gs_cspace_build_CIEDEFG(&pcs, NULL, mem->stable_memory); if (code < 0) return cie_set_finish(i_ctx_p, pcs, &procs, edepth, code); pcie = pcs->params.defg; @@ -580,8 +580,8 @@ ciedefspace(i_ctx_t *i_ctx_p, ref *CIEDict, uint64_t dictkey) check_read_type(*ptref, t_array); if (r_size(ptref) != 4) return_error(gs_error_rangecheck); - /* Stable memory due to current caching of color space */ - code = gs_cspace_build_CIEDEF(&pcs, NULL, mem->stable_memory); + /* Stable memory due to current caching of color space */ + code = gs_cspace_build_CIEDEF(&pcs, NULL, mem->stable_memory); if (code < 0) return cie_set_finish(i_ctx_p, pcs, &procs, edepth, code); pcie = pcs->params.def; diff --git a/psi/zcolor.c b/psi/zcolor.c index c0d73c28..e1b51db4 100644 --- a/psi/zcolor.c +++ b/psi/zcolor.c @@ -6423,6 +6423,7 @@ static int validate_spaces(i_ctx_t *i_ctx_p, ref *arr, int *depth) static int setcolor_cont(i_ctx_t *i_ctx_p) { + os_ptr op = osp; ref arr, *parr = &arr; es_ptr ep = esp; int i=0, code = 0, usealternate, stage, stack_depth, CIESubst = 0, IsICC = 0; @@ -6497,6 +6498,8 @@ setcolor_cont(i_ctx_t *i_ctx_p) /* Remove our next continuation and our data */ obj->numcomponents(i_ctx_p, parr, &i); + /* This would be better done sooner, but we need the color space object first */ + check_op(i); pop(i); esp -= 5; return o_pop_estack; diff --git a/psi/zdevice.c b/psi/zdevice.c index 99beaff7..7e9779f7 100644 --- a/psi/zdevice.c +++ b/psi/zdevice.c @@ -45,7 +45,7 @@ ENUM_PTRS_WITH(psi_device_ref_enum_ptrs, psi_device_ref *devref) } case 0: { - if (devref->device->memory != NULL) { + if (devref->device != NULL && devref->device->memory != NULL) { ENUM_RETURN(gx_device_enum_ptr(devref->device)); } return 0; @@ -54,7 +54,7 @@ ENUM_PTRS_END static RELOC_PTRS_WITH(psi_device_ref_reloc_ptrs, psi_device_ref *devref) - if (devref->device->memory != NULL) { + if (devref->device != NULL && devref->device->memory != NULL) { devref->device = gx_device_reloc_ptr(devref->device, gcst); } RELOC_PTRS_END @@ -71,7 +71,7 @@ psi_device_ref_finalize(const gs_memory_t *cmem, void *vptr) /* pdref->device->memory == NULL indicates either a device prototype or a device allocated on the stack rather than the heap */ - if (pdref->device->memory != NULL) + if (pdref->device != NULL && pdref->device->memory != NULL) rc_decrement(pdref->device, "psi_device_ref_finalize"); pdref->device = NULL; @@ -456,6 +456,7 @@ zmakewordimagedevice(i_ctx_t *i_ctx_p) return_error(gs_error_VMerror); } psdev->device = new_dev; + rc_increment(new_dev); make_tav(op - 4, t_device, imemory_space(iimemory) | a_all, pdevice, psdev); pop(4); } diff --git a/psi/zfapi.c b/psi/zfapi.c index 6927e60e..aa7369a1 100644 --- a/psi/zfapi.c +++ b/psi/zfapi.c @@ -2024,7 +2024,7 @@ FAPI_FF_get_glyph(gs_fapi_font *ff, gs_glyph char_code, byte *buf, int buf_lengt glyph_length = get_type1_data(ff, &glyph, buf, buf_length); } else { - ref *CharStrings, char_name, *glyph; + ref *CharStrings, *CFFCharStrings, char_name, *glyph; if (ff->char_data != NULL) { /* @@ -2069,6 +2069,20 @@ FAPI_FF_get_glyph(gs_fapi_font *ff, gs_glyph char_code, byte *buf, int buf_lengt } if (r_has_type(glyph, t_array) || r_has_type(glyph, t_mixedarray)) return gs_fapi_glyph_invalid_format; + + if (r_has_type(glyph, t_integer) + && dict_find_string(pdr, "CFFCharStrings", &CFFCharStrings) > 0) { + ref *g2; + if (dict_find(CFFCharStrings, glyph, &g2) <= 0) { + ref nd; + make_int(&nd, 0); + if (dict_find(CFFCharStrings, &nd, &g2) <= 0) { + return gs_fapi_glyph_invalid_format; + } + } + glyph = g2; + } + if (!r_has_type(glyph, t_string)) return 0; glyph_length = get_type1_data(ff, glyph, buf, buf_length); @@ -2255,6 +2269,7 @@ static const gs_fapi_font ps_ff_stub = { FAPI_FF_get_raw_subr, FAPI_FF_get_glyph, FAPI_FF_serialize_tt_font, + NULL, /* retrieve_tt_font */ FAPI_FF_get_charstring, FAPI_FF_get_charstring_name, ps_get_GlyphDirectory_data_ptr, diff --git a/psi/zfile.c b/psi/zfile.c index fe3f7e9f..e4a2a3e1 100644 --- a/psi/zfile.c +++ b/psi/zfile.c @@ -772,18 +772,25 @@ ztempfile(i_ctx_t *i_ctx_p) if (gp_file_name_is_absolute(pstr, strlen(pstr))) { int plen = strlen(pstr); const char *sep = gp_file_name_separator(); -#ifdef DEBUG int seplen = strlen(sep); - if (seplen != 1) + + /* This should not be possible if gp_file_name_is_absolute is true I think + * But let's avoid the problem. + */ + if (plen < seplen) return_error(gs_error_Fatal); -#endif + + plen -= seplen; /* strip off the file name prefix, leave just the directory name * so we can check if we are allowed to write to it */ for ( ; plen >=0; plen--) { - if (pstr[plen] == sep[0]) + if ( gs_file_name_check_separator(&pstr[plen], seplen, &pstr[plen])) break; } + if (plen < 0) + return_error(gs_error_Fatal); + memcpy(fname, pstr, plen); fname[plen] = '\0'; if (check_file_permissions(i_ctx_p, fname, strlen(fname), diff --git a/psi/zfont2.c b/psi/zfont2.c index 2be4279a..bc13fc04 100644 --- a/psi/zfont2.c +++ b/psi/zfont2.c @@ -2632,7 +2632,7 @@ parse_font(i_ctx_t *i_ctx_p, ref *topdict, /* Simple font */ unsigned int i, gid, enc_format = 0; int sid; - ref name, cstr, charstrings_dict, encoding, notdef; + ref ccoderef, name, cstr, cffcharstrings_dict, charstrings_dict, encoding, notdef; unsigned char gid2char[256]; unsigned supp_enc_offset = 0; @@ -2642,9 +2642,16 @@ parse_font(i_ctx_t *i_ctx_p, ref *topdict, return code; if ((code = dict_create(charstrings_index.count + 1, &charstrings_dict)) < 0) return code; + if ((code = dict_create(charstrings_index.count + 1, &cffcharstrings_dict)) < 0) + return code; if ((code = idict_put_c_name(i_ctx_p, topdict, STR2MEM("CharStrings"), &charstrings_dict)) < 0) return code; - if ((code = idict_put(&charstrings_dict, ¬def, &cstr)) < 0) + if ((code = idict_put_c_name(i_ctx_p, topdict, STR2MEM("CFFCharStrings"), &cffcharstrings_dict)) < 0) + return code; + make_int(&ccoderef, 0); + if ((code = idict_put(&charstrings_dict, ¬def, &ccoderef)) < 0) + return code; + if ((code = idict_put(&cffcharstrings_dict, &ccoderef, &cstr)) < 0) return code; if (offsets.encoding_off <= 1) { if ((code = ialloc_ref_array(&encoding, a_readonly, 256, "cff_parser.encoding")) < 0) @@ -2710,7 +2717,10 @@ parse_font(i_ctx_t *i_ctx_p, ref *topdict, if ((code = name_ref(imemory, (unsigned char *)buf, len, &name, 1)) < 0) return code; } - if ((code = idict_put(&charstrings_dict, &name, &cstr)) < 0) + make_int(&ccoderef, gid); + if ((code = idict_put(&charstrings_dict, &name, &ccoderef)) < 0) + return code; + if ((code = idict_put(&cffcharstrings_dict, &ccoderef, &cstr)) < 0) return code; if (offsets.encoding_off > 1 && gid < 256) { encoding.value.refs[gid2char[gid]] = name; @@ -2859,7 +2869,7 @@ zparsecff(i_ctx_t *i_ctx_p) if ((code = peek_index(&topdict_data, &topdict_len, &topdicts, &data, i_font)) < 0) return code; - if ((code = dict_create(20, &topdict)) < 0) + if ((code = dict_create(21, &topdict)) < 0) return code; if ((code = idict_put(&fontset, &name, &topdict)) < 0) diff --git a/psi/zfsample.c b/psi/zfsample.c index 00cd0cfd..791f24b4 100644 --- a/psi/zfsample.c +++ b/psi/zfsample.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -501,12 +501,9 @@ sampled_data_continue(i_ctx_t *i_ctx_p) * (unused) stack stack space to allow for this but the function * exceeded even that. Data on the stack may have been lost. * The only thing that we can do is move the stack pointer back and - * hope. (We have not seen real Postscript files that have this - * problem.) + * hope. */ push(-stack_depth_adjust); - ifree_object(penum->pfn, "sampled_data_continue(pfn)"); - ifree_object(penum, "sampled_data_continue((enum)"); return_error(gs_error_undefinedresult); } } 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; } + +/* 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 -- cgit v1.2.3-65-gdbad