summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlgs/Resource/Init
diff options
context:
space:
mode:
authorReinhard Kotucha <reinhard.kotucha@web.de>2017-10-05 20:49:39 +0000
committerReinhard Kotucha <reinhard.kotucha@web.de>2017-10-05 20:49:39 +0000
commitfda5435ca272bab86872d2627667b5b259eb5423 (patch)
tree2211c66243a4658b14be60b857eb92348579c069 /Master/tlpkg/tlgs/Resource/Init
parent6da90753bb28081fe69076b75057451a26501c67 (diff)
Upgrade gs-9.21 -> gs-9.22
git-svn-id: svn://tug.org/texlive/trunk@45477 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/tlgs/Resource/Init')
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/gs_cet.ps2
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps7
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps6
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/gs_img.ps115
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps2
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/gs_statd.ps2
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps78
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/gs_type1.ps4
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/pdf_base.ps27
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps644
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/pdf_font.ps148
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/pdf_main.ps403
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps574
13 files changed, 1351 insertions, 661 deletions
diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps
index 8eb79bb06e0..d3e1686409b 100644
--- a/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps
@@ -21,7 +21,7 @@ currentglobal //true setglobal
/serialnumber dup {233640} readonly .makeoperator put % match CPSI 3017.102 Tek shows serialnumber 1401788461
systemdict /deviceinfo undef % for CET 20-23-1
% /UNROLLFORMS true put % CET files do unreasonable things inside forms
-} superexec
+} 1183615869 internaldict /superexec get exec
/UNROLLFORMS true def
diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps b/Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps
index a57bb94ed3b..a4d6dda2a5c 100644
--- a/Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps
@@ -55,8 +55,7 @@ level2dict begin
{ //SharedFontDirectory }
{ /LocalFontDirectory .systemvar } % can't embed ref to local VM
ifelse .forceput pop % LocalFontDirectory is local, systemdict is global
- } .bind odef % must bind .forceput and .setglobal
- % even if NOBIND in effect
+ } .bind odef
% Don't just copy (load) the definition of .setglobal:
% it gets redefined for LL3.
/setshared { /.setglobal .systemvar exec } odef
@@ -86,7 +85,7 @@ level2dict begin
% definition, copy it into the local directory.
//systemdict /SharedFontDirectory .knownget
{ 1 index .knownget
- { .FontDirectory 2 index 3 -1 roll { put } //superexec } % readonly
+ { .FontDirectory 2 index 3 -1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly
if
}
if
@@ -102,7 +101,7 @@ level2dict begin
% Furthermore, if FAKEFONTS is in effect, we want global real fonts to
% override fake local ones. We handle this by brute force.
/restore % <save> restore -
- { dup //restore % bind even if NOBIND
+ { dup //restore
/LocalFontDirectory .systemvar
FAKEFONTS
{ mark
diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps b/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps
index a3da615cb3f..1f4c9eda288 100644
--- a/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps
@@ -519,11 +519,11 @@ buildfontdict 3 /.buildfont3 cvx put
% the font in LocalFontDirectory.
.currentglobal
{ //systemdict /LocalFontDirectory .knownget
- { 2 index 2 index { .growput } //superexec } % readonly
+ { 2 index 2 index { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly
if
}
if
- dup .FontDirectory 4 -2 roll { .growput } //superexec % readonly
+ dup .FontDirectory 4 -2 roll { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly
% If the font originated as a resource, register it.
currentfile .currentresourcefile eq { dup .registerfont } if
readonly
@@ -1193,7 +1193,7 @@ currentdict /.putgstringcopy .undef
.FontDirectory 1 index known not {
2 dict dup /FontName 3 index put
dup /FontType 1 put
- .FontDirectory 3 1 roll { put } //superexec % readonly
+ .FontDirectory 3 1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly
} {
pop
} ifelse
diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_img.ps b/Master/tlpkg/tlgs/Resource/Init/gs_img.ps
index f2b0f6287da..e1cd6279323 100644
--- a/Master/tlpkg/tlgs/Resource/Init/gs_img.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/gs_img.ps
@@ -746,119 +746,4 @@ if
end % img_utils_dict
-% Conditionally turn image interpolation on or off.
-% INTERPOLATE is not yet set, handle all cases
-currentdict /INTERPOLATE known
-currentdict /DOTERPOLATE known or
-currentdict /NOTERPOLATE known or not {
- currentfile 1 (%END INTERPOLATE) .subfiledecode flushfile
-} if
-
-/.interpolate {
- dup /Interpolate .knownget not { //false } if
- /INTERPOLATE .systemvar ne {
- dup gcheck .currentglobal exch .setglobal
- exch dup length dict copy
- dup /Interpolate /INTERPOLATE .systemvar put
- exch .setglobal
- } if
-} .bind odef
-
-/colorimage
- { /INTERPOLATE .systemvar
- { .currentglobal % w h bit [] {}...{} multi ncomp glob
- //false .setglobal
- 9 dict begin % w h bit [] {}...{} multi ncomp glob
- 2 .argindex { 1 index 7 add } { 8 } ifelse
- dup .argindex pop % check # of arguments
- copy gsave pop % preserve the arguments
- { 0 /DeviceGray 0 /DeviceRGB /DeviceCMYK }
- 1 index get setcolorspace % ... glob w h bit [] {}...{} multi ncomp
- {0 1 0 1 0 1 0 1}
- 1 index 2 mul 0 exch % ... glob w h bit [] {}...{} multi ncomp {0 1 ...} 0 2*ncomp
- getinterval /Decode exch def % ... glob w h bit [] {}...{} multi ncomp
- exch dup % ... glob w h bit [] {}...{} ncomp multi multi
- /MultipleDataSources exch def % ... glob w h bit [] {}...{} ncomp multi
- { array astore} { pop } ifelse % ... glob w h bit [] [{}...{}]
- /DataSource exch def % ... glob w h bit []
- /ImageMatrix exch def % ... glob w h bit
- /BitsPerComponent exch def % ... glob w h
- /Height exch def % ... glob w
- /Width exch def % ... glob
- /ImageType 1 def
- /Interpolate //true def
- .setglobal currentdict end % ... <<>>
- image grestore
- exch { 4 add } { 6 } ifelse
- { pop } repeat % -
- }
- { colorimage
- }
- ifelse
- } .bind odef
-
-/image
- { dup type /dicttype eq
- { dup /ImageType get 3 eq
- { .currentglobal //false .setglobal exch
- dup length dict copy begin .setglobal
- /DataDict DataDict .interpolate def
- /MaskDict MaskDict .interpolate def
- currentdict end
- }
- { .interpolate
- }
- ifelse
- image
- }
- { /INTERPOLATE .systemvar
- { 4 .argindex pop % check # of args
- .currentglobal //false .setglobal
- 8 dict begin .setglobal
- /ImageType 1 def
- /DataSource 1 index def
- /ImageMatrix 2 index def
- /BitsPerComponent 3 index def
- /Decode {0 1} def
- /Height 4 index def
- /Width 5 index def
- /Interpolate //true def
- currentdict end
- gsave /DeviceGray setcolorspace image grestore
- 5 { pop } repeat
- }
- { image
- }
- ifelse
- }
- ifelse
- } .bind odef
-
-/imagemask {
- dup type /dicttype eq {
- .interpolate imagemask
- } {
- /INTERPOLATE .systemvar {
- 4 .argindex pop % check # of args
- .currentglobal //false .setglobal
- 8 dict begin .setglobal
- /ImageType 1 def
- /DataSource 1 index def
- /ImageMatrix 2 index def
- /BitsPerComponent 1 def
- 2 index { {1 0} } { {0 1} } ifelse /Decode exch def
- /Height 4 index def
- /Width 5 index def
- /Interpolate //true def
- currentdict end imagemask 5 { pop } repeat
- } {
- imagemask
- } ifelse
- } ifelse
-} .bind odef
-
-currentdict /.interpolate .undef
-
-%END INTERPOLATE
-
.setglobal % restore VM mode
diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps b/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps
index a1deb5891a4..e2bffba377e 100644
--- a/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps
@@ -58,7 +58,7 @@ languagelevel dup 2 .max .setlanguagelevel
/.bind /.bind_ load odef % note that .bind_ will get bound
currentdict /.bindscratch .undef
-DELAYBIND NOBIND or not {
+DELAYBIND not {
% We can't just do
% /bind /.bind load def
% because then /bind load == prints --.bind-- .
diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_statd.ps b/Master/tlpkg/tlgs/Resource/Init/gs_statd.ps
index 18dfced1499..dbcf05199c9 100644
--- a/Master/tlpkg/tlgs/Resource/Init/gs_statd.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/gs_statd.ps
@@ -59,7 +59,7 @@ statusdict begin
% shrunk by 25 units on all 4 sides.
/note /letter load def
% End of Adobe-defined page sizes
-STRICT { (%END SIZES) .skipeof } if
+
% Other page sizes
% ISO standard paper sizes
/a0 {2384 3370 //.setpagesize exec} bind def
diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps b/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps
index ebacc6bbd0d..8cb5b390c57 100644
--- a/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps
@@ -435,7 +435,7 @@ currentdict /woff_tag_dict .undef
} bind def
% Each procedure in this dictionary is called as follows:
-% <encodingtable> proc <glypharray>
+% <encodingtable> proc <glyph dictionary>
/cmapformats mark
0 { % Apple standard 1-to-1 mapping.
6 256 getinterval_from_stringarray
@@ -538,35 +538,20 @@ currentdict /woff_tag_dict .undef
/putglyph {
glyphs code 3 -1 roll put /code code 1 add def
} bind def
- % Do a first pass to compute the size of the glyphs array.
- /numcodes 0 def
/glyphs 0 dict def
- 0 0 2 nseg2 3 sub {
- % Stack: /glyphs numglyphs i2
- /i2 exch def
- /scode startc i2 getu16a def
- /ecode endc i2 getu16a def
-
- % Bug 693538: More undocumented nonsense: in cases where scode == ecode,
- % see Bug 691326 below *except*, it seems when both are zero
- scode 0 eq ecode 0 eq and not {
- scode ecode 1 add gt { % Bug 691326.
- /ecode scode 1 add def % Acrobat does this contrary to TTF spec that
- } if % requires such intervals to be ignored.
- numcodes scode firstcode sub
- % Hack for fonts that have only 0x0000 and 0xf000 ranges
- %dup 16#e000 ge { 255 and } if
- % the previous line is obstructive to CJK fonts, so it was removed
- exch sub 0 .max ecode scode sub 1 add add
- exch 1 index add exch
- numcodes add /numcodes exch def
- } if
- } for pop
-
- % Now fill in the array.
/numcodes 0 def /code 0 def
- 0 2 nseg2 3 sub {
+ % neg2 is number of segments x 2. A format 4 cmap, with usable
+ % mappings cannot (according to the spec) have only 1 segment,
+ % since format 4 requires a closing segment with start and end
+ % codes being 0xffff. Unfortunately, we have found badly subsetted
+ % TTF fonts which have one segment with valid mappings, and no
+ % closing segment.
+ % In such a case, force the loop to work as though as we have two
+ % segments - this works as we don't rely on the terminating segment
+ % but use the loop counter to spot completion - effrectively, we
+ % ignore the closing segment when it's present, anyway.
+ 0 2 nseg2 dup 4 lt {pop 4}if 3 sub {
/i2 exch def
/scode startc i2 getu16a def
/ecode endc i2 getu16a def
@@ -633,8 +618,8 @@ currentdict /woff_tag_dict .undef
} bind
.dicttomark readonly def % cmapformats
-% <cmaptab> cmaparray <glypharray>
-/cmaparray {
+% <cmaptab> cmapdict <glyph dictionary>
+/cmapdict {
dup 0 getu16a cmapformats exch .knownget {
TTFDEBUG {
(cmap: format ) print 1 index 0 getu16a = flush
@@ -1389,7 +1374,7 @@ mark
def
} if
- /cmapa cmaptab cmaparray def
+ /cmapa cmaptab cmapdict def
% Some badly designed Chinese fonts have a post table
% in which all glyphs other than 0 are named .null.
% Use CharStrings to keep track of the reverse map from
@@ -1436,7 +1421,7 @@ mark
TTFDEBUG { (\n1 setting alias: ) print dup ==only
( to be the same as ) print 2 index //== exec } if
- 7 index 2 index 3 -1 roll exch //.growput superexec
+ 7 index 2 index 3 -1 roll exch //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse
} forall
pop pop pop
}
@@ -1454,7 +1439,7 @@ mark
exch pop
TTFDEBUG { (\n2 setting alias: ) print 1 index ==only
( to use glyph index: ) print dup //== exec } if
- 5 index 3 1 roll //.growput superexec
+ 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse
//false
}
{
@@ -1471,7 +1456,7 @@ mark
{ % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) gindex(integer)
TTFDEBUG { (\3 nsetting alias: ) print 1 index ==only
( to be index: ) print dup //== exec } if
- exch pop 5 index 3 1 roll //.growput superexec
+ exch pop 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse
}
{
pop pop
@@ -1626,7 +1611,7 @@ currentdict /postalias undef
mark
.ttkeys
/NumGlyphs numloca
- /TT_cmap cmaptab cmaparray
+ /TT_cmap cmaptab cmapdict
/file_table_pos file_table_pos
/Decoding Decoding
.dicttomark
@@ -1645,7 +1630,7 @@ currentdict /postalias undef
mark
.ttkeys
/NumGlyphs numloca
- /TT_cmap cmaptab cmaparray
+ /TT_cmap cmaptab cmapdict
% /file_table_pos file_table_pos
/Decoding Decoding
.dicttomark
@@ -1767,9 +1752,8 @@ currentdict /postalias undef
% <chartoglyphmap> <subcmap> <AGL> .pdfmapchars /CharStrings <charstrings>
/.pdfmapchars {
- exch cmaparray /cmapencoding exch def % c2g
+ exch cmapdict /cmapencoding exch def % c2g
/CharStrings 0 dict % c2g /CS <<>>
-
% Add glyphs of <AGL>*<subcmap> :
3 2 roll { % /CS <<>> v
dup type /arraytype eq { % /CS <<>> /name []
@@ -1806,13 +1790,12 @@ currentdict /postalias undef
} forall
dup /.notdef 0 put
-
} bind def
% <subtable> .pdfmapsymbolic /Encoding [] /CharStrings <<>>
/.pdfmapsymbolic {
//true /.render_notdef gput
- cmaparray
+ cmapdict
dup length 1 add dict begin
[ 64 { /.notdef /.notdef /.notdef /.notdef } repeat ]
exch { % [] char glyph
@@ -1845,7 +1828,7 @@ currentdict /postalias undef
% The following algorithms are per the PDF 1.7 Reference.
TTFDEBUG { (.pdfcharkeys beg) = } if
- % if the flags say symbolic, *and* the font contains a symbol
+ % if the flags say symbolic, *and* the font contains a symbol or UCS-2
% cmap table, ignore Encoding if there is one, treat as symbolic.
% If the flags say symbolic, and the font doesn't have a symbol cmap
% and we have an Encoding, treat it as non-symbolic
@@ -1853,7 +1836,20 @@ currentdict /postalias undef
% Finally, if none of that works, remove the Encoding, and treat it
% as non-symbolic.
is_symbolic {
- <00030000> .findcmap { //true } { prebuilt_encoding //null eq { <00010000> .findcmap}{//false}ifelse } ifelse {
+ <00030000> .findcmap
+ { //true }
+ {
+ prebuilt_encoding //null eq {
+ <00030001> .findcmap
+ {//true}
+ {<00010000> .findcmap}
+ ifelse
+ }
+ {//false}
+ ifelse
+ } ifelse
+
+ {
.pdfmapsymbolic
/prebuilt_encoding //null def
//false
diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps b/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps
index 772bb7163ff..dbd9bf38a44 100644
--- a/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps
@@ -116,7 +116,7 @@
{ % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname aglname
CFFDEBUG { (\nsetting alias: ) print dup ==only
( to be the same as glyph: ) print 1 index //== exec } if
- 3 index exch 3 index //.growput superexec
+ 3 index exch 3 index //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse
% scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname
}
{pop} ifelse
@@ -135,7 +135,7 @@
3 1 roll pop pop
} if
pop
- dup /.AGLprocessed~GS //true //.growput superexec
+ dup /.AGLprocessed~GS //true //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse
} if
%% We need to excute the C .buildfont1 in a stopped context so that, if there
diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps
index bdfe9ee8feb..f2ae2dec3ef 100644
--- a/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps
@@ -774,6 +774,11 @@ currentdict /no_debug_dict undef
% When resolving an object reference, we stop at the endobj or endstream.
/resolveopdict mark
valueopdict { } forall
+ /xref { % Bug 697761
+ ( **** Error: Encountered 'xref' while expecting 'endobj'.\n) pdfformaterror
+ ( Treating this as a missing 'endobj', output may be incorrect.\n) pdfformaterror
+ endobj exit
+ } bind
/endstream { endobj exit } bind
/endobj { endobj exit } bind
/endjobj { % Bug 689876.
@@ -786,9 +791,13 @@ currentdict /no_debug_dict undef
( Output may be incorrect.\n) pdfformaterror
endobj exit
} bind
+ /obj {
% 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
+ ( **** Error: Encountered 'obj' while expecting 'endobj'.\n) pdfformaterror
+ ( Treating this as a missing 'endobj', output may be incorrect.\n) pdfformaterror
+ pop pop endobj exit
+ } bind
.dicttomark readonly def
/resolveR { % <object#> <generation#> resolveR <object>
@@ -849,12 +858,13 @@ currentdict /no_debug_dict undef
dup type /dicttype eq % For dictionaries only
{
- dup /Type .knownget % make sure the dictionary has a type
+ dup /Type known % make sure the dictionary has a type
{
- dup /Font eq exch /FontDescriptor eq or % and ensure its a Font or FontDescriptor
- {dup 3 -1 roll /.gs.pdfobj# exch put}
- {exch pop}
- ifelse
+ %% We must not add to *all* dictionaries, because some of them are handled by
+ %% executing all the key/value pairs, and adding a integer causes problems
+ %% Since we only use this number for font identification, or checking self-references,
+ %% we only need it for dictionaries with a Type, and these are always handled more carefully.
+ dup 3 -1 roll /.gs.pdfobj# exch put
}
{exch pop}
ifelse
@@ -889,11 +899,6 @@ currentdict /no_debug_dict undef
% may have preceded the EOL, such as spaces or tabs. Thus we back up one
% character and scan until we find the \n terminator.
/stream { % <dict> stream <modified_dict>
- dup /Length knownoget {
- 0 eq {
- dup /Filter undef % don't confuse any filters that require data
- } if
- } if
dup /F known dup PDFsource PDFfile eq or {
not {
dup /File PDFfile put
diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps
index 88da2de7485..68a56a3674b 100644
--- a/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps
@@ -26,34 +26,6 @@ pdfdict begin
% PDF graphics operations, even though this is too liberal.
/drawopdict 100 dict def
-/SetGroupExtGStateDict
-<<
- /AlphaIsShape //AIS
- /FillConstantAlpha //ca
- % We don't have to worry about the enumeration order, even
- % with the color/space settings, since we only store, not
- % not set them.
- /FillColor //sc1
- /FillColorSpace { /FillColorSpace gput } bind
- /FillOverprint //op
- /SoftMask //SMask
- /StrokeConstantAlpha //CA
- /StrokeColor //SC1
- /StrokeColorSpace { /StrokeColorSpace gput } bind
- /StrokeOverprint //OP
- /TextSpacing //Tc
- % We can't use //Tz as we've stored the value we actually use,
- % not value * 100 (see /Tz in pdf_ops.ps)
- /TextHScaling { /TextHScaling gput } bind
- /Leading //TD
- /TextFont { /TextFont gput} bind
- /TextLineMatrix { /TextLineMatrix gput } bind
- /TextMatrix { /TextMatrix gput } bind
- /TextRise { /TextRise gput } bind
- /TextRenderingMode { /TextRenderingMode gput } bind
- /WordSpacing //Tw
->> def
-
% ================================ Graphics ================================ %
% ---------------- Functions ---------------- %
@@ -156,6 +128,20 @@ pdfdict begin
1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse
} bdef
+%% A BBox where width or height (or both) is 0 should still paint one pixel
+%% See the ISO 32000-2:2017 spec, section 8.7.4.3, p228 'BBox' and 8.7.3.1
+/FixPatternBBox
+{
+ dup aload pop
+ 3 index 2 index sub 0 eq {
+ 3 index 0.000001 add 3 -1 roll pop exch
+ } if
+ 2 index 1 index sub 0 eq {
+ 2 index 0.000001 add exch pop
+ }if
+ 5 -1 roll astore
+}bind def
+
% ---------------- Shadings ---------------- %
/shrdict mark
@@ -177,6 +163,7 @@ pdfdict begin
/BBox {
dup dup dup aload pop normrect_elems
5 -1 roll astore
+ FixPatternBBox
} bind
/ColorSpace {
resolvecolorspace
@@ -472,6 +459,13 @@ end
/AIS { AIS }
/BM { BM }
/TK { TK }
+ /UseBlackPtComp { UseBlackPtComp }
+ /HTO {
+ % PDF 2.0, supposed to be 'similar' to halftone phase but using a different
+ % co-ordiate system. Treat the same for now and fix if anyone ever complains.
+ aload pop transform cvi exch cvi exch 2 array astore
+ dup sethalftonephases .swapcolors sethalftonephases .swapcolors
+ }
.dicttomark readonly def
/gs { % <gsres> gs -
Page /ExtGState rget {
@@ -502,7 +496,8 @@ end
dup /None eq 1 index //null eq or PDFusingtransparency not or {
pop //null
- SoftMask //null ne {
+
+ .currentSMask //null ne {
% get rid of the current SMask (Bug 695471)
false % colorspace not set
<< /Subtype /None >> % Special type for this purpose
@@ -558,18 +553,9 @@ end
/GroupGState gstate currentgstate 6 2 roll
grestore
/GroupMat matrix currentmatrix 8 2 roll
- /GroupExtGState 1 dict
- //SetGroupExtGStateDict
- {
- exch dup where
- {
- exch get 2 index 3 1 roll put
- }
- {
- pop pop
- } ifelse
- } forall
- 10 2 roll
+% /GroupExtGState 1 dict
+% 10 2 roll
+
/.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll
pop
.dicttomark
@@ -634,48 +620,62 @@ def
3 -1 roll dup
dup 4 1 roll /BBox get aload pop .begintransparencymaskgroup
exch dup /Resources knownoget { oforce } { 2 dict } ifelse
- 3 -1 roll dup /GroupGState .knownget { 2 index /GroupGState 3 -1 roll put} if
- /GroupExtGState .knownget { 1 index /GroupExtGState 3 -1 roll put} if
+ 3 -1 roll /GroupGState .knownget { 1 index /GroupGState 3 -1 roll put} if
exch //false resolvestream
- 1 index exch .execgroup
+ 1 index exch
+
+ %% Get the current colour space and colour values (as an array), we need to pass these to .execgroup
+ %% as well, so that it can restore them, in case the colour space gets changed by transparency
+ %% graphics state stuff.
+ mark currentcolor counttomark array astore exch pop
+ currentcolorspace 4 2 roll
+
+ .execgroup
% We have to remove these in case the Form XObject is subsequently used as
% a form rather than a group - they remain in the paramdict for the SMask
% so this will all still work if the SMask is re-evaluated.
- dup /GroupGState undef
- /GroupExtGState undef
+ /GroupGState undef
+
.endtransparencymask
PDFfile exch setfileposition
mark exch /OverrideICC exch .dicttomark setuserparams
.setuseciecolor setcolorspace setcolor
setmatrix
end % restore colorspace, color and ExtGState (end)
- /SoftMask where pop /SoftMask //true put % special setting to tell us it has been rendered
+ .currentSMask /Processed //true put % special setting to tell us it has been rendered
} bdef
% Paint a Form+Group XObject, either for a transparency mask or for a Do.
-/.execgroup { % <resdict> <stream> .execgroup -
+/.execgroup { % [colour values] <colour space> <resdict> <stream> .execgroup -
pdfemptycount 3 1 roll
- /pdfemptycount count 3 sub store
+ /pdfemptycount count 5 sub store
gsave //nodict begin
% We have to set the gstate correctly for lazy evaluation of a softmask group.
- % we also must preserve the color(space) as setup in .execmaskgroup.
+ % we also must restore the color(space) as setup in .execmaskgroup or paintformgroup.
% This stuff must be done here, as .execmaskgroup can't use gsave/grestore to
% manipulate the gstates, due to the requirements of .begintransparencymaskgroup.
% We also must set the ExtGState values.
% It may seem redundant to do the color(space) twice (once here and once in
% .execmaskgroup) but we have to set it in .execmaskgroup for the background
% color and set it here once in the correct gstate.
- mark currentcolor currentcolorspace counttomark 2 add index dup
+ 1 index
/GroupGState .knownget { setgstate } if
- /GroupExtGState .knownget { { exch exec } forall } if
- setcolorspace setcolor pop
+
newpath //null SMask
1 .setopacityalpha 1 .setshapealpha
1 CA 1 ca
/Compatible .setblendmode
% Execute the body of the Form, similar to DoForm.
- pdfopdict .pdfruncontext
+ pdfopdict
+
+ %% Restore the colour space (passed in on the stack) and current colour
+ %%
+ 6 -2 roll
+ setcolorspace
+ aload pop setcolor
+
+ .pdfruncontext
end grestore
/pdfemptycount exch store
} bdef
@@ -694,6 +694,11 @@ def
% .paintgroupform implements the Form PaintProc in the case where the
% Form XObject dictionary includes a Group key. See .paintform below.
/.paintgroupform { % <resdict> <stream> <formdict> .paintgroupform -
+ %% Pass the current color space, and an array with the current color vales
+ %% as arguments to .execgroup
+ mark currentcolor counttomark array astore exch pop
+ currentcolorspace 5 2 roll
+
dup /Group oget exch /BBox oget
% Stack: resdict stream groupdict bbox
.beginformgroup
@@ -730,7 +735,8 @@ def
DataDict /Matte knownoget {
/Matte exch def
} if
- AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def
+ .currentalphaisshape
+ { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def
/ColorSpace DataDict /ColorSpace get def
} bdef
@@ -1055,13 +1061,16 @@ currentdict end readonly def
} {
% For uncolored patterns, we have to unbind the current
% color and color space before running the PaintProc.
- //null sc1 //null SC1
+ % Not true since moving the ExtGState parameters into the gstate.
+ % //null sc1 //null SC1
} ifelse
% Save old values on opstack, set pdfemptycount to new value.
pdfemptycount countdictstack mark
- /pdfemptycount count 3 sub def 5 3 roll
+ %% We can't simply 'def' into the dictionary saved by 'q' above, we need to
+ %% call gput to copy it and store inside it. Stupid or what....
+ /pdfemptycount count 3 sub gput 5 3 roll
%
% Stack: ... <old emptycount> <dictcount> mark <patdict> <resdict>
% |
@@ -1074,11 +1083,51 @@ currentdict end readonly def
{ countdictstack
2 index le { exit } if
currentdict /n known not or
- Q
- } loop {
- ( **** Error: Pattern stream has unbalanced q/Q operators \(too many q's\)\n)
- pdfformaterror
- ( Output may be incorrect.\n) pdfformaterror
+ currentdict /n known currentdict /self known or{
+ Q
+ }{
+ (\n **** Error: File has unbalanced q/Q operators \(too many Q's\)\n Output may be incorrect.\n)
+ pdfdict /.Qqwarning_issued .knownget
+ {
+ {
+ pop
+ }
+ {
+ currentglobal pdfdict gcheck .setglobal
+ pdfdict /.Qqwarning_issued //true .forceput
+ .setglobal
+ pdfformaterror
+ } ifelse
+ }
+ {
+ currentglobal pdfdict gcheck .setglobal
+ pdfdict /.Qqwarning_issued //true .forceput
+ .setglobal
+ pdfformaterror
+ } ifelse
+ end
+ } ifelse
+ } loop
+ {
+ (\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n)
+ pdfdict /.Qqwarning_issued .knownget
+ {
+ {
+ pop
+ }
+ {
+ currentglobal pdfdict gcheck .setglobal
+ pdfdict /.Qqwarning_issued //true .forceput
+ .setglobal
+ pdfformaterror
+ } ifelse
+ }
+ {
+ currentglobal pdfdict gcheck .setglobal
+ pdfdict /.Qqwarning_issued //true .forceput
+ .setglobal
+ pdfformaterror
+ } ifelse
} if
pop
@@ -1150,7 +1199,7 @@ currentdict end readonly def
2 index /Resources knownoget { oforce } { 0 dict } ifelse
/.pdfpaintproc cvx
] cvx put
- dup /BBox 2 copy knownoget { normrect put } { pop pop } ifelse
+ dup /BBox 2 copy knownoget { normrect FixPatternBBox put } { pop pop } ifelse
dup /.pattern_uses_transparency 1 index patternusestransparency put
PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Pattern: ) print dup === flush } if } if
} bdef
@@ -1189,7 +1238,12 @@ drawopdict begin
/sc { .incachedevice {
.pdfcount { pop } repeat //ignore_color_op pdfformaterror
} {
- scresolve { sc*_and_set } { sc1_and_set } ifelse
+ scresolve 1 index //null eq {
+ pop pop
+ //ignore_color_op pdfformaterror
+ } {
+ { sc*_and_set } { sc1_and_set } ifelse
+ } ifelse
} ifelse
} bdef
@@ -1233,7 +1287,12 @@ drawopdict begin
/SC { .incachedevice {
.pdfcount { pop } repeat //ignore_color_op pdfformaterror
} {
- scresolve { SC*_and_set } { SC1_and_set } ifelse
+ scresolve 1 index //null eq {
+ pop pop
+ //ignore_color_op pdfformaterror
+ }{
+ { SC*_and_set } { SC1_and_set } ifelse
+ }ifelse
} ifelse
} bdef
@@ -1300,7 +1359,7 @@ drawopdict begin
setfillstate resolvesh
//sh_save 0 save put
PDFusingtransparency {
- SoftMask //null ne {
+ .currentSMask //null ne {
//sh_group
1 index /BBox knownoget {
{ oforce } forall
@@ -1327,7 +1386,7 @@ drawopdict begin
{
.endtransparencygroup .setopacityalpha .setblendmode % end the CompatibleOverprint group
} if
- SoftMask //null ne {
+ .currentSMask //null ne {
.endtransparencygroup
} if
} {
@@ -1359,7 +1418,7 @@ end
/CIEBasedABC { 1 get /RangeABC knownoget not { //01_3 } if } bind
/CalGray { pop //01_1 } bind
/CalRGB { pop //01_3 } bind
- /Lab { 1 get /Range knownoget not { [-100 100 -100 100] } if } bind
+ /Lab { 1 get /Range knownoget not { [-100 100 -100 100] } {aload pop 0 100 6 2 roll 6 array astore}ifelse } bind
/ICCBased {
1 oget dup /Range knownoget {
exch pop
@@ -2024,7 +2083,7 @@ currentdict /last-ditch-bpc-csp undef
ColorSpace dup type /arraytype eq { 0 oget } if /Indexed eq
BitsPerComponent 1 eq and {
- % AR9 treats Indexed 1 bpc images specially. Bug 692852.
+ % AR9 treats Indexed 1 bpc images specially. Bug 692852 see also 697919 and 689717.
dup 0 oget
dup 0 lt exch 1 BitsPerComponent bitshift ge or {
% First component is invalid - AR9 ignores the mask
@@ -2037,7 +2096,33 @@ currentdict /last-ditch-bpc-csp undef
% AR5, AR9 do this for most cases. Bug 690786.
[ exch { 1 BitsPerComponent bitshift 1 sub and } forall ]
} ifelse
- } if
+ } {
+ ColorSpace dup type /arraytype eq { 0 oget } if /DeviceGray eq
+ BitsPerComponent 1 eq and {
+ %% For DeviceGray, try clamping the values to 0 and 1 respectively
+ dup 0 oget
+ dup 0 lt exch 1 gt or {
+ dup 0 oget
+ dup 0 lt {
+ pop dup 0 0 put
+ }{
+ dup 0 1 put
+ } ifelse
+ } if
+ dup 1 oget
+ dup 0 lt exch 1 gt or {
+ dup 1 oget
+ dup 0 lt {
+ pop dup 0 0 put
+ }{
+ dup 0 1 put
+ } ifelse
+ } if
+ }{
+ % AR5, AR9 do this for most cases. Bug 690786.
+ [ exch { 1 BitsPerComponent bitshift 1 sub and } forall ]
+ } ifelse
+ } ifelse
dup //null ne {
/MaskColor exch def
} {
@@ -2089,7 +2174,7 @@ currentdict /last-ditch-bpc-csp undef
.begintransparencymaskimage
PDFfile fileposition exch
gsave //nodict begin
- //null /SoftMask gput
+ //null .setSMask
1 .setopacityalpha 1 .setshapealpha
1 CA 1 ca
/Compatible .setblendmode
@@ -2109,7 +2194,7 @@ currentdict /last-ditch-bpc-csp undef
% on our lazy evaulation of SMask groups
false << /Subtype /None >> 0 0 0 0 .begintransparencymaskgroup
} {
- SoftMask //null ne {
+ .currentSMask //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
@@ -2128,6 +2213,44 @@ currentdict /last-ditch-bpc-csp undef
} bdef
} if
+/ValidateDecode { % <<image dict>> -imagemask- ValidateDecode <<image dict>>
+ exch
+ dup /Decode .knownget {
+ dup length % -imagemask- <<image dict>> [Decode] length
+ 4 -1 roll % <<image dict>> [Decode] length -imagemask-
+ {
+ 1 % ImageMask Decode arrays must be [0 1] or [1 0]
+ }
+ {
+ mark currentcolor counttomark % <<image dict>> [Decode] length [ ... component_count
+ dup 2 add 1 roll % <<image dict>> [Decode] length component_count [ ....
+ cleartomark % <<image dict>> [Decode] length component_count
+ } ifelse
+ 2 mul dup % <<image dict>> [Decode] length comp_count*2 comp_count*2
+ 3 1 roll % <<image dict>> [Decode] comp_count*2 length comp_count*2
+ eq { % <<image dict>> length of Decode matches colour space requirement
+ pop pop % <<image dict>> remove [Decode] and comp_count*2
+ }{ % <<image dict>> Decode array incorrect
+ dup 2 index length % <<image dict>> [Decode] comp_count*2 comp_count*2 length
+ exch sub 0 gt { % Decode is too long
+ (\n **** Warning: Decode array for an image is too long\n) pdfformatwarning
+ ( Output may be incorrect.\n) pdfformatwarning
+ 0 exch % <<image dict>> [Decode] 0 comp_count*2
+ getinterval % <<image dict>> [subarray of Decode]
+ 1 index exch /Decode exch % <<image dict>> <<image dict>> /Decode [subarray]
+ put % <<image dict>>
+ }{
+ % Decode is too short, Acrobat throws errors on this
+ (\n **** ERROR: Decode array for an image is too short\n) pdfformaterror
+ ( Output may be incorrect.\n) pdfformaterror
+ pop pop % remove [Decode] and comp_count*2
+ } ifelse
+ } ifelse
+ } {
+ exch pop
+ }ifelse
+}bdef
+
/doimage { % <imagemask> doimage -
% imagedict is currentdict, gets popped from dstack
//null checkOPtrans {
@@ -2160,8 +2283,8 @@ currentdict /last-ditch-bpc-csp undef
makemaskimage
} if
% Stack: datasource imagemask
- { currentdict end setfillstate { imagemask } }
- { ColorSpace setgcolorspace currentdict end setfillblend { image } }
+ { currentdict end setfillstate true ValidateDecode { imagemask } }
+ { ColorSpace setgcolorspace currentdict end setfillblend false ValidateDecode { image } }
ifelse
PDFSTOPONERROR { exec //false } { stopped } ifelse {
dup type /dicttype eq { pop } if % Sometimes image fails to restore the stack
@@ -2451,7 +2574,61 @@ currentdict end readonly def
//ocg_pocs exch get exec % bool
} ifelse
} {
- /OFF known not % OFF is inserted by process_trailer_attrs
+ dup /OFF known not % OFF is inserted by process_trailer_attrs
+ {
+ %% /OC is not in the OCProperties /OFF array, so we need to
+ %% test its usage. We may eventually have to add a /ON to the dictionary
+ %% if the OCProperties /ON array defines the /OC, I think that should override
+ % the Usage, but I don't have an example to test.
+ /Usage .knownget {
+ oforce
+ /Printed where {
+ /Printed get
+ } {
+ //false
+ }ifelse
+ {
+ %% We are behaving as a printer, check the Print state
+ /Print .knownget {
+ /PrintState .knownget {
+ oforce
+ /OFF eq {
+ //false
+ }{
+ //true
+ } ifelse
+ }{
+ //true
+ } ifelse
+ }{
+ %% If we don't know, assume its visible
+ //true
+ } ifelse
+ }{
+ %% We are behaving as a viewer, check the View state
+ /View .knownget {
+ oforce
+ /ViewState .knownget {
+ /OFF eq {
+ //false
+ }{
+ //true
+ } ifelse
+ }{
+ //true
+ } ifelse
+ }{
+ %% If we don't know, assume its visible
+ //true
+ } ifelse
+ } ifelse
+ }{
+ %% If we don't know, assume its visible
+ //true
+ } ifelse
+ }{
+ pop //false
+ }ifelse
} ifelse
} {
/OFF known not % OFF is inserted by process_trailer_attrs
@@ -2480,30 +2657,72 @@ drawopdict begin
} if
setfillblend
PDFfile fileposition exch % pos /Name
- dup Page /XObject rget {
- exch pop % pos obj
- OFFlevels length 0 eq {
- dup /OC knownoget { ocg-is-visible } { //true } ifelse
- } {
+
+ % Bug #698226, Acrobat signals an error for recursive XObjects in a PDF file
+ % but continues. This is true even if the XObject is not a simple self-reference
+ % (eg /Fm1 -> /Fm2 -> /Fm3 -> /Fm1).
+ % Normally when dealing with recursion we would put a dictionary on the stack, store the
+ % object numbers encoutnered in it, and check each new object number to see if we've
+ % already seen it. This doesn't work well for XObjects, because the operand stack can be
+ % in any state when we run a Do. So we make a new dictionary in pdfdict to hold the
+ % object numbers.
+ % We also don't usually know the object number of a Form, we just get given its name
+ % so we need a new routine to return the object number. This is because the parent XObject
+ % might reference teh object by one name, while the child references it by another, we
+ % can't permit clashes.
+ %
+ % Start by getting the object number for a Form XObject
+ dup Page /XObject obj_get dup 0 eq not {
+ % Now get the recording dictionary and see if that object number has been seen
+ pdfdict /Recursive_XObject_D get 1 index known {
+ ( **** Error: Recursive XObject detected, ignoring ") print 1 index 256 string cvs print (", object number ) print 256 string cvs print (\n) print
+ ( Output may be incorrect.\n) pdfformaterror
//false
- } ifelse {
- dup /Subtype oget //xobjectprocs exch get % pos obj {proc}
- % Don't leave extra objects on the stack while executing
- % the definition of the form.
- 3 -1 roll % obj {proc} pos
- 2 .execn % pos
+ }{
+ % We haven't seen it yet, so record it.
+ pdfdict /Recursive_XObject_D get 1 index null put
+ 3 1 roll
+ //true
+ }ifelse
+ }
+ {
+ % I don't think this should be possible, but just in case
+ ( **** Error: Unable to determine object number for ) print exch 256 string cvs print ( so ignoring it) print
+ ( Output may be incorrect.\n) pdfformaterror
+ //false
+ } ifelse
+
+ % If we could get the object number, and we haven't already seen it, then execute it.
+ {
+ dup Page /XObject rget {
+ exch pop % pos obj
+ OFFlevels length 0 eq {
+ dup /OC knownoget { ocg-is-visible } { //true } ifelse
+ } {
+ //false
+ } ifelse {
+ dup /Subtype oget //xobjectprocs exch get % pos obj {proc}
+ % Don't leave extra objects on the stack while executing
+ % the definition of the form.
+ 3 -1 roll % obj {proc} pos
+ 2 .execn % pos
+ } {
+ pop % pos
+ } ifelse
} {
- pop % pos
+ % This should cause an error, but Acrobat Reader can
+ % continue, so we do too.
+ ( **** Error: Undefined XObject resource: )
+ exch =string cvs concatstrings (\n) concatstrings
+ pdfformaterror
+ ( Output may be incorrect.\n) pdfformaterror
} ifelse
- } {
- % This should cause an error, but Acrobat Reader can
- % continue, so we do too.
- ( **** Error: Undefined XObject resource: )
- exch =string cvs concatstrings (\n) concatstrings
- pdfformaterror
- ( Output may be incorrect.\n) pdfformaterror
+ PDFfile exch setfileposition
+ pdfdict /Recursive_XObject_D get exch undef
+ }{
+ % Otherwise ignore it and tidy up the stacks
+ pop pop
} ifelse
- PDFfile exch setfileposition
} bdef
end
@@ -2854,11 +3073,15 @@ end
dup (BT ) writestring
1 index /DA fget not {
1 index /V fget {
- <FEFF> anchorsearch{
- pop pop /FallBackFont /Identity-UTF16-H [/CIDFallBack] composefont 12 scalefont setfont
- }{
+ <EFBBBF> anchorsearch {
pop /Helvetica findfont 12 scalefont setfont
- } ifelse
+ } {
+ <FEFF> anchorsearch {
+ pop pop /FallBackFont /Identity-UTF16-H [/CIDFallBack] composefont 12 scalefont setfont
+ } {
+ pop /Helvetica findfont 12 scalefont setfont
+ }ifelse
+ }ifelse
} if
()
}if
@@ -2894,11 +3117,18 @@ end
//false exch
NeedAppearances {
dup /FT fget {
- /Tx eq {
- dup /V oknown {
- pop not 1
- } if
- } if
+ dup /Tx eq {
+ pop
+ dup /V oknown {
+ pop not 1
+ } if
+ } {
+ /Ch eq {
+ dup /V oknown {
+ pop not 1
+ } if
+ } if
+ } ifelse
} if
} if
pop
@@ -2920,6 +3150,7 @@ end
% dup /AP undef
% } if
% } if
+
dup /AP knownoget {
dup /N known not {
( **** Error: Appearance dictionary (AP) lacks the mandatory normal (N) appearance.\n)
@@ -3264,6 +3495,12 @@ currentdict /set_bc_color undef
/emptydict 0 dict readonly def
/Highlight {
+% technically we should apply an appearance stream if we have one, but if we do
+% some test files don't match Acrobat. PDF 2.0 says appearance streams are mandatory,
+% and take precedence over generatig new ones, so we may need to revisit this.
+% dup /AP oknown {
+% //true
+% }{
0 setlinecap
dup annotsetcolor {
/QuadPoints knownoget {
@@ -3287,6 +3524,7 @@ currentdict /set_bc_color undef
} if
} if
//false
+% } ifelse
} bdef
currentdict /emptydict undef
currentdict /highlight-arc undef
@@ -3402,7 +3640,7 @@ currentdict /set_bc_color undef
{
gsave
- dup annotrect (rectclip from freetext annotation) == flush rectclip
+ dup annotrect rectclip
dup /CA knownoget {
.setopacityalpha
@@ -3684,7 +3922,7 @@ currentdict /set_bc_color undef
2 index 2 div add exch
3 index 2 div add exch translate % dx dy
- 50 div exch 190 div .min dup scale
+ 50 div exch 190 div .min dup 0.0 eq {pop 1.0} if dup scale
/Name knownoget not { /Draft } if
//stamp_dict 1 index known not { exch pop /Draft exch } if
@@ -3700,24 +3938,124 @@ currentdict /set_bc_color undef
} ifelse
} bdef
- currentdict /quadpoints2basis undef
+ /Popup {
+ dup /Open oknown {
+ dup /Open get {
+ dup /AP oknown {
+ //true
+ }{
+ gsave
+ newpath
+ 0.05 setlinewidth
+ dup /Parent .knownget {
+ oforce
+ } {
+ dup /P .knownget {
+ oforce
+ } {
+ dup
+ } ifelse
+ } ifelse
+ /C .knownget {
+ aload pop
+ }{
+ 1 1 0
+ }ifelse
+ setrgbcolor
+ dup /Rect get
+ dup aload pop
+ 2 index sub
+ exch 3 index sub exch
+ 4 copy
+ gsave 1 setgray rectfill grestore
+ gsave 0 setgray rectstroke grestore
+ 1 index /Parent .knownget {
+ oforce
+ }{
+ 1 index /P .knownget {
+ oforce
+ }{
+ 1 index
+ } ifelse
+ }ifelse
+ dup
+ /Contents .knownget {
+ gsave
+ 0 setgray
+ /Helvetica findfont 9 scalefont setfont
+ 2 index aload pop 3 1 roll pop pop 30 sub exch 5 add exch
+ moveto show
+ grestore
+ } if
+ exch
+ dup aload pop 3 -1 roll pop exch 2 index sub -15
+ 4 copy rectfill
+ 0 setgray rectstroke
+ exch
+ /T .knownget {
+ gsave
+ 0 setgray
+ /Helvetica findfont 9 scalefont setfont
+ dup stringwidth pop
+ 2 index aload pop pop exch pop exch sub
+ exch sub 2 div 2 index aload pop 3 1 roll pop pop 11 sub 3 1 roll add exch moveto
+ show
+ grestore
+ } if
+ grestore
+ //false
+ } ifelse
+ } {
+ pop //false
+ }ifelse
+ } {
+ pop //false
+ }ifelse
+ } bdef
+
+currentdict /quadpoints2basis undef
currentdict end readonly def
+/.PDFDrawAnnotType?
+{
+ //false exch
+ /ShowAnnotTypes where
+ {
+ /ShowAnnotTypes get
+ {
+ dup /* eq exch 2 index eq or
+ {
+ pop //true exch
+ exit
+ } if
+ } forall
+ pop
+ }
+ {pop pop //true}
+ ifelse
+} bind def
+
/drawannot { % <annot> drawannot -
dup annotvisible {
gsave
dup dup /Subtype knownoget {
- //drawannottypes exch .knownget { exec } { //true } ifelse
+ dup //.PDFDrawAnnotType? exec
{
- dup calc_annot_scale 2 copy mul 0 ne
- {
- 3 -1 roll drawwidget
- }
+ //drawannottypes exch .knownget { exec } { //true } ifelse
{
- ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror
- ( Output may be incorrect.\n) pdfformaterror
- }ifelse % Draw rejected annots as widgets
- } if % type known
+ dup calc_annot_scale 2 copy mul 0 ne
+ {
+ 3 -1 roll drawwidget
+ }
+ {
+ ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror
+ ( Output may be incorrect.\n) pdfformaterror
+ }ifelse % Draw rejected annots as widgets
+ } if % type known
+ }
+ {
+ pop
+ }ifelse
} {
pop
( **** Error: Ignoring /Annot dict without required /Subtype entry.\n)
@@ -3909,17 +4247,22 @@ currentdict end readonly def
dup annotvisible {
gsave
dup dup /Subtype knownoget {
- //preserveannottypes exch .knownget { exec } { //true } ifelse
+ dup //.PDFDrawAnnotType? exec
{
- dup calc_annot_scale 2 copy mul 0 ne
- {
- 3 -1 roll drawwidget
- }
+ //preserveannottypes exch .knownget { exec } { //true } ifelse
{
- ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror
- ( Output may be incorrect.\n) pdfformaterror
- }ifelse % Draw rejected annots as widgets
- } if % type known
+ dup calc_annot_scale 2 copy mul 0 ne
+ {
+ 3 -1 roll drawwidget
+ }
+ {
+ ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror
+ ( Output may be incorrect.\n) pdfformaterror
+ }ifelse % Draw rejected annots as widgets
+ } if
+ }
+ {pop} ifelse
+ % type known
} {
pop
( **** Error: Ignoring /Annot dict without required /Subtype entry.\n)
@@ -3931,6 +4274,7 @@ currentdict end readonly def
} bdef
currentdict /preserveannottypes undef
+currentdict /.PDFDrawAnnotType? undef
% ============================ AcroForm fields ============================ %
@@ -4013,8 +4357,8 @@ currentdict /preserveannottypes undef
{ 1 index exch write== } forall
dup 3 index /MaxLen pget not { 0 } if write=
dup 3 index /V pget not {
- 3 index /DV pget not { () } if write==
- } if
+ 3 index /DV pget not { () } if
+ } if write==
dup 3 index /Ff pget not { 0 } if write=
dup 3 index /Q pget not { 0 } if write=
dup (Tform ET) write=
@@ -4026,7 +4370,51 @@ currentdict /preserveannottypes undef
} bdef
/Ch {
- (Ch is not yet implemened) //== exec
+ dup /AP known 3 index /NeedAppearances knownoget not { //true } if not and {
+ dup 1 1 3 -1 roll drawwidget
+ } {
+ %% If we don't have a NeedApperances, treat as true, because Acrobat
+ %% always regenerates Appearances anyway.
+ 2 index /NeedAppearances knownoget not { //true } if {
+ dup /AP << /N 10 dict dup cvx begin >> put
+ /Subtype /Form def
+ /BBox [ 0 0 4 index /Rect oget { oforce } forall 3 -1 roll sub abs 3 1 roll sub abs exch ] def
+ /Resources 3 index /DR pget not { 0 dict } if def
+ /File 1000 string dup 3 1 roll def
+ /Length 1000 def
+ % <acroform> <field> <annot> (string)
+ /NullEncode filter % <acroform> <field> <annot> file
+
+ dup (BT ) writestring
+ 2 index /DA pget not { () } if
+ [ exch
+ { token {
+ dup /Tf eq {
+ 2 index 0 eq {
+ /BBox load 3 get
+ 0.75 mul % empirical constant
+ 4 -1 roll pop 3 1 roll
+ } if
+ } if
+ exch
+ } {
+ exit
+ } ifelse
+ } loop
+ ]
+ { 1 index exch write== } forall
+ dup 3 index /MaxLen pget not { 0 } if write=
+ dup 3 index /V pget not {
+ 3 index /DV pget not { () } if
+ } if write==
+ dup 3 index /Ff pget not { 0 } if write=
+ dup 3 index /Q pget not { 0 } if write=
+ dup (Tform ET) write=
+ end
+ closefile % <acroform> <field> <annot>
+ dup 1 1 3 -1 roll drawwidget
+ } if
+ } ifelse
} bdef
/Sig {
diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps
index 7060dbce6f0..02a3b0f6602 100644
--- a/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps
@@ -268,7 +268,6 @@ currentdict /known_symbolic_fonts undef
/getfontmetrics { % <font-resource> <font> <Encoding|null> getfontmetrics
% <font-resource> <font> <Encoding|null>
% <Metrics|null> <GlyphMap|null>
-
2 index /Widths oknown {
dup //null eq { pop dup /Encoding get } if
7 dict begin
@@ -871,7 +870,9 @@ setglobal
{
0 1 2 index length 1 sub
{
- dup 2 index exch get dup 0 gt % We ignore entries of zero in the widths array
+ dup 2 index exch get
+ dup type /packedarraytype eq {exec} if % Handle entries which are indirect references (seriously ? !!)
+ dup 0 gt % We ignore entries of zero in the widths array
{
exch 5 index add % add FirstChar to the idx to get a char code
dup 64 gt 1 index 91 lt and % we only want to consider A~Z and....
@@ -986,48 +987,62 @@ setglobal
.dicttomark readonly def
% When Type 1 font reading procedure is executing, a copy of this dictionary is current.
-% We have to do something special about embedded fonts that execute definefont
-% more than once -- that is the function of topFontDict.
+% topFontDict allows us to *attempt* to handle the case where a Type 1 font definition
+% does not start by creating it's own dictionary (i.e. a number of the keys end up in
+% the currentdict rather than the font dictionary).
% The whole type1 stream can be executed directly. There's no need to process
% Length1, 2, 3 keys.
/readtype1dict 10 dict dup begin
- /definefont {
- exch pop
+ /prev_definefont /definefont load def
- /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
+ /definefont {
+ % if a font defines any keys outside it's own dictionary,
+ % this attempts to cope by copying them into the font dictionary
+ [
+ /FontType % in PLRM order
+ /FontMatrix
+ /FontName
+ /FontInfo
+ /WMode
+ /Encoding
+ /FontBBox
+ /UniqueID
+ /XUID
+ /PaintType
+ /StrokeWidth
+ /Metrics
+ /Metrics2
+ /CDevProc
+ /CharStrings
+ /Private
+ /WeightVector
+ ]
+ {
+ 2 copy known
+ {pop}
+ {
+ dup where
+ {
+ 1 index get
+ 2 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)
- pdfformatwarning
- } if
+ }
+ {pop} ifelse
+ } ifelse
+ } forall
+ dup /MisplacedKey known {
+ ( **** Warning: Type 1 font defines some required keys outside the font dictionary.\n)
+ pdfformatwarning
} if
+ dup /CharStrings get /.notdef known not {
+ dup /CharStrings get
+ /.notdef <9E35CED7FFD3622F09> put
+ ( **** Warning: Type 1 font has no /.notdef entry in /CharString dictionary.\n)
+ pdfformatwarning
+ } if
dup /UniqueID .knownget {
dup dup 0 lt exch 16#ffffff gt or {
( **** Warning: Ignoring invalid /UniqueID = ) exch =string cvs
@@ -1037,17 +1052,11 @@ setglobal
pop
} ifelse
} if
- dup /CharStrings get /.notdef known not {
- dup /CharStrings get
- /.notdef <9E35CED7FFD3622F09> put
- ( **** Warning: Type 1 font has no /.notdef entry in /CharString dictionary.\n)
- pdfformatwarning
- } if
- .completefont
+ prev_definefont
} bdef
/undef_proc_warning {
- /Repaired //true store % flag that we have warnings
+ /Repaired //true store % flag that we have warnings
UndefProcList exch 2 copy .knownget { 1 add } { 1 } ifelse put
} bdef
@@ -1182,18 +1191,48 @@ currentdict /eexec_pdf_param_dict .undef
% the character code to access the Widths.
/BuildChar {
% Stack: font charcode
- 1 index begin 3 dict begin
+ 1 index begin 4 dict begin
/Font 3 -1 roll def /CharCode 1 index def
Encoding exch get CharProcs exch knownoget {
- { //false resolvestream
+ dup /Length get 0 eq {
+ pop
+ %% Detect a 0 length stream. If this occurs
+ %% then we won't execute d0 or d1, and so won't adjust the
+ %% character width. So, pretend we got a
+ %% null d1, just so that we can adjust using the /Widths
+ %% (Bug 697805)
+ 0 0 0 0 0 0
+ pdfopdict /d1 get exec
+ }{
+ { //false resolvestream
% Stack: filepos stream
% Don't let setgcolor set the color inside the BuildGlyph
% procedure, because this causes an /undefined error.
- q //null /FillColor gput //null /StrokeColor gput
- Font /Resources get exch pdfopdict .pdfruncontext
- Q
- } PDFfile fileposition 2 .execn % Keep pdfcount valid.
- PDFfile exch setfileposition
+ q
+ %% This is (currently) needed to make sure that the current dictionary, which is
+ %% 'nodict' because we did a gsave, is writeable. If we don't execute gput
+ %% to make a writeable copy then it is a no access dicitonary and the 'def'
+ %% below will fail. It would be nice to fix the cases of this someday, but
+ %% we use 'nodict'[ to store other PDF state stuff that isn't gstate, and we
+ %% probably always will, so it may well be more trouble than its worth.
+ /Dummy false gput
+ Font /Resources get exch pdfopdict
+ /BuildCharDictDepth countdictstack def
+ .pdfruncontext
+ countdictstack BuildCharDictDepth sub
+ {
+ pdfdict /.Qqwarning_issued .knownget {not}{//true} ifelse
+ {
+ (\n **** Warning: Type 3 glyph has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n)
+ pdfformatwarning
+ pdfdict /.Qqwarning_issued //true .forceput
+ } if
+ Q
+ } repeat
+ Q
+ } PDFfile fileposition 2 .execn % Keep pdfcount valid.
+ PDFfile exch setfileposition
+ } ifelse
} {
% PDF Type 3 fonts don't use .notdef
% d1 implementation adjusts the width as needed
@@ -2282,12 +2321,7 @@ currentdict /bndef undef
% in multipage documents.
/patch_font_XUID % <font dict> <patch> patch_font_XUID <font dict'>
{
- %% Allow users to specify that we should not care about font object numbers
- %% that is, don't patch the XUID with the object number and filename.
- /PDFDontUseFontObjectNum where {/PDFDontUseFontObjectNum get}{//false}ifelse
- %% Do not modify the XUID if we don't have an object number (see above)
- 1 index //null eq
- or
+ dup //null eq
{pop}
{
pdfdict /InputPDFFileName .knownget {.CRCHashFilenameAndObject} if
diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps
index 85b5848e160..a16f5806734 100644
--- a/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps
@@ -85,6 +85,9 @@ pdfdict begin
pdfformaterror
( Output may be incorrect.\n) pdfformaterror
} bind
+
+ /Recursive_XObject_D 1 dict def
+
.dicttomark readonly def
% ======================== Main program ======================== %
@@ -948,9 +951,17 @@ currentdict /xref-char-dict undef
%% Bug #695883 the test file has an XRefStm which points beyond the end of the file.
%% We check that here and simply fall back to thje classic xref if this error occurs.
dup PDFfilelen lt{
- readpdf15xref pop
+ PDFSTOPONERROR not {
+ mark exch {readpdf15xref pop} stopped
+ {
+ ( **** Error: This hybrid file's XRefStm does not point to a valid stream.\n Ignoring error, output may be incorrect.\n) pdfformaterror
+ } if
+ cleartomark
+ } {
+ readpdf15xref pop
+ } ifelse
} {
- ( **** Error: This hybrid file's XRefStm points beyond the end of file.\n Ignoring error, output may be incorrect.\n) pdfformaterror
+ ( **** Error: This hybrid file's XRefStm points beyond the end of file.\n Ignoring error, output may be incorrect.\n) pdfformaterror
pop
}ifelse
} if
@@ -1129,7 +1140,37 @@ currentdict /xref-char-dict undef
( **** ) stderrprint stderrprint
} ifelse
} ifelse
- } if
+ } {
+ % If the user told us to use a named OutputIntent
+ systemdict /UseOutputIntent .knownget {
+ cvn
+ Trailer /Root oget /OutputIntents knownoget {
+ {
+ dup /OutputConditionIdentifier get cvn
+ dup /Custom eq {
+ pop
+ dup /Info get cvn
+ }if
+ 2 index eq {
+ %% Found the required OutputIntent
+ /DestOutputProfile knownoget {
+ [ /ICCBased 3 -1 roll ] ICCBased-resolve
+ 1 get .set_outputintent
+ ()
+ } if
+ pop
+ exit
+ }{
+ pop
+ } ifelse
+ }
+ forall
+ pop
+ }{
+ pop
+ }ifelse
+ } if
+ }ifelse
Trailer /Root knownoget { /PageLabels knownoget {
%% Currenlty only the pdfwrite device can handle PageLabels
%% because we deal with these using putparams, not pdfmarks
@@ -1283,6 +1324,8 @@ currentdict /xref-char-dict undef
% Read any previous cross-reference tables. When we are done,
% verify that the entries in the xref tables are valid if NoVerifyXref
% is not defined.
+ /PrevArray [] def % Empty array, we use this to detect circular /Prev entries in xref (see below)
+ % For some reqason, leaving this on the stack messes up seom files.
Trailer
{ /Prev knownoget not { % If no previous xref table then ...
Classic-xref {
@@ -1290,10 +1333,43 @@ currentdict /xref-char-dict undef
} if
exit
} if
+
+ %% This code is used to detect circular references in xref tables. Every time
+ %% we detect a /Prev in the xref, we check the given offset of the /Prev xref
+ %% against a list of all previously encountered /Prev offsets. If we find that
+ %% we have previously seen this one, we raise an error, stop processing the xref
+ %% but carry on with the PDF file (unless PDFSTOPONERROR is true).
+ //false exch PrevArray %% Used to determine if the looop found a circular ref
+ { %% //false offset 'array entry'
+ 1 index eq {
+ exch pop //true exch %% We've seen this offset before, pop the false and replace with true
+ exit %% //true offset
+ } if
+ } forall
+
+ exch %% [...] offset bool
+ {
+ (\n **** Error: Circular /Prev entry while reading xref.\n Aborting xref read, output may be incorrect.\n)
+ pdfformaterror
+ PDFSTOPONERROR {
+ /readxref /syntaxerror cvx signalerror
+ } if
+ pop exit %% [...] and then exit this loop
+ } if
+
+ PrevArray dup %% offset [...] [...]
+ length 1 add array %% offset [...] [ ]
+ dup 3 1 roll %% offset [ ] [...] [ ]
+ copy pop %% offset [... ]
+ dup dup length 1 sub %% offset [... ] [... ] index
+ 3 index %% offset [... ] [... ] index offset
+ put /PrevArray exch def
+
{ readxref }
PDFSTOPONERROR not {
.internalstopped {
recover_xref_data % Read failed. Attempt to recover xref data.
+ /PrevArray where {/PrevArray undef} if %% remove the array we were using to detect circular references
exit % Exit loop since recover gets all obj data.
} if % If readxref stopped
} {
@@ -1312,6 +1388,7 @@ currentdict /xref-char-dict undef
} ifelse
} forall
} loop % Loop to previous trailer
+ /PrevArray where {/PrevArray undef} if %% remove the array we were using to detect circular references
} if
/NumObjects Objects length def % To check that obj# < NumObjects
@@ -1584,10 +1661,32 @@ currentdict /xref-char-dict undef
{
2 copy knownoget
{ exch pop exch pop //true }
- { exch /Parent knownoget
- { exch pget }
+ {
+ %% Check to see if there's a Parent
+ 1 index
+ 3 1 roll
+ exch /Parent knownoget
+ {
+ %% If there is a Parent, check to see if this dictionary has a stored object number
+ 3 -1 roll /.gs.pdfobj# .knownget {
+ %% if it does, check the Parent as wwell
+ 1 index /.gs.pdfobj# .knownget {
+ %% Both have object numbers, are they the same (ie its self-referencing)
+ eq {
+ pop pop
+ //false
+ }{
+ exch pget
+ }ifelse
+ }{
+ pop exch pget
+ }ifelse
+ } {
+ exch pget
+ }ifelse
+ }
% finally see if the key is (misplaced) in the Root Catalog dict
- { dup Trailer /Root oget exch knownoget dup {
+ { exch pop dup Trailer /Root oget exch knownoget dup {
3 -1 roll ( **** Error: The /) pdfformaterror 50 string cvs pdfformaterror
( key is missing from the Page tree.\n) pdfformaterror
( Output may be incorrect.\n) pdfformaterror
@@ -1600,6 +1699,30 @@ currentdict /xref-char-dict undef
ifelse
} bind def
+/obj_get {
+ LocalResources 1 index knownoget {
+ dup 4 index known {
+ 3 index get
+ 0 get 4 1 roll pop pop pop
+ } if
+ } {
+ 1 index /Resources pget {
+ 1 index knownoget {
+ dup 4 index known {
+ 3 index get
+ 0 get 4 1 roll pop pop pop
+ }{
+ pop pop pop 0
+ }ifelse
+ }{
+ pop pop pop 0
+ } ifelse
+ } {
+ pop pop pop 0
+ }ifelse
+ }ifelse
+}bind def
+
% Get the value of a resource on a given page.
/rget { % <resname> <pagedict> <restype> rget <value> -true-
% <resname> <pagedict> <restype> rget -false-
@@ -2109,14 +2232,61 @@ end readonly def
/MediaBox exch get_media_box pop
} {
oforce_elems % <<pdict>> /SomeBox x0 y0 x1 y1
+ %% Complicated stuff. We need to use the 'Box' we identified (if any), but we
+ %% need to clamp the boundaries of the 'Box' to the MediaBox. This appears to
+ %% be what Acrobat does. The complication arises because the Box values don't
+ %% have to be sensibly positive, its permissible to have the MediaBox set up
+ %% so that it extends down and left instead of up and right. We take care of the
+ %% content when we st up the CTM, but we do need to make sure that we clamp
+ %% the BoundingBox, and that means we need to take direcitonality into account...
+
6 -1 roll get_media_box { % /SomeBox x0 y0 x1 y1 [MediaBox]
aload pop % /SomeBox x0 y0 x1 y1 X0 Y0 X1 Y1
- 5 -1 roll .min exch % /SomeBox x0 y0 x1 X0 Y0 mY1 X1
- 5 -1 roll .min exch % /SomeBox x0 y0 X0 Y0 mX1 mY1
- 4 2 roll % /SomeBox x0 y0 mX1 mY1 X0 Y0
- 5 -1 roll .max exch % /SomeBox x0 mX1 mY1 mY0 X0
- 5 -1 roll .max exch % /SomeBox mX1 mY1 mX0 mY0
- 4 2 roll % /SomeBox mX0 mY0 mX1 mY1
+
+ %% Start with the width, get the X0 and X1 values of the MediaBox
+ 3 index % /SomeBox x0 y0 x1 y1 X0 Y0 X1 Y1 X0
+ 2 index % /SomeBox x0 y0 x1 y1 X0 Y0 X1 Y1 X0 X1
+ gt {
+ %% Media extends to left
+ 4 -1 roll % /SomeBox x0 y0 x1 y1 Y0 X1 Y1 X0
+ 8 -1 roll % /SomeBox y0 x1 y1 Y0 X1 Y1 X0 x0
+ .min % /SomeBox y0 x1 y1 Y0 X1 Y1 mX0
+ 7 1 roll % /SomeBox mX0 y0 x1 y1 Y0 X1 Y1
+ exch % /SomeBox mX0 y0 x1 y1 Y0 Y1 X1
+ 5 -1 roll % /SomeBox mX0 y0 y1 Y0 Y1 X1 x1
+ .max % /SomeBox mX0 y0 y1 Y0 Y1 mX1
+ 5 1 roll % /SomeBox mX0 mX1 y0 y1 Y0 Y1
+ }{
+ %% Media extends to right
+ 4 -1 roll % /SomeBox x0 y0 x1 y1 Y0 X1 Y1 X0
+ 8 -1 roll % /SomeBox y0 x1 y1 Y0 X1 Y1 X0 x0
+ .max % /SomeBox y0 x1 y1 Y0 X1 Y1 mX0
+ 7 1 roll % /SomeBox mX0 y0 x1 y1 Y0 X1 Y1
+ exch % /SomeBox mX0 y0 x1 y1 Y0 Y1 X1
+ 5 -1 roll % /SomeBox mX0 y0 y1 Y0 Y1 X1 x1
+ .min % /SomeBox mX0 y0 y1 Y0 Y1 mX1
+ 5 1 roll % /SomeBox mX0 mX1 y0 y1 Y0 Y1
+ } ifelse
+
+ %% Now deal with the height
+ 2 copy % /SomeBox mX0 mX1 y0 y1 Y0 Y1 Y0 Y1
+ gt {
+ %% Media extends down
+ exch % /SomeBox mX0 mX1 y0 y1 Y1 Y0
+ 4 -1 roll % /SomeBox mX0 mX1 y1 Y1 Y0 y0
+ .min % /SomeBox mX0 mX1 y1 Y1 mY0
+ 3 1 roll % /SomeBox mX0 mX1 mY0 y1 Y1
+ .max % /SomeBox mX0 mX1 mY0 mY1
+ }{
+ %% Media extends up
+ exch % /SomeBox mX0 mX1 y0 y1 Y1 Y0
+ 4 -1 roll % /SomeBox mX0 mX1 y1 Y1 Y0 y0
+ .max % /SomeBox mX0 mX1 y1 Y1 mY0
+ 3 1 roll % /SomeBox mX0 mX1 mY0 y1 Y1
+ .min % /SomeBox mX0 mX1 mY0 mY1
+ } ifelse
+ exch % /SomeBox mX0 mX1 mY1 mY0
+ 3 1 roll % /SomeBox mX0 mY0 mX1 mY1
} {
pop
} ifelse
@@ -2268,6 +2438,37 @@ currentdict /PDF2PS_matrix_key undef
% is not actually used on the page.
currentpagedevice /PageSpotColors known { /PageSpotColors 2 index countspotcolors def } if
+ % If the user told us to use a named OutputIntent
+ systemdict /UseOutputIntent .knownget {
+ cvn
+ % Check to see if this page has such an OutputIntent
+ 2 index /OutputIntents knownoget {
+ {
+ dup /OutputConditionIdentifier get cvn
+ dup /Custom eq {
+ pop
+ dup /Info get cvn
+ }if
+ 2 index eq {
+ %% Found the required OutputIntent
+ /DestOutputProfile knownoget {
+ [ /ICCBased 3 -1 roll ] ICCBased-resolve
+ 1 get .set_outputintent
+ ()
+ } if
+ pop
+ exit
+ }{
+ pop
+ } ifelse
+ }
+ forall
+ pop
+ }{
+ pop
+ }ifelse
+ } if
+
% Let the device know if we will be using PDF 1.4 transparency.
% The clist logic may need to adjust the size of bands.
1 index pageusestransparency /PageUsesTransparency exch def
@@ -2541,7 +2742,22 @@ currentdict /PDF2PS_matrix_key undef
} {
dup //false exch {
4 dict 1 index resourceusestransparency { pop not exit } if
- /Parent knownoget not { exit } if
+ %% Check the current dictionary and its Parent (if any) to see
+ %% if they both have stored object numbers. If they do then
+ %% check the numbers, don't allow self-references.
+ dup /Parent knownoget not { pop exit }
+ {
+ exch /.gs.pdfobj# .knownget
+ {
+ 1 index /.gs.pdfobj# .knownget {
+ eq {
+ pop exit
+ }if
+ }{
+ pop
+ }ifelse
+ }if
+ } ifelse
} loop
% Also check for transparency in the annotation (if not in resources).
{ pop //true } { annotsusetransparency } ifelse
@@ -2884,74 +3100,87 @@ currentdict /PDF2PS_matrix_key undef
} if
} bind def
-%%<Objectdict> <calling obj_num> pdfform_detect_cspacesub <boolean>
+%% <loopdict> <Objectdict> <calling obj_num> pdfform_detect_cspacesub <boolean>
%%
/pdf_object_detect_cspacesub {
- exch %% <calling obj_num> <Objectdict>
- dup pdf_colorspace_detect_cspacesub {
- pop //true
- }{ %% <calling obj_num> <Objectdict>
- /Resources knownoget { %% <calling obj_num> <Resourcesdict>
- /XObject knownoget { %% <calling obj_num> <XObjectdict>
- //false exch %% <calling obj_num> <XObjectdict> false
- %% We have files where the XObject Resource is not a dictionary
- dup type /dicttype eq { %% <calling obj_num> <XObjectdict> false
-
- %% check each Xobject entry in the dictionary,
- %% forall purs a key/value pair on the stack for us.
- %%
- { %% <calling obj_num> <XObjectdict> false key value
- exch pop %% <calling obj_num> <XObjectdict> false value
-
- %% If this is an indirect reference, check if its the smae object
- %% as the current one. If its not indirect, make the object number 0
- %% for comparison purposes.
- dup type /packedarraytype eq {
- dup 0 get dup 4 index
- eq
- } {
- 0 false
- }ifelse
+ %% use loop operator for an exitable context
+ %% we need this to detect recursion/looping
+ {
+ exch %% <loopdict> <calling obj_num> <Objectdict>
+ dup pdf_colorspace_detect_cspacesub {
+ pop pop //true exit
+ }{ %% <loopdict> <calling obj_num> <Objectdict>
+ /Resources knownoget { %% <loopdict> <calling obj_num> <Resourcesdict>
+ 2 index 1 index known {
+ %% We've already seen this object, ignore it and exit
+ pop pop //false exit
+ }{
+ 2 index 1 index //null put
+ } ifelse
- %% <calling obj_num> <XObjectdict> false value <form object or 0 if not indirect> <boolean>
- not {
- %% swap object number and value, and dereference value
- exch oforce
- %% Apparently we have files where the content of the XObject Resource dictionary is null
- dup //null ne {
- %% and files where the indivudal XObjects are not dictionaries
- dup type /dicttype eq {
- dup /Subtype get /Form eq {
- exch
- pdf_object_detect_cspacesub {
- pop //true exit
- } if
- } {
+ /XObject knownoget { %% <loopdict> <calling obj_num> <XObjectdict>
+ //false exch %% <loopdict> <calling obj_num> <XObjectdict> false
+ %% We have files where the XObject Resource is not a dictionary
+ dup type /dicttype eq { %% <loopdict> <calling obj_num> <XObjectdict> false
+
+ %% check each Xobject entry in the dictionary,
+ %% forall purs a key/value pair on the stack for us.
+ %%
+ { %% <loopdict> <calling obj_num> <XObjectdict> false key value
+ exch pop %% <loopdict> <calling obj_num> <XObjectdict> false value
+
+ %% If this is an indirect reference, check if its the smae object
+ %% as the current one. If its not indirect, make the object number 0
+ %% for comparison purposes.
+ dup type /packedarraytype eq {
+ dup 0 get dup 4 index
+ eq
+ } {
+ 0 false
+ }ifelse
+
+ %% <calling obj_num> <XObjectdict> false value <form object or 0 if not indirect> <boolean>
+ not {
+ %% swap object number and value, and dereference value
+ exch oforce
+ %% Apparently we have files where the content of the XObject Resource dictionary is null
+ dup //null ne {
+ %% and files where the indivudal XObjects are not dictionaries
+ dup type /dicttype eq {
+ dup /Subtype get /Form eq {
+ exch
+ 4 index 3 1 roll pdf_object_detect_cspacesub {
+ pop //true exit
+ } if
+ } {
+ pop pop
+ }ifelse
+ }{
pop pop
- }ifelse
+ } ifelse
}{
pop pop
- } ifelse
+ }
+ ifelse
}{
pop pop
- }
- ifelse
- }{
- pop pop
- } ifelse
- } forall
- }{
- pop
+ } ifelse
+ } forall
+ }{
+ pop
+ }ifelse
+ } {
+ %% No forms, so can't be any Default* spaces
+ //false
}ifelse
} {
- %% No forms, so can't be any Default* spaces
//false
- }ifelse
- } {
- //false
+ } ifelse
} ifelse
- } ifelse
- %% Remove the calling object ID, return our boolean
+ %% Remove the calling object ID, return our boolean
+ exch pop exit
+ } loop
+ %% remove and discard the loopdict
exch pop
} bind def
@@ -2966,12 +3195,11 @@ currentdict /PDF2PS_matrix_key undef
% not using UseCIEColor with pdfwrite.
%
/pdfshowpage_detect_cspacesub {
- dup 0 pdf_object_detect_cspacesub
+ dup 0 1 dict 3 1 roll pdf_object_detect_cspacesub
/HighLevelDevice /GetDeviceParam .special_op {
exch pop not exch pop
}if
-
} bind def
%
@@ -3110,3 +3338,36 @@ currentdict /PDF2PS_matrix_key undef
end % pdfdict
.setglobal
+
+DELAYBIND not {
+%% This list of operators are used internally by various parts of the Ghostscript PDF interpreter.
+%% Since each operator is a potential security vulnerability, and any operator listed here
+%% is not required once the initislisation is complete and functions are bound, we undefine
+%% the ones that aren't needed at runtime.
+[
+/.pdfawidthshow /.pdfwidthshow
+/.setfillcolor /.setfillcolorspace /.setstrokecolor /.setstrokecolorspace /.currentrenderingintent /.setrenderingintent
+/.currenttextrenderingmode /.settextspacing /.currenttextspacing /.settextleading /.currenttextleading
+/.settextrise /.currenttextrise /.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling
+/.settextlinematrix /.currenttextlinematrix /.currenttextmatrix /.settextmatrix /.currentblendmode
+/.currentopacityalpha /.currentshapealpha /.currenttextknockout
+/.pushextendedgstate /.popextendedgstate /.begintransparencytextgroup
+/.endtransparencytextgroup /.begintransparencymaskgroup /.begintransparencymaskimage /.endtransparencymask /.image3x
+/.abortpdf14devicefilter /.pdfinkpath /.pdfFormName /.setstrokeconstantalpha
+/.setfillconstantalpha /.setalphaisshape /.currentalphaisshape
+/.settextspacing /.currenttextspacing /.settextleading /.currenttextleading /.settextrise /.currenttextrise
+/.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling
+
+% Used by our own test suite files
+%/.pushpdf14devicefilter % transparency-example.ps
+%/.poppdf14devicefilter % transparency-example.ps
+%/.setopacityalpha % transparency-example.ps
+%/.setshapealpha % transparency-example.ps
+%/.endtransparencygroup % transparency-example.ps
+
+% undefining these causes errors/incorrect output
+%/.settextrenderingmode /.setblendmode /.begintransparencygroup /.settextknockout /check_r6_password /.setstrokeoverprint /.setfilloverprint
+%/.currentstrokeoverprint /.currentfilloverprint /.currentfillconstantalpha /.currentstrokeconstantalpha
+]
+{systemdict exch .undef} forall
+} if
diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps
index ba53b54cd7e..fabef68a90a 100644
--- a/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps
@@ -211,76 +211,69 @@ currentdict /gput_always_allow .undef
} ifelse
} bdef
-% Save most of graphic state attributes.
-% - get-gs-attrs ...
-/get-gs-attrs {
- currentsmoothness
- currentflat
- currentoverprint
- currentstrokeadjust
- currentdash
- currentmiterlimit
- currentlinejoin
- currentlinecap
- currentlinewidth
- currentfont
- currentcolor
- currentcolorspace
- { currentpoint } stopped
- matrix currentmatrix
-} bdef
-
-% Restore most of graphic state attributes.
-% ... get-gs-attrs -
-/set-gs-attrs {
- setmatrix
- { newpath } { moveto } ifelse
- setcolorspace
- setcolor
- setfont
- setlinewidth
- setlinecap
- setlinejoin
- setmiterlimit
- setdash
- setstrokeadjust
- setoverprint
- setflat
- setsmoothness
-} bdef
-
% ---------------- Color setting ---------------- %
-/fcput % <color> <colorspace> fcput -
- { /FillColorSpace gput /FillColor gput
- } bdef
-/scput % <color> <colorspace> scput -
- { /StrokeColorSpace gput /StrokeColor gput
- } bdef
-/csput % <colorspace> csput -
- { csset 2 copy fcput scput
- } bdef
-
-/csdevgray [/DeviceGray] readonly def
-/csdevrgb [/DeviceRGB] readonly def
-/csdevcmyk [/DeviceCMYK] readonly def
-/cspattern [/Pattern] readonly def
/nullpatternproc { pop } bdef
/nullpattern mark
/PatternType 1 /PaintType 1 /TilingType 3 /BBox [0 0 1 1]
/XStep 1 /YStep 1 /PaintProc //nullpatternproc
.dicttomark readonly def
-% Each entry in the color space dictionary is a procedure of the form
-% <cspace> -proc- <cspace> <initial-color>
+/PDFsetpattern {
+ % Since multiple patterns may share
+ % same data stream, we need to ensure
+ % that the stream is at 0 position.
+ % Making this consistently with resolveshading,
+ % which applies ReusableStreamDecode filter
+ % to the PS stream, which represents the
+ % PDF stream in dynamics.
+
+ dup /Shading knownoget {
+ dup /ShadingType oget 4 ge {
+ /DataSource knownoget {
+ dup type /filetype eq {
+ 0 setfileposition
+ } {
+ pop
+ } ifelse
+ } if
+ } {
+ pop
+ } ifelse
+ } if
+
+ % Associate pattern instance with the default qstate for the context.
+ % A single pattren object can be reused in several contexts.
+ dup DefaultQstate .knownget {
+ exch pop
+ } {
+ % But don't update read-only initial null pattern.
+ dup /PaintProc .knownget { //nullpatternproc ne } { //true } ifelse {
+ dup dup /Matrix knownoget not { { 1 0 0 1 0 0 } } if
+
+ gsave
+ .currentfillconstantalpha
+ .currentstrokeconstantalpha
+ DefaultQstate setqstate
+ .setstrokeconstantalpha
+ .setfillconstantalpha
+ makepattern
+ grestore
+
+ dup 3 1 roll
+ DefaultQstate exch put
+ } if
+ } ifelse
+} bdef
+
/CSdict mark
- /DeviceGray { pop //csdevgray 0 } bind
- /DeviceRGB { pop //csdevrgb [0 0 0] cvx } bind
- /DeviceCMYK { pop //csdevcmyk [0 0 0 1] cvx } bind
+ /DeviceGray { 0 } bind
+ /DeviceRGB { [0 0 0] cvx } bind
+ /DeviceCMYK { [0 0 0 1] cvx } bind
/CIEBasedA { 0 } bind
/CIEBasedABC { [0 0 0] cvx } bind
- /CalGray { pop //csdevgray 0 } bind
- /CalRGB { pop //csdevrgb [0 0 0] cvx } bind
+ /CalGray { pop /DeviceGray 0 } bind
+ /CalRGB { pop /DeviceRGB [0 0 0] cvx } bind
/Lab {[0 0 0] cvx } bind
/ICCBased { [ 1 index 1 oget /N get { 0 } repeat ] cvx } bind
/Separation { 1 } bind
@@ -288,91 +281,111 @@ currentdict /gput_always_allow .undef
[ 1 index 1 get length { 1 } repeat ] cvx
} bind
/Indexed { 0 } bind
- /Pattern {
- dup type /nametype eq 1 index length 1 eq or {
- pop //cspattern //nullpattern matrix makepattern
- } {
- //nullpattern matrix makepattern 1 index 1 get csset
- % Stack: patternspace nullpattern basecolor basespace
- pop [ 3 1 roll dup type /arraytype eq { aload pop } if
- counttomark -1 roll ] cvx
- } ifelse
- } bind
+ /Pattern { //nullpattern matrix makepattern } bind
.dicttomark readonly def
-/csset % <cspace> csset <color> <cspace>
- { dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch
- } bdef
-/g { //csdevgray fcput } bdef
-/G { //csdevgray scput } bdef
-/rg { 3 array astore cvx //csdevrgb fcput } bdef
-/RG { 3 array astore cvx //csdevrgb scput } bdef
-/k { 4 array astore cvx //csdevcmyk fcput } bdef
-/K { 4 array astore cvx //csdevcmyk scput } bdef
-%%
-%% Bug #694412, we set the colour space immediately now. Previously we
-%% only set the colour space and colour when a stroke or fill took place.
-%% if that happened inside a gsave/grestore we could end up setting the
-%% same colour space many times, which is a problem if its an expensive
-%% space, like ICCBased.
-%%
-/cs { csset dup setgcolorspace fcput } bdef
-/CS { csset dup .swapcolors setgcolorspace .swapcolors scput } bdef
-/ri { //.renderingintentdict exch .knownget { .setrenderingintent } if } bdef
-% We have to break up sc according to the number of operands.
-%%
-%% Also Bug #694412, we need to set the actual colour in response to the
-%% PDF operators as well. However, the transparenmcy code also uses the
-%% original calls (sc, SC, sc1, SC1, sc* and SC*) and so we create
-%% a duplicate set which do the same as the originals, but se the current
-%% colour as well.
-%%
-/sc1_and_set { /FillColor gput FillColor FillColorSpace setgcolor} bdef
-/sc1 { /FillColor gput } bdef
-/SC1_and_set {/StrokeColor gput .swapcolors StrokeColor StrokeColorSpace setgcolor .swapcolors } bdef
-/SC1 { /StrokeColor gput } bdef
-% We have to avoid storing into a color array associated with an outer
-% gsave level, so we do a kind of "copy on write".
-/sc* {
- currentdict /FillColor .knownget {
- astore pop
- } {
- /FillColor load
- % FillColor may contain either a single value or an array.
- dup type /arraytype eq { length }{ pop 1 } ifelse
- array astore cvx /FillColor gput
- } ifelse
-} bdef
-/SC* {
- currentdict /StrokeColor .knownget {
- astore pop
- } {
- /StrokeColor load
- % StrokeColor may contain either a single value or an array.
- dup type /arraytype eq { length }{ pop 1 } ifelse
- array astore cvx /StrokeColor gput
- } ifelse
-} bdef
+/ri {//.renderingintentdict exch .knownget { .setrenderingintent } if } bdef
+/g {/DeviceGray .setfillcolorspace .setfillcolor } bdef
+/G {/DeviceGray .setstrokecolorspace .setstrokecolor} bdef
+/rg {/DeviceRGB .setfillcolorspace .setfillcolor} bdef
+/RG {/DeviceRGB .setstrokecolorspace .setstrokecolor} bdef
+/k {/DeviceCMYK .setfillcolorspace .setfillcolor} bdef
+/K {/DeviceCMYK .setstrokecolorspace .setstrokecolor} bdef
+/cs {dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch .setfillcolorspace exec .setfillcolor} bdef
+/CS {dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch .setstrokecolorspace exec .setstrokecolor} bdef
+/sc {.setfillcolor} bdef
+/SC {.setstrokecolor} bdef
+/sc* {.setfillcolor} bdef
+/SC* {.setstrokecolor} bdef
/sc*_and_set {
- sc*
- FillColor FillColorSpace setgcolor
+ dup type /dicttype eq
+ {
+ dup /Type known
+ {
+ dup /Type get /Pattern eq {PDFsetpattern} if
+ }
+ {
+ dup /PatternType known {PDFsetpattern} if
+ } ifelse
+ } if
+ .setfillcolor
} bdef
/SC*_and_set {
- SC*
- .swapcolors StrokeColor StrokeColorSpace setgcolor .swapcolors
+ dup type /dicttype eq
+ {
+ dup /Type known
+ {
+ dup /Type get /Pattern eq {PDFsetpattern} if
+ }
+ {
+ dup /PatternType known {PDFsetpattern} if
+ } ifelse
+ } if
+ .setstrokecolor
+} bdef
+/sc1 {.setfillcolor} bdef
+/SC1 {.setstrokecolor} bdef
+/sc1_and_set {
+ dup type /dicttype eq
+ {
+ dup /Type known
+ {
+ dup /Type get /Pattern eq {PDFsetpattern} if
+ }
+ {
+ dup /PatternType known {PDFsetpattern} if
+ } ifelse
+ } if
+ .setfillcolor
+} bdef
+/SC1_and_set {
+ dup type /dicttype eq
+ {
+ dup /Type known
+ {
+ dup /Type get /Pattern eq {PDFsetpattern} if
+ }
+ {
+ dup /PatternType known {PDFsetpattern} if
+ } ifelse
+ } if
+ .setstrokecolor
} bdef
+/csput {dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch 2 copy .setfillcolorspace exec .setfillcolor .setstrokecolorspace exec .setstrokecolor} bdef
+/csset {dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch} bdef
+
+% ---------------- Color setting ---------------- %
+
% ---------------- Overprint/transparency setting ---------------- %
-/op { /FillOverprint gput } bdef % NB pdf_draw:gsparamdict handled /OP with no /op
-/OP { /StrokeOverprint gput } bdef
+/op { .setfilloverprint
+} bdef % NB pdf_draw:gsparamdict handled /OP with no /op
+/OP { .setstrokeoverprint
+} bdef
/OPM {
/.setoverprintmode where { pop dup .setoverprintmode .swapcolors .setoverprintmode .swapcolors } { pop } ifelse
} bdef
-/ca { /FillConstantAlpha gput } bdef
-/CA { /StrokeConstantAlpha gput } bdef
-/SMask { /SoftMask gput } bdef
-/AIS { /AlphaIsShape gput } bdef
+/ca { .setfillconstantalpha } bdef
+/CA { .setstrokeconstantalpha } bdef
+/SMask {
+ dup type /booleantype eq {
+ .currentSMask type /dicttype eq {
+ .currentSMask /Processed 2 index .forceput
+ } {
+ .setSMask
+ }ifelse
+ }{
+ .setSMask
+ }ifelse
+
+ %% This is some craziness to do with annotations and graphics states
+ %% the original nodict can't be written to, and we haven't (I think) done
+ %% a gsave, so we haven't copied it to /self, if we don't do that here
+ %% then transparent annotations cause an invalid access error.
+ currentdict //nodict eq {/self dup load end 5 dict begin def} if
+} bdef
+/AIS { .setalphaisshape } bdef
/BM {
/.setblendmode where {
pop [ exch dup type /nametype ne { aload pop } if /Normal ] {
@@ -386,13 +399,19 @@ currentdict /gput_always_allow .undef
/.settextknockout where { pop .settextknockout } { pop } ifelse
} bdef
+/UseBlackPtComp {
+ %% Our implementation of black point compensation uses 0 or 1, not a boolean
+ /.setblackptcomp where {pop false eq {0}{1}ifelse .setblackptcomp }{ pop } ifelse
+} bdef
+
% ---------------- Color installation ---------------- %
% Establish a given color (and color space) as current.
/.settransparencyparams { % <alpha> <smask> .settransparencyparams -
PDFusingtransparency {
/.begintransparencygroup where {
- pop AlphaIsShape {
+ pop .currentalphaisshape
+ {
1 .setopacityalpha exch .setshapealpha 1
} {
1 .setshapealpha exch .setopacityalpha 0
@@ -415,23 +434,28 @@ currentdict /gput_always_allow .undef
dup /Draw get exec
} ifelse
} {
- dup /Draw get exec
+ dup /Processed .knownget {
+ {
+ pop pop
+ } {
+ dup /Draw get exec
+ }ifelse
+ }{
+ dup /Draw get exec
+ } ifelse
} ifelse
} bdef
% (Non-mask) images must execute setfillblend.
/setfillblend {
- FillOverprint setoverprint
- FillConstantAlpha SoftMask .settransparencyparams
+ .currentfillconstantalpha
+ .currentSMask .settransparencyparams
} def
/setfillstate {
- FillColor FillColorSpace setgcolor setfillblend
+ setfillblend
} def
-
/setstrokestate {
- .swapcolors
- StrokeColor StrokeColorSpace setgcolor StrokeOverprint setoverprint
- StrokeConstantAlpha SoftMask .settransparencyparams
- .swapcolors
+ .currentstrokeconstantalpha
+ .currentSMask .settransparencyparams
} def
/Cdict 15 dict dup begin % <color...> <colorspace> -proc- -
/DeviceGray { pop setgray } bdef
@@ -530,7 +554,16 @@ currentdict /gput_always_allow .undef
% But don't update read-only initial null pattern.
dup /PaintProc .knownget { //nullpatternproc ne } { //true } ifelse {
dup dup /Matrix knownoget not { { 1 0 0 1 0 0 } } if
- gsave DefaultQstate setqstate makepattern grestore
+
+ gsave
+ .currentfillconstantalpha
+ .currentstrokeconstantalpha
+ DefaultQstate setqstate
+ .setstrokeconstantalpha
+ .setfillconstantalpha
+ makepattern
+ grestore
+
dup 3 1 roll
DefaultQstate exch put
} if
@@ -582,8 +615,10 @@ end def
pop currentcolorspace 1 get % use the base space
} if
known {
- /stroke ne { FillOverprint } { StrokeOverprint } ifelse
- .currentblendmode dup /Normal eq exch /Compatible eq or not and
+ /stroke ne { .currentfilloverprint
+ } { .currentstrokeoverprint
+ } ifelse
+ .currentblendmode dup /Normal eq exch /Compatible eq or not and
} {
pop //false
} ifelse
@@ -592,23 +627,25 @@ end def
/fsexec % <fillop|strokeop> fsexec -
{
PDFusingtransparency {
- SoftMask //null ne {
+ .currentSMask //null ne {
mark /Subtype /Group /Isolated //true .dicttomark pathbbox .begintransparencygroup
+ .currentshapealpha .currentopacityalpha 3 -1 roll % avoid double application
+ 1 .setopacityalpha 1 .setshapealpha
} if
dup checkOPtrans exch 1 index {
% We need to push a non-isolated, non-knockout transparency group and
% perform the operation in CompatibleOverprint mode, then end the
% transparency group. Do the begintransparencygroup step here.
mark /Subtype /Group /Isolated //false .dicttomark pathbbox .begintransparencygroup
- exch .currentblendmode exch .currentopacityalpha exch 4 -1 roll % save current values
+ .currentblendmode .currentopacityalpha 4 -2 roll % save current values
/CompatibleOverprint .setblendmode 1 .setopacityalpha
} if
cvx exec
{
.endtransparencygroup .setopacityalpha .setblendmode % end the CompatibleOverprint group
} if
- SoftMask //null ne {
- .endtransparencygroup
+ .currentSMask //null ne {
+ .endtransparencygroup .setopacityalpha .setshapealpha
} if
} {
cvx exec
@@ -792,29 +829,72 @@ end def
% Clipping:
-/Wdict 4 dict dup begin
+/Wdict 8 dict dup begin
/S { OFFlevels length 0 eq { gsave setstrokestate .swapcolors stroke .swapcolors grestore } if n } bdef
/f { OFFlevels length 0 eq { gsave setfillstate fill grestore } if n } bdef
/f* { OFFlevels length 0 eq { gsave setfillstate eofill grestore } if n } bdef
+/B {
+ OFFlevels length 0 eq {
+ PDFusingtransparency {
+ % knockout trans group around the filled and stroked object
+ mark
+ /Isolated //true /Knockout //true
+ .dicttomark
+ % strokepath will return empty path (no currentpoint) if nothing is stroked
+ gsave {strokepath pathbbox } stopped grestore not
+ {
+ 1 .setopacityalpha
+ .begintransparencygroup
+ gsave setfillstate fill grestore
+ setstrokestate .swapcolors /stroke fsexec .swapcolors
+ .endtransparencygroup
+ } {
+ newpath pop
+ } ifelse
+ } {
+ gsave setfillstate fill grestore
+ setstrokestate .swapcolors /stroke fsexec .swapcolors
+ } ifelse
+ } if
+ n
+} bdef
+/b { closepath B } bdef
+/B* {
+ OFFlevels length 0 eq {
+ PDFusingtransparency {
+ % knockout trans group around the filled and stroked object
+ mark
+ /Isolated //true /Knockout //true
+ .dicttomark
+ % strokepath will return empty path (no currentpoint) if nothing is stroked
+ gsave {strokepath pathbbox} stopped grestore not {
+ 1 .setopacityalpha
+ .begintransparencygroup
+ gsave setfillstate eofill grestore
+ setstrokestate .swapcolors /stroke fsexec .swapcolors
+ .endtransparencygroup
+ } { newpath pop } ifelse
+ } {
+ gsave setfillstate eofill grestore
+ setstrokestate .swapcolors /stroke fsexec .swapcolors
+ } ifelse
+ } if
+ n
+} bdef
+/b { closepath B* } bdef
/n { end { currentpoint } stopped not { pop pop clip } if newpath } bdef
end readonly def
/W { //Wdict begin } bdef
-/W*dict 4 dict dup begin
+/W*dict 8 dict dup begin
Wdict { def } forall
/n { end { currentpoint } stopped not { pop pop eoclip } if newpath } bdef
end readonly def
/W* { //W*dict begin } bdef
-
% ---------------- Text control ---------------- %
/textbeginpage
- { /TextSpacing 0 def % 0 Tc
- /TextLeading 0 def % 0 TL
- /TextRenderingMode 0 def % 0 Tr
- /TextRise 0 def % 0 Ts
- /WordSpacing 0 def % 0 Tw
- /TextHScaling 1.0 def % 100 Tz
- /TextFont //null def
+ {
+ 1.0 .settexthscaling
/FontMatrixNonHV //false def
/Show { showfirst } def
/TextFillStateNeeded //true def
@@ -844,7 +924,8 @@ end readonly def
/settextmatrix {
matrix currentmatrix
- TextMatrix concat
+ matrix .currenttextmatrix
+ concat
TestDegenerateCTM {
(\n **** Error: Degenerate text matrix detected, ignoring Tm operation\n) pdfformaterror
( Output may be incorrect.\n) pdfformaterror
@@ -852,9 +933,11 @@ end readonly def
} {
pop
} ifelse
- TextHScaling 1 ne { TextHScaling 1 scale } if
- TextRise 0 ne { 0 TextRise translate } if
- TextFont dup //null eq { pop } { setfont } ifelse
+ .currenttexthscaling
+ 1 ne { .currenttexthscaling
+ 1 scale } if
+ .currenttextrise 0 ne { 0 .currenttextrise
+ translate } if
} bdef
/settextstate {
@@ -879,14 +962,22 @@ end readonly def
/settextposition {
% Update the TextMatrix translation.
gsave TextSaveMatrix setmatrix
- {currentpoint} stopped not { TextRise sub TextMatrix 4 2 getinterval astore pop
+ {currentpoint} stopped not {
+ .currenttextrise
+ sub
+ matrix .currenttextmatrix
+ dup 5 4 -1 roll put
+ dup 4 4 -1 roll put
+ .settextmatrix
% We would like to do "grestore currentpoint translate"
% here, but some PDF files set a singular text matrix
% (0 0 0 0 <x> <y> Tm), so we can't do this.
- TextTempMatrix identmatrix setmatrix currentpoint
- grestore
- TextTempMatrix currentmatrix 4 2 getinterval astore pop
- TextTempMatrix setmatrix
+ TextTempMatrix identmatrix setmatrix currentpoint
+ matrix .currenttextmatrix
+ grestore
+ .settextmatrix
+ TextTempMatrix currentmatrix 4 2 getinterval astore pop
+ TextTempMatrix setmatrix
} {
( **** Error: Invalid currentpoint, probable degenerate CTM.\n) pdfformaterror
( Ignroing error, output may be incorrect.\n) pdfformaterror
@@ -932,10 +1023,9 @@ end readonly def
currentdict end
/.W exch def
} if
- currentdict /TextLineMatrix .knownget
- { identmatrix pop TextMatrix identmatrix pop }
- { matrix /TextLineMatrix gput matrix /TextMatrix gput }
- ifelse
+ matrix .settextlinematrix
+ matrix .settextmatrix
+
{ showfirst } /Show gput
currentdict /TextSaveMatrix .knownget not {
matrix dup /TextSaveMatrix gput
@@ -957,7 +1047,7 @@ end readonly def
/ET_NO_TXT_KO {
currentdict /TextSaveMatrix known {
- TextRenderingMode 4 ge { .currentfilladjust 0 .setfilladjust clip .setfilladjust} if
+ .currenttextrenderingmode 4 ge { .currentfilladjust 0 .setfilladjust clip .setfilladjust} if
newpath TextSaveMatrix setmatrix
currentdict /TextSaveMatrix undef
@@ -988,11 +1078,11 @@ end readonly def
} if
} bdef
-/Tc { /TextSpacing gput { showfirst } /Show gput } bdef
-/TL { /TextLeading gput } bdef
-/Tr { dup .settextrenderingmode /TextRenderingMode gput { showfirst } /Show gput } bdef
-/Ts { /TextRise gput settextstate } bdef
-/Tw { /WordSpacing gput { showfirst } /Show gput } bdef
+/Tc { .settextspacing { showfirst } /Show gput } bdef
+/TL { .settextleading } bdef
+/Tr { .settextrenderingmode { showfirst } /Show gput } bdef
+/Ts { .settextrise settextstate } bdef
+/Tw { .setwordspacing { showfirst } /Show gput } bdef
/Tz {
dup 0 eq {
(\n **** Error: Invalid 0.0 horizontal text scaling given for Tz\n)
@@ -1001,7 +1091,8 @@ end readonly def
pop 0.00000001 % handle invalid scale by using a really small value
}{
100 div
- }ifelse /TextHScaling gput settextstate} bdef
+ }ifelse .settexthscaling %/TextHScaling gput
+ settextstate} bdef
% ---------------- Font control ---------------- %
@@ -1080,7 +1171,7 @@ end readonly def
} {
pop
} ifelse
- /TextFont gput settextstate
+ setfont
} bdef
% Copy a font, removing its FID. If changed is true, also remove
@@ -1210,11 +1301,17 @@ end readonly def
( Output may be incorrect.\n) pdfformaterror
pop 0
} if
- TextLineMatrix transform TextLineMatrix 4 2 getinterval astore pop
- TextLineMatrix TextMatrix copy pop settextstate
+ matrix .currenttextlinematrix transform
+ matrix .currenttextlinematrix
+ dup 3 -1 roll 5 exch put
+ dup 3 -1 roll 4 exch put
+ .settextlinematrix
+ matrix .currenttextlinematrix .settextmatrix
+
+ settextstate
} bdef
-/TD { dup neg /TextLeading gput Td } bdef
-/T* { 0 TextLeading neg Td } bdef
+/TD { dup neg .settextleading Td } bdef
+/T* { 0 .currenttextleading neg Td } bdef
/Tm {
5 index 0 ne 3 index 0 ne and
5 index 0 ne 5 index 0 ne and or not {
@@ -1226,7 +1323,9 @@ end readonly def
0.00000001 0 0 0.00000001
6 -2 roll
}if
- TextLineMatrix astore TextMatrix copy pop settextstate
+ matrix .currenttextlinematrix astore .settextlinematrix
+ matrix .currenttextlinematrix .settextmatrix
+ settextstate
} bdef
% ---------------- Text painting ---------------- %
@@ -1329,8 +1428,8 @@ end readonly def
//false
}ifelse
{
- TextRenderingMode 1 eq TextRenderingMode 2 eq or
- TextRenderingMode 5 eq TextRenderingMode 6 eq or or {
+ .currenttextrenderingmode 1 eq .currenttextrenderingmode 2 eq or
+ .currenttextrenderingmode 5 eq .currenttextrenderingmode 6 eq or or {
setstrokestate
% Need to set the stroke width to a value which gives the correct
% width under pdfwrite. Pdfwrite uses (in text mode) an identity
@@ -1360,7 +1459,7 @@ end readonly def
/TextTransSetup { % showarg path_valid TextTransSetup false showarg
% showarg path_valid false TextTransSetup prev_BM prev_opacity true showarg
% NB: if 'show' is used, then we use the clippath, but a smaller bbox is preferred
- SoftMask //null ne {
+ .currentSMask //null ne {
dup mark /Subtype /Group /Isolated //true .dicttomark exch
{ pathbbox } { gsave clippath pathbbox grestore } ifelse
.begintransparencygroup
@@ -1385,13 +1484,15 @@ end readonly def
.endtransparencygroup
OPsavedict dup /saveOA get .setopacityalpha /saveBM get .setblendmode
} if
- SoftMask //null ne {
+ .currentSMask //null ne {
.endtransparencygroup
} if
} bind def
/setshowstate
- { WordSpacing 0 eq TextSpacing 0 eq and FontMatrixNonHV not and
+ {
+ .currentwordspacing 0 eq .currenttextspacing
+ 0 eq and FontMatrixNonHV not and
{
% Check to see if the current device supports Tr
/PreserveTrMode /GetDeviceParam .special_op {
@@ -1400,16 +1501,16 @@ end readonly def
//false
}ifelse
{
- pdfwrite_textrenderingprocs TextRenderingMode get
+ pdfwrite_textrenderingprocs .currenttextrenderingmode get
}
{
- TextRenderingMode 0 eq
- currentfont /FontType get 3 eq TextRenderingMode 3 eq not
+ .currenttextrenderingmode 0 eq
+ currentfont /FontType get 3 eq .currenttextrenderingmode 3 eq not
and or
{
{ settextfillstate //false TextTransSetup show TextTransTeardown }
} {
- TextRenderingMode 3 eq {
+ .currenttextrenderingmode 3 eq {
% Some PDF files execute 'tm' with a singular matrix,
% and then use the text rendering mode 3.
% The graphics library currently cannot handle text
@@ -1437,7 +1538,7 @@ end readonly def
moveto
}
} {
- { //false charpath textrenderingprocs TextRenderingMode get exec }
+ { //false charpath textrenderingprocs .currenttextrenderingmode get exec }
} ifelse
} ifelse
} ifelse
@@ -1446,7 +1547,7 @@ end readonly def
% If we are doing a plain old fill, or no text at all, *or* we are going to
% a device supporting text rendering modes, then go through this route.
%
- TextRenderingMode 0 eq TextRenderingMode 3 eq or
+ .currenttextrenderingmode 0 eq .currenttextrenderingmode 3 eq or
currentfont /FontType get 3 eq or
/PreserveTrMode /GetDeviceParam .special_op {
@@ -1455,7 +1556,7 @@ end readonly def
//false
}ifelse
% pdfwrite can't handle rendering modes which involve clipping
- TextRenderingMode 4 lt and or
+ .currenttextrenderingmode 4 lt and or
% Tr was set to graphic state.
{
FontMatrixNonHV {
@@ -1464,7 +1565,7 @@ end readonly def
currentlinewidth exch
setstrokeforTrpreservation
settextfillstate //false TextTransSetup
- [ TextSpacing WordSpacing 3 index
+ [ .currenttextspacing .currentwordspacing 3 index
{ % str [... weach wword c undef|ythis xthis|undef
exch % will be removed, unless FontMatrix.xx/yy == 0 (FontMatrixNonHV already true)
Vexch pop % str [... weach wword c wthis
@@ -1480,20 +1581,23 @@ end readonly def
setlinewidth TextTransTeardown
}
} {
- WordSpacing 0 eq {
+ .currentwordspacing
+ 0 eq {
{
{ setstrokeforTrpreservation
- settextfillstate //false TextTransSetup TextSpacing 0 Vexch 3 -1 roll ashow TextTransTeardown
+ settextfillstate //false TextTransSetup .currenttextspacing
+ 0 Vexch 3 -1 roll ashow TextTransTeardown
}
currentlinewidth
{ setlinewidth }
3 .execn
}
} {
- TextSpacing 0 eq {
+ .currenttextspacing 0 eq {
{ % preserve current line width around possible stroke setup
{ setstrokeforTrpreservation
- settextfillstate //false TextTransSetup WordSpacing 0 Vexch 32 4 -1 roll .pdfwidthshow
+ settextfillstate //false TextTransSetup .currentwordspacing
+ 0 Vexch 32 4 -1 roll .pdfwidthshow
TextTransTeardown
}
currentlinewidth
@@ -1503,8 +1607,9 @@ end readonly def
} {
{ % preserve current line width around possible stroke setup
{ setstrokeforTrpreservation
- settextfillstate //false TextTransSetup WordSpacing 0 Vexch 32
- TextSpacing 0 Vexch 6 -1 roll .pdfawidthshow TextTransTeardown
+ settextfillstate //false TextTransSetup .currentwordspacing
+ 0 Vexch 32
+ .currenttextspacing 0 Vexch 6 -1 roll .pdfawidthshow TextTransTeardown
}
currentlinewidth
{ setlinewidth }
@@ -1516,7 +1621,8 @@ end readonly def
}
{
{ currentlinewidth exch
- WordSpacing TextSpacing
+ .currentwordspacing
+ .currenttextspacing
% Implement the combination of t3 and false charpath.
% Note that we must use cshow for this, because we
% can't parse multi-byte strings any other way.
@@ -1543,7 +1649,7 @@ end readonly def
% or we wouldn't be here. Subtract 4 from the Tr and preserve
% that mode, then do a charpath so the clip path gets set up
% correctly.
- gsave TextRenderingMode 4 sub .settextrenderingmode
+ gsave .currenttextrenderingmode 4 sub .settextrenderingmode
setstrokeforTrpreservation
setstrokestate settextfillstate //false TextTransSetup dup show grestore TextTransTeardown } if
//false charpath
@@ -1569,7 +1675,7 @@ end readonly def
}{
//true
}ifelse {
- textrenderingprocs TextRenderingMode get exec
+ textrenderingprocs .currenttextrenderingmode get exec
} if
setlinewidth
}
@@ -1588,9 +1694,7 @@ end readonly def
OFFlevels length 0 eq {
exec
} {
- gsave get-gs-attrs nulldevice set-gs-attrs
- exec
- get-gs-attrs grestore set-gs-attrs
+ gsave nulldevice exec grestore
} ifelse
//true /TextFillStateNeeded gput
} bdef
@@ -1610,9 +1714,7 @@ end readonly def
OFFlevels length 0 eq {
exec
} {
- gsave get-gs-attrs nulldevice set-gs-attrs
- exec
- get-gs-attrs grestore set-gs-attrs
+ gsave nulldevice exec grestore
} ifelse
//true /TextFillStateNeeded gput
} bdef
@@ -1741,9 +1843,13 @@ end readonly def
2 0 moveto % start at bottom left of rect
counttomark 1 1 3 -1 roll { % for every string
pop gsave
- <FEFF> anchorsearch {
- pop
- } if
+ <EFBBBF> anchorsearch {
+ pop
+ } {
+ <FEFF> anchorsearch {
+ pop
+ } if
+ } ifelse
Show grestore % pop loop counter, show string (saving current point)
counttomark 1 add index 0 exch rmoveto % get line height, move that amount vertically.
} for
@@ -1755,9 +1861,13 @@ end readonly def
2 0 moveto % start at bottom left of rect
counttomark 1 1 3 -1 roll { % for every string
pop gsave % pop loop counter
- <FEFF> anchorsearch {
- pop
- } if
+ <EFBBBF> anchorsearch {
+ pop
+ } {
+ <FEFF> anchorsearch {
+ pop
+ } if
+ } ifelse
dup stringwidth pop counttomark 5 add index % get rectangle width
exch sub 2 div 0 rmoveto % subtract width of string, divide by 2 move that amount
Show grestore % show string
@@ -1770,9 +1880,13 @@ end readonly def
2 0 moveto % start at bottom left of rect
counttomark 1 1 3 -1 roll { % for every string
pop gsave % pop loop counter
- <FEFF> anchorsearch {
+ <EFBBBF> anchorsearch {
pop
- } if
+ } {
+ <FEFF> anchorsearch {
+ pop
+ } if
+ } ifelse
dup stringwidth pop counttomark 5 add index % get rectangle width
exch sub 2 sub 0 rmoveto % subtract width of string,move that amount
Show grestore % show string
@@ -1790,9 +1904,13 @@ end readonly def
0 exch moveto % MaxLen (V) Ff Q dx
1 index 0 ne {
3 index
- <FEFF> anchorsearch {
- pop
- } if
+ <EFBBBF> anchorsearch {
+ pop
+ } {
+ <FEFF> anchorsearch {
+ pop
+ } if
+ } ifelse
stringwidth pop % MaxLen (V) Ff Q dx w
sub exch 1 eq { 2 div } { 2 sub } ifelse % MaxLen (V) Ff (dx-w)/2
0 rmoveto % MaxLen (V) Ff
@@ -1802,9 +1920,13 @@ end readonly def
2 0 rmoveto
} ifelse
exch pop
- <FEFF> anchorsearch {
+ <EFBBBF> anchorsearch {
pop
- } if
+ } {
+ <FEFF> anchorsearch {
+ pop
+ } if
+ } ifelse
Show % -
} ifelse
} ifelse