diff options
Diffstat (limited to 'Master/xemtex/gslib/pdf_ops.ps')
-rw-r--r-- | Master/xemtex/gslib/pdf_ops.ps | 521 |
1 files changed, 521 insertions, 0 deletions
diff --git a/Master/xemtex/gslib/pdf_ops.ps b/Master/xemtex/gslib/pdf_ops.ps new file mode 100644 index 00000000000..4c98a7f23b7 --- /dev/null +++ b/Master/xemtex/gslib/pdf_ops.ps @@ -0,0 +1,521 @@ +% Copyright (C) 1994, 2000 Aladdin Enterprises. All rights reserved. +% +% This program is free software; you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by the +% Free Software Foundation; either version 2 of the License, or (at your +% option) any later version. +% +% This program is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +% Public License for more details. +% +% You should have received a copy of the GNU General Public License along +% with this program; if not, write to the Free Software Foundation, Inc., +% 59 Temple Place, Suite 330, Boston, MA, 02111-1307. + +% $Id: pdf_ops.ps,v 1.17.2.2.2.1 2003/04/12 14:02:39 giles Exp $ +% Definitions for most of the PDF operators. + +.currentglobal true .setglobal + +% Define pdfmark. Don't allow it to be bound in. +% Also don't define it in systemdict, because this leads some Adobe code +% to think this interpreter is a distiller. +% (If this interpreter really is a distiller, don't do this.) +systemdict /pdfmark known not + { userdict /pdfmark { cleartomark } bind put } if + +userdict /GS_PDF_ProcSet 127 dict dup begin + +% ---------------- Abbreviations ---------------- % + +/bdef { bind def } bind def + +% ---------------- Graphics state stack ---------------- % + +% PDF adds a number of parameters to the graphics state. +% We implement this by pushing and popping a dictionary +% each time we do a PDF gsave or grestore. +% The keys in this dictionary are as follows: +% self % identifies the dictionary as one of ours +% ClipRect % (optional) +% Show +% TextSaveMatrix % matrix at time of BT (iff within BT/ET) +% (The following correspond directly to PDF state parameters.) +% AlphaIsShape +% FillConstantAlpha +% FillColor +% FillColorSpace +% FillOverprint +% SoftMask +% StrokeConstantAlpha +% StrokeColor +% StrokeColorSpace +% StrokeOverprint +% TextSpacing +% TextHScaling +% Leading +% TextFont +% TextLineMatrix +% TextMatrix +% TextRise +% TextRenderingMode +% WordSpacing + +/nodict 1 dict def +nodict /self { //nodict } executeonly put +nodict readonly pop + +/dictbeginpage { % <initialdict> dictbeginpage - + //nodict 20 dict .copydict begin { def } forall + graphicsbeginpage textbeginpage +} bdef +/endpage { % - endpage - + showpage end +} bdef + +/graphicsbeginpage { + initgraphics + currentdict /ClipRect .knownget { aload pop rectclip } if + 0 g 0 G false op false OP 0 OPM + 1 ca 1 CA null SMask false AIS /Compatible BM true TK +} bdef + +/gput % <value> <key> gput - + { exch currentdict //nodict eq { /self dup load end 5 dict begin def } if + % If we're in a Level 1 system, we need to grow the + % dictionary explicitly. + currentdict length currentdict maxlength ge %eq + { currentdict dup length 3 mul 2 idiv 1 add dict .copydict end begin + } + if def + } bdef + +/q { + gsave //nodict begin +} bdef +% Some PDF files have excess Q operators! +/Q { + currentdict /self .knownget { exec //nodict eq { end grestore } if } if +} bdef + +% ---------------- Color setting ---------------- % + +/fcput % <color> <colorspace> fcput - + { /FillColorSpace gput /FillColor gput + } bdef +/scput % <color> <colorspace> scput - + { /StrokeColorSpace gput /StrokeColor gput + } bdef + +/csdevgray [/DeviceGray] readonly def +/csdevrgb [/DeviceRGB] readonly def +/csdevcmyk [/DeviceCMYK] readonly def +/cspattern [/Pattern] readonly def +/nullpattern1 mark + /PatternType 1 /PaintType 1 /TilingType 3 /BBox [0 0 0 0] + /XStep 1 /YStep 1 /PaintProc { } +.dicttomark readonly def +/nullpattern2 nullpattern1 dup length dict copy readonly def + +% Each entry in the color space dictionary is a procedure of the form +% <cspace> -proc- <cspace> <initial-color> +/CSdict mark + /DeviceGray { pop //csdevgray 0 } bind + /DeviceRGB { pop //csdevrgb [0 0 0] cvx } bind + /DeviceCMYK { pop //csdevcmyk [0 0 0 1] cvx } bind + /CIEBasedA { 0 } bind + /CIEBasedABC { [0 0 0] cvx } bind + /ICCBased { [ 1 index 1 oget /N get { 0 } repeat ] cvx } bind + /Separation { 1 } bind + /DeviceN { % What is the correct value?? + [ 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 //nullpattern1 matrix makepattern + } { + //nullpattern2 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 +.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 +/cs { csset fcput } bdef +/CS { csset scput } bdef +/ri { pop } bdef +% We have to break up sc according to the number of operands. +/sc1 { /FillColor gput } 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 length array astore cvx /FillColor gput + } ifelse +} bdef +/SC* { + currentdict /StrokeColor .knownget { + astore pop + } { + /StrokeColor load length array astore cvx /StrokeColor gput + } ifelse +} bdef + +% ---------------- Overprint/transparency setting ---------------- % + +/op { /FillOverprint gput } bdef +/OP { /StrokeOverprint gput } bdef +/OPM { + /.setoverprintmode where { pop .setoverprintmode } { pop } ifelse +} bdef +/ca { /FillConstantAlpha gput } bdef +/CA { /StrokeConstantAlpha gput } bdef +/SMask { /SoftMask gput } bdef +/AIS { /AlphaIsShape gput } bdef +/BM { + /.setblendmode where { + pop [ exch dup type /nametype ne { aload pop } if /Normal ] { + { .setblendmode } .internalstopped not { exit } if pop + } forall + } { + pop + } ifelse +} bdef +/TK { + /.settextknockout where { pop .settextknockout } { pop } ifelse +} bdef + +% ---------------- Color installation ---------------- % + +% Establish a given color (and color space) as current. +/.settransparencyparams { % <alpha> <smask> .settransparencyparams - + /.begintransparencymask where { + pop AlphaIsShape { + 1 .setopacityalpha 0 .inittransparencymask exch .setshapealpha 1 + } { + 1 .setshapealpha 1 .inittransparencymask exch .setopacityalpha 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 + } ifelse +} bdef +/.settransparencymask { % <paramdict> <masknum> .settransparencymask - + exch dup null eq { + pop .inittransparencymask + } { + dup /Draw get exec + } ifelse +} bdef +% (Non-mask) images must execute setfillblend. +/setfillblend { + FillOverprint setoverprint + FillConstantAlpha SoftMask .settransparencyparams +} def +/setfillstate { + FillColor FillColorSpace setgcolor setfillblend +} def +/setstrokestate { + StrokeColor StrokeColorSpace setgcolor StrokeOverprint setoverprint + StrokeConstantAlpha SoftMask .settransparencyparams +} def +/Cdict 15 dict dup begin % <color...> <colorspace> -proc- - + /DeviceGray { pop setgray } bdef + /DeviceRGB { pop setrgbcolor } bdef + /DeviceCMYK { pop setcmykcolor } bdef + /CIEBasedA + { dup currentcolorspace eq { pop } { setcolorspace } ifelse setcolor } bdef + /CIEBasedABC /CIEBasedA load def + /CIEBasedDEF /CIEBasedA load def + /CIEBasedDEFG /CIEBasedA load def + /ICCBased /CIEBasedA load def + /Separation /CIEBasedA load def + /DeviceN /CIEBasedA load def + /Indexed /CIEBasedA load def + /Pattern + { dup currentcolorspace eq { pop } { setcolorspace } ifelse + dup /Matrix .knownget not { matrix } if + gsave DefaultMatrix setmatrix makepattern grestore setcolor + } bdef +end def +/setgcolor % (null | <color...>) <colorspace> setgcolor - + { 1 index null eq + { pop pop } + { dup 0 get //Cdict exch get exec } + ifelse + } bdef +/fsexec % <fillop|strokeop> fsexec - + { % Preserve the current point, if any. + { currentpoint } stopped + { $error /newerror false put cvx exec } + { 3 -1 roll cvx exec moveto } + ifelse + } bdef + +% ---------------- Path painting and clipping ---------------- % + +/S { setstrokestate /stroke fsexec } bdef +/f { setfillstate /fill fsexec } bdef +/f* { setfillstate /eofill fsexec } bdef +/n { newpath } bdef % don't allow n to get bound in +/s { closepath S } bdef +/B { gsave setfillstate fill grestore S } bdef +/b { closepath B } bdef +/B* { gsave setfillstate eofill grestore S } bdef +/b* { closepath B* } bdef + +% Clipping: + +/Wdict 4 dict dup begin +/S { gsave setstrokestate stroke grestore n } bdef +/f { gsave setfillstate fill grestore n } bdef +/f* { gsave setfillstate eofill grestore n } bdef +/n { end clip newpath } bdef +end readonly def +/W { //Wdict begin } bdef +/W*dict 4 dict dup begin +Wdict { def } forall +/n { end eoclip 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 + /Show { showfirst } def + } bdef + +% Contrary to the statement in the PDF manual, BT and ET *can* be nested, +% if the CharProc for a Type 3 font does a BT/ET itself. +% Since we always call the CharProc inside a q/Q, we simply ensure that +% the text state is saved and restored like the rest of the extended +% graphics state. + +/settextmatrix { + TextMatrix concat + TextHScaling 1 ne { TextHScaling 1 scale } if + TextRise 0 ne { 0 TextRise translate } if + TextFont dup null eq { pop } { setfont } ifelse +} bdef +/settextstate { + % The text state can be set even outside BT/ET. + currentdict /TextSaveMatrix known { + TextSaveMatrix setmatrix settextmatrix + } if +} bdef +/settextposition { + % Update the TextMatrix translation. + gsave TextSaveMatrix setmatrix + currentpoint TextMatrix 4 2 getinterval astore pop + % 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 +} bdef + +/BT { + currentdict /TextLineMatrix .knownget + { identmatrix pop TextMatrix identmatrix pop } + { matrix /TextLineMatrix gput matrix /TextMatrix gput } + ifelse + { showfirst } /Show gput + currentdict /TextSaveMatrix .knownget not { + matrix dup /TextSaveMatrix gput + } if currentmatrix pop settextmatrix + matrix /TextTempMatrix gput % see settextposition +} bdef +/ET { + TextRenderingMode 4 ge { clip newpath } if + TextSaveMatrix setmatrix + currentdict /TextSaveMatrix undef +} bdef +/Tc { /TextSpacing gput { showfirst } /Show gput } bdef +/TL { /TextLeading gput } bdef +/Tr { /TextRenderingMode gput { showfirst } /Show gput } bdef +/Ts { /TextRise gput settextstate } bdef +/Tw { /WordSpacing gput { showfirst } /Show gput } bdef +/Tz { 100 div /TextHScaling gput settextstate} bdef + +% ---------------- Font control ---------------- % + +/Tf { % <font> <scale> Tf - + dup 1 eq { pop } { scalefont } ifelse + /TextFont gput settextstate +} bdef + +% Read a CFF font. +/FRD % <resname> <file> FRD - + { /FontSetInit /ProcSet findresource begin true ReadData + } bdef + +% Copy a font, removing its FID. If changed is true, also remove +% the UniqueID and XUID, if any. If the original dictionary doesn't have +% the keys being removed, don't copy it. +/.copyfontdict % <font> <changed> .copyfontdict <dict> + { 1 index /FID known + 1 index { 2 index /UniqueID known or 2 index /XUID known or } if + { % 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 4 index + { 2 index /UniqueID eq or 2 index /XUID eq or } + if not { 3 copy put } if pop pop + } + forall exch + } + if pop + } bdef + +% Insert a new Encoding or Metrics into a font if necessary. +% Return a possibly updated font, and a flag to indicate whether +% the font was actually copied. +/.updatefontmetrics { % <font> <Metrics|null> .updatefontmetrics + % <font'> <copied> + dup null ne { + exch true .copyfontdict dup /Metrics 4 -1 roll put true + } { + pop false + } ifelse +} bdef +/.updatefontencoding { % <font> <Encoding|null> .updatefontencoding + % <font'> <copied> + dup null ne { dup 2 index /Encoding get ne } { false } ifelse { + exch false .copyfontdict dup /Encoding 4 -1 roll put true + } { + pop false + } ifelse +} bdef +/.updatefont { % <font> <Encoding|null> <Metrics|null> .updatefont + % <font'> <copied> + 3 -1 roll exch .updatefontmetrics + % Stack: enc|null font' copied + 3 1 roll exch .updatefontencoding 3 -1 roll or +} bdef + +% ---------------- Text positioning ---------------- % + +/Td { + TextLineMatrix transform TextLineMatrix 4 2 getinterval astore pop + TextLineMatrix TextMatrix copy pop settextstate +} bdef +/TD { dup neg /TextLeading gput Td } bdef +/T* { 0 TextLeading neg Td } bdef +/Tm { + TextLineMatrix astore TextMatrix copy pop settextstate +} bdef + +% ---------------- Text painting ---------------- % + +/Vexch { + rootfont /WMode .knownget { 1 eq { exch } if } if +} bind def + +/textrenderingprocs [ % (0 is handled specially) + % Painting-only modes + { tf } { tS } { tB } { tn } + % Clipping modes + { gsave tf grestore tW } + { gsave tS grestore tW } + { gsave tB grestore tW } + { tW } +] readonly def +/setshowstate + { WordSpacing 0 eq TextSpacing 0 eq and + { TextRenderingMode 0 eq + { { setfillstate show } } + { { false charpath textrenderingprocs TextRenderingMode get exec } } + ifelse + } + { TextRenderingMode 0 eq + { WordSpacing 0 eq + { { setfillstate TextSpacing 0 Vexch 3 -1 roll ashow } } + { TextSpacing 0 eq + { { setfillstate WordSpacing 0 Vexch 32 4 -1 roll widthshow } } + { { setfillstate WordSpacing 0 Vexch 32 + TextSpacing 0 Vexch 6 -1 roll awidthshow } } + ifelse + } + ifelse + } + { { WordSpacing TextSpacing + % 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. + % Stack: string xword xchar + { pop pop (x) dup 0 3 index put false charpath + % Stack: xword xchar ccode + 3 copy 32 eq { add } { exch pop } ifelse 0 Vexch rmoveto pop + } + 4 -1 roll cshow pop pop + textrenderingprocs TextRenderingMode get exec + } + } + ifelse + } + ifelse /Show gput + } bdef +/showfirst { setshowstate Show } def + +/Tj { + 0 0 moveto Show settextposition +} bdef +/' { T* Tj } bdef +/" { exch Tc exch Tw T* Tj } bdef +/TJ { + 0 0 moveto { + dup type /stringtype eq { + Show + } { -1000 div + currentfont /ScaleMatrix .knownget { 0 get mul } if + 0 Vexch rmoveto + } ifelse + } forall settextposition +} bdef + +/tf { setfillstate currentpoint fill moveto } bdef +/tn { currentpoint newpath moveto } bdef +% For stroking characters, temporarily restore the graphics CTM so that +% the line width will be transformed properly. +/Tmatrix matrix def +/tS + { setstrokestate + currentpoint //Tmatrix currentmatrix TextSaveMatrix setmatrix stroke + setmatrix moveto + } bdef +/tB { gsave tf grestore tS } bdef +% This does the wrong thing if there have been multiple text operations +% within a single BT/ET pair, but it's a start. +/tW { } bdef + +end readonly put % GS_PDF_ProcSet + +.setglobal |