% 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 9796 2009-06-17 02:17:49Z 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
} bdef
% Some PDF files have excess Q operators!
/Q {
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
% ---------------- 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
/nullpattern1 mark
/PatternType 1 /PaintType 1 /TilingType 3 /BBox [0 0 1 1]
/XStep 1 /YStep 1 /PaintProc { pop } bind
.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 { //.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
} {
dup dup /Matrix knownoget not { { 1 0 0 1 0 0 } } if
gsave DefaultQstate setqstate makepattern grestore
dup 3 1 roll
DefaultQstate exch put
} 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 -
{ % Preserve the current point, if any.
SoftMask //null ne {
mark /Subtype /Group /Isolated true .dicttomark pathbbox .begintransparencygroup
} if
{ currentpoint } stopped
{ $error /newerror false put cvx exec }
{ 3 -1 roll cvx exec moveto }
ifelse
SoftMask //null ne {
.endtransparencygroup
} if
} 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
/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
} 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 % 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
Copyright 2K16 - 2K18 Indonesian Hacker Rulez