diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 16:53:33 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 16:53:33 +0300 |
commit | e463eb40363ff4c68b1d903f4e0cdd0ac1c5977f (patch) | |
tree | d5e9f57c28f026cb21de3bd77cc10cd7f64aaa85 /sys/lib/ghostscript/pdf_ops.ps | |
parent | b41b9034225ab3e49980d9de55c141011b6383b0 (diff) |
Import sources from 2011-03-30 iso image - sys/lib
Diffstat (limited to 'sys/lib/ghostscript/pdf_ops.ps')
-rwxr-xr-x | sys/lib/ghostscript/pdf_ops.ps | 676 |
1 files changed, 676 insertions, 0 deletions
diff --git a/sys/lib/ghostscript/pdf_ops.ps b/sys/lib/ghostscript/pdf_ops.ps new file mode 100755 index 000000000..202053468 --- /dev/null +++ b/sys/lib/ghostscript/pdf_ops.ps @@ -0,0 +1,676 @@ +% 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,v 1.41 2005/09/28 04:33:27 dan 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 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 + % 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 + +% 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. +/grestore_nopath { + % Collect the upath with an identity CTM + { matrix setmatrix //false upath } stopped { + pop grestore newpath + } { + % Save the CTM, set identity during the uappend, then set the CTM + grestore matrix currentmatrix matrix setmatrix + exch newpath uappend setmatrix + } ifelse +} bdef + +/q { + gsave //nodict begin +} bdef +% Some PDF files have excess Q operators! +/Q { + currentdict /self .knownget { + exec //nodict eq { end grestore_nopath false } { true } ifelse + } { + true % formaterror -- not a gsave dict + } ifelse + { (\n **** File has imbalanced 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 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 + % 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 - + /.inittransparencymask 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 { 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 + + dup /Matrix knownoget not { matrix } if + gsave DefaultQstate setqstate 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 +% 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. + { 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 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 ---------------- % + +/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 + 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 + +% 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 +/setshowstate + { WordSpacing 0 eq TextSpacing 0 eq and + { 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 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 + 1 index setfillstate show % Tr was set to graphic state. + setmatrix + % now set the currentpoint using the original matrix + false charpath currentpoint newpath moveto + } + } { + { false charpath textrenderingprocs TextRenderingMode get exec } + } ifelse + } ifelse + } + { TextRenderingMode 0 eq TextRenderingMode 3 eq or + % Tr was set to graphic state. + { 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 % 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 + +end readonly put % GS_PDF_ProcSet + +.setglobal |