123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- % Copyright (C) 1994, 2000 Aladdin Enterprises. All rights reserved.
- %
- % This file is part of AFPL Ghostscript.
- %
- % AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
- % distributor accepts any responsibility for the consequences of using it, or
- % for whether it serves any particular purpose or works at all, unless he or
- % she says so in writing. Refer to the Aladdin Free Public License (the
- % "License") for full details.
- %
- % Every copy of AFPL Ghostscript must include a copy of the License, normally
- % in a plain ASCII text file named PUBLIC. The License grants you the right
- % to copy, modify and redistribute AFPL Ghostscript, but only under certain
- % conditions described in the License. Among other things, the License
- % requires that the copyright notice and this notice be preserved on all
- % copies.
- % $Id: pdf_ops.ps,v 1.17.2.1 2001/12/22 07:34:23 masata-y 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
|