123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974 |
- % Copyright (C) 1994, 2000 Aladdin Enterprises. All rights reserved.
- %
- % This software is provided AS-IS with no warranty, either express or
- % implied.
- %
- % This software is distributed under license and may not be copied,
- % modified or distributed except as expressly authorized under the terms
- % of the license contained in the file LICENSE in this distribution.
- %
- % For more information about licensing, please refer to
- % http://www.ghostscript.com/licensing/. For information on
- % commercial licensing, go to http://www.artifex.com/licensing/ or
- % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
- % San Rafael, CA 94903, U.S.A., +1(415)492-9861.
-
- % $Id: pdf_ops.ps 10687 2010-02-02 07:23:57Z alexcher $
- % 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
- % (The following is cached information derived from other graphics state params)
- % FontMatrixNonHV % TextFont.FontMatrix alters horz/vert glyph advance vector direction
-
- /nodict 1 dict def
- nodict /self { //nodict } executeonly put % to avoid recursion in dumps
- nodict readonly pop
-
- /dictbeginpage { % <initialdict> dictbeginpage -
- 20 dict copy dup begin
- 1 packedarray cvx executeonly /self exch def
- graphicsbeginpage textbeginpage
- } bdef
- /endpage { % - endpage -
- showpage end
- } bdef
-
- /graphicsbeginpage {
- initgraphics
- //true .setaccuratecurves
- currentdict /ClipRect knownoget { 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
- def
- } bdef
-
- /q {
- gsave //nodict begin
- PDFusingtransparency {.pushextendedgstate cvx} if
- } bdef
-
- % Some PDF files have excess Q operators!
- /Q {
- PDFusingtransparency {.popextendedgstate cvx} if
- currentdict /self .knownget {
- exec //nodict eq {
- end
- % Restore graphics state, but do not modify path. Paths are not part
- % of the PDF graphics state; see 4.4.1 of PDF reference 3rd ed.
- % Collecting the path with one ctm and re-playing it with another ctm
- % transforms the path exactly as PDF needs.
- .getpath grestore newpath { exec } forall
- //false
- } {
- //true
- } ifelse
- } {
- //true % formaterror -- not a gsave dict
- } ifelse
- { (\n **** File has unbalanced q/Q operators \(too many Q's\) ****\n)
- pdfformaterror
- } if
- } bdef
-
- % Save PDF gstate
- /qstate { % - qstate <qstate>
- gstate
- } bdef
-
- % Set PDF gstate
- /setqstate { % <qstate> setqstate -
- { matrix setmatrix //false upath } stopped {
- pop setgstate newpath
- } {
- % Save the CTM, set identity during the uappend, then set the CTM
- exch setgstate matrix currentmatrix matrix setmatrix
- exch newpath uappend setmatrix
- } 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>
- /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 //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
- .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 { //.renderingintentdict exch .knownget { .setrenderingintent } if } 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
- % 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
-
- % ---------------- 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 -
- PDFusingtransparency {
- /.begintransparencygroup where {
- pop AlphaIsShape {
- 1 .setopacityalpha exch .setshapealpha 1
- } {
- 1 .setshapealpha 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
- } {
- pop pop
- } ifelse
- } bdef
- /.settransparencymask { % <paramdict> <masknum> .settransparencymask -
- exch dup null eq {
- PDFusingtransparency {
- pop pop
- } {
- dup /Draw get exec
- } ifelse
- } {
- 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 { setgcolorspace 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
- { setgcolorspace
-
- % 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 DefaultQstate setqstate makepattern grestore
- dup 3 1 roll
- DefaultQstate exch put
- } if
- } ifelse
- setcolor
- } bdef
- end def
- /setgcolor % (null | <color...>) <colorspace> setgcolor -
- { 1 index null eq
- { pop pop }
- { dup 0 get //Cdict exch get exec }
- ifelse
- } bdef
- % Compare the old and new color spaces in an attempt to avoid expensive
- % reloads of CIEBased color spaces.
- /PCSdict 15 dict dup begin % <colorspace> -proc- <colorspace|pdfcspace>
- /CIEBasedA { dup 1 get /PDFColorSpace .knownget { exch pop } if } bdef
- /CIEBasedABC /CIEBasedA load def
- /CIEBasedDEF /CIEBasedA load def
- /CIEBasedDEFG /CIEBasedA load def
- /Indexed {
- dup 1 get dup pdfcolorspace 2 copy ne { 3 1 roll } if pop pop
- } bdef
- end def
- /pdfcolorspace { % <colorspace> pdfcolorspace <colorspace|pdfcspace>
- dup type /arraytype eq {
- //PCSdict 1 index 0 get .knownget { exec } if
- } if
- } bdef
- /setgcolorspace { % <colorspace> setgcolorspace -
- dup pdfcolorspace currentcolorspace pdfcolorspace eq {
- pop
- } {
- setcolorspace
- } ifelse
- } bdef
- /fsexec % <fillop|strokeop> fsexec -
- {
- SoftMask //null ne {
- mark /Subtype /Group /Isolated true .dicttomark pathbbox .begintransparencygroup
- } if
- cvx exec
- SoftMask //null ne {
- .endtransparencygroup
- } if
- } bdef
-
- % ---------------- Path painting and clipping ---------------- %
-
- /S {
- OFFlevels length 0 eq {
- setstrokestate /stroke fsexec
- } {
- newpath
- } ifelse
- } bdef
-
- /f {
- OFFlevels length 0 eq {
- setfillstate /fill fsexec
- } {
- newpath
- } ifelse
- } bdef
-
- /f* {
- OFFlevels length 0 eq {
- setfillstate /eofill fsexec
- } {
- newpath
- } ifelse
- } bdef
-
- /n { newpath } bdef % don't allow n to get bound in
-
- /s { closepath S } bdef
-
- /B {
- OFFlevels length 0 eq {
- gsave setfillstate fill grestore
- setstrokestate /stroke fsexec
- } {
- newpath
- } ifelse
- } bdef
-
- /b { closepath B } bdef
-
- /B* {
- OFFlevels length 0 eq {
- gsave setfillstate eofill grestore
- setstrokestate /stroke fsexec
- } {
- newpath
- } ifelse
- } bdef
-
- /b* { closepath B* } bdef
-
- % Clipping:
-
- /Wdict 4 dict dup begin
- /S { OFFlevels length 0 eq { gsave setstrokestate stroke 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
- /n { end { currentpoint } stopped not { pop pop clip } if newpath } bdef
- end readonly def
- /W { //Wdict begin } bdef
- /W*dict 4 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
- /FontMatrixNonHV //false 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 TextRise sub 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 { dup .settextrenderingmode /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 ---------------- %
-
- % Test if the FontMatrix could transform a horizontal/vertical (depending
- % on writing mode) advance vector in glyph space into one with a different
- % direction in text space.
- % - if FontMatrix = [a b c d tx ty], this condition translates to:
- % b != 0 for horizontal writing mode
- % c != 0 for vertical writing mode
- % - when false, we automatically have wy/x == 0 in text space whenever wy/x == 0
- % in glyph space, and can avoid the slow method that is otherwise necessary
- % to implement zeroing wy/x cf PDF Ref 5.3.3 "Text space details"
- % Worker procedure for testing a single font matrix
- /?FontMatrixNonHV { % ?horz <<fontdict>> -- ?horz ?nonhv
- /FontMatrix .knownget {
- 1 index { 1 } { 2 } ifelse get 0 ne
- } {
- //false
- } ifelse
- } bdef
- % Worker procedure for recursive checking of font matrices
- /?FontMatrixNonHV { % {self} ?horz <<font>> -- {self} ?horz ?nonhv
- 2 copy //?FontMatrixNonHV exec { % check the font's own FontMatrix
- pop pop //true
- } {
- % look for descendents/ components
- pop % {self} ?horz <<font>>
- dup /FontType get
- dup 0 eq { % Type 0: look into FDepVector
- pop /FDepVector get 2 index % {self} ?horz [fonts..] {testproc}
- } {
- 9 eq { % Type 9 (CIDFontType 0): check FDArray
- /FDArray get //?FontMatrixNonHV
- } { % all others: nothing more to check
- pop {} {}
- } ifelse
- } ifelse
- %stack: {self} ?horz [fonts..] {testproc}
- //false 5 2 roll { % {testproc} false {self} ?horz <<subfont>>
- 4 index exec {
- 4 -1 roll pop //true 4 1 roll
- exit
- } if
- } forall
- %stack: {testproc} ?nonhv {self} ?horz
- 4 2 roll exch pop
- } ifelse
- } bdef
- % Main procedure
- /?FontMatrixNonHV { % <<rootfont>> -- ?nonhv
- //?FontMatrixNonHV exch
- % determine WMode
- dup /WMode .knownget { 0 eq } { //true } ifelse % {proc} <<rootfont>> ?horz
- exch
- % call the worker procedure
- //?FontMatrixNonHV exec
- exch pop exch pop
- } bdef
-
- /Tf { % <font> <scale> Tf -
- dup 0 eq {
- (\n **** Warning: Invalid 0.0 font scale given for Tf ****\n)
- pdfformaterror
- pop 0.00000001 % handle invalid scale by using a really small value
- } if
- 1 index type /dicttype ne {
- selectfont currentfont
- } {
- dup 1 eq { pop } { scalefont } ifelse
- }
- ifelse
- dup ?FontMatrixNonHV dup FontMatrixNonHV ne {
- /FontMatrixNonHV gput
- { showfirst } /Show gput
- } {
- pop
- } ifelse
- /TextFont gput settextstate
- } 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
-
- % Duplicate keys in CharString dictionary according to GlyphMap: <</new_glyph /old_glyph>>
- % We have to do this because PDF fonts can associate multiple widths with the same glyph
- % but Metrics dictionary works by the glyph name.
- /.update_charstring { % <font> <GlyphMap> .update_charstring <font'> <copied>
- dup //null ne {
- exch //true .copyfontdict % map font
- dup dup /CharStrings get % map font font cstr
- dup length % map font font cstr len
- 4 index length add % map font font cstr len+map_len
- dict copy dup begin % map font font cstr'
- /CharStrings exch put % map font
- exch { % font /new /old
- currentdict exch .knownget {
- def
- } {
- currentdict /.notdef .knownget {
- def
- } {
- pop
- % The font has no .notdef.
- % Could not resolve the conflict,
- % but either the font is invalid or the glyph name is never used.
- } ifelse
- } ifelse
- } forall
- end //true
- } {
- pop //false
- } ifelse
- } bdef
-
- /.updatefont { % <font> <Encoding|null> <Metrics|null> <GlyphMap|null>
- % .updatefont <font'> <copied>
- 4 2 roll % <Metrics|null> <GlyphMap> <font> <Encoding|null>
- .updatefontencoding % <Metrics|null> <GlyphMap> <font> bool
- 4 1 roll exch % bool <Metrics|null> <font> <GlyphMap>
- .update_charstring % bool <Metrics|null> <font> bool
- 3 1 roll exch % bool bool <font> <Metrics|null>
- .updatefontmetrics % bool bool <font> bool
- 4 2 roll or or % <font> is_copied
- } 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 knownoget { 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
-
- /pdfwrite_textrenderingprocs [
- { setfillstate show } bind
- { setstrokestate
- % 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
- % if the CTM had been unity.
- currentlinewidth dup
- matrix defaultmatrix idtransform TextSaveMatrix dtransform
- 2 copy eq {
- pop
- }{
- % non-square scaling reduces to Text matrix in pdfwrite , so
- % we can ignore it. (wrong answer, but consistent)
- pop pop currentlinewidth
- }ifelse setlinewidth
- show } bind
- { gsave 0 .settextrenderingmode
- setfillstate dup show currentpoint 3 -1 roll
- grestore gsave setstrokestate
- false charpath
- % We need to make sure the matrix used for the stroke
- % and therefore stroke width does not include the
- % Text Matrix Tm.
- TextSaveMatrix setmatrix
- stroke
- grestore moveto
- } bind
- { setfillstate show } bind
- { gsave 0 .settextrenderingmode
- setfillstate dup show grestore true charpath } bind
- { gsave 1 .settextrenderingmode
- setstrokestate dup show grestore
- true charpath } bind
- { gsave 0 .settextrenderingmode
- setfillstate dup show grestore gsave dup
- setstrokestate false charpath
- % We need to make sure the matrix used for the stroke
- % and therefore stroke width does not include the
- % Text Matrix Tm.
- TextSaveMatrix setmatrix
- stroke grestore
- true charpath } bind
- { true charpath } bind
- ] readonly def
-
- /setshowstate
- { WordSpacing 0 eq TextSpacing 0 eq and FontMatrixNonHV not and
- {
- currentdevice .devicename /pdfwrite eq
- {
- pdfwrite_textrenderingprocs TextRenderingMode get
- }
- {
- TextRenderingMode 0 eq {
- { setfillstate show }
- } {
- TextRenderingMode 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
- % 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
- 2 index setfillstate show % Tr was set to graphic state.
- setmatrix
- % now set the currentpoint using the original matrix
- gsave
- setmatrix
- false charpath currentpoint newpath
- grestore
- moveto
- }
- } {
- { false charpath textrenderingprocs TextRenderingMode get exec }
- } ifelse
- } ifelse
- } ifelse
- }
- { TextRenderingMode 0 eq TextRenderingMode 3 eq or
- % Tr was set to graphic state.
- { FontMatrixNonHV {
- {
- setfillstate
- [ TextSpacing WordSpacing 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
- 3 index add exch 32 eq {1 index add} if % str [... weach wword w
- 3 1 roll % str [... w weach wword
- }
- % for the "exch" removed or not below, see comment in pdf_font.ps::getfontmetrics
- currentfont /FontMatrix get 0 3 Vexch pop get 0 ne {
- 1 1 index length 1 sub getinterval cvx
- } if
- cshow pop pop ]
- { xshow } { yshow } Vexch pop exec
- }
- } {
- 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
- } 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 wword wchar
- {
- exch % will be removed, unless FontMatrixNonHV && FontMatrix.xx/yy == 0
- % Stack: str wword wchar ccode xthis ythis
- Vexch pop currentpoint 6 3 roll
- % Stack: str wthis xorig yorig wword wchar ccode
- (x) dup 0 3 index put //false charpath
- 3 copy 32 eq { add } { exch pop } ifelse
- % Stack: str wthis xorig yorig wword wchar ccode wextra
- 7 -3 roll moveto add
- 0 Vexch rmoveto pop
- }
- % for the "exch" removed or not below, see comment in pdf_font.ps::getfontmetrics
- FontMatrixNonHV dup not exch {
- currentfont /FontMatrix get 0 3 Vexch pop get 0 ne
- } if {
- 1 1 index length 1 sub getinterval cvx
- } if
- 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 }
- OFFlevels length 0 eq {
- exec
- } {
- gsave get-gs-attrs nulldevice set-gs-attrs
- exec
- get-gs-attrs grestore set-gs-attrs
- } ifelse
- } 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
- }
- OFFlevels length 0 eq {
- exec
- } {
- gsave get-gs-attrs nulldevice set-gs-attrs
- exec
- get-gs-attrs grestore set-gs-attrs
- } ifelse
- } bdef
-
- /tf { setfillstate currentpoint fill moveto } bdef
- /tn { currentpoint newpath moveto } bdef % Obsolete, never used.
- % 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
-
- % Text formatting and painting for the AcroForm field without appearance streams.
- /Tform { % <MaxLen> (V) <Ff> <Q> Tform -
- clippath pathbbox 4 2 roll pop pop % MaxLen (V) Ff Q dx dy
- currentfont /ScaleMatrix .knownget { 3 get } { 1 } ifelse % MaxLen (V) Ff Q dx dy yy
- currentfont /FontBBox get dup 1 get neg exch 3 get % MaxLen (V) Ff Q dx dy yy desc asc
- dup 0 ne { div } { pop pop 0 } ifelse % MaxLen (V) Ff Q dx dy yy desc/asc
- 1 index mul % MaxLen (V) Ff Q dx dy yy desc/asc*yy
-
- 4 index 16#1000 and 0 ne { % multiline
- 8 { pop } repeat (Multiline form fields are not yet implemented.) =
- } {
- 4 index 16#1000000 and 0 ne { % comb
- 8 { pop } repeat (Combed form fields are not yet implemented.) =
- } { % plain text
- 3 1 roll sub add 2 div % MaxLen (V) Ff Q dx (dy-yy+desc)/2
- 0 exch moveto % MaxLen (V) Ff Q dx
- 1 index 0 ne {
- 3 index 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
- pop % MaxLen (V)
- } {
- pop pop pop % MaxLen (V)
- 2 0 rmoveto
- } ifelse
- exch pop Show % -
- } ifelse
- } ifelse
- } bdef
-
- end readonly put % GS_PDF_ProcSet
-
- .setglobal
|