diff options
Diffstat (limited to 'Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps')
-rw-r--r-- | Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps | 347 |
1 files changed, 164 insertions, 183 deletions
diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps index d594035c066..47ff512d927 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps @@ -1,4 +1,4 @@ -% Copyright (C) 2001-2019 Artifex Software, Inc. +% Copyright (C) 2001-2020 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or @@ -279,8 +279,8 @@ currentdict /gput_always_allow .undef /DeviceCMYK { [0 0 0 1] cvx } bind executeonly /CIEBasedA { 0 } bind executeonly /CIEBasedABC { [0 0 0] cvx } bind executeonly - /CalGray { pop /DeviceGray 0 } bind executeonly - /CalRGB { pop /DeviceRGB [0 0 0] cvx } bind executeonly + /CalGray { 0 } bind executeonly + /CalRGB { [0 0 0] cvx } bind executeonly /Lab {[0 0 0] cvx } bind executeonly /ICCBased { [ 1 index 1 oget /N get { 0 } repeat ] cvx } bind executeonly /Separation { 1 } bind executeonly @@ -304,7 +304,6 @@ currentdict /gput_always_allow .undef 4 2 roll //CSdict exch get exec exch .setfillcolorspace exec {.setfillcolor} stopped { - (error) == flush cleartomark [//null /DeviceGray //null /DeviceRGB /DeviceCMYK] exch {get} stopped @@ -483,19 +482,19 @@ currentdict /gput_always_allow .undef % ---------------- Color installation ---------------- % % Establish a given color (and color space) as current. -/.settransparencyparams { % <alpha> <smask> .settransparencyparams - +/.settransparencyparams { % <smask> .settransparencyparams - PDFusingtransparency { .currentalphaisshape { - 1 .setopacityalpha exch .setshapealpha 1 + 1 } { - 1 .setshapealpha exch .setopacityalpha 0 + 0 } ifelse % Set the soft mask by rendering the XObject. Doing this every time % is obviously very inefficient; we'll improve it later. .settransparencymask } { - pop pop + pop } ifelse } bind executeonly def /.settransparencymask { % <paramdict> <masknum> .settransparencymask - @@ -517,16 +516,7 @@ currentdict /gput_always_allow .undef } ifelse } ifelse } bind executeonly def -% (Non-mask) images must execute setfillblend. -/setfillblend { - .currentfillconstantalpha - .currentSMask .settransparencyparams -} bind executeonly def -/setfillstate { - setfillblend -} bind executeonly def -/setstrokestate { - .currentstrokeconstantalpha +/setsmaskstate { .currentSMask .settransparencyparams } bind executeonly def /Cdict 15 dict dup begin % <color...> <colorspace> -proc- - @@ -673,12 +663,12 @@ end def } ifelse } bind executeonly def -/OPsaveDstack 6 dict def % for GroupPushed, saveOP, saveSA, saveBM +/OPsaveDstack 6 dict def % for GroupPushed, saveOP, saveFillAlpha, saveBM //OPsaveDstack begin /GroupPushed //false def /ChangeBM //false def - /saveOA 1 def - /saveSA 1 def + /saveStrokeAlpha 1 def + /saveFillAlpha 1 def /saveBM /Normal def /previous 1 dict def % for nested setup_trans levels end @@ -694,14 +684,14 @@ end /okOPcs mark /DeviceGray 0 /DeviceCMYK 1 /DeviceN 2 /Separation 3 .dicttomark def % Take care of pushing a transparency group if we need it for SMask or for Overprint.. -% After pushing the group, we save the opacityalpha and shapealpha and change them +% After pushing the group, we save the ca and CA and change them % both to 1. For overprint if the colorspace is acceptable, also change to % CompatibleOverprint if the device needs it. % NB: setup_trans is defined as either setupOPtrans (for devices that can support % overprint, or as setupSMtrans which pushes a group for SMask. % Also see 'teardown_trans' that pops the group and resets the changed values. -/setupOPtrans % <fillop|strokeop> setup_trans +/setupOPtrans % [ pathbbox ] <fillop|strokeop> setup_trans { % Check OP and BM in case we need to push a group //OPsaveDstack begin //Dpush exec % push the current OPsaveDstack values into 'previous' @@ -719,52 +709,46 @@ end } ifelse .currentSMask //null ne or { % push a group for OP or SMask mark /Subtype /Group /Isolated .currentSMask //null ne .dicttomark - 1 index /stroke eq { - % BBox needs to include line width / line join expansion. - gsave strokepath pathbbox grestore - } { - pathbbox % fill/eofill cases - } ifelse + 2 index aload pop % pathbbox .begintransparencygroup - % After group pushed, set opacityalpha, shapealpha and blendmode - /saveOA .currentopacityalpha def - /saveSA .currentshapealpha def - 1 .setopacityalpha 1 .setshapealpha + % After group pushed, set alphas and blendmode + /saveStrokeAlpha .currentstrokeconstantalpha def + /saveFillAlpha .currentfillconstantalpha def + 1 .setfillconstantalpha 1 .setstrokeconstantalpha /GroupPushed //true def - } if + } { + /GroupPushed //false def + } ifelse % we may change to CompatibleOverprint even if we didn't push a group. ChangeBM { /saveBM .currentblendmode def /CompatibleOverprint .setblendmode } if pop % fillop/strokeop + pop % pathbbox array end % OPsaveDstack } bind executeonly def % Also see 'teardown_trans' that pops the group and resets the changed values. -/setupSMtrans % <fillop|strokeop> setup_trans +/setupSMtrans % [ pathbbox ] <fillop|strokeop> setup_trans { //OPsaveDstack begin //Dpush exec % push the current OPsaveDstack values into 'previous' .currentSMask //null ne 1 index /image ne and % only push for SMask if not from image { mark /Subtype /Group /Isolated //true .dicttomark - exch /stroke eq { - % BBox needs to include line width / line join expansion. - gsave strokepath pathbbox grestore - } { - pathbbox % fill/eofill cases - } ifelse + 2 index aload pop % pathbbox .begintransparencygroup - % After group pushed, set opacityalpha, shapealpha and blendmode - /saveOA .currentopacityalpha def - /saveSA .currentshapealpha def - 1 .setopacityalpha 1 .setshapealpha + % After group pushed, set alphas and blendmode + /saveStrokeAlpha .currentstrokeconstantalpha def + /saveFillAlpha .currentfillconstantalpha def + 1 .setfillconstantalpha 1 .setstrokeconstantalpha /GroupPushed //true def } { /GroupPushed //false def - pop % fillop/strokeop } ifelse end % OPsaveDstack + pop % fillop/strokeop + pop % pathbbox array } bind executeonly def % If a transparency group was pushed, pop it, and reset the settings. @@ -772,9 +756,9 @@ end /teardown_trans { //OPsaveDstack begin GroupPushed { - % pop the group, then restore the opacityalpha and shapealpha + % pop the group, then restore the alphas .endtransparencygroup % end the group - saveOA .setopacityalpha saveSA .setshapealpha + saveStrokeAlpha .setstrokeconstantalpha saveFillAlpha .setfillconstantalpha } if % Also, if we changed the BM, restore it (AFTER the group was popped) .currentblendmode /CompatibleOverprint eq { @@ -791,9 +775,23 @@ currentdict dup /Dpush .undef /Dpop .undef /fsexec % <fillop|strokeop> fsexec - { PDFusingtransparency { - dup setup_trans - cvx exec - teardown_trans + dup /stroke eq 1 index /.fillstroke eq or 1 index /.eofillstroke eq or { + % BBox needs to include line width / line join expansion. + % strokepath will return empty path (no currentpoint) if nothing is stroked + { gsave strokepath pathbbox } stopped grestore { + % If we get an error, just emit an empty box + 0 0 0 0 + } if + } { + % If we get an error, just emit an empty box + { pathbbox } stopped { 0 0 0 0 } if + } ifelse + % pathbbox valid -- proceed with drawing + 4 array astore % pathbbox + 1 index + setup_trans + cvx exec + teardown_trans } { cvx exec } ifelse @@ -896,7 +894,7 @@ currentdict dup /Dpush .undef /Dpop .undef /S { OFFlevels length 0 eq { - setstrokestate .swapcolors /stroke fsexec .swapcolors + setsmaskstate .swapcolors /stroke fsexec .swapcolors } { newpath } ifelse @@ -904,7 +902,7 @@ currentdict dup /Dpush .undef /Dpop .undef /f { OFFlevels length 0 eq { - setfillstate /fill fsexec + setsmaskstate /fill fsexec } { newpath } ifelse @@ -912,7 +910,7 @@ currentdict dup /Dpush .undef /Dpop .undef /f* { OFFlevels length 0 eq { - setfillstate /eofill fsexec + setsmaskstate /eofill fsexec } { newpath } ifelse @@ -924,23 +922,7 @@ currentdict dup /Dpush .undef /Dpop .undef /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 + setsmaskstate /.fillstroke fsexec } { newpath } ifelse @@ -950,23 +932,7 @@ currentdict dup /Dpush .undef /Dpop .undef /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 + setsmaskstate /.eofillstroke fsexec } { newpath } ifelse @@ -977,54 +943,19 @@ currentdict dup /Dpush .undef /Dpop .undef % Clipping: /Wdict 8 dict dup begin -/S { OFFlevels length 0 eq { gsave setstrokestate .swapcolors stroke .swapcolors grestore } if n } bind executeonly def -/f { OFFlevels length 0 eq { gsave setfillstate fill grestore } if n } bind executeonly def -/f* { OFFlevels length 0 eq { gsave setfillstate eofill grestore } if n } bind executeonly def +/S { OFFlevels length 0 eq { gsave setsmaskstate .swapcolors stroke .swapcolors grestore } if n } bind executeonly def +/f { OFFlevels length 0 eq { gsave setsmaskstate fill grestore } if n } bind executeonly def +/f* { OFFlevels length 0 eq { gsave setsmaskstate eofill grestore } if n } bind executeonly def /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 + .fillstroke } if n } bind executeonly def /b { closepath B } bind executeonly def /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 + .eofillstroke } if n } bind executeonly def @@ -1213,15 +1144,25 @@ end readonly def %% can come into pdf_text_begin with an opacity not equal to 1. PDFusingtransparency .currenttextknockout and currentdict /illegal_BT get not and -{ + { .begintransparencytextgroup } if } bind executeonly def +/clip_if_required { + .currenttextrenderingmode 4 ge + {currentpoint} //.internalstopped exec + {//false} + {pop pop //true} + ifelse and + { .currentfilladjust2 0 dup .setfilladjust2 clip .setfilladjust2} if + newpath +} bind def + /ET_NO_TXT_KO { currentdict /TextSaveMatrix known { - .currenttextrenderingmode 4 ge { .currentfilladjust2 0 dup .setfilladjust2 clip .setfilladjust2 newpath} if + //clip_if_required exec TextSaveMatrix setmatrix currentdict /TextSaveMatrix undef @@ -1244,6 +1185,8 @@ end readonly def } if } bind executeonly def +currentdict /clip_if_required .undef + /ET { //ET_NO_TXT_KO exec % Group push occurred in pdf14_text_begin. @@ -1252,7 +1195,17 @@ end readonly def } if } bind executeonly def -/Tc { .settextspacing { showfirst } /Show gput } bind executeonly def +/Tc { + {.settextspacing} stopped + { + (\n **** Error: A ) pdfformaterror + $error /errorname get 256 string cvs pdfformaterror + ( error occured while setting the Text Character spacing to ) pdfformaterror + 256 string cvs pdfformaterror + (\n Output may be incorrect.\n) pdfformaterror + } if + { showfirst } /Show gput +} bind executeonly def /TL { .settextleading } bind executeonly def /Tr { .settextrenderingmode { showfirst } /Show gput } bind executeonly def /Ts { .settextrise settextstate } bind executeonly def @@ -1375,10 +1328,10 @@ end readonly def { % We add 1 to the length just in case the original % didn't have a FID. exch dup length 1 add dict exch - { % Stack: changed newfont key value - 1 index /FID eq - not { 3 copy put } if pop pop - } + { % Stack: changed newfont key value + 1 index /FID eq + not { 3 copy put } if pop pop + } forall exch } if pop @@ -1518,9 +1471,9 @@ end readonly def /pdfwrite_textrenderingprocs [ % Tr 0 - Fill - { setfillstate show } bind executeonly + { setsmaskstate show } bind executeonly % Tr 1 - Stroke - { currentlinewidth exch setstrokestate + { currentlinewidth exch setsmaskstate % Need to set the stroke width to a value which gives the correct % width under pdfwrite. Pdfwrite uses (in text mode) an identity % CTM, so we need to calculate the stroke width which would result @@ -1540,7 +1493,7 @@ end readonly def }ifelse setlinewidth show setlinewidth} bind executeonly % Tr 2 - Fill then Stroke - { currentlinewidth exch setstrokestate + { currentlinewidth exch setsmaskstate % Need to set the stroke width to a value which gives the correct % width under pdfwrite. Pdfwrite uses (in text mode) an identity % CTM, so we need to calculate the stroke width which would result @@ -1558,9 +1511,9 @@ end readonly def % we can ignore it. (wrong answer, but consistent) pop pop currentlinewidth }ifelse setlinewidth - setfillstate show setlinewidth} bind executeonly + setsmaskstate show setlinewidth} bind executeonly % Tr 3 - Neither fill nor stroke - { setfillstate show } bind executeonly + { setsmaskstate show } bind executeonly % % pdfwrite emits all text inside a gsave/grestore pair. As % a result we can't preserve any of the 'clip' modes, as the @@ -1569,7 +1522,7 @@ end readonly def % % Tr 4 - Fill, add to clip { gsave 0 .settextrenderingmode - setfillstate dup show grestore //true charpath } bind executeonly + setsmaskstate dup show grestore //true charpath } bind executeonly % Tr 5 - Stroke, add to clip { gsave 1 .settextrenderingmode currentlinewidth dup @@ -1581,7 +1534,7 @@ end readonly def % we can ignore it. (wrong answer, but consistent) pop pop currentlinewidth }ifelse setlinewidth - setstrokestate dup show grestore + setsmaskstate dup show grestore //true charpath} bind executeonly % Tr 6 - Fill, stroke, add to clip { gsave 2 .settextrenderingmode @@ -1598,7 +1551,7 @@ end readonly def % we can ignore it. (wrong answer, but consistent) pop pop currentlinewidth }ifelse setlinewidth - setstrokestate setfillstate dup show grestore + setsmaskstate dup show grestore //true charpath} bind executeonly % Tr 7 - Add to clip { //true charpath} bind executeonly @@ -1614,7 +1567,7 @@ end readonly def { .currenttextrenderingmode 1 eq .currenttextrenderingmode 2 eq or .currenttextrenderingmode 5 eq .currenttextrenderingmode 6 eq or or { - setstrokestate + setsmaskstate % Need to set the stroke width to a value which gives the correct % width under pdfwrite. Pdfwrite uses (in text mode) an identity % CTM, so we need to calculate the stroke width which would result @@ -1636,14 +1589,25 @@ end readonly def % conditionally set fillstate to avoid multiple operations during text operators /settextfillstate { - TextFillStateNeeded { setfillstate //false /TextFillStateNeeded gput } if + TextFillStateNeeded { setsmaskstate //false /TextFillStateNeeded gput } if } bind executeonly def % If current path is not known to be valid, use the clip path /TextTransSetup { % showarg path_valid TextTransSetup showarg % showarg path_valid false TextTransSetup showarg + gsave % NB: if 'show' is used, then we use the clippath, but a smaller bbox is preferred - not dup { gsave clippath } if //null setup_trans { grestore } if + { + % path was (probably) valid (CTM may not be invertable) + % Since TR mode may include stroking, expand for stroke + % If we get an error, just emit an empty box + { strokepath pathbbox } stopped { 0 0 0 0 } if + } { + clippath pathbbox stopped { 0 0 0 0 } if + } ifelse + grestore + 4 array astore //null + setup_trans } bind executeonly def /TextTransTeardown { @@ -1678,25 +1642,35 @@ end readonly def % operations when the CTM is singular. % Work around this here. { - matrix currentmatrix dup dup - dup 0 get 0 eq 1 index 1 get 0 eq and { - dup dup 2 get 0 eq { 0 }{ 1 } ifelse 1 put - } if - dup 2 get 0 eq 1 index 3 get 0 eq and { - dup dup 1 get 0 eq { 3 }{ 2 } ifelse 1 put - } if - setmatrix - currentpoint - % don't worry about transparency for invisible text - 4 index settextfillstate show % Tr was set to graphic state. - moveto - setmatrix - % now set the currentpoint using the original matrix - gsave - setmatrix - //false charpath currentpoint newpath - grestore - moveto + matrix currentmatrix + % Previously we tested specifically for a scale factor of 0, + % but bug #701875 has a CTM which is minute, but not zero. If + % we try to use that at anything except low resolution FreeType + % ends up trying to deal with glyph metrics where one dimension is 0 + % and it throws an error. So instead of looking for zero, we'll look + % for a really tiny CTM. + % We also used to patch up the CTM, and still use it, but frankly + % this is too much trouble. If the CTM is tiny then the displacement + % due to drawing the text will also be tiny. Negligible in fact. + % So if its that small then lets just ignore it. + dup 0 get abs 0.00001 lt 1 index 1 get 0.00001 abs lt and not { + dup 2 get abs 0.00001 lt 1 index 3 get abs 0.00001 lt and not { + pop + currentpoint + % don't worry about transparency for invisible text + 2 index settextfillstate show % Tr was set to graphic state. + moveto + % now set the currentpoint using the original matrix + gsave + //false charpath currentpoint newpath + grestore + moveto + } { + pop pop + }ifelse + } { + pop pop + }ifelse } } { { //false charpath textrenderingprocs .currenttextrenderingmode get exec } @@ -1812,7 +1786,7 @@ end readonly def % correctly. gsave .currenttextrenderingmode 4 sub .settextrenderingmode setstrokeforTrpreservation - setstrokestate settextfillstate //false TextTransSetup dup show grestore TextTransTeardown } if + setsmaskstate settextfillstate //false TextTransSetup dup show grestore TextTransTeardown } if //false charpath 3 copy 32 eq { add } { exch pop } ifelse % Stack: str wthis xorig yorig wword wchar ccode wextra @@ -1899,7 +1873,7 @@ end readonly def } { .currentPDFfontsize 0 eq not { - setstrokestate //true TextTransSetup + setsmaskstate //true TextTransSetup currentpoint //Tmatrix currentmatrix TextSaveMatrix setmatrix currentdict /qTextSaveMatrix known {qTextSaveMatrix setmatrix} if .swapcolors stroke TextTransTeardown .swapcolors @@ -1911,22 +1885,29 @@ end readonly def % Handle transparency the same as /B operator /tB { - PDFusingtransparency { - % knockout trans group around the filled and stroked object - mark - /Isolated //true /Knockout //true - .dicttomark - 1 .setopacityalpha - % While text will always have a currentpoint, strokepath seems to mess with it. - % we get the currentpoint, then use moveto to restore it for pathbbox - gsave currentpoint strokepath moveto pathbbox grestore - .begintransparencygroup - gsave tf grestore tS - .endtransparencygroup - } { - gsave tf grestore tS - } ifelse - //true /TextFillStateNeeded gput + % Type 3 fonts don't honour text rendering modes, see note on p401 of the 1.7 PDF Reference + currentfont /FontType get 3 eq + { + settextfillstate //true TextTransSetup currentpoint fill TextTransTeardown moveto + } + { + % Don't try to draw text when the point size is 0 + .currentPDFfontsize 0 eq not { + setsmaskstate settextfillstate + % While text will always have a currentpoint, strokepath seems to mess with it. + % we get the currentpoint, then use moveto to restore it. + currentpoint + + % For stroking characters, temporarily restore the graphics CTM so that + % the line width will be transformed properly. + //Tmatrix currentmatrix TextSaveMatrix setmatrix + currentdict /qTextSaveMatrix known {qTextSaveMatrix setmatrix} if + B + setmatrix + moveto + } if + } ifelse + //true /TextFillStateNeeded gput } bind executeonly def % This does the wrong thing if there have been multiple text operations |