From 43f8a1989aa709749ce9aedd4feba6c4f6306925 Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Fri, 10 Jul 2009 14:49:27 -0300 Subject: gs: add 8.64 This has based in Debian's 8.64~dfsg-12 package and all patches has been taken from it. Signed-off-by: Otavio Salvador --- recipes/gs/gs/0001_svn_snapshot.patch | 24362 +++++++++++++++++++ recipes/gs/gs/0002_svn_snapshot_jbig2dec.patch | 17181 +++++++++++++ recipes/gs/gs/1001_install_cjk_examples.patch | 18 + recipes/gs/gs/1002_ps2pdf_man_fix.patch | 126 + .../gs/1003_fix_autoconf_create_from_infiles.patch | 14 + ...CVE-2009-0792_CVE-2009-0584_CVE-2009-0583.patch | 1154 + recipes/gs/gs/1006_system-jasper.patch | 28 + recipes/gs/gs/1007_fix_pphs_script_not_lib.patch | 22 + recipes/gs/gs/2001_docdir_fix_for_debian.patch | 16 + recipes/gs/gs/2002_gs_man_fix_debian.patch | 40 + recipes/gs/gs_8.64.bb | 54 + 11 files changed, 43015 insertions(+) create mode 100644 recipes/gs/gs/0001_svn_snapshot.patch create mode 100644 recipes/gs/gs/0002_svn_snapshot_jbig2dec.patch create mode 100644 recipes/gs/gs/1001_install_cjk_examples.patch create mode 100644 recipes/gs/gs/1002_ps2pdf_man_fix.patch create mode 100644 recipes/gs/gs/1003_fix_autoconf_create_from_infiles.patch create mode 100644 recipes/gs/gs/1004_CVE-2009-0792_CVE-2009-0584_CVE-2009-0583.patch create mode 100644 recipes/gs/gs/1006_system-jasper.patch create mode 100644 recipes/gs/gs/1007_fix_pphs_script_not_lib.patch create mode 100644 recipes/gs/gs/2001_docdir_fix_for_debian.patch create mode 100644 recipes/gs/gs/2002_gs_man_fix_debian.patch create mode 100644 recipes/gs/gs_8.64.bb diff --git a/recipes/gs/gs/0001_svn_snapshot.patch b/recipes/gs/gs/0001_svn_snapshot.patch new file mode 100644 index 0000000000..4650b11e73 --- /dev/null +++ b/recipes/gs/gs/0001_svn_snapshot.patch @@ -0,0 +1,24362 @@ +Description: /jbig2dec changes r9437 → r9781 (release 8.64 → 2009-06-08) + - subdirs /jasper, /libpng and /jbig2dec skipped + - version bump skipped + - some $Id$ changes suppressed or fuzzy +Author: Jonas Smedegaard +diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps +--- a/Resource/Init/gs_init.ps ++++ b/Resource/Init/gs_init.ps +@@ -209,7 +209,7 @@ currentdict /DEVICE known not + % during initialization. + /MaxDictStack 500 + /MaxExecStack 5000 +- /MaxOpStack 65414 ++ /MaxOpStack 100000 + .dicttomark .setuserparams + } if + +diff --git a/Resource/Init/gs_pdfwr.ps b/Resource/Init/gs_pdfwr.ps +--- a/Resource/Init/gs_pdfwr.ps ++++ b/Resource/Init/gs_pdfwr.ps +@@ -665,18 +665,28 @@ currentdict /.pdf_hook_DSC_Creator undef + /MonoImageResolution { } + % Font embedding parameters + /AlwaysEmbed +- { dup length 0 gt +- { dup 0 get false eq ++ { dup length 0 gt ++ { dup 0 get type /booleantype eq } { false } ifelse ++ { dup 0 get ++ { dup length 1 sub 1 exch getinterval ++ } + { dup length 1 sub 1 exch getinterval exch pop /~AlwaysEmbed exch +- } if +- } if ++ } ifelse ++ } ++ { exch pop /.AlwaysEmbed exch ++ } ifelse + } + /NeverEmbed +- { dup length 0 gt +- { dup 0 get false eq +- { dup length 1 sub 1 exch getinterval exch pop /~NeverEmbed exch +- } if +- } if ++ { dup length 0 gt ++ { dup 0 get type /booleantype eq } { false } ifelse ++ { dup 0 get ++ { dup length 1 sub 1 exch getinterval ++ } ++ { dup length 1 sub 1 exch getinterval exch pop /~NeverEmbed exch ++ } ifelse ++ } ++ { exch pop /.NeverEmbed exch ++ } ifelse + } + /CannotEmbedFontPolicy { } + /EmbedAllFonts { } +diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps +--- a/Resource/Init/gs_res.ps ++++ b/Resource/Init/gs_res.ps +@@ -349,6 +349,15 @@ ne { + } if + pop pop + ++pssystemparams dup /GenericResourceDir get exch /GenericResourcePathSep get ++(Init) exch (gs_init.ps) concatstrings concatstrings concatstrings ++status { ++ pop pop pop pop ++} { ++ (\n*** Warning: GenericResourceDir doesn't point to a valid resource directory.) = ++ ( the -sGenericResourceDir=... option can be used to set this.\n) = ++} ifelse ++ + % Define the generic algorithm for computing resource file names. + /.rfnstring 8192 string def + /.genericrfn % .genericrfn +diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps +--- a/Resource/Init/gs_setpd.ps ++++ b/Resource/Init/gs_setpd.ps +@@ -171,13 +171,8 @@ level2dict begin + % the default policy to "7" (impose) to avoid numerous problems with + % printing within CUPS... + % +- NOMEDIAATTRS { +- /PolicyNotFound 7 +- /PageSize 7 +- } { +- /PolicyNotFound 1 +- /PageSize 0 +- } ifelse ++ /PageSize NOMEDIAATTRS { 7 } { 0 } ifelse ++ /PolicyNotFound 1 + /PolicyReport { + dup /.LockSafetyParams known { + % Only possible error is invalidaccess +@@ -810,20 +805,17 @@ SETPDDEBUG { (Installing.) = pstack flush } if + % NB: This shoud be the only use of the .setuseciecolor + % operator anywhere. + % +- % If UseCIEColor is transitioned to false, set some +- % color space other than /DeviceGray, to insure that +- % initgraphics will actually perform a setcolorspace ++ % Set some color space other than /DeviceGray, to insure ++ % that initgraphics will actually perform a setcolorspace + % operation (there is an optimization in setcolorspace + % that does nothing if the operand and current color +- % spaces are the same, and UseCIEColor is false). ++ % spaces are the same) + + /.setuseciecolor where + { + pop 1 index /UseCIEColor .knownget + { +- dup .setuseciecolor not +- { /DeviceRGB setcolorspace } +- if ++ .setuseciecolor /DeviceRGB setcolorspace + } + if + } +diff --git a/Resource/Init/gs_statd.ps b/Resource/Init/gs_statd.ps +--- a/Resource/Init/gs_statd.ps ++++ b/Resource/Init/gs_statd.ps +@@ -109,6 +109,8 @@ STRICT { (%END SIZES) .skipeof } if + /halfletter {396 612 //.setpagesize exec} bind def + % minimum of a4 and letter (a4 width, letter length) + /pa4 {595 792 //.setpagesize exec} bind def ++ % Japanese postcard size, 100mm x 148mm ++ /hagaki {283 420 //.setpagesize exec} bind def + % /tabloid {792 1224 //.setpagesize exec} bind def % 11x17 portrait + % /csheet {1224 1584 //.setpagesize exec} bind def % ANSI C 17x22 + % /dsheet {1584 2448 //.setpagesize exec} bind def % ANSI D 22x34 +@@ -134,7 +136,7 @@ STRICT { (%END SIZES) .skipeof } if + /flsa /flse /halfletter + /isob0 /isob1 /isob2 /isob3 /isob4 /isob5 /isob6 + /jisb0 /jisb1 /jisb2 /jisb3 /jisb4 /jisb5 /jisb6 +- /pa4 ++ /pa4 /hagaki + %END SIZES + ] cvlit readonly def + +diff --git a/Resource/Init/gs_ttf.ps b/Resource/Init/gs_ttf.ps +--- a/Resource/Init/gs_ttf.ps ++++ b/Resource/Init/gs_ttf.ps +@@ -827,7 +827,8 @@ end readonly def % .loadttfontdict + } if + /ttc_offset 0 def + } ifelse +- /tables f offsets 4 getu16 16 mul string readstring pop def ++ % Peek because table counter may be incorrect. ++ /tables f offsets 4 getu16 16 mul string .peekstring pop def + /tabdict tables length 16 idiv dict def + % tabs = tables we want to keep, sorted by file position. + /tabs [ 0 16 tables length 1 sub { +@@ -868,7 +869,7 @@ mark + % Read data. Updates offsets, tabs; stores data in tabdict. + /.readttdata { + /file_table_pos 10 dict def +- /fpos offsets length tables length add ttc_offset add def ++ /fpos offsets length ttc_offset add def + /sfpos offsets length tabs length 16 mul add def + offsets 4 tabs length putu16 + tabs { +diff --git a/Resource/Init/gs_typ32.ps b/Resource/Init/gs_typ32.ps +--- a/Resource/Init/gs_typ32.ps ++++ b/Resource/Init/gs_typ32.ps +@@ -37,7 +37,8 @@ systemdict /.makeglyph32 .undef + % Define a string large enough to hold the metrics, + % an uncompressed bitmap (worst case = 5x expansion), + % and the 2 RTC codes (3 bytes). +- dup length 4 index length 5 mul add 10 add string ++ dup length 4 index length 5 mul add 10 add ++ 65535 .min string + % Stack: metrics bitmap cid font metstr buffer + dup 0 3 index putinterval + dup 2 index length 1 index length 1 index sub getinterval +diff --git a/Resource/Init/opdfread.ps b/Resource/Init/opdfread.ps +--- a/Resource/Init/opdfread.ps ++++ b/Resource/Init/opdfread.ps +@@ -152,6 +152,7 @@ end % A dictionary for local binding + /TTFDEBUG DefaultSwitch + /RotatePages DefaultSwitch + /FitPages DefaultSwitch ++/CenterPages DefaultSwitch + /SetPageSize DefaultSwitch + + /error % mark .... error - +@@ -167,10 +168,16 @@ end % A dictionary for local binding + } bind def + + //SetPageSize { +- //RotatePages //FitPages or { +- mark (/RotatePages, /FitPages are not allowed with /SetPageSize) //error exec ++ //RotatePages //FitPages or //CenterPages or{ ++ mark (/RotatePages, /FitPages and CenterPages are not allowed with /SetPageSize) //error exec + } if +-} if ++} ++{ ++ //FitPages //CenterPages and { ++ mark (CenterPages is not allowed with /FitPages) //error exec ++ } if ++} ++ifelse + + % ===================== Utilities ========================================= + +@@ -851,23 +858,43 @@ currentdict end readonly def + } { + false + } ifelse +- { //FitPages { +- 1 index 5 index div 1 index 7 index div % bw bh px0 py0 pw ph sx sy +- 2 copy gt { +- exch ++ { //CenterPages { ++ //PDFR_DEBUG { ++ (Rotating page, and then centering it) == ++ } if ++ 90 rotate ++ 0 5 index neg translate ++ 5 index 1 index exch sub 2 div ++ 2 index 6 index sub 2 div neg % bw bh px0 py0 pw ph lm bm ++ translate ++ } { ++ //FitPages { ++ 1 index 5 index div 1 index 7 index div % bw bh px0 py0 pw ph sx sy ++ 2 copy gt { ++ exch ++ } if ++ pop dup scale % bw bh px0 py0 pw ph + } if +- pop dup scale % bw bh px0 py0 pw ph +- } if +- 90 rotate +- 0 5 index neg translate ++ 90 rotate ++ 0 5 index neg translate ++ } ifelse + } { +- //FitPages { +- 1 index 6 index div 1 index 6 index div % bw bh px0 py0 pw ph sx sy +- 2 copy gt { +- exch ++ //CenterPages { ++ //PDFR_DEBUG { ++ (Ccentering page) == ++ } if ++ 1 index 6 index sub 2 div ++ 1 index 6 index sub 2 div % bw bh px0 py0 pw ph lm bm ++ translate ++ } { ++ //FitPages { ++ 1 index 6 index div 1 index 6 index div % bw bh px0 py0 pw ph sx sy ++ 2 copy gt { ++ exch ++ } if ++ pop dup scale % bw bh px0 py0 pw ph + } if +- pop dup scale % bw bh px0 py0 pw ph +- } if ++ } ifelse + } ifelse + pop pop % bw bh px0 py0 + translate % bw bh +diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps +--- a/Resource/Init/pdf_base.ps ++++ b/Resource/Init/pdf_base.ps +@@ -720,6 +720,10 @@ currentdict /no_debug_dict undef + ( **** Operator 'endobj' is misspelled as 'endjobj'.\n) pdfformaterror + endobj exit + } bind ++ /enbobj { % Bug 690397. ++ ( **** Operator 'endobj' is misspelled as 'enbobj'.\n) pdfformaterror ++ endobj exit ++ } bind + % OmniForm generates PDF file with endobj missing in some + % objects. AR ignores this. So we have to do it too. + /obj { pop pop endobj exit } bind +diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps +--- a/Resource/Init/pdf_draw.ps ++++ b/Resource/Init/pdf_draw.ps +@@ -397,16 +397,20 @@ end + % Stack: mark ... smaskdict + dup /BC knownoget { + dup /Background exch 4 2 roll +- gsave ++ gsave //nodict begin + 1 index /G oget /Group oget /CS knownoget { + resolvecolorspace dup setgcolorspace csput + } if + aload pop setcolor [ currentgray ] +- grestore ++ end grestore + /GrayBackground exch 3 2 roll + } if + dup /TR knownoget { +- resolveidfnproc /TransferFunction exch 3 2 roll ++ dup /Identity eq { ++ pop ++ } { ++ resolvefnproc /TransferFunction exch 3 2 roll ++ } ifelse + } if + dup /G oget dup /BBox oget /BBox exch 4 2 roll + /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll +@@ -414,16 +418,44 @@ end + } ifelse SMask + } bdef + ++% Functions specific to the Device* colorspaces to force the switch to ++% the Device* colorspace so that the SMask will not get a CIEBased* colorspace ++% in the case when UseCIEColor changes the Device* colorspace to something else. ++% Also see the logic in pdf_main.ps:pdfopen that similarly defines these resources. ++/forceDefaultCS << ++ { ++ currentcolorspace setcolorspace % this will switch to Device colorspace ++ } bind ++ /DeviceGray exch ++ /DeviceRGB 1 index ++ /DeviceCMYK 1 index ++>> ++def ++ + % This procedure is called to actually render the soft mask. + /.execmaskgroup { % .execmaskgroup - +- % Save our place in PDFfile, and do a gsave to avoid resetting +- % the color space. +- currentcolorspace 4 1 roll ++ % Save our place in PDFfile. Do not use gsave-grestore when creating ++ % a soft mask with .begintransparencygroup because high level devices ++ % need to modify the graphic state by storing the soft mask ID. ++ % Save the ExtGState (//nodict begin) BEFORE changing the colorspace ++ mark currentcolor counttomark dup 4 add exch roll pop ++ currentcolorspace 4 1 roll .getuseciecolor 4 1 roll //nodict begin + PDFfile fileposition 4 1 roll + % We have to select the group's color space so that the + % background color will be interpreted correctly. +- dup /Group oget /CS knownoget { resolvecolorspace dup setgcolorspace csput } if +- exch dup /BBox get aload pop .begintransparencymaskgroup { ++ % [save/restore]DefaultCS make sure that the SMask logic sees ++ % the Device* spaces, not CIEBased* that UseCIEColor may have ++ % established. ++ false .setuseciecolor % SMask gets processed without UseCIEColor ++ dup /Group oget /CS knownoget { ++ resolvecolorspace dup setgcolorspace csput ++ //true % use currentcolorspace ++ } { ++ % inheriting the colorspace -- make sure Device* spaces are not CIEBased ++ forceDefaultCS currentcolorspace 0 get .knownget { exec } if ++ //false % no defined colorspace ++ } ifelse ++ 3 -1 roll dup /BBox get aload pop .begintransparencymaskgroup { + dup /Resources knownoget { oforce } { 0 dict } ifelse + exch false resolvestream + .execgroup .endtransparencymask +@@ -431,12 +463,12 @@ end + .discardtransparencymask stop + } if + PDFfile exch setfileposition +- setcolorspace ++ .setuseciecolor setcolorspace setcolor end % restore colorspace, color and ExtGState (end) + } bdef + % Paint a Form+Group XObject, either for a transparency mask or for a Do. + /.execgroup { % .execgroup - + gsave //nodict begin +- null SMask ++ newpath null SMask + 1 .setopacityalpha 1 .setshapealpha + /Compatible .setblendmode + % Execute the body of the Form, similar to DoForm. +@@ -773,7 +805,7 @@ currentdict end readonly def + exch //false resolvestream pdfopdict .pdfruncontext + + countdictstack exch sub dup 0 gt { +- ( **** Warning: Pattern stream has imbalanced q/Q operators (too many q's)\n) ++ ( **** Warning: Pattern stream has unbalanced q/Q operators \(too many q's\)\n) + pdfformaterror + { Q } repeat + } { +@@ -796,16 +828,18 @@ currentdict end readonly def + 1 index /File get dup fileposition 3 1 roll + % Stack: dict savepos pos file + dup 3 -1 roll setfileposition +- dup 3 index /Length oget +- +- dup 65535 le { +- dup 0 eq { +- pop pop () ++ dup 3 index /Length knownoget { ++ dup 65535 le { ++ dup 0 eq { ++ pop pop () ++ } { ++ string readstring pop ++ } ifelse + } { +- string readstring pop ++ () /SubFileDecode filter /ReusableStreamDecode filter + } ifelse + } { +- () /SubFileDecode filter /ReusableStreamDecode filter ++ 0 (endstream) /SubFileDecode filter /ReusableStreamDecode filter + } ifelse + % Stack: dict savepos file string + 3 1 roll exch setfileposition +@@ -820,6 +854,7 @@ currentdict end readonly def + 2 index /Resources knownoget { oforce } { 0 dict } ifelse + /.pdfpaintproc cvx + ] cvx put ++ dup /.pattern_uses_transparency 1 index patternusestransparency put + PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { true } ifelse { (%Pattern: ) print dup === flush } if } if + } bdef + +@@ -1108,24 +1143,41 @@ end + } bdef + + /doimagesmask { % doimagesmask - +- PDFusingtransparency { currentdict /SMask knownoget } { false } ifelse { +- .begintransparencymaskimage +- PDFfile fileposition exch +- gsave //nodict begin +- null /SoftMask gput +- 1 .setopacityalpha 1 .setshapealpha +- /Compatible .setblendmode +- DoImage +- end grestore +- PDFfile exch setfileposition +- 0 .endtransparencymask ++ PDFusingtransparency { ++ currentdict /SMask knownoget ++ } { ++ false ++ } ifelse ++ { % We are doing transparency and SMask is present in the image ++ % stack: ++ currentdevice .devicename /pdfwrite eq { ++ pop % pdfwrite will process SMask directly during 'doimage' ++ } { ++ .begintransparencymaskimage ++ PDFfile fileposition exch ++ gsave //nodict begin ++ null /SoftMask gput ++ 1 .setopacityalpha 1 .setshapealpha ++ /Compatible .setblendmode ++ DoImage ++ end grestore ++ PDFfile exch setfileposition ++ 0 .endtransparencymask ++ } ifelse + << /Subtype /Group /Isolated true + /.image_with_SMask true % pdfwrite needs : see gs/src/ztrans.c, gs/src/gdevpdft.c + >> 0 0 1 1 .begintransparencygroup + doimage + .endtransparencygroup + } { +- doimage ++ SoftMask //null ne { ++ % the image doesn't have an SMask, but the ExtGState does, force a group. ++ << /Subtype /Group /Isolated true >> 0 0 1 1 .begintransparencygroup ++ doimage ++ .endtransparencygroup ++ } ++ { doimage } ++ ifelse + } ifelse + } bdef + +@@ -1164,9 +1216,7 @@ end + % which is done under a rush of 8.63 release. + % The purpose is to disable a conversion of an image with soft mask + % into a Type 103 image, which currently allocates a full mask buffer +- % before writing clist. Note that imagemask installs +- % the transparency mask anyway (likely another bug), +- % so the image is still masked. ++ % before writing clist. + % With this workaround the Matte color is not working (ignored). + is_big_mask not + } { +@@ -1226,11 +1276,17 @@ end + /.paintform cvx + ] cvx /PaintProc exch put + % Adjust pdfemptycount since we have an extra dictionary on the stack +- pdfemptycount exch +- /pdfemptycount where pop count 2 sub /pdfemptycount exch put +- q execform Q % gsave / grestore around the Form ++ pdfemptycount countdictstack 3 -1 roll ++ /pdfemptycount count 1 sub store ++ q execform % gsave / grestore around the Form + % Restore pdfemptycount +- /pdfemptycount where pop exch /pdfemptycount exch put ++ countdictstack exch sub ++ dup 1 gt { ++ ( **** Warning: Pattern stream has unbalanced q/Q operators \(too many q's\)\n) ++ pdfformaterror ++ } if ++ { Q } repeat ++ /pdfemptycount exch store + } bdef + + /_dops_save 1 array def +@@ -1298,6 +1354,8 @@ end + oforce //unabbrevtypedict 1 index type .knownget { exec } if + } bdef + ++/is_space_dict << 0 0 9 9 10 10 12 12 13 13 32 32 >> readonly def ++ + drawopdict begin + /BI { mark } bdef + /ID { +@@ -1314,23 +1372,34 @@ drawopdict begin + % between the last byte of valid data and an EOL. + % Some files (PDFOUT v3.8d by GenText) have EI immediately following + % the stream. Some have no EOL and garbage bytes. +- % Therefore, we skip all bytes before EI or EOL +- 0 +- { PDFsource read not { //true exit } if +- dup 10 eq 1 index 13 eq or +- { pop PDFsource token pop /EI ne exit +- } +- if +- exch 69 eq 1 index 73 eq and { //false exit } if % 'EI' +- } +- loop +- exch pop +- { /ID cvx /syntaxerror signalerror +- } +- if ++ % Sometimes (bug 690300) CCITTDecode filter consumes 'E' in 'EI'. ++ % Therefore, we search for I or EI ++ PDFsource read not { ++ /ID cvx /syntaxerror signalerror ++ } if ++ dup 73 eq { ++ pop 10 69 73 % Seed to: EI ++ } { ++ 10 10 3 -1 roll % Seed to: ++ } ifelse ++ { PDFsource read not dup { 10 exch } if ++ //is_space_dict 2 index known ++ 3 index 73 eq and 4 index 69 eq and ++ //is_space_dict 6 index known and { ++ pop pop pop pop pop exit ++ } { ++ { ++ pop pop pop /ID cvx /syntaxerror signalerror ++ } { ++ 4 -1 roll pop ++ } ifelse ++ } ifelse ++ } loop + } bdef + end + ++currentdict /is_space_dict undef ++ + % ================================ Text ================================ % + + drawopdict begin +@@ -1401,38 +1470,42 @@ end + /drawborder { % drawborder - + gsave + dup /BS known 1 index /Border known or { +- dup /BS knownoget { ++ dup /BS knownoget { + dup type /dicttype ne % + } { + dup /Border oget +- dup type /arraytype ne % [border] +- } ifelse +- { +- ( **** Warning: Wrong type of annotation border object.\n) ++ dup type /arraytype eq { ++ dup length 3 lt ++ } { ++ //true ++ } ifelse % [border] ++ } ifelse { ++ ( **** Warning: Wrong annotation border object, no border is drawn.\n) + pdfformaterror ++ pop { 0 0 0 } + } if + dup type /dicttype eq { +- dup /W knownoget not { 1 } if ++ dup /W knownoget not { 1 } if + % Per PDF1.6 Reference table 8.13, /W in the border style dictionary is + % expressed in points (an absolute unit), so compensate here for any + % scaling of the PostScript user space done due to /UserUnit. + % Scaling due to -dPDFFitPage is not undone, to keep the correct border width + % compared to the size of the surrounding marks. +- //systemdict /NoUserUnit .knownget not { false } if not ++ //systemdict /NoUserUnit .knownget not { //false } if not + //systemdict /PDFFitPage known not and { % UserUnit is ignored if -dPDFFitPage + Page /UserUnit knownoget { div } if + } if +- [] 2 index /S knownoget { +- /D eq { 2 index /D knownoget not { [3] } if exch pop } if +- } if 3 -1 roll pop strokeborder +- } { ++ {} 2 index /S knownoget { ++ /D eq { 2 index /D knownoget not { {3} } if exch pop } if ++ } if 3 -1 roll pop strokeborder ++ } { + dup 2 get +- exch dup length 3 gt { 3 get } { pop [] } ifelse ++ exch dup length 3 gt { 3 get } { pop {} } ifelse + strokeborder + } ifelse +- } { +- 1 [] strokeborder +- } ifelse ++ } { ++ 1 {} strokeborder ++ } ifelse + grestore + } bdef + +diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps +--- a/Resource/Init/pdf_font.ps ++++ b/Resource/Init/pdf_font.ps +@@ -652,6 +652,11 @@ setglobal + % Yet another case of broken PDF's that Adobe Reader accepts. + 1 index dup /FontName known { + /FontName oget ++ dup type /nametype ne { ++ ( **** /FontName attribute in FontDescriptor is not a name.\n) ++ pdfformaterror ++ cvn ++ } if + } { + ( **** FontDescriptor missing required /FontName key. BaseFont name used.\n) + pdfformaterror +@@ -735,9 +740,43 @@ setglobal + % The whole type1 stream can be executed directly. There's no need to process + % Length1, 2, 3 keys. + +-/readtype1dict 5 dict dup begin ++/readtype1dict 10 dict dup begin + /definefont { + exch pop ++ ++ /topFontDict where { ++ { /FontType % in PLRM order ++ /FontMatrix ++ /FontName ++ /FontInfo ++ /WMode ++ /Encoding ++ /FontBBox ++ /UniqueID ++ /XUID ++ /PaintType ++ /StrokeWidth ++ /Metrics ++ /Metrics2 ++ /CDevProc ++ /CharStrings ++ /Private ++ /WeightVector ++ } { ++ 2 copy .knownget { ++ % Stack: font topFontDict /key val ++ 3 index 3 1 roll put ++ dup /MisplacedKey 0 put ++ } { ++ pop ++ } ifelse ++ } forall ++ /MisplacedKey known { ++ ( **** Warning: Type 1 font defines some of the keys in the external scope.\n) ++ pdfformaterror ++ } if ++ } if ++ + dup /UniqueID .knownget { + dup dup 0 lt exch 16#ffffff gt or { + ( **** Warning: Ignoring invalid /UniqueID = ) exch =string cvs +@@ -793,10 +832,31 @@ setglobal + pdfformaterror + } ifelse } .bind def + +- currentdict dup dup +- /undef_proc_warning undef +- /missing-type1-procs undef +- /readonly-op-dict undef ++ /prev_get /get load def ++ ++ /get { ++ dup /FontName eq { ++ % No warning, probably FontName is defined elsewhere; see definefont above. ++ .knownget not { /Missing } if ++ } { ++ dup /UniqueID eq { ++ % We don't want fonts to check /UniqueID and do 'restore'. ++ pop pop 16#FEDCBA98 % Arbitrary and invalid value ++ } { ++ prev_get ++ } ifelse ++ } ifelse ++ } bdef ++ ++ /prev_begin /begin load def ++ ++ /begin { ++ dup //systemdict eq { pop 0 dict } if ++ prev_begin ++ } bdef ++ ++ { /undef_proc_warning /missing-type1-procs /readonly-op-dict } ++ { currentdict exch undef } forall + + end readonly def + +@@ -1348,8 +1408,8 @@ currentdict /eexec_pdf_param_dict .undef + concatstrings concatstrings + cvn + QUIET not { +- (Substituting CID font resource ) print dup ==only +- ( for ) print 1 index ==only (.\n) print ++ (Substituting CID font ) print dup ==only ++ ( for ) print 1 index ==only (, see doc/Use.htm#CIDFontSubstitution.) = + } if + exch pop + dup /CIDFont resourcestatus { +@@ -1579,11 +1639,11 @@ currentdict /eexec_pdf_param_dict .undef + } 2 bndef + + <01000401> <01000402> <01000403> <01000404> % Type 1C +- <01000C02> ++ <01000C02> <01000C03> + { exch pop + dup /Subtype get + fontloadprocs exch get exec +- } 5 bndef ++ } 6 bndef + + <00010000> (true) (typ1) (ttcf) % TrueType OpenType + { exch pop readtruetype +@@ -1627,9 +1687,15 @@ currentdict /bndef undef + % /key res res desc stream + dup //null ne { + PDFfile fileposition +- 1 index //true resolvestream dup +- 4 string readstring pop +- exch closefile ++ mark { ++ 2 index //true resolvestream dup ++ 4 string readstring pop ++ exch closefile ++ } stopped { ++ cleartomark /bad_stream ++ } { ++ exch pop ++ } ifelse + PDFfile 3 -1 roll setfileposition + dup length 4 lt { pop /bad_stream } if + } { +diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps +--- a/Resource/Init/pdf_main.ps ++++ b/Resource/Init/pdf_main.ps +@@ -955,15 +955,22 @@ pdfdict begin + { Trailer /Root oget /Pages oget + dup /Count knownoget { + dup 0 le { +- pop ( **** Warning: Invalid Page count.\n) pdfformaterror +- % find the last page and use that as the Count +- 1 1 999999999 { +- dup pdffindpage? +- exch pop +- //null eq { exit } { pop } ifelse +- } for +- 1 sub % decrement to last page that we were able to find +- 2 copy /Count exch put ++ pop ++ dup /Kids knownoget { ++ pop ++ ( **** Warning: Invalid Page count.\n) pdfformaterror ++ % find the last page and use that as the Count ++ 1 1 999999999 { ++ dup pdffindpage? ++ exch pop ++ //null eq { exit } { pop } ifelse ++ } for ++ 1 sub % decrement to last page that we were able to find ++ 2 copy /Count exch put ++ } { ++ 0 % return 0 and keep 0 page count. ++ ( **** Warning: PDF document has no pages.\n) pdfformaterror ++ } ifelse + } if + exch pop + } { +@@ -1215,9 +1222,18 @@ end readonly def + /Link { + mark exch + dup /C knownoget { /Color exch 3 -1 roll } if +- { /Rect /Border } +- { 2 copy knownoget { 3 -1 roll } { pop } ifelse } +- forall dup /A knownoget { ++ dup /Rect knownoget { /Rect exch 3 -1 roll } if ++ dup /Border knownoget { ++ dup type /arraytype eq { ++ dup length 3 lt ++ } { ++ //true ++ } ifelse { ++ pop [ 0 0 0 ] % Following AR5 use invisible border. ++ } if ++ /Border exch 3 -1 roll ++ } if ++ dup /A knownoget { + dup /URI known { + /A mark 3 2 roll % <<>> /A [ <> + { oforce } forall +@@ -1539,7 +1555,7 @@ currentdict /PDF2PS_matrix_key undef + % Some PDF files don't have matching q/Q (gsave/grestore) so we need + % to clean up any left over dicts from the dictstack + countdictstack PDFdictstackcount sub dup 0 ne { +- ( **** Warning: File has imbalanced q/Q operators \(too many q's\)\n) ++ ( **** Warning: File has unbalanced q/Q operators \(too many q's\)\n) + pdfformaterror + { end } repeat + } { +@@ -1626,17 +1642,27 @@ currentdict /PDF2PS_matrix_key undef + /extgstateusestransparency { % extgstateusestransparency + //false exch % Assume no transparency + { % establish loop context +- exch pop oforce + dup /BM knownoget { dup /Normal ne exch /Compatible ne and + { pop not exit } if + } if + dup /ca knownoget { 1 ne { pop not exit } if } if + dup /CA knownoget { 1 ne { pop not exit } if } if + dup /SMask knownoget { /None ne { pop not exit } if } if +- pop +- } forall ++ pop exit ++ } loop + } bind def + ++% Check if transparency is used in a Pattern ++/patternusestransparency { % patternusestransparency ++ //false exch % Assume no transparency ++ { ++ 4 dict 1 index resourceusestransparency { pop not exit } if ++ dup /ExtGState knownoget { extgstateusestransparency { pop not exit } if } if ++ pop exit ++ } loop ++} bind def ++ ++ + % Check the Resources of a page or Form. Check for loops in the resource chain. + /resourceusestransparency { % resourceusestransparency + { % Use loop to provide an exitable context. +@@ -1651,19 +1677,33 @@ currentdict /PDF2PS_matrix_key undef + } if + 2 copy //true put % In the current chain. + dup /ExtGState knownoget { +- extgstateusestransparency ++ //false exch ++ { exch pop oforce extgstateusestransparency { pop //true exit } if ++ } forall ++ { pop //true exit } if ++ } if ++ dup /Pattern knownoget { ++ //false exch ++ { exch pop oforce patternusestransparency { pop //true exit } if ++ } forall + { pop //true exit } if + } if + dup /XObject knownoget { +- //false exch { +- exch pop oforce dup /Subtype get +- dup /Image eq { 1 index /SMask known { pop pop not exit } if } if +- /Form eq { +- 3 index exch resourceusestransparency { not exit } if +- } { +- pop +- } ifelse +- } forall { pop //true exit } if ++ dup type /dicttype eq { ++ //false exch { ++ exch pop oforce dup /Subtype get ++ dup /Image eq { 1 index /SMask known { pop pop not exit } if } if ++ /Form eq { ++ 3 index exch resourceusestransparency { not exit } if ++ } { ++ pop ++ } ifelse ++ } forall { pop //true exit } if ++ } { ++ ( **** Ignoring non-dictionary /XObject attribute.\n) ++ pdfformaterror ++ pop ++ } ifelse + } if + 2 copy //false put % Visited but not in the current chain. + pop //false exit +@@ -1748,9 +1788,13 @@ currentdict /PDF2PS_matrix_key undef + { exch pop oforce /ColorSpace oget 3 index colorspacespotcolors } forall + } if + /XObject knownoget { +- { exch pop oforce dup +- /Subtype get /Form eq { resourcespotcolors } { pop } ifelse +- } forall ++ dup type /dicttype eq { ++ { exch pop oforce dup ++ /Subtype get /Form eq { resourcespotcolors } { pop } ifelse ++ } forall ++ } { ++ pop % Just ignore here, already reported by resourceusestransparency. ++ } ifelse + } if + exit + } loop +diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps +--- a/Resource/Init/pdf_ops.ps ++++ b/Resource/Init/pdf_ops.ps +@@ -115,7 +115,7 @@ nodict readonly pop + } { + //true % formaterror -- not a gsave dict + } ifelse +- { (\n **** File has imbalanced q/Q operators \(too many Q's\) ****\n) ++ { (\n **** File has unbalanced q/Q operators \(too many Q's\) ****\n) + pdfformaterror + } if + } bdef +@@ -371,10 +371,16 @@ end def + } bdef + /fsexec % fsexec - + { % Preserve the current point, if any. ++ SoftMask //null ne { ++ mark /Subtype /Group /Isolated true .dicttomark pathbbox .begintransparencygroup ++ } if + { currentpoint } stopped + { $error /newerror false put cvx exec } + { 3 -1 roll cvx exec moveto } + ifelse ++ SoftMask //null ne { ++ .endtransparencygroup ++ } if + } bdef + + % ---------------- Path painting and clipping ---------------- % +diff --git a/Resource/Init/pdf_sec.ps b/Resource/Init/pdf_sec.ps +--- a/Resource/Init/pdf_sec.ps ++++ b/Resource/Init/pdf_sec.ps +@@ -328,16 +328,17 @@ def + pop + % this step is for the AES cipher only + Trailer /Encrypt oget +- dup /StmF known +- { +- dup /StmF oget +- exch /CF oget exch oget /CFM oget +- /AESV2 eq { +- (sAlT) concatstrings +- } if +- } +- { pop } +- ifelse ++ dup /StmF knownoget { ++ exch /CF knownoget { ++ exch oget /CFM oget /AESV2 eq { ++ (sAlT) concatstrings ++ } if ++ } { ++ pop ++ } ifelse ++ } { ++ pop ++ } ifelse + md5 0 FileKey length 5 add 2 index length .min getinterval + } bind def + +@@ -397,12 +398,15 @@ def + { % If StrF is present ... + dup /Identity eq not % Check if StrF != Identity + { /StdCF eq +- { Trailer /Encryption oget /StdCF oget /CFM oget +- /AESV2 eq +- % Decrypt string +- { 1 index aesdecode } +- { 1 index arc4decode } +- ifelse ++ { Trailer /Encrypt oget /CF knownoget { ++ /StdCF oget /CFM oget /AESV2 eq ++ } { ++ //false ++ } ifelse { % Decrypt string ++ 1 index aesdecode ++ } { ++ 1 index arc4decode ++ } ifelse + } + { 1 index arc4decode } + ifelse % If StrF != StdCF +@@ -477,8 +481,10 @@ currentdict /PDFScanRules_null undef + } if + % Check if the stream encryption handler (StmF) == Identity. + PDFDEBUG { +- Trailer /Encrypt oget /CF get /StdCF get /CFM get +- (Encrypt StmF is StdCF with CFM ) print = ++ Trailer /Encrypt oget /CF knownoget { ++ /StdCF oget /CFM oget ++ (Encrypt StmF is StdCF with CFM ) print = ++ } if + } if + /StmF knownoget % Get StmF (if present) + not { /Identity } if % If StmF not present default = Identity +@@ -504,13 +510,13 @@ currentdict /PDFScanRules_null undef + exch + % Stack: readdata? dict parms filternames file/string + 3 index /StreamKey get +- Trailer /Encrypt oget dup /StmF +- known +- { +- dup /StmF oget % stack: key Encrypt StmF +- exch /CF oget +- exch oget /CFM oget % stack: key StmF-CFM +- /AESV2 eq ++ Trailer /Encrypt oget ++ dup /StmF knownoget ++ { % stack: key Encrypt StmF ++ exch /CF knownoget { ++ exch oget /CFM oget % stack: key StmF-CFM ++ /AESV2 eq ++ } { pop //false } ifelse + { aesdecodefilter } % install the requested filter + { arc4decodefilter } + ifelse +diff --git a/base/Makefile.in b/base/Makefile.in +--- a/base/Makefile.in ++++ b/base/Makefile.in +@@ -82,6 +82,7 @@ CUPSLIBDIRS=@CUPSLIBDIRS@ + CUPSSERVERBIN=@CUPSSERVERBIN@ + CUPSSERVERROOT=@CUPSSERVERROOT@ + CUPSDATA=@CUPSDATA@ ++CUPSPDFTORASTER=@CUPSPDFTORASTER@ + + # Define the default directory/ies for the runtime + # initialization and font files. Separate multiple directories with a :. +@@ -180,11 +181,14 @@ JBIG2_LIB=jbig2dec + SHARE_JBIG2=@SHARE_JBIG2@ + JBIG2SRCDIR=@JBIG2DIR@ + +-# uncomment the following to compile in the Luratech ldf_jb2 codec ++# uncomment the following three lines and one of the last two to ++# compile in the Luratech ldf_jb2 codec + #JBIG2_LIB=luratech + #SHARE_JBIG2=0 + #JBIG2SRCDIR=ldf_jb2 +-#JBIG2_CFLAGS=-DUSE_LDF_JB2 ++#JBIG2_CFLAGS=-DUSE_LDF_JB2 -DLINUX ++#JBIG2_CFLAGS=-DUSE_LDF_JB2 -DMAC -DMAC_OS_X_BUILD ++ + + # Choose the library to use for (JPXDecode support) + # whether to link to an external build or compile in from source +@@ -194,11 +198,13 @@ SHARE_JPX=@SHARE_JASPER@ + JPXSRCDIR=@JASPERDIR@ + JPX_CFLAGS=-DJAS_CONFIGURE + +-# uncomment the following to compile in the Luratech lwf_jp2 codec ++# uncomment the following three lines and one of the last two to ++# compile in the Luratech lwf_jp2 codec + #JPX_LIB=luratech + #SHARE_JPX=0 + #JPXSRCDIR=lwf_jp2 + #JPX_CFLAGS=-DUSE_LWF_JP2 -DLINUX ++#JPX_CFLAGS=-DUSE_LWF_JP2 -DMAC -DMAC_OS_X_BUILD + + # Define the directory where the icclib source are stored. + # See icclib.mak for more information +@@ -506,7 +512,7 @@ include $(GLSRCDIR)/unixinst.mak + # Clean up after the autotools scripts + # configure.ac and Makefile.in are symlinks from a subdir + # (created by autogen.sh) and so are safe to remove +-distclean : clean config-clean ++distclean : clean config-clean soclean debugclean + -$(RM_) -r $(BINDIR) $(GLOBJDIR) $(PSOBJDIR) + -$(RM_) -r autom4te.cache + -$(RM_) config.log config.status +diff --git a/base/configure.ac b/base/configure.ac +--- a/base/configure.ac ++++ b/base/configure.ac +@@ -420,6 +420,9 @@ dnl look for CUPS... + AC_ARG_ENABLE([cups], AC_HELP_STRING([--disable-cups], + [Don't include CUPS support])) + ++AC_ARG_WITH([pdftoraster], AC_HELP_STRING([--without-pdftoraster], ++ [Don't include CUPS' pdftoraster filter])) ++ + CUPSDEV="" + CUPSINCLUDE="" + CUPSCFLAGS="" +@@ -429,6 +432,8 @@ CUPSCONFIG="${CUPSCONFIG:=}" + CUPSSERVERBIN="" + CUPSSERVERROOT="" + CUPSDATA="" ++CUPSVERSION="0" ++CUPSPDFTORASTER="0" + + if ( test -d cups ); then + if test x$enable_cups != xno; then +@@ -446,6 +451,12 @@ if ( test -d cups ); then + CUPSDATA="`$CUPSCONFIG --datadir`" + CUPSINCLUDE="include cups/cups.mak" + CUPSDEV="\$(DD)cups.dev" ++ CUPSVERSION="`$CUPSCONFIG --version`" ++ if ( test x$with_pdftoraster != xno ); then ++ if test "$CUPSVERSION" ">" "1.2"; then ++ CUPSPDFTORASTER="1" ++ fi ++ fi + fi + fi + fi +@@ -458,6 +469,7 @@ AC_SUBST(CUPSINCLUDE) + AC_SUBST(CUPSSERVERBIN) + AC_SUBST(CUPSSERVERROOT) + AC_SUBST(CUPSDATA) ++AC_SUBST(CUPSPDFTORASTER) + + + dnl look for IJS implementation +@@ -781,7 +793,7 @@ P_DEVS="" + F_DEVS="" + + dnl Known printers +-HP_DEVS="cdj500 djet500 djet500c dnj650c cljet5pr deskjet laserjet ljetplus ljet2p ljet3 ljet3d ljet4 ljet4d lj4dith lj5mono lj5gray cdeskjet cdjcolor cdjmono cdj550 pj pjxl pjxl300 lp2563 paintjet pjetxl cljet5 cljet5c pxlmono pxlcolor cdj670 cdj850 cdj880 cdj890 cdj970 cdj1600 chp2200 pcl3 hpdjplus hpdjportable hpdj310 hpdj320 hpdj340 hpdj400 hpdj500 hpdj500c hpdj510 hpdj520 hpdj540 hpdj550c hpdj560c hpdj600 hpdj660c hpdj670c hpdj680c hpdj690c hpdj850c hpdj855c hpdj870c hpdj890c hpdj1120c lj3100sw" ++HP_DEVS="cdj500 djet500 djet500c dnj650c cljet5pr deskjet laserjet ljetplus ljet2p ljet3 ljet3d ljet4 ljet4d lj4dith lj5mono lj5gray cdeskjet cdjcolor cdjmono cdj550 pj pjxl pjxl300 lp2563 paintjet pjetxl cljet5 cljet5c pxlmono pxlcolor cdj670 cdj850 cdj880 cdj890 cdj970 cdj1600 cdnj500 chp2200 pcl3 hpdjplus hpdjportable hpdj310 hpdj320 hpdj340 hpdj400 hpdj500 hpdj500c hpdj510 hpdj520 hpdj540 hpdj550c hpdj560c hpdj600 hpdj660c hpdj670c hpdj680c hpdj690c hpdj850c hpdj855c hpdj870c hpdj890c hpdj1120c lj3100sw" + PCLXL_DEVS="pxlmono pxlcolor" + EPSON_DEVS="eps9high eps9mid epson epsonc escp lp8000 lq850 photoex st800 stcolor alc1900 alc2000 alc4000 alc4100 alc8500 alc8600 alc9100 lp3000c lp8000c lp8200c lp8300c lp8500c lp8800c lp9000c lp9200c lp9500c lp9800c lps6500 epl2050 epl2050p epl2120 epl2500 epl2750 epl5800 epl5900 epl6100 epl6200 lp1800 lp1900 lp2200 lp2400 lp2500 lp7500 lp7700 lp7900 lp8100 lp8300f lp8400f lp8600 lp8600f lp8700 lp8900 lp9000b lp9100 lp9200b lp9300 lp9400 lp9600 lp9600s lps4500" + CANON_DEVS="bj10e bj200 bjc600 bjc800 lbp8 lips3 bjcmono bjcgray bjccmyk bjccolor" +diff --git a/base/contrib.mak b/base/contrib.mak +--- a/base/contrib.mak ++++ b/base/contrib.mak +@@ -782,7 +782,7 @@ $(DD)inferno.dev : $(inferno_) $(DD)page.dev + $(SETPDEV) $(DD)inferno $(inferno_) + + $(GLOBJ)gdevifno.$(OBJ) : $(GLSRC)gdevifno.c $(PDEVH)\ +- $(gsparam_h) $(gxlum_h) ++ $(gsparam_h) + $(GLCC) $(GLO_)gdevifno.$(OBJ) $(C_) $(GLSRC)gdevifno.c + + ### --------------------------- MGR devices ---------------------------- ### +diff --git a/base/devs.mak b/base/devs.mak +--- a/base/devs.mak ++++ b/base/devs.mak +@@ -418,12 +418,10 @@ $(GLOBJ)gdevvglb.$(OBJ) : $(GLSRC)gdevvglb.c $(GDEV) $(gdevpccm_h) $(gsparam_h) + ### NON PORTABLE, ONLY UNIX WITH GCC SUPPORT + + $(GLOBJ)lvga256.so : $(lvga256_) +- $(CCLD) -shared -Wl,'-solvga256.so' $(lvga256_) -lvga -lvgagl +- mv lvga256.so $(GLOBJ)lvga256.so ++ $(CCLD) $(LDFLAGS) -shared -o $(GLOBJ)lvga256.so $(lvga256_) -lvga -lvgagl + + $(GLOBJ)vgalib.so : $(vgalib_) +- $(CCLD) -shared -Wl,'-sovgalib.so' $(vgalib_) -lvga -lvgagl +- mv vgalib.so $(GLOBJ)vgalib.so ++ $(CCLD) $(LDFLAGS) -shared -o $(GLOBJ)vgalib.so $(vgalib_) -lvga -lvgagl + + ### -------------------------- The X11 device -------------------------- ### + +@@ -526,8 +524,7 @@ $(GLOBJ)gdevxalt.$(OBJ) : $(GLSRC)gdevxalt.c $(GDEVX) $(math__h) $(memory__h)\ + ### NON PORTABLE, ONLY UNIX WITH GCC SUPPORT + + $(GLOBJ)X11.so : $(x11alt_) $(x11_) +- $(CCLD) -shared -Wl,'-soX11.so' $(x11alt_) $(x11_) -L/usr/X11R6/lib -lXt -lSM -lICE -lXext -lX11 $(XLIBDIRS) +- mv X11.so $(GLOBJ)X11.so ++ $(CCLD) $(LDFLAGS) -shared -o $(GLOBJ)X11.so $(x11alt_) $(x11_) -L/usr/X11R6/lib -lXt -lSM -lICE -lXext -lX11 $(XLIBDIRS) + + ###### --------------- Memory-buffered printer devices --------------- ###### + +diff --git a/base/dmmain.c b/base/dmmain.c +--- a/base/dmmain.c ++++ /dev/null +@@ -1,997 +0,0 @@ +-/* Copyright (C) 2001-2006 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 that +- license. Refer to licensing information at http://www.artifex.com/ +- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, +- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. +-*/ +-/* $Id: dmmain.c 8022 2007-06-05 22:23:38Z giles $ */ +- +-/* Ghostscript shlib example wrapper for Macintosh (Classic/Carbon) contributed +- by Nigel Hathaway. Uses the Metrowerks CodeWarrior SIOUX command-line library. +- */ +- +-#if __ide_target("Ghostscript PPC (Debug)") || __ide_target("Ghostscript PPC (Release)") +-#define TARGET_API_MAC_CARBON 0 +-#define TARGET_API_MAC_OS8 1 +-#define ACCESSOR_CALLS_ARE_FUNCTIONS 1 +-#endif +- +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "gscdefs.h" +-#define GSREVISION gs_revision +-#include "ierrors.h" +-#include "iapi.h" +- +-#if DEBUG +-#include "vdtrace.h" +-#endif +- +-#include "gdevdsp.h" +- +-#define kScrollBarWidth 15 +-#define MAX_ARGS 25 +- +-Boolean gRunningOnX = false; +-Boolean gDone; +-ControlActionUPP gActionFunctionScrollUPP; +- +-const char start_string[] = "systemdict /start get exec\n"; +-void *instance; +- +-const unsigned int display_format = DISPLAY_COLORS_RGB | DISPLAY_UNUSED_FIRST | +- DISPLAY_DEPTH_8 | DISPLAY_BIGENDIAN | +- DISPLAY_TOPFIRST; +-typedef struct IMAGE_S IMAGE; +-struct IMAGE_S { +- void *handle; +- void *device; +- WindowRef windowRef; +- ControlRef scrollbarVertRef; +- ControlRef scrollbarHorizRef; +- PixMapHandle pixmapHdl; +- UInt64 update_time; +- int update_interval; +- IMAGE *next; +-}; +- +-IMAGE *first_image; +- +-static IMAGE *image_find(void *handle, void *device); +- +-static int GSDLLCALL gsdll_stdin(void *instance, char *buf, int len); +-static int GSDLLCALL gsdll_stdout(void *instance, const char *str, int len); +-static int GSDLLCALL gsdll_stderr(void *instance, const char *str, int len); +-static int GSDLLCALL gsdll_poll(void *handle); +- +-static int display_open(void *handle, void *device); +-static int display_preclose(void *handle, void *device); +-static int display_close(void *handle, void *device); +-static int display_presize(void *handle, void *device, int width, int height, +- int raster, unsigned int format); +-static int display_size(void *handle, void *device, int width, int height, +- int raster, unsigned int format, unsigned char *pimage); +-static int display_sync(void *handle, void *device); +-static int display_page(void *handle, void *device, int copies, int flush); +-static int display_update(void *handle, void *device, +- int x, int y, int w, int h); +- +-static size_t get_input(void *ptr, size_t size); +- +-static void window_create (IMAGE *img); +-static void window_invalidate (WindowRef windowRef); +-static void window_adjust_scrollbars (WindowRef windowRef); +- +-void main (void); +-OSErr quitAppEventHandler (AppleEvent *,AppleEvent *,SInt32); +-void doEvents (EventRecord *); +-void doMouseDown (EventRecord *); +-void doUpdate (EventRecord *); +-void doUpdateWindow (EventRecord *); +-void doOSEvent (EventRecord *); +-void doInContent (EventRecord *,WindowRef); +-pascal void actionFunctionScroll (ControlRef,ControlPartCode); +- +-/*********************************************************************/ +-/* stdio functions */ +-static int GSDLLCALL +-gsdll_stdin(void *instance, char *buf, int len) +-{ +- if (isatty(fileno(stdin))) +- return get_input(buf, len); +- else +- return fread(buf, 1, len, stdin); +-} +- +-static int GSDLLCALL +-gsdll_stdout(void *instance, const char *str, int len) +-{ +- int n = fwrite(str, 1, len, stdout); +- fflush(stdout); +- return n; +-} +- +-static int GSDLLCALL +-gsdll_stderr(void *instance, const char *str, int len) +-{ +- return gsdll_stdout(instance, str, len); +-} +- +-/* Poll the caller for cooperative multitasking. */ +-/* If this function is NULL, polling is not needed */ +-static int GSDLLCALL gsdll_poll(void *handle) +-{ +- EventRecord eventStructure; +- +- while (WaitNextEvent(everyEvent, &eventStructure, 0, NULL)) +- doEvents(&eventStructure); +- +- return (gDone ? e_Fatal : 0); +-} +-/*********************************************************************/ +- +-/* new dll display device */ +- +-/* New device has been opened */ +-/* This is the first event from this device. */ +-static int display_open(void *handle, void *device) +-{ +- IMAGE *img = (IMAGE *)malloc(sizeof(IMAGE)); +- if (img == NULL) +- return -1; +- memset(img, 0, sizeof(IMAGE)); +- +- /* add to list */ +- if (first_image) +- img->next = first_image; +- first_image = img; +- +- /* remember device and handle */ +- img->handle = handle; +- img->device = device; +- +- /* create window */ +- window_create(img); +- +- gsdll_poll(handle); +- return 0; +-} +- +-/* Device is about to be closed. */ +-/* Device will not be closed until this function returns. */ +-static int display_preclose(void *handle, void *device) +-{ +- /* do nothing - no thread synchonisation needed */ +- return 0; +-} +- +-/* Device has been closed. */ +-/* This is the last event from this device. */ +-static int display_close(void *handle, void *device) +-{ +- IMAGE *img = image_find(handle, device); +- if (img == NULL) +- return -1; +- +- gsdll_poll(handle); +- +- /* remove from list */ +- if (img == first_image) +- first_image = img->next; +- else +- { +- IMAGE *tmp; +- for (tmp = first_image; tmp!=0; tmp=tmp->next) +- { +- if (img == tmp->next) +- tmp->next = img->next; +- } +- } +- +- DisposePixMap(img->pixmapHdl); // need to go in doCloseWindow() +- DisposeWindow(img->windowRef); +- +- free(img); +- +- return 0; +-} +- +-/* Device is about to be resized. */ +-/* Resize will only occur if this function returns 0. */ +-static int display_presize(void *handle, void *device, int width, int height, +- int raster, unsigned int format) +-{ +- /* Check for correct format (32-bit RGB), fatal error if not */ +- if (format != display_format) +- { +- printf("DisplayFormat has been set to an incompatible value.\n"); +- fflush(stdout); +- return e_rangecheck; +- } +- +- return 0; +-} +- +-/* Device has been resized. */ +-/* New pointer to raster returned in pimage */ +-static int display_size(void *handle, void *device, int width, int height, +- int raster, unsigned int format, unsigned char *pimage) +-{ +- PixMapPtr pixmap; +- IMAGE *img = image_find(handle, device); +- if (img == NULL) +- return -1; +- +- /* Check that image is within allowable bounds */ +- if (raster > 0x3fff) +- { +- printf("QuickDraw can't cope with an image this big.\n"); +- fflush(stdout); +- if (img->pixmapHdl) +- { +- DisposePixMap(img->pixmapHdl); +- img->pixmapHdl = NULL; +- } +- return e_rangecheck; +- } +- +- /* Create the PixMap */ +- if (!img->pixmapHdl) +- img->pixmapHdl = NewPixMap(); +- +- pixmap = *(img->pixmapHdl); +- pixmap->baseAddr = (char*)pimage; +- pixmap->rowBytes = (((SInt16)raster) & 0x3fff) | 0x8000; +- pixmap->bounds.right = width; +- pixmap->bounds.bottom = height; +- pixmap->packType = 0; +- pixmap->packSize = 0; +- pixmap->pixelType = RGBDirect; +- pixmap->pixelSize = 32; +- pixmap->cmpCount = 3; +- pixmap->cmpSize = 8; +- +- /* Update the display window */ +- window_adjust_scrollbars(img->windowRef); +- window_invalidate(img->windowRef); +- return gsdll_poll(handle); +-} +- +-/* flushpage */ +-static int display_sync(void *handle, void *device) +-{ +- IMAGE *img = image_find(handle, device); +- if (img == NULL) +- return -1; +- +- window_invalidate(img->windowRef); +- gsdll_poll(handle); +- +- return 0; +-} +- +-/* showpage */ +-/* If you want to pause on showpage, then don't return immediately */ +-static int display_page(void *handle, void *device, int copies, int flush) +-{ +- return display_sync(handle, device); +-} +- +-/* Poll the caller for cooperative multitasking. */ +-/* If this function is NULL, polling is not needed */ +-static int display_update(void *handle, void *device, +- int x, int y, int w, int h) +-{ +- UInt64 t1; +- UInt64 t2; +- int delta; +- IMAGE *img = image_find(handle, device); +- if (img == NULL) +- return -1; +- +- Microseconds((UnsignedWide*)&t1); +- delta = (t1 - img->update_time) / 1000000L; +- if (img->update_interval < 1) +- img->update_interval = 1; /* seconds */ +- if (delta < 0) +- img->update_time = t1; +- else if (delta > img->update_interval) +- { +- /* redraw window */ +- window_invalidate(img->windowRef); +- +- /* Make sure the update interval is at least 10 times +- * what it takes to paint the window +- */ +- Microseconds((UnsignedWide*)&t2); +- delta = (t2 - t1) / 1000; +- if (delta < 0) +- delta += 60000; /* delta = time to redraw */ +- if (delta > img->update_interval * 100) +- img->update_interval = delta/100; +- img->update_time = t2; +- } +- +- return gsdll_poll(handle); +-} +- +-display_callback display = { +- sizeof(display_callback), +- DISPLAY_VERSION_MAJOR, +- DISPLAY_VERSION_MINOR, +- display_open, +- display_preclose, +- display_close, +- display_presize, +- display_size, +- display_sync, +- display_page, +- display_update, +- NULL, /* memalloc */ +- NULL, /* memfree */ +- NULL /* display_separation */ +-}; +- +-static IMAGE * image_find(void *handle, void *device) +-{ +- IMAGE *img; +- for (img = first_image; img!=0; img=img->next) { +- if ((img->handle == handle) && (img->device == device)) +- return img; +- } +- return NULL; +-} +- +-/*********************************************************************/ +- +-static char *stdin_buf = NULL; +-static size_t stdin_bufpos = 0; +-static size_t stdin_bufsize = 0; +- +-/* This function is a fudge which allows the SIOUX window to be waiting for +- input and not be modal at the same time. (Why didn't MetroWerks think of that?) +- It is based on the SIOUX function ReadCharsFromConsole(), and contains an +- event loop which allows other windows to be active. +- It collects characters up to when the user presses ENTER, stores the complete +- buffer and gives as much to the calling function as it wants until it runs +- out, at which point it gets another line (or set of lines if pasting from the +- clipboard) from the user. +-*/ +-static size_t get_input(void *ptr, size_t size) +-{ +- EventRecord eventStructure; +- long charswaiting, old_charswaiting = 0; +- char *text; +- +-#if SIOUX_USE_WASTE +- Handle textHandle; +-#endif +- +- /* If needing more input, set edit start position */ +- if (!stdin_buf) +-#if SIOUX_USE_WASTE +- SIOUXselstart = WEGetTextLength(SIOUXTextWindow->edit); +-#else +- SIOUXselstart = (*SIOUXTextWindow->edit)->teLength; +-#endif +- +- /* Wait until user presses exit (or quits) */ +- while(!gDone && !stdin_buf) +- { +-#if SIOUX_USE_WASTE +- charswaiting = WEGetTextLength(SIOUXTextWindow->edit) - SIOUXselstart; +-#else +- if ((*SIOUXTextWindow->edit)->teLength > 0) +- charswaiting = (*SIOUXTextWindow->edit)->teLength - SIOUXselstart; +- else +- charswaiting = ((unsigned short) (*SIOUXTextWindow->edit)->teLength) - SIOUXselstart; +-#endif +- +- /* If something has happened, see if we need to do anything */ +- if (charswaiting != old_charswaiting) +- { +-#if SIOUX_USE_WASTE +- textHandle = WEGetText(SIOUXTextWindow->edit); +- HLock(textHandle); +- text = *textHandle + SIOUXselstart; +-#else +- text = (*(*SIOUXTextWindow->edit)->hText) + SIOUXselstart; +-#endif +- /* If user has pressed enter, gather up the buffer ready for returning */ +- if (text[charswaiting-1] == '\r') +- { +- stdin_buf = malloc(charswaiting); +- if (!stdin_buf) +- return -1; +- stdin_bufsize = charswaiting; +- memcpy(stdin_buf, text, stdin_bufsize); +- SIOUXselstart += charswaiting; +- +- text = stdin_buf; +- while (text = memchr(text, '\r', charswaiting - (text - stdin_buf))) +- *text = '\n'; +- } +-#if SIOUX_USE_WASTE +- HUnlock(textHandle); +-#endif +- old_charswaiting = charswaiting; +- +- if (stdin_buf) +- break; +- } +- +- /* Wait for next event and process it */ +- SIOUXState = SCANFING; +- +- if(WaitNextEvent(everyEvent, &eventStructure, SIOUXSettings.sleep ,NULL)) +- doEvents(&eventStructure); +- else +- SIOUXHandleOneEvent(&eventStructure); +- +- SIOUXState = IDLE; +- } +- +- /* If data has been entered, return as much as has been requested */ +- if (stdin_buf && !gDone) +- { +- if (size >= stdin_bufsize - stdin_bufpos) +- { +- size = stdin_bufsize - stdin_bufpos; +- memcpy (ptr, stdin_buf + stdin_bufpos, size); +- free(stdin_buf); +- stdin_buf = NULL; +- stdin_bufpos = 0; +- stdin_bufsize = 0; +- } +- else +- { +- memcpy (ptr, stdin_buf + stdin_bufpos, size); +- stdin_bufpos += size; +- } +- return size; +- } +- else if (stdin_buf) +- { +- free(stdin_buf); +- stdin_buf = NULL; +- stdin_bufpos = 0; +- stdin_bufsize = 0; +- } +- +- return 0; +-} +- +-/*********************************************************************/ +- +-static void window_create(IMAGE *img) +-{ +- WindowRef windowRef; +- Str255 windowTitle = "\pGhostscript Image"; +- Rect windowRect = {20,4,580,420};//, portRect; +- Rect scrollbarRect = {0,0,0,0}; +- +-#if TARGET_API_MAC_CARBON +- GetAvailableWindowPositioningBounds(GetMainDevice(),&windowRect); +-#endif +- +- /* Create a new suitablty positioned window */ +- windowRect.top = windowRect.top * 2 + 2; +- windowRect.bottom -= 10; +- windowRect.left += 4; +- windowRect.right = ((windowRect.bottom - windowRect.top) * 3) / 4 + windowRect.left; +- +- if(!(windowRef = NewCWindow(NULL, &windowRect, windowTitle, true, +- zoomDocProc, (WindowRef) -1, false, 0))) +- ExitToShell(); +- +- img->windowRef = windowRef; +- +- SetWRefCon(img->windowRef, (SInt32)img); +- +- /* Create the window's scrollbars */ +-#if TARGET_API_MAC_CARBON +- if(gRunningOnX) +- ChangeWindowAttributes(windowRef,kWindowLiveResizeAttribute,0); +- +- CreateScrollBarControl(windowRef, &scrollbarRect, 0, 0, 0, 0, +- true, gActionFunctionScrollUPP, &(img->scrollbarVertRef)); +- +- CreateScrollBarControl(windowRef, &scrollbarRect, 0, 0, 0, 0, +- true, gActionFunctionScrollUPP, &(img->scrollbarHorizRef)); +-#else +- img->scrollbarVertRef = NewControl(windowRef,&scrollbarRect,"\p",false,0,0,0,scrollBarProc,0); +- img->scrollbarHorizRef = NewControl(windowRef,&scrollbarRect,"\p",false,0,0,0,scrollBarProc,0); +-#endif +- +- window_adjust_scrollbars(windowRef); +-} +- +-static void window_invalidate(WindowRef windowRef) +-{ +- Rect portRect; +- +- GetWindowPortBounds(windowRef, &portRect); +- InvalWindowRect(windowRef, &portRect); +-} +- +-static void window_adjust_scrollbars(WindowRef windowRef) +-{ +- IMAGE *img; +- Rect portRect; +- +- img = (IMAGE*)GetWRefCon(windowRef); +- GetWindowPortBounds(windowRef,&portRect); +- +- /* Move the crollbars to the edges of the window */ +- HideControl(img->scrollbarVertRef); +- HideControl(img->scrollbarHorizRef); +- +- MoveControl(img->scrollbarVertRef,portRect.right - kScrollBarWidth, +- portRect.top - 1); +- MoveControl(img->scrollbarHorizRef,portRect.left - 1, +- portRect.bottom - kScrollBarWidth); +- +- SizeControl(img->scrollbarVertRef,kScrollBarWidth + 1, +- portRect.bottom - portRect.top - kScrollBarWidth + 1); +- SizeControl(img->scrollbarHorizRef, portRect.right - portRect.left - kScrollBarWidth + 1, +- kScrollBarWidth + 1); +- +- /* Adjust the scroll position showing */ +- if (img->pixmapHdl) +- { +- PixMap *pixmap = *(img->pixmapHdl); +- int visibleHeight = portRect.bottom - portRect.top - kScrollBarWidth; +- int visibleWidth = portRect.right - portRect.left - kScrollBarWidth; +- +- if (pixmap->bounds.bottom > visibleHeight) +- { +- SetControl32BitMaximum(img->scrollbarVertRef, +- pixmap->bounds.bottom - visibleHeight); +- SetControlViewSize(img->scrollbarVertRef,visibleHeight); +- } +- else +- SetControlMaximum(img->scrollbarVertRef, 0); +- +- if (pixmap->bounds.right > visibleWidth) +- { +- SetControl32BitMaximum(img->scrollbarHorizRef, +- pixmap->bounds.right - visibleWidth); +- SetControlViewSize(img->scrollbarHorizRef, visibleWidth); +- } +- else +- SetControlMaximum(img->scrollbarHorizRef, 0); +- } +- +- ShowControl(img->scrollbarVertRef); +- ShowControl(img->scrollbarHorizRef); +-} +- +-/*********************************************************************/ +-void main(void) +-{ +- int code; +- int exit_code; +- int argc; +- char **argv; +- char dformat[64], ddevice[32]; +- SInt32 response; +- +- /* Initialize operating environment */ +-#if TARGET_API_MAC_CARBON +- MoreMasterPointers(224); +-#else +- MoreMasters(); +-#endif +- InitCursor(); +- FlushEvents(everyEvent,0); +- +- if (AEInstallEventHandler(kCoreEventClass,kAEQuitApplication, +- NewAEEventHandlerUPP((AEEventHandlerProcPtr) quitAppEventHandler), +- 0L,false) != noErr) +- ExitToShell(); +- +- gActionFunctionScrollUPP = NewControlActionUPP(&actionFunctionScroll); +- +- Gestalt(gestaltMenuMgrAttr,&response); +- if(response & gestaltMenuMgrAquaLayoutMask) +- gRunningOnX = true; +- +- /* Initialize SIOUX */ +- SIOUXSettings.initializeTB = false; +- SIOUXSettings.standalone = false; +- SIOUXSettings.asktosaveonclose = false; +- SIOUXSettings.sleep = GetCaretTime(); +- SIOUXSettings.userwindowtitle = "\pGhostscript"; +- +- /* Get arguments from user */ +- argc = ccommand(&argv); +- +- /* Show command line window */ +- if (InstallConsole(0)) +- ExitToShell(); +- +- /* Part of fudge to make SIOUX accept characters without becoming modal */ +- SelectWindow(SIOUXTextWindow->window); +- PostEvent(keyDown, 0x4c00); // Enter +- ReadCharsFromConsole(dformat, 0x7FFF); +- clrscr(); +- +- /* Add in the display format as the first command line argument */ +- if (argc >= MAX_ARGS - 1) +- { +- printf("Too many command line arguments\n"); +- return; +- } +- +- memmove(&argv[3], &argv[1], (argc-1) * sizeof(char**)); +- argc += 2; +- argv[1] = ddevice; +- argv[2] = dformat; +- +- sprintf(ddevice, "-sDEVICE=display"); +- sprintf(dformat, "-dDisplayFormat=%d", display_format); +- +- /* Run Ghostscript */ +- if (gsapi_new_instance(&instance, NULL) < 0) +- { +- printf("Can't create Ghostscript instance\n"); +- return; +- } +- +-#ifdef DEBUG +- visual_tracer_init(); +- set_visual_tracer(&visual_tracer); +-#endif +- +- gsapi_set_stdio(instance, gsdll_stdin, gsdll_stdout, gsdll_stderr); +- gsapi_set_poll(instance, gsdll_poll); +- gsapi_set_display_callback(instance, &display); +- +- code = gsapi_init_with_args(instance, argc, argv); +- if (code == 0) +- code = gsapi_run_string(instance, start_string, 0, &exit_code); +- else +- { +- printf("Failed to initialize. Error %d.\n", code); +- fflush(std