diff options
author | Karl Berry <karl@freefriends.org> | 2005-12-28 00:07:27 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2005-12-28 00:07:27 +0000 |
commit | 30dd9f517c9c093ff3319061647a4555264f7914 (patch) | |
tree | 0d7a349bf99be5a42cc9c5a80a30f3b7136c4ccd /Master/xemtex/gslib/pdf_draw.ps | |
parent | 08ab8dce83f53b0f915cb66a37bbc8478b22c307 (diff) |
trunk
git-svn-id: svn://tug.org/texlive/trunk@9 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/xemtex/gslib/pdf_draw.ps')
-rw-r--r-- | Master/xemtex/gslib/pdf_draw.ps | 1151 |
1 files changed, 1151 insertions, 0 deletions
diff --git a/Master/xemtex/gslib/pdf_draw.ps b/Master/xemtex/gslib/pdf_draw.ps new file mode 100644 index 00000000000..b75a84e725a --- /dev/null +++ b/Master/xemtex/gslib/pdf_draw.ps @@ -0,0 +1,1151 @@ +% Copyright (C) 1994, 2000 Aladdin Enterprises. All rights reserved. +% +% This program is free software; you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by the +% Free Software Foundation; either version 2 of the License, or (at your +% option) any later version. +% +% This program is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +% Public License for more details. +% +% You should have received a copy of the GNU General Public License along +% with this program; if not, write to the Free Software Foundation, Inc., +% 59 Temple Place, Suite 330, Boston, MA, 02111-1307. + +% $Id: pdf_draw.ps,v 1.36.2.2.2.1 2003/04/12 14:02:39 giles Exp $ +% pdf_draw.ps +% PDF drawing operations (graphics, text, and images). + +/.setlanguagelevel where { pop 2 .setlanguagelevel } if +.currentglobal true .setglobal +/pdfdict where { pop } { /pdfdict 100 dict def } ifelse +GS_PDF_ProcSet begin +pdfdict begin + +% For simplicity, we use a single interpretation dictionary for all +% PDF graphics operations, even though this is too liberal. +/drawopdict 100 dict def + +% ================================ Graphics ================================ % + +% ---------------- Functions ---------------- % + +% Note that resolvefunction converts a PDF Function to a PostScript Function; +% resolve*fnproc converts a PDF function to a PostScript procedure. + +/fnrdict mark + 0 { .resolvefn0 } + 2 { } + 3 { .resolvefn3 } + 4 { .resolvefn4 } +.dicttomark readonly def + +/.resolvefn0 { + % Don't lose our place in PDFfile. + PDFfile fileposition exch + dup true resolvestream + % The stream isn't positionable, so read all the data now. + % Stack: filepos fndict stream + 1 index /Range oget length 2 idiv 2 index /BitsPerSample oget mul + 2 index /Size oget { mul } forall + 7 add 8 idiv string + 1 index exch readstring pop exch closefile + % Stack: filepos fndict data + exch dup length 1 add dict .copydict + dup /DataSource 4 -1 roll put + exch PDFfile exch setfileposition +} bdef + +/.resolvefn3 { + dup length dict .copydict + dup /Bounds 2 copy knownoget { put } { pop pop } ifelse + dup /Encode 2 copy knownoget { put } { pop pop } ifelse + dup /Functions 2 copy oget mark exch dup { + oforce .resolvefn + } forall + counttomark -1 roll astore exch pop put +} bdef + +/.resolvefn4 { + PDFfile fileposition exch % filepos fndict + dup true resolvestream % filepos fndict stream + exch dup length dict copy % filepos stream fndict2 + dup /Function undef % filepos stream fndict2 + exch dup token not { + () /rangecheck cvx signalerror + } if + exch token { + /rangecheck cvx signalerror + } if + % Use .bind to avoid idiom recognition. + .bind + 1 index /Function 3 -1 roll put + exch PDFfile exch setfileposition +} bdef +currentdict /tfopdict undef + +/.resolvefn { % <fndict> .resolvefn <fndict'> + dup /FunctionType oget //fnrdict exch get exec +} bdef + +/resolvefunction { % <fndict> resolvefunction <function> + .resolvefn + DEBUG { (%Function: ) print dup === flush } if +} bdef + +/resolvefnproc { % <fndict> resolvefnproc <proc> + resolvefunction .buildfunction +} bdef + +/resolveidfnproc { % <fndict> resolveidfnproc <proc> + dup /Identity eq { pop { } } { resolvefnproc } ifelse +} bdef + +/resolvedefaultfnproc { % <fndict> <default> resolved'fnproc <proc> + 1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse +} bdef + +% ---------------- Shadings ---------------- % + +/shrdict mark + /ColorSpace { + resolvecolorspace + } + /Function { + dup type /dicttype eq { + resolvefunction + } { + [ exch { oforce resolvefunction } forall ] + } ifelse + } +.dicttomark readonly def + +/resolveshading { % <shadingstream> resolveshading <shading> + PDFfile fileposition exch + mark exch { + oforce //shrdict 2 index .knownget { exec } if + } forall .dicttomark + dup /ShadingType get 4 ge { + dup dup true resolvestream + % Make a reusable stream so that the shading doesn't + % reposition PDFfile at unexpected times. + /ReusableStreamDecode filter /DataSource exch put + } if exch PDFfile exch setfileposition +} bdef +/resolvesh { % <shname> resolveshading <shading> + Page /Shading rget { + resolveshading + } { + null + }ifelse +} bdef + +% ---------------- Halftones ---------------- % + +/spotfunctions mark + /Round { + abs exch abs 2 copy add 1 le { + dup mul exch dup mul add 1 exch sub + } { + 1 sub dup mul exch 1 sub dup mul add 1 sub + } ifelse + } + /Diamond { + abs exch abs 2 copy add .75 le { + dup mul exch dup mul add 1 exch sub + } { + 2 copy add 1.23 le { + .85 mul add 1 exch sub + } { + 1 sub dup mul exch 1 sub dup mul add 1 sub + } ifelse + } ifelse + } + /Ellipse { + abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt { + pop dup mul exch .75 div dup mul add 4 div 1 exch sub + } { + dup 1 gt { + pop 1 exch sub dup mul exch 1 exch sub + .75 div dup mul add 4 div 1 sub + } { + .5 exch sub exch pop exch pop + } ifelse + } ifelse + } + /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub } + /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub } + /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub } + /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub } + /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub } + /Line { exch pop abs neg } + /LineX { pop } + /LineY { exch pop } + /Square { abs exch abs 2 copy lt { exch } if pop neg } + /Cross { abs exch abs 2 copy gt { exch } if pop neg } + /Rhomboid { abs exch abs 0.9 mul add 2 div } + /DoubleDot { 2 {360 mul sin 2 div exch } repeat add } + /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg } + /SimpleDot { dup mul exch dup mul add 1 exch sub } + /InvertedSimpleDot { dup mul exch dup mul add 1 sub } + /CosineDot { 180 mul cos exch 180 mul cos add 2 div } + /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add } + /InvertedDouble { + exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg + } +.dicttomark readonly def + +/htrdict mark + 1 { .resolveht1 } + 5 { .resolveht5 } + % We don't support types 6, 10, or 16 yet. +.dicttomark readonly def + +/.resolveht1 { + mark exch { + oforce + 1 index /SpotFunction eq { + dup type /nametype eq + { //spotfunctions exch get } { resolvefnproc } + ifelse + } { + 1 index /TransferFunction eq { + resolveidfnproc + } if + } ifelse + } forall .dicttomark +} bdef + +/.resolveht5 { + mark exch { + oforce dup type /dicttype eq { resolvehalftone } if + } forall .dicttomark +} bdef + +/resolvehalftone { % <dict> resolvehalftone <halftone> + dup /HalftoneType get //htrdict exch get exec +} bdef + +% ---------------- Graphics state management ---------------- % + +/cmmatrix matrix def +drawopdict begin + % Graphics state stack + /q { q } def + /Q { Q } def + % Graphics state setting + /cm { //cmmatrix astore concat } def + /i /setflat load def + /J /setlinecap load def + /d /setdash load def + /j /setlinejoin load def + /w /setlinewidth load def + /M /setmiterlimit load def + /gs { gs } def +end + +% Each entry in this dictionary is +% <gsres> <value> -proc- <gsres> +/gsbg { + /BGDefault load resolvedefaultfnproc setblackgeneration +} bdef +/gsucr { + /UCRDefault load resolvedefaultfnproc setundercolorremoval +} bdef +/gstr { + dup type /arraytype eq { + { oforce /TRDefault load resolvedefaultfnproc } forall + setcolortransfer + } { + /TRDefault load resolvedefaultfnproc settransfer + } ifelse +} bdef +/gsparamdict mark + /SA { setstrokeadjust } + /OP { 1 index /op known not { dup op } if OP } + % The PDF 1.3 specification says that the name /Default is only + % recognized for {BG,UCR,TR}2. However, PDF 1.3 files produced + % by Adobe Acrobat Distiller 4.0 for Windows use the name /Default + % with the older keys, so we have to implement this. + /BG { 1 index /BG2 known { pop } { gsbg } ifelse } + /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse } + /TR { 1 index /TR2 known { pop } { gstr } ifelse } + /HT { + dup /Default eq { + pop .setdefaultscreen + } { + %****** DOESN'T IMPLEMENT THE STREAM CASE YET ****** + resolvehalftone sethalftone + } ifelse + } + /HTP { + % HTP may be present even if this isn't a DPS interpreter. + /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse + } + % PDF 1.3 + /Font { aload pop Tf } + /LW { setlinewidth } + /LC { setlinecap } + /LJ { setlinejoin } + /ML { setmiterlimit } + /D { aload pop setdash } + /RI { ri } + /op { op } + /OPM { OPM } + /BG2 { gsbg } + /UCR2 { gsucr } + /TR2 { gstr } + /FL { setflat } + /SM { + % SM may be present even if this is only a Level 2 interpreter. + /setsmoothness where { pop setsmoothness } { pop } ifelse + } + % PDF 1.4 + % All of these require the "transparency" feature in the interpreter. + /ca { ca } + /CA { CA } + /SMask { gssmask } + /AIS { AIS } + /BM { BM } + /TK { TK } +.dicttomark readonly def +/gs { % <gsres> gs - + Page /ExtGState rget { + % We keep the dictionary on the stack during the forall so that + % keys that interact with each other have access to it. + dup { + oforce exch gsparamdict exch .knownget { exec } { pop } ifelse + } forall pop + } if +} bdef + +% ------ Transparency support ------ % + +/gssmask { + dup /None eq { + pop null + } { + % Preprocess the SMask value into a parameter dictionary for + % .begintransparencymask, with added /BBox and /Draw keys. + mark exch % Stack: mark smaskdict + dup /S oget /Subtype exch 3 2 roll + % Stack: mark ... smaskdict + dup /BC knownoget { /Background exch 3 2 roll } if + dup /TR knownoget { + resolveidfnproc /TransferFunction exch 3 2 roll + } if + dup /G oget dup /BBox oget /BBox exch 4 2 roll + /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll + pop .dicttomark + } ifelse SMask +} bdef + +% This procedure is called to actually render the soft mask. +/.execmaskgroup { % <masknum> <paramdict> <formdict> .execmaskgroup - + % Save our place in PDFfile, and do a gsave to avoid resetting + % the color space. + gsave PDFfile fileposition 4 1 roll + % We have to select the group's color space so that the + % background color will be interpreted correctly. + dup /Group oget /CS knownoget { csresolve setcolorspace } if + exch dup /BBox get aload pop .begintransparencymask { + dup /Resources knownoget { oforce } { 0 dict } ifelse + exch false resolvestream + .execgroup .endtransparencymask + } .internalstopped { + .discardtransparencymask stop + } if + PDFfile exch setfileposition grestore +} bdef +% Paint a Form+Group XObject, either for a transparency mask or for a Do. +/.execgroup { % <resdict> <stream> .execgroup - + gsave + 1 .setopacityalpha 1 .setshapealpha + 0 .inittransparencymask 1 .inittransparencymask + /Compatible .setblendmode + % Execute the body of the Form, similar to DoForm. + pdfopdict .pdfruncontext + grestore +} bdef + +/.beginformgroup { % groupdict bbox .beginformgroup - + exch mark exch % bbox mark groupdict + dup /CS knownoget { csresolve setcolorspace } if + dup /I knownoget { /Isolated exch 3 2 roll } if + dup /K knownoget { /Knockout exch 3 2 roll } if + pop .dicttomark + % Stack: bbox paramdict + exch aload pop + .begintransparencygroup +} bdef + +% .paintgroupform implements the Form PaintProc in the case where the +% Form XObject dictionary includes a Group key. See .paintform below. +/.paintgroupform { % <resdict> <stream> <formdict> .paintgroupform - + dup /Group oget exch /BBox oget + % Stack: resdict stream groupdict bbox + .beginformgroup { + .execgroup + } .internalstopped { + .discardtransparencygroup stop + } if .endtransparencygroup +} bdef + +% Make an ImageType 103 (soft-masked) image. +/makesoftmaskimage { % <datasource> <imagemask> <SMask> makesoftmaskimage + % <datasource> <imagemask>, updates currentdict = + % imagedict + % See the ImageType 3 case of makemaskimage below. + % SMask is a stream, another Image XObject. + % Stack: datasource imagemask(false) smaskstreamdict + PDFfile fileposition exch + dup /Matte knownoget { /Matte exch def } if + dup length dict makeimagedict pop + % In order to prevent the two data sources from being + % aliased, we need to make at least one a reusable stream. + % We pick the mask, since it's smaller (in case we need to + % read all its data now). + % Stack: datasource imagemask(false) savedpos + % maskdict is currentdict + /DataSource DataSource mark + /Intent 1 + /AsyncRead true + .dicttomark .reusablestreamdecode def + PDFfile exch setfileposition + currentdict end currentdict end + 5 dict begin + /ImageType 103 def + /DataDict exch def + dup /InterleaveType 3 put + DataDict /Matte .knownget { + /Matte exch def + } if + AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def + /ColorSpace DataDict /ColorSpace get def +} bdef + +% ---------------- Color setting ---------------- % + +/01_1 [0 1] readonly def +/01_3 [0 1 0 1 0 1] readonly def +/01_4 [0 1 0 1 0 1 0 1] readonly def + +% The keys here are resolved (PostScript, not PDF) color space names. +/csncompdict mark + /DeviceGray { pop 1 } + /DeviceRGB { pop 3 } + /DeviceCMYK { pop 4 } + /CIEBasedA { pop 1 } + /CIEBasedABC { pop 3 } + /ICCBased { 1 oget /N oget } + /Separation { pop 1 } + /DeviceN { 1 oget length } +.dicttomark readonly def + +% Perhaps some of the values in the following need to be modified +% depending on the WhitePoint value.... +/cslabinit mark + /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind] + /MatrixABC [1 1 1 1 0 0 0 0 -1] + /DecodeLMN [ + {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse + 0.9505 mul} bind + {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse + } bind + {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse + 1.0890 mul} bind + ] +.dicttomark readonly def + +/csrdict mark + /DeviceGray { + /DefaultGray Page /ColorSpace rget { exch pop resolvecolorspace } if + } + /DeviceRGB { + /DefaultRGB Page /ColorSpace rget { exch pop resolvecolorspace } if + } + /DeviceCMYK { } + /CalGray { + 1 oget 6 dict begin + dup /Gamma knownoget { + /exp load 2 packedarray cvx /DecodeA exch def + } if + dup /BlackPoint knownoget { /BlackPoint exch def } if + dup /WhitePoint knownoget { /WhitePoint exch def } if + pop [ /CIEBasedA currentdict end ] + } + /CalRGB { + 1 oget 6 dict begin + dup /Gamma knownoget { + [ exch { /exp load 2 packedarray cvx } forall + ] /DecodeABC exch def + } if + dup /Matrix knownoget { /MatrixABC exch def } if + dup /BlackPoint knownoget { /BlackPoint exch def } if + dup /WhitePoint knownoget { /WhitePoint exch def } if + pop [ /CIEBasedABC currentdict end ] + } + /CalCMYK { + pop /DeviceCMYK % not defined by Adobe + } + /Lab { + 1 oget 6 dict begin + dup /Range knownoget not { [-100 100 -100 100] } if + [0 100 null null null null] dup 2 4 -1 roll putinterval + /RangeABC exch def + //cslabinit { def } forall + dup /BlackPoint knownoget { /BlackPoint exch def } if + dup /WhitePoint knownoget { /WhitePoint exch def } if + pop [ /CIEBasedABC currentdict end ] + } + /ICCBased { + PDFfile fileposition exch + dup dup 1 oget + mark exch { oforce } forall .dicttomark + dup dup true resolvestream + /ReusableStreamDecode filter /DataSource exch put + 1 exch put + exch PDFfile exch setfileposition + } bind + /Separation { + aload pop exch oforce resolvecolorspace exch oforce resolvefnproc + 4 array astore + } + /DeviceN { + 0 4 getinterval % ignore attributes + aload pop 3 -1 roll oforce + 3 -1 roll oforce resolvecolorspace + 3 -1 roll oforce resolvefnproc + 4 array astore + } + /Indexed { + aload pop 3 -1 roll oforce resolvecolorspace + % If the underlying space is a Lab space, we must scale + % the output of the lookup table as part of DecodeABC. + dup dup type /arraytype eq { 0 get } if /CIEBasedABC eq { + dup 1 get /DecodeLMN known { + 1 get dup length dict copy + begin /DecodeABC [ 0 2 4 { + RangeABC 1 index 1 add get RangeABC 2 index get sub /mul load + RangeABC 3 index get /add load + DecodeABC 6 -1 roll 2 idiv get [ 6 1 roll aload pop ] cvx + } for ] def + /RangeABC //01_3 def + currentdict end /CIEBasedABC exch 2 array astore + } if + } if + 3 1 roll + oforce dup type /stringtype ne { + % The color lookup table is a stream. + % Get its contents. Don't lose our place in PDFfile. + % Stack: /Indexed basespace hival lookup + PDFfile fileposition 5 1 roll true resolvestream + % Stack: filepos /Indexed basespace hival lookupstream + 1 index 1 add + % Stack: filepos /Indexed basespace hival lookupstream len + 3 index + dup dup type /arraytype eq { 0 get } if + //csncompdict exch get exec mul + string readstring pop + % Stack: filepos /Indexed basespace hival table + 5 -1 roll PDFfile exch setfileposition + } + if 4 array astore + } + /Pattern { + dup type /nametype ne { + dup length 1 gt { + 1 oget resolvecolorspace + /Pattern exch 2 array astore + } if + } if + } +.dicttomark readonly def + +/cssubst { % <csname> cssubst <cspace'> true + % <csname> cssubst false + dup resolvecolorspace + dup 1 index ne { exch pop true } { pop pop false } ifelse +} bdef + +/csnames mark + /DeviceGray dup /DeviceRGB dup /DeviceCMYK dup /Pattern dup +.dicttomark readonly def +/csresolve { % <csresourcename> csresolve <cspace> + dup Page /ColorSpace rget { + exch pop resolvecolorspace + } { + //csnames 1 index known not { /undefined cvx signalerror } if + } ifelse +} bdef +/resolvecolorspace { % <cspace> resolvecolorspace <cspace'> + dup dup type /arraytype eq { 0 get } if + //csrdict exch .knownget { + exec dup type /nametype ne { dup length 1 eq { 0 get } if } if + } { + csresolve + } ifelse +} bdef + +/scresolve { % <c0> ... scresolve <multi> + % We can't really make sc[n] and SC[N] work, because + % the color space information isn't available at + % conversion time; so we hack it by assuming that + % all the operands on the stack are used, and that + % if the top operand is a name, it's a Pattern resource. + dup type /nametype eq + { Page /Pattern rget { resolvepattern } { null } ifelse } + if + dup type /dicttype eq { + % Check the PaintType, if any (shading patterns don't + % have one). + dup /PaintType .knownget { 2 eq } { false } ifelse + } { + .pdfcount 1 gt + } ifelse +} bdef + +/.pdfpaintproc { % <patdict> <resdict> .pdfpaintproc - + DEBUG { (%Begin PaintProc) = flush } if + % For uncolored patterns, we have to unbind the current + % color and color space before running the PaintProc. + % There's no harm in doing this for colored patterns, + % so for simplicity, we always do it. + PDFfile fileposition 3 1 roll + q + null sc1 null SC1 + exch false resolvestream pdfopdict .pdfruncontext + Q + DEBUG { (%End PaintProc) = flush } if + PDFfile exch setfileposition +} bdef + +/resolvepattern { % <patternstreamdict> resolvepattern <patterndict> + % Don't do the resolvestream now: just capture the data + % from the file if necessary. + dup length dict copy + dup /FilePosition .knownget { + 1 index /File get dup fileposition 3 1 roll + % Stack: dict savepos pos file + dup 3 -1 roll setfileposition + dup 3 index /Length oget string readstring pop + % Stack: dict savepos file string + 3 1 roll exch setfileposition + 1 index /File 3 -1 roll put + dup /FilePosition undef + } if + dup /Shading knownoget { + resolveshading 1 index /Shading 3 -1 roll put + } if + dup /PaintProc [ + % Bind the resource dictionary into the PaintProc. + 2 index /Resources knownoget { oforce } { 0 dict } ifelse + /.pdfpaintproc cvx + ] cvx put + DEBUG { + (%Pattern: ) print dup === flush + } if +} bdef + +drawopdict begin + /g { /DeviceGray cssubst { cs sc1 } { g } ifelse } bdef + /rg { /DeviceRGB cssubst { cs sc* } { rg } ifelse } bdef + /k { k } bdef + /cs { csresolve cs } bdef + /sc { scresolve { sc* } { sc1 } ifelse } bdef + /scn /sc load def + /G { /DeviceGray cssubst { CS SC1 } { G } ifelse } bdef + /RG { /DeviceRGB cssubst { CS SC* } { RG } ifelse } bdef + /K { K } bdef + /CS { csresolve CS } bdef + /ri { ri } bdef + /SC { scresolve { SC* } { SC1 } ifelse } bdef + /SCN /SC load def +end + +% ---------------- Paths ---------------- % + +drawopdict begin + % Path construction + /m /moveto load def + /l /lineto load def + /c /curveto load def + /v { currentpoint 6 2 roll curveto } def + /y { 2 copy curveto } def + /re { + 4 2 roll moveto exch dup 0 rlineto 0 3 -1 roll rlineto neg 0 rlineto + closepath + } def + /h /closepath load def + % Path painting and clipping + /n { n } def + /S { S } def + /s { s } def + /f { f } def + /f* { f* } def + /B { B } def + /b { b } def + /B* { B* } def + /b* { b* } def + /W { W } def + /W* { W* } def + /sh { resolvesh shfill } def +end + +% ---------------- XObjects ---------------- % + +/xobjectprocs mark % <dict> -proc- - + /Image { DoImage } + /Form { DoForm } + /PS { DoPS } +.dicttomark readonly def + +% Note that the keys in defaultdecodedict are resolved (PostScript, not PDF) +% color space names. +/defaultdecodedict mark + /DeviceGray { pop //01_1 } bind + /DeviceRGB { pop //01_3 } bind + /DeviceCMYK { pop //01_4 } bind + /CIEBasedA { 1 get /RangeA .knownget not { //01_1 } if } bind + /CIEBasedABC { 1 get /RangeABC .knownget not { //01_3 } if } bind + /ICCBased { + 1 oget dup /Range .knownget { + exch pop + }{ + /N get [ exch {0 1} repeat ] readonly + } ifelse + } bind + /Separation { pop //01_1 } bind + /DeviceN { + 1 oget length [ exch {0 1} repeat ] readonly + } bind + /Indexed { + pop [ 0 1 BitsPerComponent bitshift 1 sub ] + } bind +.dicttomark readonly def + +/checkaltimage { % <resdict> checkaltimage <resdict[']> + Printed { + dup /Alternates knownoget { + { + dup /DefaultForPrinting knownoget { + { + /Image oget exch pop exit + } { + pop + } ifelse + } { + pop + } ifelse + } forall + } if + } if +} bdef + +/makeimagedict { % <resdict> <newdict> makeimagedict <imagemask> + % On return, newdict' is currentdict + begin + /Width 2 copy oget def + /Height 2 copy oget def + /BitsPerComponent 2 copy oget def + /Interpolate 2 copy knownoget { def } { pop } ifelse + makeimagekeys +} bdef +/makeimagekeys { % <resdict> makeimagekeys <imagemask> + % newdict is currentdict + % Assumes Width, Height, BPC, Interpolate already copied. + /ImageType 1 def + /ImageMatrix Width 0 0 + % Handle 0-height images specially. + Height dup 0 eq { pop 1 } if neg 0 1 index neg + 6 array astore def + dup /ImageMask knownoget dup { and } if { + % Image mask + % Decode is required for the PostScript image operators. + % AI8 writes bogus decode array [0 1 0 0 0 0 0 0] + /Decode 2 copy knownoget { 0 2 getinterval } { //01_1 } ifelse def + % BitsPerComponent may be missing for masks. + % The spec requires it, but some producers omit it, and + % Acrobat Reader doesn't care. + /BitsPerComponent 2 copy known { pop } { 1 def } ifelse + true + } { + % Opaque image + dup /ColorSpace oget resolvecolorspace /ColorSpace exch def + % Decode is required for the PostScript image operators. + /Decode 2 copy knownoget not { + ColorSpace //defaultdecodedict + ColorSpace dup type /arraytype eq { 0 get } if get exec + } if def + false + } ifelse + % Even though we're going to read data, + % pass false to resolvestream so that + % it doesn't try to use Length (which may not be present). + exch false resolvestream /DataSource exch def +} bdef + +/DoImage { + checkaltimage dup length 6 add dict + 1 index /SMask knownoget { 1 index exch /SMask exch put } if + 1 index /Mask knownoget { 1 index exch /Mask exch put } if + makeimagedict doimage +} bdef +/makemaskimage { % <datasource> <imagemask> <Mask> makemaskimage + % <datasource> <imagemask>, updates currentdict = + % imagedict + dup type /arraytype eq { + /ImageType 4 def + /MaskColor exch def + } { + % Mask is a stream, another Image XObject. + % Stack: datasource imagemask(false) maskstreamdict + PDFfile fileposition exch + dup length dict makeimagedict pop + % In order to prevent the two data sources from being + % aliased, we need to make at least one a reusable stream. + % We pick the mask, since it's smaller (in case we need to + % read all its data now). + % Stack: datasource imagemask(false) savedpos + % maskdict is currentdict + /DataSource DataSource mark + /Intent 1 + /AsyncRead true + .dicttomark .reusablestreamdecode def + PDFfile exch setfileposition + currentdict end currentdict end + 5 dict begin + /ImageType 3 def + /InterleaveType 3 def + /DataDict exch def + /MaskDict exch def + /ColorSpace DataDict /ColorSpace get def + } ifelse +} bdef +/doimage { % <imagemask> doimage - + % imagedict is currentdict, gets popped from dstack + DataSource exch + PDFversion 1.4 ge { currentdict /SMask knownoget } { false } ifelse { + makesoftmaskimage + } { + currentdict /Mask knownoget { + makemaskimage + } if + } ifelse + % Stack: datasource imagemask + % image and imagemask can be redefined in gs_init.ps to tweak interpolation + % after device-specific files are run. Don't bind them here. + { currentdict end setfillstate /imagemask } + { ColorSpace setcolorspace currentdict end setfillblend /image } + ifelse + .systemvar exec + + % Close the input stream, unless it is PDFfile or + % PDFsource. + dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse +} bdef + +/.paintform { % <formdict> <resdict> <stream> .paintform - + 3 -1 roll dup /Group known { + .paintgroupform + } { + pop pdfopdict .pdfruncontext + } ifelse +} bdef + +/DoForm { + % Adobe 2nd edition of the PDF 1.3 spec makes /FormType + % and /Matrix keys optional. Cope with the missing keys. + dup length + 1 index /Matrix known + { dict + } + { 1 add dict + dup /Matrix { 1 0 0 1 0 0 } cvlit put + } + ifelse + copy + dup /FormType known not { + dup length 1 add dict copy dup /FormType 1 put + } if + + dup [ 2 index /Resources knownoget { oforce } { 0 dict } ifelse + 3 index false /resolvestream cvx + /.paintform cvx + ] cvx /PaintProc exch put + execform +} bdef + +/DoPS { + true resolvestream cvx exec +} bdef + +drawopdict begin + /Do { + setfillblend + PDFfile fileposition exch + dup Page /XObject rget { + exch pop dup /Subtype get xobjectprocs exch get + % Don't leave extra objects on the stack while executing + % the definition of the form. + 3 -1 roll 2 .execn + } { + % This should cause an error, but Acrobat Reader can + % continue, so we do too. + (%stderr) (w) file + dup (****************Undefined XObject resource: ) writestring + dup 3 -1 roll write=== + flushfile + } ifelse + PDFfile exch setfileposition + } bdef +end + +% ---------------- In-line images ---------------- % + +% Undo the abbreviations in an in-line image dictionary. +% Note that we must look inside array values. +% /I is context-dependent. +/unabbrevkeydict mark + /BPC /BitsPerComponent /CS /ColorSpace /D /Decode /DP /DecodeParms + /F /Filter /H /Height /I /Interpolate /IM /ImageMask /W /Width +.dicttomark readonly def +/unabbrevvaluedict mark + /AHx /ASCIIHexDecode /A85 /ASCII85Decode /CC /CalCMYK + /CCF /CCITTFaxDecode /CG /CalGray /CR /CalRGB + /DCT /DCTDecode /CMYK /DeviceCMYK /Fl /FlateDecode + /G /DeviceGray /RGB /DeviceRGB + /I /Indexed /LZW /LZWDecode /RL /RunLengthDecode +.dicttomark readonly def +/unabbrevtypedict mark + /nametype { + //unabbrevvaluedict 1 index .knownget { exch pop } if + } + /arraytype { + dup 0 1 2 index length 1 sub { + 2 copy get unabbrevvalue put dup + } for pop + } +.dicttomark readonly def +/unabbrevvalue { % <obj> unabbrevvalue <obj'> + oforce //unabbrevtypedict 1 index type .knownget { exec } if +} bdef + +drawopdict begin + /BI { mark } bdef + /ID { + counttomark 2 idiv dup 6 add dict begin { + exch //unabbrevkeydict 1 index .knownget { exch pop } if + exch unabbrevvalue def + } repeat pop + /File PDFsource def + currentdict makeimagekeys doimage + % The Adobe documentation says that the data following ID + % consists of "lines", and some PDF files (specifically, some files + % produced by PCL2PDF from Visual Software) contain garbage bytes + % between the last byte of valid data and an EOL. + % Some files (PDFOUT v3.8d by GenText) have EI immediately following + % the stream. Some have no EOL and garbage bytes. + % Therefore, we skip all bytes before EI or EOL + 0 + { PDFsource read not { //true exit } if + dup 10 eq 1 index 13 eq or + { pop PDFsource token pop /EI ne exit + } + if + exch 69 eq 1 index 73 eq and { //false exit } if % 'EI' + } + loop + exch pop + { /ID cvx /syntaxerror signalerror + } + if + } bdef +end + +% ================================ Text ================================ % + +drawopdict begin + % Text control + /BT { BT } def + /ET { ET } def + /Tc { Tc } def + /TL { TL } def + /Tr { Tr } def + /Ts { Ts } def + /Tw { Tw } def + /Tz { Tz } def + % Text positioning + /Td { Td } def + /TD { TD } def + /Tm { Tm } def + /T* { T* } def + % Text painting + /Tj { Tj } def + /' { ' } def + /" { " } def + /TJ { TJ } def +end + +% ============================== Annotations ============================== % + + + +% Get and normalize an annotation's rectangle. +/annotrect { % <annot> annotrect <x> <y> <w> <h> + /Rect get aload pop + exch 3 index sub dup 0 lt { dup 5 -1 roll add 4 1 roll neg } if + exch 2 index sub dup 0 lt { dup 4 -1 roll add 3 1 roll neg } if +} bdef + +% Set an annotation color. +/annotsetcolor { % <annot> annotsetcolor - + /C knownoget { aload pop setrgbcolor } { 0 setgray } ifelse +} bdef + +% Draw the border. Currently, we ignore requests for beveling, and we +% don't round the corners of rectangles. +/strokeborder { % <annot> <width> <dash> strokeborder - + 1 index 0 ne { % do not draw if border width is 0 + gsave + 2 index annotsetcolor + 0 setdash dup setlinewidth + exch annotrect + 2 { 4 index sub 4 1 roll } repeat + 2 { 4 index 0.5 mul add 4 1 roll } repeat + rectstroke pop + grestore + } { + pop pop pop + } ifelse +} bdef + +% Draw an annotation border. +/drawborder { % <annot> drawborder - + gsave + dup /BS knownoget { + dup /W knownoget not { 1 } if + [] 2 index /S knownoget { + /D eq { 2 index /D knownoget not { [3] } if exch pop } if + } if 3 -1 roll pop strokeborder + } { + dup /Border knownoget { + dup 2 get + exch dup length 3 gt { 3 get } { pop [] } ifelse + strokeborder + } { + 1 [] strokeborder + } ifelse + } ifelse + grestore +} bdef + +% +% The PDF annotation F (flags) integer is bit encoded. +% Bit 1 (LSB) Invisible: 1 --> Do not display if no handler. +% Note: We have no handlers but we ignore this bit. +% Bit 2 Hidden: 1 --> Do not display. We will not display if this bit is set. +% Bit 3 Print: 1 --> Display if printing. We will display if this bit set +% (and not hidden) and Printed is true +% Bit 4 NoZoom: 1 --> Do not zoom annotation even if image is zoomed. +% Bit 5 NoRotate: 1 --> Do not rotate annotation even if image is rotated. +% Bit 6 NoView: 0 --> Display if this is a 'viewer'. We will display +% if this bit is not set (and not hidden) and Printed is false +% Bit 7 Read Only - 1 --> No interaction. We ignore this bit +% +/annotvisible { % <annot> annotvisible <visible> + /F knownoget not { 0 } if % Get flag value + dup 2 and 0 eq % Check hidden flag + exch dup 4 and 0 ne Printed and % Check print flag + exch 64 and 0 eq Printed not and % Check noview flag + or % Combine print and view + and % Combine with 'hidden' flag test +} bdef + +/drawwidget { % <scalefactor> <annot> drawwidget - + dup /AP knownoget { + % Always use the Normal appearance. + /N oget + % Acrobat Distiller produces files in which this Form + % XObject lacks Type and Subtype keys. This is illegal, + % but Acrobat Reader accepts it. The only way we can + % tell whether this is a Form or a set of sub-appearances + % is by testing for the stream Length key. + dup /Length known { + % If this is a form then simply use it + true + } { + 1 index /AS knownoget not { + % If we do not have AS then use any appearance + { exch pop oforce exit } forall true + } { + % Stack: annot Ndict AS + % Get the specified appearance. If no appearance, then + % display nothing - set stack = false. + knownoget + } ifelse + } ifelse + + % Stack: scale annot appearance true + % Stack: scale annot false + { + % Draw appearance + 1 index annotrect pop pop translate + 2 index dup scale % Apply scale factor + DoForm + } if + } if pop pop +} bdef + +% +% For stamp object we have to determine the size of the output rectangle +% and the size of the BBox for the stamp image. From these we calculate +% a scale factor for drawing the stamp. +% +/calcstampscale { % <annot> calcstampscale scale + dup annotrect 4 -2 roll pop pop pop % get x width + dup 0 lt { neg } if % get magnitude + exch /AP knownoget { + /N knownoget { + /BBox knownoget { + aload pop 4 -2 roll pop pop pop + div + } { + pop 1 % default to unity scaling + } ifelse % if we have /BBox + } { + pop 1 + } ifelse % if we have /N + } { + pop 1 + } ifelse % if we have /AP +} bdef + +/drawlink { % <annot> drawlink - + dup drawborder + 1 exch drawwidget +} bdef + +% Draw an annotation. +/drawannottypes mark + /Link { drawlink } bind + /Stamp { dup calcstampscale exch drawwidget } bind +.dicttomark readonly def +/drawannot { % <annot> drawannot - + dup annotvisible { + gsave + dup dup /Subtype get //drawannottypes exch .knownget { + exec + } { + 1 exch drawwidget % Use drawwidget for everything else + } ifelse % type known + grestore + } if pop % annotvisible +} bdef +currentdict /drawannottypes undef + +end % pdfdict +end % GS_PDF_ProcSet +.setglobal |