/
usr
/
share
/
ghostscript
/
Resource
/
Init
/
/usr/share/ghostscript/Resource/Init
mkdir
upload
Name
Size
Mode
Actions
cidfmap
2156
0644
edit
dl
rm
FAPIcidfmap
1483
0644
edit
dl
rm
FAPIconfig
815
0644
edit
dl
rm
FAPIfontmap
1468
0644
edit
dl
rm
FCOfontmap-PCLPS2
2857
0644
edit
dl
rm
Fontmap
109
0644
edit
dl
rm
Fontmap.GS
12929
0644
edit
dl
rm
gs_agl.ps
218021
0644
edit
dl
rm
gs_btokn.ps
12765
0644
edit
dl
rm
gs_cet.ps
4964
0644
edit
dl
rm
gs_cff.ps
6969
0644
edit
dl
rm
gs_cidcm.ps
16827
0644
edit
dl
rm
gs_ciddc.ps
8505
0644
edit
dl
rm
gs_cidfm.ps
8069
0644
edit
dl
rm
gs_cidfn.ps
14547
0644
edit
dl
rm
gs_cidtt.ps
5847
0644
edit
dl
rm
gs_cmap.ps
18444
0644
edit
dl
rm
gs_cspace.ps
4059
0644
edit
dl
rm
gs_dbt_e.ps
2134
0644
edit
dl
rm
gs_diskn.ps
6867
0644
edit
dl
rm
gs_dps1.ps
4756
0644
edit
dl
rm
gs_dps2.ps
8771
0644
edit
dl
rm
gs_dscp.ps
3938
0644
edit
dl
rm
gs_epsf.ps
12161
0644
edit
dl
rm
gs_fapi.ps
15611
0644
edit
dl
rm
gs_fntem.ps
11389
0644
edit
dl
rm
gs_fonts.ps
48531
0644
edit
dl
rm
gs_frsd.ps
3780
0644
edit
dl
rm
gs_icc.ps
3104
0644
edit
dl
rm
gs_il1_e.ps
2722
0644
edit
dl
rm
gs_img.ps
23998
0644
edit
dl
rm
gs_init.ps
94572
0644
edit
dl
rm
gs_lev2.ps
43850
0644
edit
dl
rm
gs_ll3.ps
19572
0644
edit
dl
rm
gs_mex_e.ps
3843
0644
edit
dl
rm
gs_mgl_e.ps
2181
0644
edit
dl
rm
gs_mro_e.ps
2506
0644
edit
dl
rm
gs_pdfwr.ps
32179
0644
edit
dl
rm
gs_pdf_e.ps
1556
0644
edit
dl
rm
gs_res.ps
42450
0644
edit
dl
rm
gs_resmp.ps
22482
0644
edit
dl
rm
gs_setpd.ps
38487
0644
edit
dl
rm
gs_statd.ps
17851
0644
edit
dl
rm
gs_std_e.ps
3143
0644
edit
dl
rm
gs_sym_e.ps
3104
0644
edit
dl
rm
gs_trap.ps
2946
0644
edit
dl
rm
gs_ttf.ps
66173
0644
edit
dl
rm
gs_typ32.ps
4560
0644
edit
dl
rm
gs_typ42.ps
2096
0644
edit
dl
rm
gs_type1.ps
12543
0644
edit
dl
rm
gs_wan_e.ps
1563
0644
edit
dl
rm
pdf_base.ps
60815
0644
edit
dl
rm
pdf_draw.ps
188723
0644
edit
dl
rm
pdf_font.ps
98378
0644
edit
dl
rm
pdf_main.ps
143907
0644
edit
dl
rm
pdf_ops.ps
75878
0644
edit
dl
rm
pdf_rbld.ps
20480
0644
edit
dl
rm
pdf_sec.ps
27865
0644
edit
dl
rm
xlatmap
1767
0644
edit
dl
rm
Edit:
/usr/share/ghostscript/Resource/Init/pdf_draw.ps
(188723B)
% Copyright (C) 2001-2021 Artifex Software, Inc. % 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. % % Refer to licensing information at http://www.artifex.com or contact % Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, % CA 94945, U.S.A., +1(415)492-9861, for further information. % % pdf_draw.ps % PDF drawing operations (graphics, text, and images). /.setlanguagelevel where { pop 2 .setlanguagelevel } if .currentglobal //true .setglobal /GS_PDF_ProcSet load 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. % We need to process all required and optional parameters to resolve any % use of indirect references. /fnrdict mark 0 { .resolvefn0 } 2 { .resolvefn2 } 3 { .resolvefn3 } 4 { .resolvefn4 } .dicttomark readonly def /.resolvefn0 { dup length 1 add dict .copydict % make room for DataSource % now resolve any indirect references dup /Size 2 copy knownoget { put } { pop pop } ifelse dup /BitsPerSample 2 copy knownoget { put } { pop pop } ifelse dup /Order 2 copy knownoget { put } { pop pop } ifelse dup /Encode 2 copy knownoget { put } { pop pop } ifelse dup /Decode 2 copy knownoget { put } { pop pop } ifelse % 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 get length 2 idiv 2 index /BitsPerSample get mul 2 index /Size get { mul } forall 7 add 8 idiv dup 65535 le { string 1 index exch readstring pop } { 1 index exch () /SubFileDecode filter /ReusableStreamDecode filter } ifelse exch closefile % Stack: filepos fndict data exch dup /DataSource 4 -1 roll put exch PDFfile exch setfileposition } bind executeonly def /.resolvefn2 { dup length dict .copydict dup /C0 2 copy knownoget { put } { pop pop } ifelse dup /C1 2 copy knownoget { put } { pop pop } ifelse dup /N 2 copy knownoget { put } { pop pop } ifelse } bind executeonly def /.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 } bind executeonly def /.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 } bind executeonly def /.resolvefn { % <fndict> .resolvefn <fndict'> dup length dict .copydict dup /Domain 2 copy knownoget { put } { pop pop } ifelse dup /Range 2 copy knownoget { put } { pop pop } ifelse dup /FunctionType oget //fnrdict exch get exec } bind executeonly def /resolvefunction { % <fndict> resolvefunction <function> .resolvefn PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Function: ) print dup === flush } if } if } bind executeonly def /resolvefnproc { % <fndict> resolvefnproc <proc> resolvefunction .buildfunction } bind executeonly def /resolveidfnproc { % <fndict> resolveidfnproc <proc> dup /Identity eq { pop { } } { resolvefnproc } ifelse } bind executeonly def /resolvedefaultfnproc { % <fndict> <default> resolved'fnproc <proc> 1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse } bind executeonly def %% A BBox where width or height (or both) is 0 should still paint one pixel %% See the ISO 32000-2:2017 spec, section 8.7.4.3, p228 'BBox' and 8.7.3.1 /FixPatternBBox { dup aload pop 3 index 2 index sub 0 eq { 3 index 0.000001 add 3 -1 roll pop exch } if 2 index 1 index sub 0 eq { 2 index 0.000001 add exch pop }if 5 -1 roll astore }bind executeonly def % ---------------- Shadings ---------------- % /shrdict mark /Coords { aload 5 1 roll 4 { % Bug 694542 dup type dup /integertype ne exch /realtype ne and { ( **** Error: replacing malformed number ') pdfformaterror pdfstring cvs pdfformaterror (' with 0.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror 0 } if 4 1 roll } repeat 5 -1 roll astore } bind executeonly /BBox { dup dup dup aload pop normrect_elems 5 -1 roll astore FixPatternBBox } bind executeonly /ColorSpace { resolvecolorspace } bind executeonly /Function { dup type /dicttype eq { resolvefunction } { [ exch { oforce resolvefunction } forall ] } ifelse } bind executeonly /Extend { mark exch {oforce} forall ] } bind executeonly .dicttomark readonly def /resolveshading { % <shadingstream> resolveshading <shading> dup /.shading_dict .knownget { exch pop dup /ShadingType get 4 ge { dup /DataSource get 0 setfileposition } if } { dup 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 dup 3 1 roll /.shading_dict exch put } ifelse } bind executeonly def /resolvesh { % <shname> resolvesh <shading> % <shname> resolvesh <null> Page /Shading rget { %% Horrible hacky fix, see /DoImage later in ths file for more information %% dup /ColorSpace known { dup /ColorSpace get dup type /arraytype eq { exch dup length dict copy exch dup length array copy /ColorSpace exch 2 index 3 1 roll put } {pop} ifelse } if resolveshading } { //null }ifelse } bind executeonly def % ---------------- 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 } bind executeonly /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 } bind executeonly /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 } bind executeonly /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub } bind executeonly /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub } bind executeonly /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub } bind executeonly /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub } bind executeonly /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub } bind executeonly /Line { exch pop abs neg } bind executeonly /LineX { pop } bind executeonly /LineY { exch pop } bind executeonly /Square { abs exch abs 2 copy lt { exch } if pop neg } bind executeonly /Cross { abs exch abs 2 copy gt { exch } if pop neg } bind executeonly /Rhomboid { abs exch abs 0.9 mul add 2 div } bind executeonly /DoubleDot { 2 {360 mul sin 2 div exch } repeat add } bind executeonly /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg } bind executeonly /SimpleDot { dup mul exch dup mul add 1 exch sub } bind executeonly /InvertedSimpleDot { dup mul exch dup mul add 1 sub } bind executeonly /CosineDot { 180 mul cos exch 180 mul cos add 2 div } bind executeonly /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add } bind executeonly /InvertedDouble { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg } bind executeonly .dicttomark readonly def /.resolveht1 { mark exch { oforce 1 index /SpotFunction eq { dup type /arraytype eq { %% check all the names in the array in turn, stop when we find %% the first one we recognise. { //spotfunctions exch .knownget { exit } if } forall dup type /nametype eq { %% If we didn't find any that we recognise, then use %% the default halftone's spot function .setdefaulthalftone currenthalftone dup /SpotFunction .knownget { exch pop }{ /GraySpotFunction .knownget not { //spotfunctions /Round get } if }ifelse } if }{ dup type /nametype eq { //spotfunctions exch get } { resolvefnproc } ifelse } ifelse } { 1 index /TransferFunction eq { resolveidfnproc } if } ifelse } forall .dicttomark } bind executeonly def /.resolveht5 { mark exch { oforce dup type /dicttype eq { resolvehalftone } if } forall .dicttomark } bind executeonly def /.resolveht6 { %% resolvestream will reposition PDFfile. If we are in the middle %% of reading a content stream from PDFfile when we execute this, %% then reading the next buffer will read from the wrong place. We %% must save and restore the position of PDFfile. See the definition %% of resolvestream. Bug #695886 PDFfile fileposition exch mark exch { oforce } forall .dicttomark dup dup //false resolvestream /ReusableStreamDecode filter /Thresholds exch put dup /TransferFunction .knownget { resolveidfnproc 1 index exch /TransferFunction exch put } if exch PDFfile exch setfileposition } bind executeonly def /htrdict mark 1 //.resolveht1 5 //.resolveht5 6 //.resolveht6 10 //.resolveht6 16 //.resolveht6 .dicttomark readonly def currentdict /.resolveht1 undef currentdict /.resolveht5 undef currentdict /.resolveht6 undef /resolvehalftone { % <dict> resolvehalftone <halftone> dup /HalftoneType oget dup //htrdict exch .knownget { exch pop exec } { =string cvs ( **** Error: Incorrect halftone type ) exch concatstrings (. Using defailt.\n) concatstrings pdfformaterror ( Output may be incorrect.\n) pdfformaterror gsave .setdefaulthalftone currenthalftone grestore } ifelse } bind executeonly def % ---------------- Graphics state management ---------------- % /cmmatrix matrix def drawopdict begin % Graphics state stack /q { q } executeonly def /Q { Q } executeonly def % Graphics state setting /cm { //cmmatrix astore .getpath exch concat newpath { exec } forall % If inside a BT/ET block, we need to update the TextSaveMatrix currentdict /TextSaveMatrix .knownget { //cmmatrix exch dup concatmatrix pop } if % And if we ha\ve done a gsave inside a text block, we need to update % that matrix instead. currentdict /qTextSaveMatrix .knownget { //cmmatrix exch dup concatmatrix pop } if } bind executeonly def /i { 1 .min setflat } bind executeonly def /J { setlinecap } bind 0 get def /d { setdash } bind 0 get def /j { setlinejoin } bind 0 get def /w { setlinewidth } bind 0 get def /M { 1 .max setmiterlimit } bind executeonly def /gs { gs } executeonly def end % Each entry in this dictionary is % <gsres> <value> -proc- <gsres> /gsbg { /BGDefault load resolvedefaultfnproc setblackgeneration } bind executeonly def /gsucr { /UCRDefault load resolvedefaultfnproc setundercolorremoval } bind executeonly def /gstr { dup type /arraytype eq { { oforce /TRDefault load resolvedefaultfnproc } forall setcolortransfer } { /TRDefault load resolvedefaultfnproc settransfer } ifelse } bind executeonly def /gsparamdict mark /SA { setstrokeadjust } executeonly /OP { 1 index /op known not { dup op } if OP } executeonly % 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 } executeonly /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse } executeonly /TR { 1 index /TR2 known { pop } { gstr } ifelse } executeonly % Some functions used to implement phases of HT and HTP /sethalftones { % As is so often the case, if we get an error we need to clean up the stack, but we can't % use mark/cleartomark, because the action which caused the error may have left a mark % on the stack. So we need to define our own mark. On an error we'll clean up the stack % until we reach this unique key on the stack /SethalftonesMark exch dup /Default eq { pop .setdefaulthalftone pop } { {resolvehalftone} stopped { (\n **** Error resolving halftone. Ignoring the halftone, output may be incorrect.\n) pdfformaterror % Clean up the stack by checking every entry until we find our unique key {/SethalftonesMark eq {exit} if} loop } { {sethalftone} stopped { (\n **** Error setting halftone. Ignoring the halftone, output may be incorrect.\n) pdfformaterror % Clean up the stack by checking every entry until we find our unique key {/SethalftonesMark eq {exit} if} loop } { pop }ifelse }ifelse } ifelse } bind executeonly def /sethalftonephases { {aload pop -1 2 index 2 index .setscreenphase pop pop} stopped { (\n **** Error setting halftone phase. Ignoring the phase, output may be incorrect.\n) pdfformaterror } if } bind executeonly def /HT { dup sethalftones .swapcolors sethalftones .swapcolors % the transfer function may dependent on the halftone, so make sure % it is set if included in the graphic state (otherwise this is % subject to order of a dictionary forall, which is unpredictable) dup /TR2 .knownget { dup /Default eq { oforce gsparamdict /TR2 get exec } { pop } ifelse } { dup /TR .knownget { /dup /Default eq { oforce gsparamdict /TR get exec } { pop } ifelse } if } ifelse } executeonly /HTP { % HTP may be present even if this isn't a DPS interpreter. dup sethalftonephases .swapcolors sethalftonephases .swapcolors } executeonly % PDF 1.3 % The font is an indirect reference, not a resource name /Font { aload pop exch oforce resourcefont exch Tf } /LW { setlinewidth } executeonly /LC { setlinecap } executeonly /LJ { setlinejoin } executeonly /ML { 1 .max setmiterlimit } executeonly /D { aload pop setdash } executeonly /RI { ri } executeonly /op { op } executeonly /OPM { OPM } executeonly /BG2 { gsbg } executeonly /UCR2 { gsucr } executeonly /TR2 { gstr } executeonly /FL { 1 .min setflat } executeonly /SM { % SM may be present even if this is only a Level 2 interpreter. /setsmoothness where { pop setsmoothness } { pop } ifelse } executeonly % PDF 1.4 % All of these require the "transparency" feature in the interpreter. /ca { ca } executeonly /CA { CA } executeonly /SMask { {gssmask} PDFSTOPONERROR { exec //false } { stopped } ifelse { pop (\n **** Error in SMask during ExtGState. Ignoring the mask, output may be incorrect.\n) pdfformaterror } if } executeonly /AIS { AIS } executeonly /BM { BM } executeonly /TK { TK } executeonly /UseBlackPtComp { UseBlackPtComp } executeonly /HTO { % PDF 2.0, supposed to be 'similar' to halftone phase but using a different % co-ordiate system. Treat the same for now and fix if anyone ever complains. aload pop transform cvi exch cvi exch 2 array astore dup sethalftonephases .swapcolors sethalftonephases .swapcolors } executeonly .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 } { //pdfdict /.gs_warning_issued known not { (\n **** Error 'gs' ignored -- ExtGState missing from Resources.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror //pdfdict /.gs_warning_issued //true .forceput PDFSTOPONERROR { /gs /undefined signalerror } if } executeonly if } executeonly ifelse } bind executeonly def % ------ Transparency support ------ % /gssmask { { dup type /dicttype eq { dup /G knownogetdict {pop} { ( **** Error: Ignoring invalid transparency SMask group\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror % replace the invalid SMask object pop /None } ifelse } if dup /None eq 1 index //null eq or PDFusingtransparency not or { pop //null .currentSMask //null ne { % get rid of the current SMask (Bug 695471) //false % colorspace not set << /Subtype /None >> % Special type for this purpose 0 0 0 0 % fake BBox .begintransparencymaskgroup } if exit } if % Preprocess the SMask value into a parameter dictionary for % .begintransparencymaskgroup, 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 { dup /Background exch 4 2 roll 1 index /G oget /Group knownoget not { ( **** Error: Ignoring a transparency group XObject without /Group attribute.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror cleartomark //null exit } if gsave //nodict begin dup /CS knownoget { exch pop resolvecolorspace dup setgcolorspace csput } { % Group attributes dictionaries are supposed to contain a /CS % entry, but Acrobat apparently also handles a /ColorSpace.... /ColorSpace knownoget { ( **** Error: A transparency group XObject has a /ColorSpace instead of /CS attribute.\n) pdfformaterror resolvecolorspace dup setgcolorspace csput } { ( **** Error: Ignoring a transparency group XObject without /CS attribute.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror cleartomark //null exit }ifelse } ifelse aload pop setcolor [ currentgray ] end grestore /GrayBackground exch 3 2 roll } if dup /TR knownoget { dup /Identity eq { pop } { resolvefnproc /TransferFunction exch 3 2 roll } ifelse } if dup /G oget dup /BBox oget oforce_array 1 index /Matrix knownoget { oforce_array .bbox_transform 4 array astore } if /BBox exch 4 2 roll % Because we don't execute the group form stream until we find % out whether we're actually going to draw through it, we need % to save the current gstate with the other parameters, so % we can subsequently execute it in the correct graphics state. % We need to concatenate the Matrix in this gstate as per the PDF % spec 7.5.4 (p. 552 in the PDF 1.7 Ref) (bug 694455). gsave dup /Matrix knownoget { matrix currentmatrix matrix concatmatrix setmatrix } if /GroupGState gstate currentgstate 6 2 roll grestore /GroupMat matrix currentmatrix 8 2 roll % /GroupExtGState 1 dict % 10 2 roll /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll pop .dicttomark exit } loop SMask } bind executeonly def % Functions specific to the Device* colorspaces to force the switch to % the Device* colorspace so that the SMask will not get a CIEBased* colorspace % in the case when UseCIEColor changes the Device* colorspace to something else. % Also see the logic in pdf_main.ps:pdfopen that similarly defines these resources. /forceDefaultCS << { currentcolorspace setcolorspace % this will switch to Device colorspace } bind executeonly /DeviceGray exch /DeviceRGB 1 index /DeviceCMYK 1 index >> def % This procedure is called to actually render the soft mask. /.execmaskgroup { % <masknum> <paramdict> <formdict> .execmaskgroup - % Save our place in PDFfile. Do not use gsave-grestore when creating % a soft mask with .begintransparencygroup because high level devices % need to modify the graphic state by storing the soft mask ID. % Save the ExtGState (//nodict begin) BEFORE changing the colorspace //nodict begin matrix currentmatrix 4 1 roll mark currentcolor counttomark dup 4 add exch roll pop currentcolorspace 4 1 roll .getuseciecolor 4 1 roll .swapcolors mark currentcolor counttomark dup 4 add exch roll pop currentcolorspace 4 1 roll .swapcolors currentuserparams /OverrideICC get 4 1 roll mark /OverrideICC //true .dicttomark setuserparams % We can't simply set the group's gstate here because % we can't use gsave/grestore. So we actually set it % in .execgroup. But the matrix needs set here for % .begintransparencymaskgroup to correctly work. % It might seem we should also set the colorspace % in case the group doesn't have one, *but* empirical % suggests that is not the case - fts_26_2600.pdf and % fts_26_2603.pdf render incorrectly if we set the % colrospace 1 index /GroupMat .knownget { setmatrix } if PDFfile fileposition 4 1 roll % We have to select the group's color space so that the % background color will be interpreted correctly. % [save/restore]DefaultCS make sure that the SMask logic sees % the Device* spaces, not CIEBased* that UseCIEColor may have % established. //false .setuseciecolor % SMask gets processed without UseCIEColor dup /Group oget /CS knownoget { resolvecolorspace dup setgcolorspace csput //true % use currentcolorspace } { % Group attributes dictionaries are supposed to contain a /CS % entry, but Acrobat apparently also handles a /ColorSpace.... dup /Group oget /ColorSpace knownoget { ( **** Error: A transparency group attribute dictionary has a /ColorSpace instead of /CS attribute.\n) pdfformaterror resolvecolorspace dup setgcolorspace csput //true % use currentcolorspace } { % inheriting the colorspace -- make sure Device* spaces are not CIEBased forceDefaultCS currentcolorspace 0 get .knownget { exec } if //false % no defined colorspace } ifelse } ifelse 3 -1 roll dup dup 4 1 roll /BBox get aload pop .begintransparencymaskgroup exch dup /Resources knownoget { oforce } { 2 dict } ifelse 3 -1 roll /GroupGState .knownget { 1 index /GroupGState 3 -1 roll put} if exch //false resolvestream 1 index exch %% Get the current colour space and colour values (as an array), we need to pass these to .execgroup %% as well, so that it can restore them, in case the colour space gets changed by transparency %% graphics state stuff. mark currentcolor counttomark array astore exch pop currentcolorspace 4 2 roll .execgroup % We have to remove these in case the Form XObject is subsequently used as % a form rather than a group - they remain in the paramdict for the SMask % so this will all still work if the SMask is re-evaluated. /GroupGState undef .endtransparencymask PDFfile exch setfileposition mark exch /OverrideICC exch .dicttomark setuserparams .swapcolors setcolorspace setcolor .swapcolors .setuseciecolor setcolorspace setcolor setmatrix end % restore colorspace, color and ExtGState (end) .currentSMask /Processed //true put % special setting to tell us it has been rendered } bind executeonly def % Paint a Form+Group XObject, either for a transparency mask or for a Do. /.execgroup { % [colour values] <colour space> <resdict> <stream> .execgroup - pdfemptycount 3 1 roll /pdfemptycount count 5 sub store gsave //nodict begin % We have to set the gstate correctly for lazy evaluation of a softmask group. % we also must restore the color(space) as setup in .execmaskgroup or paintformgroup. % This stuff must be done here, as .execmaskgroup can't use gsave/grestore to % manipulate the gstates, due to the requirements of .begintransparencymaskgroup. % We also must set the ExtGState values. % It may seem redundant to do the color(space) twice (once here and once in % .execmaskgroup) but we have to set it in .execmaskgroup for the background % color and set it here once in the correct gstate. 1 index /GroupGState .knownget { setgstate } if newpath //null SMask 1 CA 1 ca /Compatible .setblendmode % Execute the body of the Form, similar to DoForm. pdfopdict %% Restore the colour space (passed in on the stack) and current colour %% 6 -2 roll setcolorspace aload pop setcolor .pdfruncontext end grestore % check for extra garbage on the operand stack and clean it up count pdfemptycount sub dup 0 ne { ( **** Error: Transparency Group, Form XObject execution corrupted the stack.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror PDFSTOPONERROR { /.execgroup cvx /rangecheck signalerror } { dup 0 gt { { pop } repeat }{ pop } ifelse } ifelse } { pop } ifelse /pdfemptycount exch store } bind executeonly def /.beginformgroup { % groupdict bbox .beginformgroup - exch mark exch % bbox mark groupdict dup /CS knownoget { resolvecolorspace dup setgcolorspace /CS exch 3 2 roll} 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 } bind executeonly def /.beginpagegroup { % groupdict bbox .beginformgroup - currentcolorspace 3 1 roll exch mark exch % bbox mark groupdict dup /CS knownoget { resolvecolorspace dup setgcolorspace /CS exch 3 2 roll} 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 .begintransparencypagegroup setcolorspace } bind executeonly def % .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 - %% Pass the current color space, and an array with the current color vales %% as arguments to .execgroup mark currentcolor counttomark array astore exch pop currentcolorspace 5 2 roll dup /Group oget dup type /dicttype eq { exch /BBox oget dup type /arraytype eq { % Stack: resdict stream groupdict bbox .beginformgroup .execgroup .endtransparencygroup }{ ( **** Error: Form XObject has a BBox entry with an invalid type.\n) pdfformaterror ( Ignoring transparency Group, output may be incorrect.\n) pdfformaterror pop pop pop pop pop pop } ifelse } { ( **** Error: Form XObject has a Group entry with an invalid type.\n) pdfformaterror ( Ignoring transparency Group, output may be incorrect.\n) pdfformaterror pop pop pop pop pop pop } ifelse } bind executeonly def % 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} stopped {pop} if def PDFfile exch setfileposition currentdict end currentdict end 5 dict begin /ImageType 103 def /DataDict exch def dup /InterleaveType 3 put DataDict /Matte knownoget { /Matte exch def } if .currentalphaisshape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def /ColorSpace DataDict /ColorSpace get def } bind executeonly def % ---------------- 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 9 dict begin /DeviceGray { pop 1 } bind executeonly def /DeviceRGB { pop 3 } bind executeonly def /DeviceCMYK { pop 4 } bind executeonly def /CIEBasedA //DeviceGray def /CIEBasedABC //DeviceRGB def /CalGray //DeviceGray def /CalRGB //DeviceRGB def /Lab //DeviceRGB def /ICCBased { 1 oget /N oget } bind executeonly def /Separation //DeviceGray def /DeviceN { 1 oget length } bind executeonly def /Indexed //DeviceGray def currentdict end readonly def % <colorspace> csncomp <n> /csncomp { dup dup type /arraytype eq { 0 oget } if //csncompdict exch get exec } bind executeonly def currentdict /csncompdict undef /ICCBased-resolve { PDFfile fileposition exch dup dup 1 oget mark exch { oforce } forall .dicttomark dup dup //true resolvestream { /ReusableStreamDecode filter } stopped { pop null % ( **** Error: Failed to read ICC profile for an ICCBased colour space.\n) pdfformaterror % ( Falling back to a colour space determined by the /N value.\n) pdfformaterror }if /DataSource exch put dup /.hash 0 put % placeholder for use by seticc icc_profile_cache key % Check that the number of components (/N) defined in the ICCBased % dictionry matches the actual profile. Bug #696120 dup /N get 1 index %% If we get an error reading the profile, just assume that /N is correct %% If its genuinely faulty we will use an alternate based on /N. {.numicc_components} stopped {pop dup} if dup 3 -1 roll ne { %% /N and the actual number of components don't match. Ensure %% that we have a valid number of components from the ICC %% profile. Certain kinds of profile can't determine the numebr of components %% and in ths case we must not override the /N value. dup 0 gt { ( **** Error: ICCbased space /N value does not match the ICC profile.\n) pdfformaterror ( Using the number of channels from the profile.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror 1 index dup /N get /OrigN exch put 1 index exch /N exch put }{ pop } ifelse } { pop } ifelse 1 exch put exch PDFfile exch setfileposition % Resolve alternate color space dup 1 get % Get colorspace dictionary dup /Alternate .knownget { % Check for alternate color space oforce resolvecolorspace /Alternate exch put % resolve and replace } { pop % remove colorspace dictionary } ifelse } bind executeonly def /csrdict 13 dict begin /DeviceGray { } bind executeonly def /DeviceRGB { } bind executeonly def /DeviceCMYK { } bind executeonly def /CalGray { 1 oget [ exch /CalGray exch ] } bind executeonly def /CalRGB { 1 oget [ exch /CalRGB exch ] } bind executeonly def /Lab { 1 oget [ exch /Lab exch ] } bind executeonly def /CalCMYK { pop /DeviceCMYK % not defined by Adobe } bind executeonly def /ICCBased { dup 1 get type /dicttype ne { % don't resolve more than once ICCBased-resolve } if } bind executeonly def /Separation { aload pop exch oforce resolvecolorspace % Contrary to PDF manuals up to v.1.5, Acrobat Distiller 3.01 % can use /Identity name here instead of a function. exch oforce resolveidfnproc %% Make sure the ink name is not an indirect object.... 3 -1 roll oforce 3 1 roll 4 array astore } bind executeonly def /DeviceN { [ exch aload pop ] % Copy into a new array dup dup 1 oget % Resolve Names array [ exch { oforce } forall ] % resolve each of the names 1 exch put dup dup 2 oget resolvecolorspace 2 exch put dup dup 3 oget resolvefnproc 3 exch put dup length 4 gt { % Check for attributes dict dup dup 4 oget % devn_array devn_array attr_dict dup /Colorants knownoget % Check for Colorants Dict { % Create a new attribute dict with only a Colorants dict entry. % Resolve all of the Colorant dict entries. This is needed % to prevent a conflict if we attempt to resolve the tint % transform functions of the Colorant color spaces multiple % times. exch pop % Remove old attributes dict << exch % Start new attributes dict % Build new Colorants dict with resolved entries << exch { oforce resolvecolorspace } forall >> /Colorants exch >> % Finish new attributes dict } if % devn_array devn_array <<..attributes..>> 1 index 4 oget /Process knownoget { dup /ColorSpace knownoget { 1 index exch resolvecolorspace /ColorSpace exch put } if % devn_array devn_array <<..attributes..>> <<..Process..>> 1 index /Process 3 -1 roll put } if 4 exch put % Put resolved or new attributes dict } if } bind executeonly def /Indexed { aload pop %% Resolve 'hival' in case it is an indirect reference. This is kind of %% dumb, it just makes the file bigger, but it *is* legal. 3 1 roll oforce 3 -1 roll 1 index -1 eq { exch pop 255 exch ( **** Error: Highest color index given as -1. Assuming this actually means 255.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } if 3 -1 roll oforce resolvecolorspace % Stack: /Indexed hival lookup basespace % 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 % Stack: /Indexed csp comp table 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 dup /Filter oknown not { % For Bug691941.pdf and similar lossage dup /Length knownoget not { 0 } if } { 0 } ifelse % Stack: filepos /Indexed basespace hival lookup Length 2 index 1 add % Stack: filepos /Indexed basespace hival lookup Length len 4 index csncomp mul .max string % Stack: filepos /Indexed basespace hival lookup (...) exch //true resolvestream 1 index readstring not { % The string is padded with 0s ( **** Error: Short look-up table in the Indexed color space was padded with 0's.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } if pop % Stack: filepos /Indexed basespace hival (...) PDFfile 6 -1 roll setfileposition } if 4 array astore % Stack: [filepos /Indexed basespace hival (...)] % Replace the PDFColorSpace with the Indexed space if needed. dup 1 get dup type /arraytype eq { dup length 2 ge { dup 1 get type /dicttype eq { dup 1 get /PDFColorSpace known { dup 1 get /PDFColorSpace 3 index put } if } if } if } if pop } bind executeonly def /I { % Bug 689815 ( **** Error: The name /Indexed cannot be abbreviated to /I in the color space\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror dup 0 /Indexed put //Indexed exec } bind executeonly def /Pattern { dup type /nametype ne { dup length 1 gt { 1 oget resolvecolorspace /Pattern exch 2 array astore } if } if } bind executeonly def currentdict end readonly def /cssubst { % <csname> cssubst <cspace'> true % <csname> cssubst false dup resolvecolorspace dup 1 index ne { exch pop //true } { pop pop //false } ifelse } bind executeonly def /csnames mark /DeviceGray dup /DeviceRGB dup /DeviceCMYK dup /Pattern dup .dicttomark readonly def /csresolve { % <csresourcename> csresolve <cspace> <true> | <false> dup type /nametype ne { (\n **** Error: CS/cs (setcolorspace) operand not a name: ) pdfformaterror dup stderrfile dup 3 -1 roll write==only flushfile ( ****\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror dup type /arraytype eq { % Adobe InDesign + PDF Library has array resolvecolorspace } if //true } { dup Page /ColorSpace rget { exch pop resolvecolorspace //true } { //csnames 1 index known { //true } { ( **** Error: Undefined space resource: /) exch .namestring concatstrings (\n) concatstrings pdfformaterror ( Output may be incorrect.\n) pdfformaterror //false } ifelse } ifelse } ifelse } bind executeonly def /resolvecolorspace { % <cspace> resolvecolorspace <cspace'> dup type /dicttype eq { dup /N known { ( **** ICCBased color space is a bare stream dictionary\n) pdfformatwarning [ /ICCBased 3 -1 roll ] ICCBased-resolve exec //false } { dup /ColorSpace knownoget { ( **** Error: unrecognised color space <</ColorSpace /Device...>>\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror exch pop //true } { //true } ifelse } ifelse } { //true } ifelse { dup dup type /arraytype eq { 0 get } if dup type /packedarraytype eq {exch pop exec dup} if //csrdict exch .knownget { exec dup type /nametype ne { dup length 1 eq { 0 get } if } if } { dup type /nametype eq { csresolve not { /DeviceRGB } if % Arbitrary } { csset exch pop } ifelse } ifelse } if } bind executeonly def /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 knownoget { 2 eq } { //false } ifelse } { .pdfcount 1 gt } ifelse } bind executeonly def %% Bug #696017 When we begin a text block, we switch to a special set of marking operations %% for paths, these ops don't use the current CTM, but the 'SavedTextMatrix', in order to %% correctly position marks which are illegally present inside a text block. But, if we are %% executing a PaintProc (eg for a pattern) we *don't* want to do that or the pattern will be wrong. %% So we moved the .pdfpaintproc to .actual_pdfpaintproc, and redefined .pdfpaintproc to test %% the current value of /m. We always switch to the regular marking operations, but if the definition %% of /m at the start of the PaintProc was a special text version, then we switch back to that after we %% finished running the PaintProc. /.actual_pdfpaintproc { % <patdict> <resdict> .pdfpaintproc - PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Begin PaintProc) print dup === flush } if } if PDFfile fileposition 3 1 roll q 1 index /PaintType oget 1 eq { % For colored patterns, set default fill and stroke colors. 0 g 0 G } { % For uncolored patterns, we have to unbind the current % color and color space before running the PaintProc. % Not true since moving the ExtGState parameters into the gstate. % //null sc1 //null SC1 } ifelse % Save old values on opstack, set pdfemptycount to new value. pdfemptycount countdictstack mark %% We can't simply 'def' into the dictionary saved by 'q' above, we need to %% call gput to copy it and store inside it. Stupid or what.... /pdfemptycount count 3 sub gput 5 3 roll % % Stack: ... <old emptycount> <dictcount> mark <patdict> <resdict> % | % New empty count points here -----------+ exch //false resolvestream pdfopdict .pdfruncontext cleartomark //false { countdictstack 2 index le { exit } if currentdict /n known not or currentdict /n known currentdict /self known or{ Q }{ (\n **** Error: File has unbalanced q/Q operators \(too many Q's\)\n Output may be incorrect.\n) //pdfdict /.Qqwarning_issued .knownget { { pop } { currentglobal //pdfdict gcheck .setglobal //pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror } executeonly ifelse } executeonly { currentglobal //pdfdict gcheck .setglobal //pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror } executeonly ifelse end } executeonly ifelse } executeonly loop { (\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) //pdfdict /.Qqwarning_issued .knownget { { pop } { currentglobal //pdfdict gcheck .setglobal //pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror } executeonly ifelse } executeonly { currentglobal //pdfdict gcheck .setglobal //pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror } executeonly ifelse } executeonly if pop % restore pdfemptycount /pdfemptycount exch def Q PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if PDFfile exch setfileposition } bind executeonly odef /.pdfpaintproc { %% Get the /m from pdfopdict (must be present) %% and check its a packedarray pdfopdict /m get dup type /packedarraytype eq { %% The non-text version of /m is executeonly, so if we can't read it, its not a text block. dup rcheck { %% get the initial element of the packedarray %% and check its a name 0 get dup type /nametype eq { %% If the name is inside_text_m then we are in a text block /inside_text_m eq }{ pop //false } ifelse }{ pop //false } ifelse }{ pop //false } ifelse %% rearrange the operands, move the boolean to the back 3 1 roll %% Uncopnditionally use the normal marking ops switch_to_normal_marking_ops .actual_pdfpaintproc %% If we were in a text block, restore the text marking ops. { switch_to_text_marking_ops } if }bind executeonly odef /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 knownoget { dup 65535 le { dup 0 eq { pop pop () } { string readstring pop } ifelse } { () /SubFileDecode filter /ReusableStreamDecode filter } ifelse } { 0 (endstream) /SubFileDecode filter /ReusableStreamDecode filter } ifelse % 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 dup /BBox 2 copy knownoget { normrect FixPatternBBox put } { pop pop } ifelse dup /.pattern_uses_transparency 1 index patternusestransparency put PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Pattern: ) print dup === flush } if } if } bind executeonly def /ignore_color_op ( **** Error: Ignoring a color operation in a cached context.\n Output may be incorrect.\n) readonly def drawopdict begin /g { .incachedevice { % Bug 689302 pop //ignore_color_op pdfformaterror } { /DeviceGray cssubst { cs sc1 } { g } ifelse } ifelse } bind executeonly def /rg { .incachedevice { pop pop pop //ignore_color_op pdfformaterror } { /DeviceRGB cssubst { cs sc* } { rg } ifelse } ifelse } bind executeonly def /k { .incachedevice { pop pop pop pop //ignore_color_op pdfformaterror } { k } ifelse } bind executeonly def /cs { .incachedevice { pop //ignore_color_op pdfformaterror } { csresolve { cs } if } ifelse } bind executeonly def /sc { .incachedevice { .pdfcount { pop } repeat //ignore_color_op pdfformaterror } { scresolve 1 index //null eq { pop pop //ignore_color_op pdfformaterror } { { sc*_and_set } { sc1_and_set } ifelse } ifelse } ifelse } bind executeonly def /scn /sc load def /G { .incachedevice { pop //ignore_color_op pdfformaterror } { /DeviceGray cssubst { CS SC1 } { G } ifelse } ifelse } bind executeonly def /RG { .incachedevice { pop pop pop //ignore_color_op pdfformaterror } { /DeviceRGB cssubst { CS SC* } { RG } ifelse } ifelse } bind executeonly def /K { .incachedevice { pop pop pop pop //ignore_color_op pdfformaterror } { K } ifelse } bind executeonly def /CS { .incachedevice { pop //ignore_color_op pdfformaterror } { csresolve { CS } if } ifelse } bind executeonly def /ri { .incachedevice { pop //ignore_color_op pdfformaterror } { ri } ifelse } bind executeonly def /SC { .incachedevice { .pdfcount { pop } repeat //ignore_color_op pdfformaterror } { scresolve 1 index //null eq { pop pop //ignore_color_op pdfformaterror }{ { SC*_and_set } { SC1_and_set } ifelse }ifelse } ifelse } bind executeonly def /SCN /SC load def end currentdict /ignore_color_op undef % ---------------- Paths ---------------- % drawopdict begin % Path construction /m { { moveto } stopped { count pdfemptycount sub 2 .min { pop } repeat 0 0 moveto } if } bind executeonly def /l { { lineto } stopped { count pdfemptycount sub 2 .min { pop } repeat } if } bind executeonly def /c { { curveto } stopped { count pdfemptycount sub 6 .min { pop } repeat } if } bind executeonly def /v { count pdfemptycount sub 4 ge { { currentpoint 6 2 roll curveto } stopped { count pdfemptycount sub 6 .min { pop } repeat } if } { count pdfemptycount sub { pop } repeat } ifelse } bind executeonly def /y { { 2 copy curveto } stopped { count pdfemptycount sub 6 .min { pop } repeat } if } bind executeonly def /re { 4 2 roll moveto exch dup 0 rlineto 0 3 -1 roll rlineto neg 0 rlineto closepath } bind executeonly def /h { closepath } bind 0 get def % Path painting and clipping /n { n } executeonly def /S { S } executeonly def /s { s } executeonly def /f { f } executeonly def /f* { f* } executeonly def /B { B } executeonly def /b { b } executeonly def /B* { B* } executeonly def /b* { b* } executeonly def /W { W } executeonly def /W* { W* } executeonly def /sh_save 1 array def /do_shade { 0 .setoverprintmode { dup /.shading .knownget { exch pop } { .buildshading_and_shfill } ifelse } stopped { pop ( **** Error: Ignoring invalid smooth shading object, output may be incorrect.\n) pdfformaterror } if } bind executeonly def /sh { OFFlevels length 0 eq { setsmaskstate resolvesh //sh_save 0 save put PDFusingtransparency { gsave dup /BBox knownoget { { oforce } forall 4 2 roll moveto exch 0 lineto 0 exch lineto closepath } { clippath } ifelse % If we get an error, just emit an empty box { pathbbox } stopped { 0 0 0 0 } if 4 array astore grestore //null setup_trans //do_shade exec teardown_trans } { //do_shade exec } ifelse //sh_save 0 get restore } { pop } ifelse } bind executeonly def currentdict dup /sh_save undef /sh_group undef end % ---------------- XObjects ---------------- % /xobjectprocs mark % <dict> -proc- - /Image { DoImage } executeonly /Form { DoForm } executeonly /PS { DoPS } executeonly .dicttomark readonly def % Note that the keys in defaultdecodedict are resolved (PostScript, not PDF) % color space names. /defaultdecodedict mark /DeviceGray { pop //01_1 } bind executeonly /DeviceRGB { pop //01_3 } bind executeonly /DeviceCMYK { pop //01_4 } bind executeonly /CIEBasedA { 1 get /RangeA knownoget not { //01_1 } if } bind executeonly /CIEBasedABC { 1 get /RangeABC knownoget not { //01_3 } if } bind executeonly /CalGray { pop //01_1 } bind executeonly /CalRGB { pop //01_3 } bind executeonly /Lab { 1 get /Range knownoget not { [-100 100 -100 100] } {aload pop 0 100 6 2 roll 6 array astore}ifelse } bind executeonly /ICCBased { 1 oget dup /Range knownoget { exch pop }{ /N get [ exch {0 1} repeat ] readonly } ifelse } bind executeonly /Separation { pop //01_1 } bind executeonly /DeviceN { 1 oget length [ exch {0 1} repeat ] readonly } bind executeonly /Indexed { pop [ 0 1 BitsPerComponent bitshift 1 sub ] } bind executeonly .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 } bind executeonly def % <string> <index> getu16 <integer> /getu16 { 2 copy get 8 bitshift 3 1 roll 1 add get add } bind executeonly def % <string> <index> getu32 <integer> /getu32 { 2 copy getu16 16 bitshift 3 1 roll 2 add getu16 add } bind executeonly def /jp2_csp_dict mark 12 { /DeviceCMYK } % CMYK 14 { [ /Lab << /WhitePoint [ 0.9505 1 1.0890 ] readonly >> ] } % LAB, WhitePoint == D65 16 { /sRGBICC /ColorSpace findresource } bind executeonly 17 { /sGrayICC /ColorSpace findresource } bind executeonly 18 3 index % YCC is converted to RGB % 19 % CIEJab not supportec by PDF 1.7 20 { /esRGBICC /ColorSpace findresource } bind executeonly % e-sRGB 21 { /rommRGBICC /ColorSpace findresource} bind executeonly % ROMMRGB 24 { /esRGBICC /ColorSpace findresource } bind executeonly % e-sYCC .dicttomark readonly def % Process jp2 blocks (aka boxes). All procedures have the signature % <file> <length> -> ... <file> <flush_length> /jp2_tag_dict 10 dict begin /jp2h { % descend into a sub-stream, don't return. () /SubFileDecode filter 0 } bind executeonly def /ihdr { 14 sub % file len-14 1 index (1234567890abcd) readstring pop % file len-14 (14) /JPXComponents 1 index 8 getu16 % file len-14 (14) /JPXComponents NC def % file len-14 (14) 10 get %% If the BPC is 255 then each component has variable depth %% we can't handle this, but JasPer is known to produce %% images whcih declare this, but are actually all equal, we cater %% for that in the bpcc box below. dup 16#FF eq not { 16#7F and 1 add dup 12 eq { pop 16 } if /BitsPerComponent exch def % file len-14 } {pop} ifelse } bind executeonly def %% if the ihdr has a BPC of 255 then we get a bpcc box which %% gives the bpc for each component individually. We cannot %% actually deal with differing component depths, but it %% seems JasPer produces images with this box where all the %% component depths are in fact the same. /bpcc { JPXComponents sub 1 index JPXComponents string readstring pop dup 0 get /BitsPerComponent exch def 1 1 JPXComponents 1 sub { 1 index exch get BitsPerComponent eq not { ( **** Error: JPX image colour channels do not all have the same colour depth\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } if } for pop /BitsPerComponent BitsPerComponent 1 add def } bind executeonly def /colr { currentdict /ColorSpace known not { 3 sub 1 index (123) readstring pop % file len-3 (3) 0 get dup 1 eq { pop 4 sub % file len-7 1 index (1234) readstring pop % file len-16 (4) 0 getu32 % file len-16 enum //jp2_csp_dict exch .knownget { exec /ColorSpace exch def % file len-7 } { ( **** Error: Unknown enumerated color space in JPX stream.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse } { dup 2 eq exch 3 eq or { 1 index exch () /SubFileDecode filter /ReusableStreamDecode filter /JPXICC exch def 0 % file 0 } { ( **** Error: Unknown color space method in JPX stream.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse } ifelse } if } bind executeonly def % Palette colors are decoded by the library. /pclr { 4 sub 1 index (1234) readstring pop 3 get 16#7F and 1 add /BitsPerComponent exch def } bind executeonly def /cdef { pop dup (12) readstring pop 0 getu16 { dup (123456) readstring pop 2 getu16 dup 3 lt { { /JPXColors /JPXOpacity /JPXPremult } exch get currentdict 1 index .knownget { 1 add } { 1 } ifelse def } { pop } ifelse } repeat 0 } bind executeonly def currentdict end readonly def % Parse jp2 file format to get color space and image depth info. % <file> get_jp2_csp - /get_jp2_csp { { dup (01234567) readstring pop % f (LBoxTBox) dup length 8 lt { pop exit } if dup 4 4 getinterval exch % f (TBox) (LBoxTBox) 0 getu32 % f (TBox) LBox dup 0 eq { pop pop exit % cannot happen } { dup 1 eq { pop 1 index (01234567) readstring pop 4 getu32 % f (TBox) LBox 16 sub } { 8 sub } ifelse } ifelse % f (TBox) LBox-8..16 PDFDEBUG { 2 copy 2 packedarray //== exec % f (TBox) LBox-8..16 } if //jp2_tag_dict 3 -1 roll .knownget { exec } if % f flush dup 0 ne { 1 index exch % f f flush () /SubFileDecode filter flushfile % skip unwanted blocks } { pop } ifelse } loop pop } bind executeonly def currentdict /jp2_tag_dict .undef currentdict /jp2_csp_dict .undef % Add a key-value pair to the last /DecodeParms dictionary % Copy the objects to avoid spoiling shared ones. % <resdict> <key> <value> -> <resdict> /add-to-last-param { 2 index /DecodeParms knownoget { dup {} eq { pop //false } { //true } ifelse } { //false } ifelse { dup type /arraytype eq { [ exch { oforce } forall dup //null eq { pop 1 dict } if ] dup dup length 1 sub get % <resdict> <key> <value> [] <<>> } { dup length 1 add dict copy dup % <resdict> <key> <value> <<>> <<>> } ifelse 4 2 roll put % <resdict> obj } { % <resdict> <key> <value> mark 3 1 roll .dicttomark % <resdict> obj 1 index /Filter knownoget { dup type /arraytype eq { length array % <resdict> obj [...] dup dup length 1 sub % <resdict> obj [...] [...] len-1 4 -1 roll put % <resdict> [... obj] } { pop } ifelse } if } ifelse 1 index exch /DecodeParms exch put % <resdict> } bind executeonly def % Add a key-value pair to the all the /DecodeParms % dictionaries (i.e. handle the array) % Copy the objects to avoid spoiling shared ones. % <resdict> <patch dict> -> <resdict> /add-to-all-params { 1 index % <resdict> <patch dict> <resdict> /Filter knownoget { % <resdict> <patch dict> </name or [array]> dup type /arraytype eq { length % <resdict> <patch dict> <len> dup 0 gt { 2 index /DecodeParms knownoget { oforce_recursive % resolve indirect references exch pop % <resdict> <patch dict> [array] [ exch { dup type /dicttype eq { mark exch {} forall .dicttomark } { pop 1 dict } ifelse } forall ] % <resdict> <patch dict> [array] } { % <resdict> <patch dict> <len> % create an array of dictionaries [ 0 1 4 -1 roll 1 sub { pop 1 dict } for ] % <resdict> <patch dict> [array] } ifelse dup % <resdict> <patch dict> [array] [array] { % <resdict> <patch dict> [array] [dict] 2 index % <resdict> <patch dict> [array] [dict] <patch dict> { % <resdict> <patch dict> [array] [dict] </key> <value> 2 index % <resdict> <patch dict> [array] [dict] </key> <value> [dict] 3 1 roll put } forall pop } forall % <resdict> <patch dict> [array] exch pop % <resdict> [dict/array] 1 index exch /DecodeParms exch put } { pop pop } ifelse } { % <resdict> <patch dict> </name> pop 1 index /DecodeParms knownoget { oforce_recursive dup type /dicttype eq { mark exch {} forall .dicttomark } { pop 1 dict } ifelse } { 1 dict } ifelse % <resdict> <patch dict> [dict] 1 index % <resdict> <patch dict> [dict] <patch dict> { % <resdict> <patch dict> [dict] </key> <value> 2 index 3 1 roll put } forall exch pop % <resdict> [dict/array] 1 index exch /DecodeParms exch put } ifelse } {pop} ifelse } bind def /last-ditch-bpc-csp { currentdict /BitsPerComponent oknown not { ( **** Error: image has no /BitsPerComponent key; assuming 8 bit.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror /BitsPerComponent 8 def } if currentdict /ColorSpace knownoget not { dup /ColorSpace knownoget not { ( **** Error: image has no /ColorSpace key; assuming /DeviceRGB.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror /DeviceRGB } if } if resolvecolorspace %% This section is to deal with the horrible pair of files in Bug #696690 and Bug #696120 %% These files have ICCBased spaces where the value of /N and the number of components %% in the profile differ. In addition the profile in Bug #696690 is invalid. In the %% case of Bug #696690 the /N value is correct, and the profile is wrong, in the case %% of Bug #696120 the /N value is incorrect and the profile is correct. %% We 'suspect' that Acrobat uses the fact that Bug #696120 is a pure image to detect %% that the /N is incorrect, we can't be sure whether it uses the profile or just uses %% the /N to decide on a device space. What we now do is; If the /N and device profile %% number of components don't match, we assume the device profile is correct and patch %% /N to be the same as the profile (see /ICCBased-resolve), but we save the original %% value of /N in /OrigN. In setcolor, if the space is a genuine ICCBased space %% (not a replacement for a device profile) we call set_dev_color which will actually %% exercise the profile. If that fails we return an error. Here we run setcolor in a %% stopped context, and if it fails we check to see if there is a /OrigN (ths occurs %% only if the /N was different to the number of components in the profile). If there %% is a /OrigN then prefer that to the profile, otherwise they agreed, so just use %% /N and select a device space. If we can't select a device space with the correct %% number of components, give up and throw an error. See also 'Cdict' in pdf_ops.ps. dup type /arraytype eq { dup 0 get /ICCBased eq { gsave dup setcolorspace dup 1 get /N get 1 sub mark exch 0 1 3 -1 roll {pop 0} for {setcolor} stopped grestore { cleartomark 1 get dup /OrigN .knownget {exch pop}{/N get} ifelse [//null /DeviceGray //null /DeviceRGB /DeviceCMYK] exch {get} stopped { ( **** Error: Unable to set an ICCBased colour space, and cannot set an alternate from the number of components.\n) print /setcolorspace cvx /undefined signalerror } { dup //null eq { ( **** Error: Unable to set an ICCBased colour space, and cannot set an alternate from the number of components.\n) print /setcolorspace cvx /undefined signalerror }{ ICCProfileNError not { ( **** Warning : Error setting an ICCBased colour space, using /N to set an alternate device space.\n) print ( Output may be incorrect.\n) print } if } ifelse }ifelse /ICCProfileNError //true def }{cleartomark}ifelse } if } if /ColorSpace exch def } bind executeonly def /get-smask-in-data { % <dict> -> <int> /SMaskInData knownoget { dup dup 1 ne exch 2 ne and { pop 0 } if } { 0 } ifelse } bind executeonly def /makeimagedict { % <resdict> <newdict> makeimagedict <imagemask?> % On return, newdict' is currentdict begin /Width 2 copy oget def /Height 2 copy oget def % Handle missing BitsPerComponent later. /BitsPerComponent 2 copy knownoget { cvi def } { pop } ifelse /Interpolate 2 copy knownoget { def } { pop } ifelse makeimagekeys } bind executeonly def /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 %% If the image has a rendering intent, get its numeric equivalent %% from renderingintentdict, and save it in the dictionary we pass %% on to render images. dup /Intent knownoget { //.renderingintentdict exch .knownget { /Intent exch def } if } if 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 is optional for masks. /BitsPerComponent 2 copy known { pop } { 1 def } 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). % Bug 701083: We add a /ErrsAsEOD key to the DecodeParms here too. <</ErrsAsEOD //true>> //add-to-all-params exec //false resolvestream /DataSource exch def //true } { % Opaque image dup /Filter knownoget { dup type /arraytype eq { dup length dup 0 gt { 1 sub get oforce } { pop } ifelse } if /JPXDecode eq } { //false } ifelse { % /JPXDecode tricks % Previously we only ran the code to extract the Color Space and Bits Per Component % from the JOX stream if the image dict had either BPC or ColorSpace undefined. % However, while this is correct for the ColorSpace, its *not* correct for the BPC. % According to the spec we should ignore any BPC in the image dicitonary and % always use the BPC from the JPX stream. % Now the code in get_jp2_csp always overwrites the ColorSpace (in the image resource dict) % which technically is fine, because the image dictionary entry must be either not present or the % same as the JPX stream. However, this doesn't work, so instead we just save the existing % color space (if any). Then after extracting the color space and BPC from the JPX stream % we put back the saved color space, but only if there was one previously. dup /ColorSpace oknown { dup dup /ColorSpace get /ImageDictColorSpace exch put } if dup /IDFlag known { ( **** Warning: PDF spec bans inline JPX images.\n) pdfformatwarning % Inline stream is not positionable. Cannot get ColorSpace. } { % Drop the last filter (JPXDecode) from the pipeline dup dup length dict copy dup /Filter oget dup type /arraytype eq { dup length 1 gt { dup length 1 sub 0 exch getinterval 1 index exch /Filter exch put dup /DecodeParms knownoget { dup type /arraytype eq { dup length 1 gt { dup length 1 sub 0 exch getinterval 1 index exch /DecodeParms exch put } { pop dup /DecodeParms undef } ifelse } { pop dup /DecodeParms undef } ifelse } if } { pop dup /Filter undef dup /DecodeParms undef } ifelse } { pop dup /Filter undef dup /DecodeParms undef } ifelse //false resolvestream get_jp2_csp currentdict /ColorSpace oknown not { currentdict /JPXICC .knownget { [ /ICCBased mark /DataSource 5 -1 roll /N currentdict /JPXColors .knownget not { currentdict /JPXComponents get } if .dicttomark ] /ColorSpace exch def } if } if { /JPXICC /JPXColors /JPXComponents /JPXOpacity /JPXPremult } { currentdict exch undef } forall } ifelse % If we had a Color Space in the image dictionary before we read the JPX % stream, put it back now. We mujst do this before last-ditch-bpc-csp % because that resolves any indirect references to the color space. dup /ImageDictColorSpace known { dup /ImageDictColorSpace get currentdict /ColorSpace 3 -1 roll put } if //last-ditch-bpc-csp exec dup /ColorSpace oknown { % Propagate known color space to the filter /ColorSpace currentdict /ColorSpace get //add-to-last-param exec } if /Decode 2 copy knownoget not { ColorSpace //defaultdecodedict ColorSpace dup type /arraytype eq { 0 get } if get exec } if def dup get-smask-in-data dup 0 ne { PDFusingtransparency { currentdict dup length dict copy begin {/Mask/SMask/SMaskInData/Name} { currentdict exch undef } forall 2 eq { /Matte [ Decode length 2 idiv { 0 } repeat ] def } if /Decode //01_1 def /ColorSpace /DeviceGray def {/File /FilePosition /Filter /Length /DecodeParms /FFilter /FDecodeParms } { 2 copy knownoget { def } { pop } ifelse } forall currentdict /Alpha //true //add-to-last-param exec pop /SMask currentdict end def } { pop } ifelse } { pop } ifelse } { % not JPX image //last-ditch-bpc-csp exec /Decode 2 copy knownoget not { ColorSpace //defaultdecodedict ColorSpace dup type /arraytype eq { 0 get } if get exec } if def } ifelse % fi JPX tricks % Add a /Height key containing the image height to the DecodeParms % for any Filters we will apply. If there are no DecodeParms for any % filter, create one and add a /Height key. This is to solve the problem % in Bug #695116 where a JPEG image has a bad height, which is later % fixed up using a DNL marker. By placing the image height from the % PDF in the DecodeParms we can use it in the DCTDecode filter to % work around this. % Bug 701083: We add a /ErrsAsEOD key to the DecodeParms here too. << /Height 2 index /Height oget round cvi /ErrsAsEOD //true >> //add-to-all-params exec % 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). //false resolvestream /DataSource exch def //false } ifelse } bind executeonly def currentdict /add-to-last-param undef currentdict /add-to-all-params undef currentdict /last-ditch-bpc-csp undef /DoImage { %% Bug #696439. This is incredibly icky. When we find indirect obects we resolve them %% and store the resolved object in the containing object. This means that we retain %% the image dicionary here until the end of job. Potentially wasteful. Even worse though %% is the case where the image has a ColorSpace which is not an indirect object, but *is* %% an ICCBased colour space. In ths case we end up resolving the colour space and storing it %% here. Unfortunately, we use a ReusableStreamDecode filter on the ICC profile, which means %% we end up retaining the memory for that too. ICC profiles can be large, and if there are a %% lot of places where they get used, we can exhaust memory. %% Here we check if the ColorSpace is an array object, if it is we *copy* the image dictionary %% and use the copy instead. The copy is (eventually) discarded so we don't retain the ICC profile %% and don't exhaust memory. Note that we have to copy the actual colour space array too, copying %% the dictionary just copies the opriginal array as well. %% dup /ColorSpace known { dup /ColorSpace get dup type /arraytype eq { exch dup length dict copy exch dup length array copy /ColorSpace exch 2 index 3 1 roll put } {pop} ifelse } if checkaltimage dup length 6 add dict % <<image>> <<>> 1 index /SMask knownoget { % <<image>> <<>> <<sm>> dup 3 index ne { % <<image>> <<>> <<sm>> <<sm>> 1 index exch /SMask exch put } { pop ( **** Error: ignoring recursive /SMask attribute.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse } if 1 index /Mask knownoget { dup type dup /dicttype eq exch /arraytype eq or { % Bug #703681 1 index exch /Mask exch put } { pop ( **** Error: Ignoring Mask attribute that is not an array or a dictionary.\n) pdfformaterror } ifelse } if makeimagedict doimagesmask } bind executeonly def /makemaskimage { % <datasource> <imagemask> <Mask> makemaskimage % <datasource> <imagemask>, updates currentdict = % imagedict dup type /arraytype eq { /ImageType 4 def % Check that every element of the Mask is an integer. //false 1 index { type /integertype ne or } forall { oforce_array //false 1 index { type /integertype ne or } forall { (\n **** Error: Some elements of Mask array are not integers.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror [ exch { 0.5 add cvi } forall ] % following AR4, 5, 6 implementation } if } if % Check elements of array are within 0::(2**BitsPerComponent)-1 % This is a PostScript error, but AR tries to fix the Mask. 1 BitsPerComponent bitshift 1 sub //false 2 index { % stack: max_value result_bool value dup 0 lt exch 3 index gt or or } forall exch pop { ( **** Error: Some elements of Mask array are out of range.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror ColorSpace dup type /arraytype eq { 0 oget } if /Indexed eq BitsPerComponent 1 eq and { % AR9 treats Indexed 1 bpc images specially. Bug 692852 see also 697919 and 689717. dup 0 oget dup 0 lt exch 1 BitsPerComponent bitshift ge or { % First component is invalid - AR9 ignores the mask pop //null } { % Second component is invalid; AR9 replaces it with 1. [ exch 0 oget 1 ] } ifelse } { BitsPerComponent 1 eq { dup length 2 gt { % There are too many Mask entries, discard the Mask array pop //null }{ % Bug 701468 and 689717, the latter requires us to set the Mask values % so that the value is calculated from the BPC, the other requires us % to ignore the Mask. The only difference between the two files is the % actual range of the Mask values. This may yet need more work. % Note! Both files are technically invalid.... aload 3 1 roll eq { % There's only one Mask value, but its illegal, substitute with the % calculated maximum. [ exch { 1 BitsPerComponent bitshift 1 sub and } forall ] } { % The Mask values are not the same. This is a 2 colour image, if % we mask off any range then the result will be blank, so ignore the Mask pop //null } ifelse } ifelse } { % We think AR5, AR9 do this for most other cases. Originally Bug 690786, % but that is actually handled in the /Indexed case above. [ exch { 1 BitsPerComponent bitshift 1 sub and } forall ] } ifelse } ifelse } if dup //null ne { /MaskColor exch def } { pop /ImageType 1 def } ifelse } { % 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} stopped {pop} if 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 } bind executeonly def /doimagesmask { % <imagemask> doimagesmask - PDFusingtransparency not /PreserveSMask /GetDeviceParam .special_op { exch pop } { //false } ifelse or { % not using transparency OR the device supports SMask (e.g. pdfwrite) doimage } { currentdict /SMask knownoget { % We are doing transparency and SMask is present in the image % stack: <imagemask> <SMask> % Normalize /Matte attribute for .begintransparencymaskimage dup /Matte .knownget { oforce dup //null eq { pop dup /Matte undef } { 1 index /Matte [ 4 -1 roll { oforce } forall ] put } ifelse } if .begintransparencymaskimage PDFfile fileposition exch gsave //nodict begin //null .setSMask 1 CA 1 ca /Compatible .setblendmode DoImage end grestore PDFfile exch setfileposition 0 .endtransparencymask << /Subtype /Group /Isolated //true /.image_with_SMask //true % pdfwrite needs : see gs/src/ztrans.c, gs/src/gdevpdft.c % Code to deal with a Matte in the SMask. We know the image dictionary must have an SMask % entry if we get here, so we don't need to check its existence. Just pull it out and see if % the SMask has a Matte entry. If it does, get the ColorSpace from the parent image and % put a /CS key with that colour space in the Group that we manufacture. Bug #700686 % We also need to actually set the current colour space to be the same as the group % code only picks up the current colour space, not the space from the dictionary. currentdict /SMask get /Matte known {/CS currentdict /ColorSpace get dup pdfopdict /cs get exec } if >> 0 0 1 1 gsave 1 1 moveto 0 0 lineto % If we get an error, just emit an empty box { pathbbox } stopped { 0 0 0 0 } if 4 array astore grestore /image setup_trans .begintransparencygroup .currentstrokeconstantalpha .currentfillconstantalpha 3 -1 roll 1 .setfillconstantalpha 1 .setstrokeconstantalpha doimage .setfillconstantalpha .setstrokeconstantalpha .endtransparencygroup % tell the compositor we're done with the SMask. % Note that any SMask in the ExtGState should be reapplied % by the next call to setfill(stroke)state AND this relies % on our lazy evaulation of SMask groups //false << /Subtype /None >> 0 0 0 0 .begintransparencymaskgroup } { % We don't have an SMask in the image but there might be an SMask in the ExtGState .currentSMask //null ne { % the image doesn't have an SMask, but the ExtGState does, force a group. << /Subtype /Group /Isolated //true >> 0 0 1 1 .begintransparencygroup .currentstrokeconstantalpha .currentfillconstantalpha 3 -1 roll 1 .setfillconstantalpha 1 .setstrokeconstantalpha doimage .setfillconstantalpha .setstrokeconstantalpha .endtransparencygroup } { doimage } ifelse } ifelse } ifelse } bind executeonly def % For development needs we define a special option for running with a new handler % for images with a soft mask. //systemdict /NEW_IMAGE3X .knownget not { //false } if { /doimagesmask { % <imagemask> doimagesmask - doimage } bind executeonly def } if /ValidateDecode { % <<image dict>> -imagemask- ValidateDecode <<image dict>> exch dup /Decode .knownget { dup length % -imagemask- <<image dict>> [Decode] length 4 -1 roll % <<image dict>> [Decode] length -imagemask- { 1 % ImageMask Decode arrays must be [0 1] or [1 0] } { mark currentcolor counttomark % <<image dict>> [Decode] length [ ... component_count dup 2 add 1 roll % <<image dict>> [Decode] length component_count [ .... cleartomark % <<image dict>> [Decode] length component_count } ifelse 2 mul dup % <<image dict>> [Decode] length comp_count*2 comp_count*2 3 1 roll % <<image dict>> [Decode] comp_count*2 length comp_count*2 eq { % <<image dict>> length of Decode matches colour space requirement pop pop % <<image dict>> remove [Decode] and comp_count*2 }{ % <<image dict>> Decode array incorrect dup 2 index length % <<image dict>> [Decode] comp_count*2 comp_count*2 length exch sub 0 gt { % Decode is too long (\n **** Warning: Decode array for an image is too long\n) pdfformatwarning ( Output may be incorrect.\n) pdfformatwarning 0 exch % <<image dict>> [Decode] 0 comp_count*2 getinterval % <<image dict>> [subarray of Decode] 1 index exch /Decode exch % <<image dict>> <<image dict>> /Decode [subarray] put % <<image dict>> }{ % Decode is too short, Acrobat throws errors on this (\n **** ERROR: Decode array for an image is too short\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror pop pop % remove [Decode] and comp_count*2 } ifelse } ifelse } { exch pop }ifelse }bind executeonly def /doimage { % <imagemask> doimage - % imagedict is currentdict, gets popped from dstack %% We must save the colour space, in case it gets changed. I did try doing this %% at a higher level (/Do) but that caused numerous problems with pdfwrite. currentcolorspace exch %% save the current rendering intent .currentrenderintent exch %% Check the image dictionary to see if there is a /Intent currentdict /Intent known { %% and set the current rendering intent to match if so Intent .setrenderingintent } if DataSource exch currentdict /SMask known PDFusingtransparency and { /PreserveSMask /GetDeviceParam .special_op { pop pop currentdict /SMask oget makesoftmaskimage } if } if currentdict /Mask knownoget { makemaskimage } if % Stack: datasource imagemask { currentdict end setsmaskstate //true ValidateDecode { imagemask } } { ColorSpace setgcolorspace currentdict end setsmaskstate //false ValidateDecode { image } } ifelse PDFSTOPONERROR { exec //false } { stopped } ifelse { dup type /dicttype eq { pop } if % Sometimes image fails to restore the stack $error /errorname get dup /ioerror eq { pop (\n **** Error: File has insufficient data for an image.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } { (\n **** Error: File encountered ') exch 40 string cvs concatstrings (' error while processing an image.\n) concatstrings pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse } if % Close the input stream, unless it is PDFfile or % PDFsource. dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse %% restore the rendering intent .setrenderingintent %% and restore the colour space. We need to do this in a stopped context because %% if we are rendering a glyph, the cache device will throw an error if we try %% to change colour space (even when the new space is the same as the old space) %% We can't tell if we are rendering a bitmap for a glyph, and its hard to compare %% colour spaces, so just ignore errors for now. {setcolorspace} stopped {pop} if teardown_trans } bind executeonly def /.paintform { % <formdict> <resdict> <stream> .paintform - 1 index /FormResDict gput % For broken forms that inherit resources from the context. 3 -1 roll dup /Group oknown PDFusingtransparency and { .paintgroupform } { pop pdfopdict .pdfruncontext } ifelse } bind executeonly def /IncrementAppearanceNumber { //pdfdict /AppearanceNumber .knownget { 1 add //pdfdict /AppearanceNumber 3 -1 roll .forceput } executeonly { //pdfdict /AppearanceNumber 0 .forceput } executeonly ifelse }bind executeonly odef /MakeAppearanceName { //pdfdict /AppearanceNumber get 10 string cvs dup length 10 add string dup 0 (\{FormName) putinterval dup 3 -1 roll 9 exch putinterval dup dup length 1 sub (\}) putinterval } bind executeonly def /MakeNewAppearanceName { IncrementAppearanceNumber MakeAppearanceName }bind executeonly def /DoAppearance { %% Might need to rethink this. The problem is that if the page has a CropBox, we apply %% that as an initial clip. When we run the form, we don't apply the /Rect from the %% annotation, which means that the form could be out of the clip, which results in %% content going missing. Resetting the clip prevents this. gsave initclip MakeNewAppearanceName .pdfFormName //pdfdict /.PreservePDFForm known {//pdfdict /.PreservePDFForm get} {//false}ifelse exch //pdfdict /.PreservePDFForm //true .forceput DoForm //pdfdict /.PreservePDFForm 3 -1 roll .forceput grestore } bind executeonly odef %% We don't want to do any high level forms stuff if the source %% is PDF because : %% 1) Transparent forms are handled separately and we don't want to ge confused %% 2) PDF forms are too llikely to trip over the limitations in our support %% 3) Its highly unusual to find a PDF file which uses forms sensibly. %% %% So we have a special PDF version of execform which doesn't do high level forms. pdfdict /.PDFexecform { % This is a separate operator so that the stacks will be restored % properly if an error occurs. dup /Matrix get concat dup /BBox get aload pop exch 3 index sub exch 2 index sub rectclip dup /PaintProc get 1 index /Implementation known not { 1 index dup /Implementation //null .forceput readonly pop } executeonly if exec } .bind executeonly put pdfdict /PDFexecform { gsave { //.PDFexecform exec } stopped grestore {stop} if } .bind executeonly put /DoForm { %% save the current value, if its true we will set it to false later, in order %% to prevent us preserving Forms which are used *from* an annotation /Appearance. //pdfdict /.PreservePDFForm known {//pdfdict /.PreservePDFForm get} {//false}ifelse exch %% We may alter the Default* colour spaces, if the Resources %% ColorSpace entry contains one of them. But we don't want that %% to become the new default, we want to revert to any existing %% definition, or the Device space. The Default* spaces are defined %% as ColorSpace resources, so the only way to handle them is to %% save and restore round the definitions 3 dict dup begin /saved_DG /DefaultGray /ColorSpace findresource def /saved_DRGB /DefaultRGB /ColorSpace findresource def /saved_DCMYK /DefaultCMYK /ColorSpace findresource def end exch % Adobe 2nd edition of the PDF 1.3 spec makes /FormType % and /Matrix keys optional. Cope with the missing keys. begin << currentdict /FormType known not { /FormType 1 } if currentdict /Matrix known not { /Matrix { 1 0 0 1 0 0 } cvlit } { 0 1 Matrix length 1 sub { dup Matrix exch get type dup /integertype eq exch /realtype eq or not { (\n **** Error: Invalid element in /Form XObject matrix.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror Matrix exch 0.00 put } { pop } ifelse } for } ifelse currentdict /BBox known not { (\n **** Error: Required entry /BBox not present in Form.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror /BBox [0 1 0 1] } if currentdict end { oforce } forall >> dup [ 2 index /Resources knownoget { oforce } { 0 dict } ifelse %% Ugly hackery for Default* colour spaces in forms %% dup /ColorSpace knownoget { oforce { //false 3 1 roll exch dup /DefaultGray eq { pop exec resolvecolorspace dup csncomp 1 eq { dup type /nametype eq { 1 array astore } if /DefaultGray exch /ColorSpace defineresource pop pop //true }{ pop ( **** Error: ignoring invalid /DefaultGray color space.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse }{ dup /DefaultRGB eq { pop exec resolvecolorspace dup csncomp 3 eq { dup type /nametype eq { 1 array astore } if /DefaultRGB exch /ColorSpace defineresource pop pop //true }{ pop ( **** Error: ignoring invalid /DefaultRGB color space in Form Resources.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse }{ /DefaultCMYK eq { exec resolvecolorspace dup csncomp 4 eq { dup type /nametype eq { 1 array astore } if /DefaultCMYK exch /ColorSpace defineresource pop pop //true }{ pop ( **** Error: ignoring invalid /DefaultCMYK color space in Form Resources.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse }{ pop } ifelse } ifelse }ifelse { % if using color space substitution, "transition" the current color space currentcolorspace dup length 1 eq { % always an array 0 get dup /DeviceGray eq 1 index /DeviceRGB eq or 1 index /DeviceCMYK eq or { /Pattern setcolorspace setcolorspace } { pop } ifelse } { pop } ifelse } if } forall } if 3 index % /Contents for the stream is not per the spec, but Acrobat handles it dup /Contents knownoget { % We want to make it's a dictionary, and represents a stream dup type /dicttype eq { dup /FilePosition known { PDFSTOPONERROR { /DoForm cvx /undefinedresource signalerror } if ( **** Error: Invalid Form definition. Output may be incorrect.\n) pdfformaterror exch pop } {pop} ifelse } { pop } ifelse }if //false /resolvestream cvx /.paintform cvx ] cvx /PaintProc exch put % Adjust pdfemptycount since we have an extra dictionary on the stack pdfemptycount countdictstack 3 -1 roll /pdfemptycount count 4 sub store //pdfdict /.PreservePDFForm known {//pdfdict /.PreservePDFForm get}{//false} ifelse { %% We must *not* preserve any subsidiary forms (curently at least) as PDF %% form preservation doesn't really work. This is used just for Annotation %% Appearances currently, and if they should happen to use a form, we do not %% want to preserve it. //pdfdict /.PreservePDFForm //false .forceput /q cvx /execform cvx 5 -2 roll } executeonly { /q cvx /PDFexecform cvx 5 -2 roll } ifelse 4 .execn % Restore pdfemptycount 0 { countdictstack 2 index le { exit } if currentdict /n known not { 1 add } if countdictstack Q countdictstack eq {end} if } loop 1 gt { ( **** Error: Form stream has unbalanced q/Q operators \(too many q's\)\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } if pop /pdfemptycount exch store % We've now seen Form XObjects leaving junk on the stack, so we % can't assume that when we finish the form the stack will be restored % nor can we assume that the junk won't include a 'mark' so we an't % simply do a cleartomark. Instead clear the stack until we get back % to a dictionary which contains /saved_DG. We can still get errors; % if the stream removes too many objects from the stack we will end % up with a stackunderflow, but there's nothing we can do about that. dup type /dicttype eq not { //true } { dup /saved_DG known { //false } { //true } ifelse } ifelse { ( **** Error: Form stream left garbage on the stack, attempting to recover.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror { dup type /dicttype eq not { pop } { dup /saved_DG known { exit } { pop } ifelse } ifelse } loop } if %% Put back pre-existing Default* ColorSpace definitions. dup type /dicttype eq { begin saved_DG /DefaultGray exch /ColorSpace defineresource pop saved_DRGB /DefaultRGB exch /ColorSpace defineresource pop saved_DCMYK /DefaultCMYK exch /ColorSpace defineresource pop end } if //pdfdict /.PreservePDFForm 3 -1 roll .forceput } bind executeonly odef /_dops_save 1 array def /DoPS { DOPS { //_dops_save 0 save put //true resolvestream cvx exec //_dops_save 0 get restore } { pop } ifelse } bind executeonly def currentdict /_dops_save undef /ocg_pocs 4 dict begin /AllOn { //true exch { oforce dup type /dicttype eq { /OFF known not and } { pop } ifelse } forall } bind executeonly def /AnyOn { //false exch { oforce dup type /dicttype eq { /OFF known not or } { pop } ifelse } forall } bind executeonly def /AnyOff { //AllOn exec not } bind executeonly def /AllOff { //AnyOn exec not } bind executeonly def currentdict end readonly def % Check whether OCG or OCMD is visible % <dict> oc-is-visible <bool> /ocg-is-visible { dup /Type knownoget { /OCMD eq { dup /OCGs knownoget not { {} } if % OC OCGs dup type /dicttype eq { 1 array astore } if //true 1 index { //null eq and } forall { pop pop //true % all nulls => show } { exch /P knownoget not { /AnyOn } if % OCGs P //ocg_pocs exch get exec % bool } ifelse } { dup /OFF known not % OFF is inserted by process_trailer_attrs { %% /OC is not in the OCProperties /OFF array, so we need to %% test its usage. We may eventually have to add a /ON to the dictionary %% if the OCProperties /ON array defines the /OC, I think that should override % the Usage, but I don't have an example to test. /Usage .knownget { oforce /Printed where { /Printed get } { //false }ifelse { %% We are behaving as a printer, check the Print state /Print .knownget { /PrintState .knownget { oforce /OFF eq { //false }{ //true } ifelse }{ //true } ifelse }{ %% If we don't know, assume its visible //true } ifelse }{ %% We are behaving as a viewer, check the View state /View .knownget { oforce /ViewState .knownget { /OFF eq { //false }{ //true } ifelse }{ //true } ifelse }{ %% If we don't know, assume its visible //true } ifelse } ifelse }{ %% If we don't know, assume its visible //true } ifelse }{ pop //false }ifelse } ifelse } { /OFF known not % OFF is inserted by process_trailer_attrs } ifelse } bind executeonly def drawopdict begin /Do { % /Name %% Bug 695897 This file has nested text blocks and also a Do image inside %% a text block. Here we attempt to detect and recover from this by setting the %% CTM to the matrix we saved before the text block. NB we update the 'TextSaveMatrix' %% or 'qTextSaveMatrix' whenever a 'cm' is issued, even if we are in a text block, so %% these matrices 'ought' to be correct. %% Of course, the file is badly broken, but 'Acrobat can open it....' currentdict /TextSaveMatrix known { gsave ( **** Error: Executing Do inside a text block, attempting to recover\n) pdfformaterror currentdict /TextSaveMatrix get setmatrix ( Output may be incorrect.\n) pdfformaterror } if currentdict /qTextSaveMatrix known { gsave ( **** Error: Executing Do inside a text block, attempting to recover\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror currentdict /qTextSaveMatrix get setmatrix } if setsmaskstate PDFfile fileposition exch % pos /Name % Bug #698226, Acrobat signals an error for recursive XObjects in a PDF file % but continues. This is true even if the XObject is not a simple self-reference % (eg /Fm1 -> /Fm2 -> /Fm3 -> /Fm1). % Normally when dealing with recursion we would put a dictionary on the stack, store the % object numbers encoutnered in it, and check each new object number to see if we've % already seen it. This doesn't work well for XObjects, because the operand stack can be % in any state when we run a Do. So we make a new dictionary in pdfdict to hold the % object numbers. % We also don't usually know the object number of a Form, we just get given its name % so we need a new routine to return the object number. This is because the parent XObject % might reference teh object by one name, while the child references it by another, we % can't permit clashes. % % Start by getting the object number for a Form XObject dup Page /XObject obj_get dup 0 eq not { % Now get the recording dictionary and see if that object number has been seen //pdfdict /Recursive_XObject_D get 1 index known { ( **** Error: Recursive XObject detected, ignoring ") print 1 index 256 string cvs print (", object number ) print 256 string cvs print (\n) print ( Output may be incorrect.\n) pdfformaterror //false }{ % We haven't seen it yet, so record it. //pdfdict /Recursive_XObject_D get 1 index //null put 3 1 roll //true }ifelse } { % I don't think this should be possible, but just in case ( **** Error: Unable to determine object number for ) print exch 256 string cvs print ( so ignoring it) print ( Output may be incorrect.\n) pdfformaterror //false } ifelse % If we could get the object number, and we haven't already seen it, then execute it. { dup Page /XObject rget { exch pop % pos obj OFFlevels length 0 eq { dup /OC knownoget { ocg-is-visible } { //true } ifelse } { //false } ifelse { dup /Subtype oget //xobjectprocs exch get % pos obj {proc} % Don't leave extra objects on the stack while executing % the definition of the form. 3 -1 roll % obj {proc} pos 2 .execn % pos } { pop % pos } ifelse } { % This should cause an error, but Acrobat Reader can % continue, so we do too. ( **** Error: Undefined XObject resource: ) exch =string cvs concatstrings (\n) concatstrings pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse PDFfile exch setfileposition //pdfdict /Recursive_XObject_D get exch undef }{ % Otherwise ignore it and tidy up the stacks pop pop } ifelse } bind executeonly def end currentdict /xobjectprocs .undef currentdict /ocg_pocs .undef % ---------------- 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 } bind executeonly def /is_space_dict << 0 0 9 9 10 10 12 12 13 13 32 32 >> readonly def drawopdict begin /BI { mark } bind executeonly def /ID { gsave %% Bug 696547, related to Bug 695897 (see /Do above) This file has an inline image inside %% a text block. Here we attempt to detect and recover from this by setting the %% CTM to the matrix we saved before the text block. NB we update the 'TextSaveMatrix' %% or 'qTextSaveMatrix' whenever a 'cm' is issued, even if we are in a text block, so %% these matrices 'ought' to be correct. %% Of course, the file is badly broken, but 'Acrobat can open it....' currentdict /TextSaveMatrix known { ( **** Error: Executing ID inside a text block, attempting to recover\n) pdfformaterror currentdict /TextSaveMatrix get setmatrix ( Output may be incorrect.\n) pdfformaterror } if currentdict /qTextSaveMatrix known { ( **** Error: Executing ID inside a text block, attempting to recover\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror currentdict /qTextSaveMatrix get setmatrix } if counttomark 2 idiv dup 7 add dict begin { exch //unabbrevkeydict 1 index .knownget { exch pop } if exch unabbrevvalue def } repeat pop /IDFlag //true def % flag for stream processing. /File PDFsource def currentdict makeimagekeys OFFlevels length 0 eq { gsave 1 1 moveto 0 0 lineto % If we get an error, just emit an empty box { pathbbox } stopped { 0 0 0 0 } if 4 array astore grestore /image setup_trans doimage } { pop Width currentdict /ImageMask knownoget dup { and } if not { ColorSpace oforce csncomp mul BitsPerComponent mul } if 7 add 8 idiv Height mul DataSource exch () /SubFileDecode filter flushfile end } ifelse % 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. % Sometimes (bug 690300) CCITTDecode filter consumes 'E' in 'EI'. % Therefore, we search for <start>I<sp|end> or <start|sp>EI<sp|end> PDFsource read not { /ID cvx /syntaxerror signalerror } if dup 73 eq { pop 10 69 73 % Seed to: <sp>EI } { 10 10 3 -1 roll % Seed to: <sp><sp><any> } ifelse { PDFsource read not dup { 10 exch } if //is_space_dict 2 index known 3 index 73 eq and 4 index 69 eq and //is_space_dict 6 index known and { pop pop pop pop pop exit } { { pop pop pop /ID cvx /syntaxerror signalerror } { 4 -1 roll pop } ifelse } ifelse } loop grestore } bind executeonly def end currentdict /is_space_dict undef % ================================ Text ================================ % drawopdict begin % Text control /BT { BT } executeonly def /ET { ET } executeonly def /Tc { Tc } executeonly def /TL { TL } executeonly def /Tr { Tr } executeonly def /Ts { Ts } executeonly def /Tw { Tw } executeonly def /Tz { Tz } executeonly def % Text positioning /Td { Td } executeonly def /TD { TD } executeonly def /Tm { Tm } executeonly def /T* { T* } executeonly def % Text painting /Tj { Tj } executeonly def /' { ' } executeonly def /" { " } executeonly def /TJ { TJ } executeonly def /Tform { Tform } executeonly def % Text formatting and painting for AcroForm % without appearance streams. end % ======================= Invalid operators ============================ % drawopdict begin /QBT { Q BT ( **** Error: invalid operator QBT processed as Q BT .\n) pdfformaterror % Bug 690089 ( Output may be incorrect.\n) pdfformaterror } executeonly def /. { 0. ( **** Error: invalid operator . processed as number 0. .\n) pdfformaterror % Bug 690730 ( Output may be incorrect.\n) pdfformaterror } executeonly def end % ============================== Annotations ============================== % % Create links from separate widget annotations to the parent field nodes. % Surprisingly, separate widget annotations don't have a link to the parent % from which they inherit some data. /link_widget_annots { % <<parent>> <<kid>> -> <<parent>> <<kid>> dup /Kids knownoget { { oforce dup type /dicttype eq { link_widget_annots } if pop } forall } if dup /Parent oknown not { 2 copy exch /ParentField exch put } if } bind executeonly def % Get and normalize an annotation's rectangle. /annotrect { % <annot> annotrect <x> <y> <w> <h> /Rect oget oforce_recursive 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 } bind executeonly def % Set an annotation color. % If the /C array is empty we don't want to draw the annotation % /annotsetcolor { % <annot> annotsetcolor bool /C knownoget { dup length 4 eq { aload pop setcmykcolor //true }{ dup length 3 eq { aload pop setrgbcolor //true }{ dup length 1 eq { aload pop setgray //true } { dup length 0 eq { pop //false }{ ( **** Error: invalid color specified for annotation /C entry) pdfformaterror //false ( Output may be incorrect.\n) pdfformaterror } ifelse } ifelse } ifelse } ifelse } { 0 setgray //true} ifelse } bind executeonly def % Set an annotation color. % If the /C array is empty we don't want to draw the annotation % /annotsetinteriorcolor { % <annot> annotsetcolor bool /IC knownoget { dup length 4 eq { aload pop setcmykcolor //true }{ dup length 3 eq { aload pop setrgbcolor //true }{ dup length 1 eq { aload pop setgray //true } { dup length 0 eq { pop //false }{ ( **** Error: invalid color specified for annotation /C entry) pdfformaterror //false ( Output may be incorrect.\n) pdfformaterror } ifelse } ifelse } ifelse } ifelse } { //false } ifelse } bind executeonly def % 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 dup annotrect 5 -1 roll /RD knownoget { applyRD } if 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 } { pop pop pop }ifelse } bind executeonly def % Draw an annotation border. /drawborder { % <annot> drawborder - gsave dup /BS known 1 index /Border known or { dup /BS knownoget { dup type /dicttype ne % <annot> <border> <bad?> } { dup /Border oget dup type /arraytype eq { dup length 3 lt } { //true } ifelse % <annot> [border] <bad?> } ifelse { ( **** Error: Invalid annotation border object, border has not been drawn.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror pop { 0 0 0 } } if dup type /dicttype eq { dup /W knownoget not { 1 } if % Per PDF1.6 Reference table 8.13, /W in the border style dictionary is % expressed in points (an absolute unit), so compensate here for any % scaling of the PostScript user space done due to /UserUnit. % Scaling due to -dPDFFitPage is not undone, to keep the correct border width % compared to the size of the surrounding marks. //systemdict /NoUserUnit .knownget not { //false } if not //systemdict /PDFFitPage known not and % Don't apply USerUnit if we are passing it to the device /PassUserUnit /GetDeviceParam .special_op {exch pop} {//false} ifelse not and { % UserUnit is ignored if -dPDFFitPage Page /UserUnit knownoget { div } if } if {} 2 index /S knownoget { /D eq { 2 index /D knownoget not { {3} } if exch pop } if } if 3 -1 roll pop strokeborder } { dup 2 get exch dup length 3 gt { 3 get } { pop {} } ifelse strokeborder } ifelse } { 1 {} strokeborder } ifelse grestore } bind executeonly def % stroke the path of an annotation border. /strokeborderpath { % <annot> strokeborderpath - gsave dup /BS known 1 index /Border known or { dup /BS knownoget { dup type /dicttype ne % <annot> <border> <bad?> } { dup /Border oget dup type /arraytype eq { dup length 3 lt } { //true } ifelse % <annot> [border] <bad?> } ifelse { ( **** Error: Invalid annotation border object, border has not been drawn.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror pop { 0 0 0 } } if dup type /dicttype eq { dup /W knownoget not { 1 } if % Per PDF1.6 Reference table 8.13, /W in the border style dictionary is % expressed in points (an absolute unit), so compensate here for any % scaling of the PostScript user space done due to /UserUnit. % Scaling due to -dPDFFitPage is not undone, to keep the correct border width % compared to the size of the surrounding marks. //systemdict /NoUserUnit .knownget not { //false } if not //systemdict /PDFFitPage known not and % Don't apply USerUnit if we are passing it to the device /PassUserUnit /GetDeviceParam .special_op {exch pop} {//false} ifelse not and { % UserUnit is ignored if -dPDFFitPage Page /UserUnit knownoget { div } if } if {} 2 index /S knownoget { /D eq { 2 index /D knownoget not { {3} } if exch pop } if } if 3 index /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if 3 -1 roll pop % 2 index annotsetcolor { 0 setdash setlinewidth stroke % } if } { dup 2 get % If element 3 of the /Border array is 0, then don't draw the border dup 0 ne { exch dup length 3 gt { 3 get } { pop {} } ifelse 3 index /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if % 2 index annotsetcolor { 0 setdash setlinewidth stroke % } if }{ pop pop } ifelse } ifelse } { dup /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if 1 {} % 2 index annotsetcolor { 0 setdash setlinewidth stroke % } if } ifelse pop grestore } bind executeonly def /fillborderpath { % <annot> fillborderpath - gsave dup /ca knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if annotsetinteriorcolor {fill} if grestore }bind executeonly def % % 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 % % AR8 and AR9 print 3D annotations even if Print flag is off. Bug 691486. % /annotvisible { % <annot> annotvisible <visible> dup /Subtype knownoget { /3D eq } { //false } ifelse % 3D annot exch /F knownoget not { 0 } if % Get flag value dup 2 and 0 eq { /Printed load { 4 and 4 eq or % Printed or 3D } { 32 and 0 eq exch pop % not NoView } ifelse } { pop pop //false % Hidden } ifelse } bind executeonly def /set_bc_color << 1 { 0 get oforce setgray } bind executeonly 3 { { oforce } forall setrgbcolor } bind executeonly 4 { { oforce } forall setcmykcolor } bind executeonly >> readonly def % Get an inherited attribute from a node through /Parent and /ParentField % links. The latter is set at start-up to access parents of annotations and % defaults at AcroForm. /fget % <field> <key> fget <value> -true- { % <field> <key> fget -false- { 2 copy knownoget { exch pop exch pop //true exit } { exch dup /Parent knownoget { exch pop exch } { /ParentField knownoget { exch } { pop //false exit } ifelse } ifelse } ifelse } loop } bind executeonly def % <annot> foo <annot> /make_tx_da { dup /AP << /N 10 dict dup cvx begin >> put /Subtype /Form def /BBox [ 0 0 4 index /Rect oget { oforce } forall 3 -1 roll sub abs 3 1 roll sub abs exch ] def /Resources 1 index /DR fget not { 0 dict } if def /File 1 index /V fget not { () } if length 2 index /DA fget not { () } if length add 500 add 65535 .min string dup 3 1 roll def /NullEncode filter % <annot> file dup (BT ) writestring 1 index /DA fget not { 1 index /V fget { <EFBBBF> anchorsearch { pop /Helvetica findfont 12 scalefont setfont } { <FEFF> anchorsearch { pop pop /FallBackFont /Identity-UTF16-H [/CIDFallBack] composefont 12 scalefont setfont } { pop /Helvetica findfont % re-encode the font to PDFDocEncoding dup length dict begin { 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse } forall /Encoding /PDFDocEncoding /Encoding findresource def /FontName /Helvetica-PDFDocEncoding def currentdict end /Helvetica-PDFDocEncoding exch definefont 12 scalefont setfont }ifelse }ifelse } if () }if [ exch { token { dup /Tf eq { 2 index 0 eq { /BBox load 3 get 0.75 mul % empirical constant 4 -1 roll pop 3 1 roll } if } if exch } { exit } ifelse } loop ] { 1 index exch write== } forall dup 2 index /MaxLen fget not { 0 } if write= dup 2 index /V fget not { () } if write== dup 2 index /Ff fget not { 0 } if write= dup 2 index /Q fget not { 0 } if write= dup (Tform ET) write= dup .fileposition /Length exch def /File File 0 Length getinterval def closefile % <annot> end } bind executeonly def /can-regenerate-ap { % <annot> -> <bool> //false exch NeedAppearances { dup /FT fget { dup /Tx eq { pop dup /V oknown { pop not 1 } if } { /Ch eq { dup /V oknown { pop not 1 } if } if } ifelse } if } if pop } bind executeonly def /drawwidget { % <scalefactor_x> <scalefactor_y> <annot> drawwidget - %% This code checks to see if we can geenrate an appearance stream for the %% given widget, and if we can it ignores the given Appearance stream, so that %% we generate one instead. This seems wrong to me, if we've been given an %% appearance stream we should use it, no synthesize something else. Several %% files in our regression test suite render 'incorrectly' when compared to %% Acrobat with this removed, clearly Acrobat always ignores appearances. However %% several other files are rendered better when we *don't* ignore the Appearance %% So on balance I'm choosing to honour the appearance. %% % dup /UpdatedAP known not { % dup can-regenerate-ap { % dup /AP undef % } if % } if % Acrobat doesn't draw Widget annotations unles they have both /FT % (which is defined as required) and /T keys present. Annoyingly % these can either be inherited from the Form Definition Field % dictionary (via the AcroForm tree) or present directly in the % annotation, so we need to check the annotation to make sure its % a Widget, then follow any /Parent key up to the root node % extracting and storing any FT or T keys as we go (we only care if % these are present, their value is immaterial). If after all that % both keys are not present, then we don't draw the annotation. dup /Subtype get /Widget eq { dup /FT known 1 index /T known and not { dup { dup /FT knownoget { /FT exch 3 index 3 1 roll put } if dup /T knownoget { /T exch 3 index 3 1 roll put } if /Parent knownoget not { exit } if } loop } if dup /FT known 1 index /T known and { //true } { ( **** Warning: A Widget annotation dictionary lacks either the FT or T key.\n) pdfformaterror ( Acrobat ignores such annotations, annotation will not be rendered.\n) pdfformaterror ( Output may not be as expected.\n) pdfformaterror //false } ifelse } { //true }ifelse { dup /AP knownoget { dup /N known not { ( **** Error: Appearance dictionary (AP) lacks the mandatory normal (N) appearance.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } if //false [/N /R /D] { % stack: scalex scaley annot appearance false key 2 index exch knownogetdict { exch not exit } if } forall % stack: scalex scaley annot appearance value true % stack: scalex scaley annot appearance false dup { pop exch pop % 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 or File key. % If the stream lacks Length key, try File key. dup /Length knownoget { type /integertype eq } { //false } ifelse 1 index /File knownoget { type /filetype eq or } if { % 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 } { exch pop % discard useless AP dictionary } ifelse % Stack: scalex scaley annot appearance true % Stack: scalex scaley annot false { dup type /dicttype eq { % Draw appearance % Initialize graphic following "7.4.4 Appearance Streams" q graphicsbeginpage textbeginpage 1 index annotrect pop pop translate 3 index 3 index scale % Apply scale factors dup /BBox knownoget { 1 index /Matrix knownoget not { {1 0 0 1 0 0} } if .bbox_transform pop pop % Compensate for non-zero origin of BBox neg exch neg exch translate } if DoForm Q } { ( **** Error: Annotation's appearance is not a dictionary.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse } if } { dup /MK knownoget { % mk dup /BG knownoget { % mk bg dup length % mk bg len //set_bc_color exch .knownget { gsave exec 3 index 3 index scale 1 index annotrect rectfill grestore } { pop } ifelse } if dup /BC knownoget { dup length //set_bc_color exch .knownget { gsave exec 1 setlinewidth 3 index 3 index scale 1 index annotrect rectstroke grestore } { pop } ifelse } if pop } if dup can-regenerate-ap { make_tx_da dup /UpdatedAP //true put 3 copy drawwidget } if } ifelse } if pop pop pop } bind executeonly def currentdict /set_bc_color undef % For annotation object we have to determine the size of the output rectangle % and the size of the BBox for the form XObject. From these we calculate % a scale factors for drawing it. /calc_annot_scale { % <annot> calc_annot_scale <x_scale> <y_scale> dup /Rect knownoget { pop dup annotrect 4 2 roll pop pop % get width height size in user space 2 index /AP knownoget { /N knownogetdict { % <<Annot>> x y <<N>> dup 4 index /AS knownoget { knownoget { exch pop } if } { pop } ifelse dup /Matrix knownoget not { {1 0 0 1 0 0} } if exch /BBox knownoget { % <<>> x y {matrix} [box] exch .bbox_transform % <<>> x y x0 y0 x1 y1 3 -1 roll sub % <<>> x y x0 x1 y1-y0 3 1 roll exch sub % <<>> x y y1-y0 x1-x0 2 copy mul 0 eq { ( **** Error: /BBox has zero width or height, which is not allowed.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror pop pop pop pop 1 1 % zero size -- revert to unity scaling } { 3 1 roll div % <<>> x x1-x0 y/(y1-y0) 3 1 roll div % <<>> y/(y1-y0) x/(x1-x0) exch % <<>> x/(x1-x0) y/(y1-y0) } ifelse } { pop pop pop 1 1 % default to unity scaling } ifelse % if we have /BBox } { pop pop 1 1 } ifelse % if we have /N } { pop pop 1 1 } ifelse % if we have /AP 3 -1 roll pop } { ( **** Error: /Annot dict is missing required /Rect entry.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror pop 1 1 } ifelse } bind executeonly def /applyRD { % x y w h [l t r b] dup 0 get % x y w h [] l 6 -1 roll add 5 1 roll %x+l y w h [] dup 1 get %x+l y w h [] b 5 -1 roll add %x+l w h [] b+y 4 1 roll %x+l y+b w h [] aload pop %x+l y+b w h l t r b exch %x+l y+b w h l t b r 4 -1 roll add %x+l y+b w h t b r+l 3 1 roll add %x+l y+b w h r+l t+b 3 -1 roll exch sub %x+l y+b w r+l h-(t+b) 3 1 roll sub %x+l y+b h-(t+b) w-(r+l) exch } bind executeonly def % Draw an annotation. /drawannottypes 20 dict begin /startannottransparency { PDFusingtransparency { dup /BM known { dup /BM get << exch /BM exch >> } { << >> }ifelse %% We should be able to use the Rect to create the group, but it seems %% Acrobat ignores this, or at least doesn't clip the annotation to it :-( % 1 index /Rect known { % 1 index annotrect exch % llx lly h w % 3 index add exch % x y urx h % 2 index add % }{ clippath pathbbox newpath % } ifelse .begintransparencygroup } if }bind executeonly def /endannottransparency { PDFusingtransparency { .endtransparencygroup } if }bind executeonly def /ValidateAP { dup /AP oknown { dup /AP oget /N oknown not { //false } { //true } ifelse } { //false }ifelse } bind executeonly def % x0 y0 x1 y1 x2 y2 x3 y3 -> x0 y0 x1-x0 y1-y0 x2-x0 y2-y0 /quadpoints2basis { 8 { oforce 8 1 roll } repeat % The text is oriented with respect to the vertex with the smallest % y value (or the leftmost of those, if there are two such vertices) % (x0, y0) and the next vertex in a counterclockwise direction % (x1, y1), regardless of whether these are the first two points in % the QuadPoints array. 2 { 2 index 1 index eq { 3 index 2 index gt { 4 2 roll } if } { 2 index 1 index gt { 4 2 roll } if } ifelse 8 4 roll } repeat 6 index 3 index gt { 8 4 roll } if % ^ % | % * (x2,y2) * (x3,y3) % | % | % *------------*-> % (x0,y0) (x1,y1) pop pop % x0 y0 x1 y1 x2 y2 4 index sub exch % x0 y0 x1 y1 y2-y0 x2 5 index sub exch % x0 y0 x1 y1 x2-x0 y2-y0 4 2 roll 4 index sub exch % x0 y0 x2-x0 y2-y0 y1-y0 x1 5 index sub exch % x0 y0 x2-x0 y2-y0 x1-x0 y1-y0 4 2 roll % x0 y0 x1-x0 y1-y0 x2-x0 y2-y0 } bind executeonly def /Square { //ValidateAP exec { //true } { gsave //startannottransparency exec dup annotsetinteriorcolor { gsave dup /ca knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if dup annotrect 5 index /RD knownoget { applyRD } if rectfill grestore dup /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if dup annotsetcolor { drawborder } if //false }{ dup annotrect 5 index /RD knownoget { applyRD } if drawopdict /re get exec dup annotsetcolor { strokeborderpath } if } ifelse //endannottransparency exec grestore //false }ifelse } bind executeonly def %% Width Height drawellipse - /drawellipse { %% Don Lancaster's code for drawing an ellipse 0.55228475 0.00045 sub % improved magic value 3 1 roll % magic width height 2 div exch 2 div % magic y-radius x-radius dup 3 index mul % magic y-radius x-radius x-magic 2 index % magic y-radius x-radius x-magic y-radius 5 -1 roll mul % magic y-radius x-radius x-magic y-magic 2 index neg 0 moveto % xrad neg 0 moveto 2 index neg 1 index 3 index neg 6 index 0 8 index curveto % xrad neg ymag xmag neg yrad 0 yrad curveto 1 index 4 index 4 index 3 index 1 index 0 curveto % xmag yrad xrad ymag xrad 0 curveto 2 index 1 index neg 3 index 6 index neg 0 1 index curveto % xrad ymag neg xmag yrad neg 0 yrad neg curveto % Stack: yrad xrad xmag ymag exch neg 4 1 roll 3 -1 roll neg 3 1 roll exch neg exch neg 1 index 0 curveto % xmag neg yrad neg xrad neg ymag neg 0 curveto }bind executeonly def /Circle { //ValidateAP exec { //true } { gsave //startannottransparency exec dup annotrect 5 index /RD knownoget { applyRD } if 4 2 roll exch 3 index 2 div add exch 2 index 2 div add translate //drawellipse exec dup fillborderpath dup annotsetcolor { strokeborderpath } if //endannottransparency exec grestore //false } ifelse } bind executeonly def /Polygon { //ValidateAP exec { //true } { gsave //startannottransparency exec dup /Vertices knownoget { dup length 2 div 1 sub cvi 0 1 3 -1 roll { 2 mul dup 2 index exch 2 getinterval aload pop 3 -1 roll 0 eq { moveto }{ lineto } ifelse } for pop closepath //true } { ( **** Error: Invalid Vertices for Polygon, annotation has not been drawn.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror //false } ifelse 1 index annotsetinteriorcolor { //true }{ //false }ifelse and { gsave dup /ca knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if fill grestore dup /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if dup annotsetcolor { strokeborderpath } if } { dup annotsetcolor { strokeborderpath } if } ifelse //endannottransparency exec //false grestore } ifelse } bind executeonly def /LineEnd_dict 10 dict begin %% Stack contains <annot> %% CTM rotated so line segment is vertical, translated so line endpoint at 0,0 /Square { dup /BS knownoget { /W knownoget { }{ 1 }ifelse }{ 1 }ifelse dup 2.5 mul gsave dup neg 1 index neg exch moveto dup neg 1 index lineto dup 1 index exch lineto dup neg lineto closepath 1 index /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if 1 index fillborderpath grestore 3 mul dup neg 1 index neg exch moveto dup neg 1 index lineto dup 1 index exch lineto dup neg lineto closepath strokeborderpath } bind executeonly def /Circle { dup /BS knownoget { /W knownoget { }{ 1 }ifelse }{ 1 }ifelse dup gsave 2.5 mul dup 0 moveto 0 0 3 -1 roll 0 360 arc 1 index /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if 1 index fillborderpath grestore 3 mul dup 0 moveto 0 0 3 -1 roll 0 360 arc strokeborderpath } bind executeonly def /Diamond { dup /BS knownoget { /W knownoget { }{ 1 }ifelse }{ 1 }ifelse dup 2.5 mul gsave dup neg 0 exch moveto dup neg 0 lineto dup 0 exch lineto 0 lineto closepath 1 index /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if 1 index fillborderpath grestore 3 mul dup neg 0 exch moveto dup neg 0 lineto dup 0 exch lineto 0 lineto closepath strokeborderpath } bind executeonly def /OpenArrow { dup gsave /BS knownoget { /W knownoget { }{ 1 }ifelse }{ 1 }ifelse 0 setlinejoin dup 6 mul neg 1 index 4 mul neg moveto dup 1.2 div neg 0 lineto dup 6 mul neg exch 4 mul lineto strokeborderpath grestore } bind executeonly def /ClosedArrow { dup gsave /BS knownoget { /W knownoget { }{ 1 }ifelse }{ 1 }ifelse dup gsave 0 setlinejoin dup 6 mul neg 1 index 4 mul neg moveto dup 1.2 div neg 0 lineto dup 6 mul neg exch 4 mul lineto closepath 1 index strokeborderpath grestore dup 1.3 mul neg 0 translate dup 2 div sub dup 8.4 mul neg 1 index 5.9 mul neg moveto dup 1.2 div neg 0 lineto dup 8.4 mul neg exch 5.9 mul lineto closepath dup /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if fillborderpath grestore } bind executeonly def /None {pop} bind executeonly def /Butt { dup /BS knownoget { /W knownoget { }{ 1 }ifelse }{ 1 }ifelse 3 mul dup neg 0 exch moveto 0 exch lineto strokeborderpath } bind executeonly def /ROpenArrow { gsave dup /BS knownoget { /W knownoget { }{ 1 }ifelse }{ 1 }ifelse 180 rotate 0 setlinejoin dup 6 mul neg 1 index 4 mul neg moveto dup 1.2 div neg 0 lineto dup 6 mul neg exch 4 mul lineto strokeborderpath grestore } bind executeonly def /RClosedArrow { gsave dup /BS knownoget { /W knownoget { }{ 1 }ifelse }{ 1 }ifelse 180 rotate dup gsave 0 setlinejoin dup 6 mul neg 1 index 4 mul neg moveto dup 1.2 div neg 0 lineto dup 6 mul neg exch 4 mul lineto closepath 1 index strokeborderpath grestore dup 1.3 mul neg 0 translate dup 2 div sub dup 8.4 mul neg 1 index 5.9 mul neg moveto dup 1.2 div neg 0 lineto dup 8.4 mul neg exch 5.9 mul lineto closepath dup /CA knownoget {dup .setstrokeconstantalpha .setfillconstantalpha} if fillborderpath grestore } bind executeonly def /Slash { gsave dup /BS knownoget { /W knownoget { }{ 1 }ifelse }{ 1 }ifelse 330 rotate 3 mul dup neg 0 exch moveto 0 exch lineto strokeborderpath grestore } bind executeonly def currentdict end readonly def /Line { //ValidateAP exec { //true } { gsave //startannottransparency exec dup annotsetcolor { dup /L knownoget { 1 index /LE knownoget { % <annot> [x1 y1 x2 y2] [LE1 LE2] gsave 1 index aload pop % <annot> [x1 y1 x2 y2] [LE1 LE2] x1 y1 x2 y2 3 -1 roll sub % <annot> [x1 y1 x2 y2] [LE1 LE2] x1 x2 dy 3 1 roll exch sub % <annot> [x1 y1 x2 y2] [LE1 LE2] dy dx 3 index aload pop 4 2 roll pop pop translate 0 0 moveto {atan} stopped {pop pop 0} if % <annot> [x1 y1 x2 y2] [LE1 LE2] rotate dup 1 get % <annot> [x1 y1 x2 y2] [LE1 LE2] LE1 dup //LineEnd_dict exch known not { pop /None } if //LineEnd_dict exch % <annot> [x1 y1 x2 y2] [LE1 LE2] <dict> LE1 get % <annot> [x1 y1 x2 y2] [LE1 LE2] {} 3 index exch % <annot> [x1 y1 x2 y2] [LE1 LE2] <annot> {} exec grestore gsave 1 index aload pop % x1 y1 x2 y2 3 -1 roll sub % x1 x2 dy 3 1 roll exch sub % dy dx 3 index aload pop pop pop translate 0 0 moveto {atan} stopped {pop pop 0} if 180 add rotate 0 get dup //LineEnd_dict exch known not {pop /None} if //LineEnd_dict exch get 3 index exch exec grestore }if aload pop 4 2 roll moveto lineto strokeborderpath }{ ( **** Error: Invalid L array for Line, annotation has not been drawn.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror pop } ifelse } if //endannottransparency exec //false grestore } ifelse } bind executeonly def /PolyLine { //ValidateAP exec { //true } { gsave //startannottransparency exec dup annotsetcolor pop dup /Vertices knownoget { 1 index /LE knownoget { gsave 1 index 0 4 getinterval aload pop 4 2 roll 2 copy translate 4 2 roll 3 -1 roll exch sub % x1 x2 dy 3 1 roll sub % dy dx {atan} stopped {pop pop 0} if rotate dup 0 get dup //LineEnd_dict exch known not {pop /None} if //LineEnd_dict exch get 3 index exch exec grestore gsave 1 index dup length 4 sub 4 getinterval aload pop 2 copy translate 3 -1 roll sub % x1 x2 dy 3 1 roll exch sub % dy dx {atan} stopped {pop pop 0} if rotate 1 get dup //LineEnd_dict exch known not {pop /None} if //LineEnd_dict exch get 3 index exch exec grestore } if dup length 2 div 1 sub cvi 0 1 3 -1 roll { 2 mul dup 2 index exch 2 getinterval aload pop 3 -1 roll 0 eq { moveto }{ lineto } ifelse } for pop //true } { ( **** Error: Invalid Vertices for Polygon, annotation has not been drawn.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror //false } ifelse { strokeborderpath } if //endannottransparency exec //false grestore } ifelse } bind executeonly def /Link { % <annot> -> <false> //startannottransparency exec dup annotsetcolor { dup drawborder dup calc_annot_scale 2 copy mul 0 ne {3 -1 roll drawwidget} { pop pop ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror }ifelse } if //endannottransparency exec //false } bind executeonly def /Ink { % <annot> -> <annot> <true> % <annot> -> <false> //ValidateAP exec { //true } { //startannottransparency exec 1 setlinewidth 1 setlinecap 1 setlinejoin dup annotsetcolor { dup calc_annot_scale 2 copy mul 0 ne { scale dup /InkList knownoget { { oforce mark exch { oforce } forall .pdfinkpath stroke } forall pop } { /Path knownoget { oforce dup length 1 sub 0 1 3 -1 roll { dup 0 eq { 1 index exch get aload pop moveto } { 1 index exch get dup length 2 eq { aload pop lineto }{ aload pop curveto } ifelse }ifelse } for pop dup strokeborderpath } if }ifelse } { pop pop ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse } if //endannottransparency exec //false } ifelse } bind executeonly def /Underline { //ValidateAP exec { //true } { 0 setlinecap dup annotsetcolor { dup calc_annot_scale 2 copy mul 0 ne { scale /QuadPoints knownoget { aload length 8 idiv { //quadpoints2basis exec % Acrobat draws the line at 1/7 of the box width from the bottom % of the box and 1/16 thick of the box width. /Rect is ignored. 2 copy dup mul exch dup mul add sqrt 16 div setlinewidth 7 div 4 index add exch % x0 y0 x1-x0 y1-y0 (y2-y0)/7+y0 x2-x0 7 div 5 index add exch % x0 y0 x1-x0 y1-y0 (x2-x0)/7+x0 (y2-y0)/7+y0 2 copy moveto 2 index add exch 3 index add exch lineto % x0 y0 x1-x0 y1-y0 pop pop pop pop stroke } repeat } if } { pop pop ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse } if //false } ifelse } bind executeonly def /StrikeOut { //ValidateAP exec { //true } { 0 setlinecap dup annotsetcolor { dup calc_annot_scale 2 copy mul 0 ne { scale /QuadPoints knownoget { aload length 8 idiv { //quadpoints2basis exec % Acrobat draws the line at 3/7 of the box width from the bottom % of the box and 1/16 thick of the box width. /Rect is ignored. 2 copy dup mul exch dup mul add sqrt 16 div setlinewidth 0.4285714 mul 4 index add exch % x0 y0 x1-x0 y1-y0 (y2-y0)*3/7+y0 x2-x0 0.4285714 mul 5 index add exch % x0 y0 x1-x0 y1-y0 (x2-x0)*3/7+x0 (y2-y0)*3/7+y0 2 copy moveto 2 index add exch 3 index add exch lineto % x0 y0 x1-x0 y1-y0 pop pop pop pop stroke } repeat } if } { pop pop ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse } if //false } ifelse } bind executeonly def % Connect 2 points with an arc that has max distance from the line % segment to the ark equal 1/4 of the radius. /highlight-arc { % x1 y1 x0 y0 -> - 4 2 roll % x0 y0 x1 y1 dup 3 index add 2 div % x0 y0 x1 y1 (y1+y0)/2 2 index 5 index sub .9375 mul sub % x0 y0 x1 y1 (y1+y0)/2-15/16*dx=yc 4 index 3 index add 2 div % x0 y0 x1 y1 yc (x0+x1)/2 2 index 5 index sub .9375 mul add % x0 y0 x1 y1 yc xc exch % x0 y0 x1 y1 xc yc dup 3 index exch sub % x0 y0 x1 y1 xc yc y1-yc 4 index 3 index sub % x0 y0 x1 y1 xc yc y1-yc x1-xc dup dup mul 2 index dup mul add sqrt %x0 y0 x1 y1 xc yc y1-yc x1-xc r 3 1 roll atan % x0 y0 x1 y1 xc yc r a1 6 index 3 index sub % x0 y0 x1 y1 xc yc r a1 y0-yc 8 index 5 index sub % x0 y0 x1 y1 xc yc r a1 y0-yc x0-xc atan % x0 y0 x1 y1 xc yc r a1 a2 exch arcn % x0 y0 x1 y1 pop pop pop pop } bind executeonly def /emptydict 0 dict readonly def /Highlight { //ValidateAP exec { //true } { 0 setlinecap dup annotsetcolor { /QuadPoints knownoget { aload length 8 idiv { 6 -2 roll 2 copy moveto //highlight-arc exec 2 copy lineto //highlight-arc exec closepath } repeat PDFusingtransparency { //emptydict % If we get an error, just emit an empty box { pathbbox } stopped { 0 0 0 0 } if 2 index add exch 3 index add exch .begintransparencygroup /Multiply .setblendmode fill .endtransparencygroup } { % for -dNOTRANSPARENCY stroke newpath } ifelse } if } if //false } ifelse } bind executeonly def currentdict /emptydict undef currentdict /highlight-arc undef /Squiggly { //ValidateAP exec { //true } { //startannottransparency exec dup annotsetcolor { dup calc_annot_scale 2 copy mul 0 ne { scale /QuadPoints knownoget { aload length 8 idiv { gsave 8 copy moveto lineto 4 2 roll lineto lineto closepath clip newpath //quadpoints2basis exec 6 -2 roll translate % adjust for x0 y0 % x1-x0 y1-y0 x2-x0 y2-y0 1 index 56 div 1 index 56 div translate % zigzag box is 1/56 up 1 index 72 div 1 index 72 div translate % the line in the box is 1/72 up 2 copy dup mul exch dup mul add sqrt % x1-x0 y1-y0 x2-x0 y2-y0 |p2| 4 index dup mul 4 index dup mul add sqrt % x1-x0 y1-y0 x2-x0 y2-y0 |p2| |p1| dup 0 gt 2 index 0 gt and { div % x1-x0 y1-y0 x2-x0 y2-y0 |p2|/|p1|=p12 dup 1 exch div 4 mul 1 add cvi exch 6 2 roll % cnt p12 x1-x0 y1-y0 x2-x0 y2-y0 4 2 roll % cnt p12 x2-x0 y2-y0 x1-x0 y1-y0 4 index mul exch 4 index mul exch % cnt p12 x2-x0 y2-y0 (x1-x0)*p12 (y1-y0)*p12 4 2 roll 0 0 6 array astore concat % cnt p12 1 40 div 1 72 div scale pop % cnt 0 0 moveto 1 setlinecap 1 setlinejoin 1 setlinewidth { 5 10 lineto 10 0 lineto 10 0 translate } repeat stroke } { 6 { pop } repeat } ifelse grestore } repeat } if } { pop pop ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse } if //endannottransparency exec //false } ifelse } bind executeonly def /Text { //ValidateAP exec { //true } { //startannottransparency exec dup calc_annot_scale 2 copy mul 0 ne { scale annotrect 4 2 roll translate exch pop % Draw a page icon 0.5 exch 18.5 sub translate 1 setlinewidth 0.75 setgray 0.5 -1 moveto 10 -1 lineto 15 4 lineto 15 17.5 lineto stroke 0 0 moveto 9 0 lineto 14 5 lineto 14 18 lineto 0 18 lineto closepath gsave .5 setgray fill grestore 0 setgray stroke 3 8 moveto 7.5 8 lineto 3 11 moveto 10 11 lineto 3 14 moveto 10 14 lineto 9 0 moveto 9 5 lineto 14 5 lineto stroke } { pop pop ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse //endannottransparency exec //false } ifelse } bind executeonly def /FreeText { //ValidateAP exec { //true } %% We either have no appearance, or its invalid, make one up. { gsave //startannottransparency exec dup annotrect rectclip dup /CA knownoget { dup .setstrokeconstantalpha .setfillconstantalpha } if dup /ca knownoget { dup .setstrokeconstantalpha .setfillconstantalpha } if dup /C knownoget { dup length 4 eq { aload pop setcmykcolor //true }{ dup length 3 eq { aload pop setrgbcolor //true }{ dup length 1 eq { aload pop setgray //true } { dup length 0 eq { pop //false }{ ( **** Error: invalid color specified for FreeText annotation /C entry) pdfformaterror ( Output may be incorrect.\n) pdfformaterror //false } ifelse } ifelse } ifelse } ifelse }{ //false } ifelse { dup annotrect 5 index /RD knownoget { applyRD } if rectfill } if %% get and process the default appearance string, if we don't have one, use a default /DA_Action_Dict << /Tf { exch dup /Helv eq { pop /Helvetica dup findfont } {dup findfont}ifelse % re-encode the font to PDFDocEncoding dup length dict begin { 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse } forall /Encoding /PDFDocEncoding /Encoding findresource def /FontName /Helvetica-PDFDocEncoding def currentdict end definefont exch scalefont setfont } /r {aload pop setrgbcolor} % Can't find this actually defined anywhere, but Acrobat seems to honour it :-( /rg {setrgbcolor} /RG {setrgbcolor} /G {setgray} /g {setgray} /k {setcmykcolor} /K {setcmykcolor} >> def dup /DA knownoget { length string /tempstr exch def dup /DA get tempstr copy pop gstate mark { { %% This is kind of ugly, we use token to process the string %% and process each token separately. tempstr token { exch /tempstr exch def %% If the token is a name %% dup type /nametype eq { %% Is it a name we want to take actionon dup DA_Action_Dict exch known { DA_Action_Dict exch get exec }{ %% Its not a name we know, is it executable dup xcheck {exec} if } ifelse }{ %% Not a name, just make it executable and execute it cvx exec }ifelse }{ exit }ifelse } loop } stopped {cleartomark setgstate} {cleartomark pop} ifelse } { 0 setgray /Helvetica findfont % re-encode the font to PDFDocEncoding dup length dict begin { 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse } forall /Encoding /PDFDocEncoding /Encoding findresource def /FontName /Helvetica-PDFDocEncoding def currentdict end /Helvetica-PDFDocEncoding exch definefont 12 scalefont setfont }ifelse %% draw the border, if we don't have a border style dictionary, draw a default one. dup /BS knownoget { pop dup drawborder }{ newpath 0 setgray 1 setlinewidth dup annotrect 5 index /RD knownoget { applyRD 4 -1 roll 4 -1 roll 4 -1 roll 4 -1 roll 4 2 roll } { 4 -1 roll 1 add 4 -1 roll 1 add 4 -1 roll 2 sub 4 -1 roll 2 sub 4 2 roll }ifelse moveto currentpoint exch 3 index add exch lineto currentpoint 2 index add lineto exch currentpoint 3 1 roll exch sub exch lineto currentpoint 3 -1 roll sub lineto stroke }ifelse gsave % in case we rotate the contents %% Start the current point at the top left of the annotation Rect %% dup /Rotate knownoget % x y w h - x' w' x' y' { dup 90 eq { pop dup annotrect 5 index /RD knownoget { applyRD } if exch pop 3 -1 roll 2 index moveto 90 rotate 1 index add } { dup 180 eq { pop dup annotrect 5 index /RD knownoget { applyRD } if pop 3 -1 roll 1 index add -1 mul exch 1 index -1 mul 4 -1 roll moveto 180 rotate 1 index add }{ 270 eq { dup annotrect 5 index /RD knownoget { applyRD } if dup 4 -1 roll add 3 -1 roll 3 index add exch moveto 270 rotate exch pop currentpoint pop dup 3 -1 roll add }{ dup annotrect 5 index /RD knownoget { applyRD 3 -1 roll add 2 index exch moveto 1 index add }{ 4 -1 roll 2 add 4 -1 roll 2 add 4 -1 roll 4 sub 4 -1 roll 4 sub 3 -1 roll add 2 index exch moveto 1 index add } ifelse } ifelse } ifelse } ifelse }{ dup annotrect 5 index /RD knownoget { applyRD 3 -1 roll add 2 index exch moveto 1 index add }{ 4 -1 roll 2 add 4 -1 roll 2 add 4 -1 roll 4 sub 4 -1 roll 4 sub 3 -1 roll add 2 index exch moveto 1 index add } ifelse } ifelse %% Get the Contents string, if we don't have one, we're done %% 2 index /Contents knownoget { dup length 0 gt { PDFusingtransparency { .begintransparencytextgroup } if %% Check for UTF16-BE, we probably don't work properly with this yet. %% (If the string is less than 4 bytes its either not UTF16-BE or it is %% but has no actual content) dup length 4 ge { dup 0 get 254 eq 1 index 1 get 255 eq and }{ //false } ifelse { /FallBackFont /Identity-UTF16-H [/CIDFallBack] composefont 12 scalefont setfont dup length 2 div 1 sub 0 1 3 -1 roll { %% llx urx (string) index 1 index exch 2 mul 2 getinterval %% llx urx (string) (substring) dup stringwidth pop currentpoint pop add 3 index gt { currentpoint exch pop 4 index exch 12 sub moveto } if show } for pop } { %% Heuristic to determine the height (ascender to descender) of the text %% for when we move down a line. gsave /..TextHeight (Hy) //false charpath pathbbox exch pop exch sub exch pop def grestore %% and use it immediatley to start the text one line down %% currentpoint ..TextHeight sub moveto %% Now we process each character code in the string. If we find %% a /r/ or /n then we drop a line. If the character would end up %% outside the Annot Rect, then we drop a line before showing it. %% dup length 1 sub 0 1 3 -1 roll { %% llx urx (string) index 1 index exch get %% llx urx (string) int dup 10 eq 1 index 13 eq or { pop currentpoint exch pop 3 index exch ..TextHeight sub moveto } { 1 string dup 0 4 -1 roll put dup %% llx urx (string) (int) (int) stringwidth pop currentpoint pop add 3 index gt { currentpoint exch pop 4 index exch ..TextHeight sub moveto } if show } ifelse } for pop }ifelse PDFusingtransparency { .endtransparencytextgroup } if } { pop } ifelse } if pop pop grestore % in case the contents were rotated dup /CL knownoget { dup length 6 eq { dup aload pop pop pop } { dup length 4 eq { dup aload pop } { pop 0 } ifelse } ifelse 4 2 roll exch 4 -1 roll sub 3 1 roll exch sub atan exch aload pop moveto lineto lineto currentpoint % stroke % 0 1 0 setrgbcolor moveto currentpoint translate 0 0 moveto 360 exch sub rotate currentpoint -5 -8 rlineto moveto 5 -8 rlineto stroke } if //endannottransparency exec //false grestore } ifelse } bind executeonly def /frame { { 255 div } forall setrgbcolor -95 -25 translate 2 190 atan rotate { 6 0 moveto 190 0 190 6 6 arct 190 47 184 47 6 arct 0 47 0 41 6 arct 0 0 6 0 6 arct closepath 10 4 moveto 185 4 185 9 5 arct 185 43 180 43 5 arct 5 43 5 38 5 arct 5 4 9 4 5 arct closepath eofill } gsave 1 -1 translate 0.75 setgray dup exec grestore exec } bind executeonly def % (text) y h -> - /text { PDFusingtransparency { .begintransparencytextgroup } if /Times-Bold findfont % re-encode the font to PDFDocEncoding dup length dict begin { 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse } forall /Encoding /PDFDocEncoding /Encoding findresource def /FontName /Times-Bold-PDFDocEncoding def currentdict end /Times-Bold-PDFDocEncoding exch definefont exch scalefont setfont % (text) y gsave 0 0 moveto 1 index //false charpath flattenpath pathbbox pop exch pop sub 2 div grestore 95 add exch moveto gsave 1 -1 rmoveto 0.75 setgray dup show grestore show PDFusingtransparency { .endtransparencytextgroup } if } bind executeonly def /red <ef4023> readonly def /green <3fae49> readonly def /blue <0072bc> readonly def /stamp_dict 14 dict begin /Approved { //green //frame exec (APPROVED) 13 30 //text exec } bind executeonly def /AsIs { //red //frame exec (AS IS) 13 30 //text exec } bind executeonly def /Confidential { //red //frame exec (CONFIDENTIAL) 17 20 //text exec } bind executeonly def /Departmental { //blue //frame exec (DEPARTMENTAL) 17 20 //text exec } bind executeonly def /Draft { //red //frame exec (DRAFT) 13 30 //text exec } bind executeonly def /Experimental { //blue //frame exec (EXPERIMENTAL) 17 20 //text exec } bind executeonly def /Expired { //red //frame exec (EXPIRED) 13 30 //text exec } bind executeonly def /Final { //red //frame exec (FINAL) 13 30 //text exec } bind executeonly def /ForComment { //green //frame exec (FOR COMMENT) 17 20 //text exec } bind executeonly def /ForPublicRelease { //green //frame exec (FOR PUBLIC) 26 18 //text exec (RELEASE) 8.5 18 //text exec } bind executeonly def /NotApproved { //red //frame exec (NOT APPROVED) 17 20 //text exec } bdef /NotForPublicRelease { //red //frame exec (NOT FOR) 26 18 //text exec (PUBLIC RELEASE) 8.5 18 //text exec } bind executeonly def /Sold { //blue //frame exec (SOLD) 13 30 //text exec } bind executeonly def /TopSecret { //red //frame exec (TOP SECRET) 14 26 //text exec } bind executeonly def currentdict end readonly def {/text/frame/red/green/blue} {currentdict exch undef} forall /Stamp { //ValidateAP exec { //true } { //startannottransparency exec dup calc_annot_scale 2 copy mul 0 ne { scale % translate to the center of Rect dup annotrect 4 2 roll % dx dy x0 y0 2 index 2 div add exch 3 index 2 div add exch translate % dx dy 50 div exch 190 div .min dup 0.0 eq {pop 1.0} if dup scale /Name knownoget not { /Draft } if //stamp_dict 1 index known not { exch pop /Draft exch } if //stamp_dict exch get exec } { pop pop ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse //endannottransparency exec //false } ifelse } bind executeonly def /Popup { dup /Open oknown { dup /Open get { //ValidateAP exec { //true } { gsave //startannottransparency exec newpath 0.05 setlinewidth dup /Parent .knownget { oforce } { dup /P .knownget { oforce } { dup } ifelse } ifelse /C .knownget { aload pop }{ 1 1 0 }ifelse setrgbcolor dup /Rect get dup aload pop 2 index sub exch 3 index sub exch 4 copy gsave 1 setgray rectfill grestore gsave 0 setgray rectstroke grestore 1 index /Parent .knownget { oforce }{ 1 index /P .knownget { oforce }{ 1 index } ifelse }ifelse dup /Contents .knownget { gsave PDFusingtransparency { .begintransparencytextgroup } if 0 setgray /Helvetica findfont % re-encode the font to PDFDocEncoding dup length dict begin { 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse } forall /Encoding /PDFDocEncoding /Encoding findresource def /FontName /Helvetica-PDFDocEncoding def currentdict end /Helvetica-PDFDocEncoding exch definefont 9 scalefont setfont 2 index aload pop 3 1 roll pop pop 30 sub exch 5 add exch moveto show PDFusingtransparency { .endtransparencytextgroup } if grestore } if exch dup aload pop 3 -1 roll pop exch 2 index sub -15 4 copy rectfill 0 setgray rectstroke exch /T .knownget { gsave PDFusingtransparency { .begintransparencytextgroup } if 0 setgray /Helvetica findfont % re-encode the font to PDFDocEncoding dup length dict begin { 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse } forall /Encoding /PDFDocEncoding /Encoding findresource def /FontName /Helvetica-PDFDocEncoding def currentdict end /Helvetica-PDFDocEncoding exch definefont 9 scalefont setfont dup stringwidth pop 2 index aload pop pop exch pop exch sub exch sub 2 div 2 index aload pop 3 1 roll pop pop 11 sub 3 1 roll add exch moveto show PDFusingtransparency { .endtransparencytextgroup } if grestore } if grestore //endannottransparency exec //false } ifelse } { pop //false }ifelse } { pop //false }ifelse } bind executeonly def /Redact { %% Redact annotations are part of a process, a Redact annotation is only present %% until the content is removed, before that the content should be present and %% I beleive we should print it. So take no action for Redact annotations if they %% have no appearance. //ValidateAP exec { //true } { //false } ifelse } bind executeonly def currentdict /startannottransparency undef currentdict /endannottransparency undef currentdict /ValidateAP undef currentdict /quadpoints2basis undef currentdict /drawellipse undef currentdict end readonly def /.PDFDrawAnnotType? { //false exch /ShowAnnotTypes where { /ShowAnnotTypes get { dup /* eq exch 2 index eq or { pop //true exch exit } if } forall pop } {pop pop //true} ifelse } bind executeonly def /.PDFPreserveAnnotType? { //false exch /PreserveAnnotTypes where { /PreserveAnnotTypes get { dup /* eq exch 2 index eq or { pop //true exch exit } if } forall pop } {pop pop //true} ifelse } bind executeonly def /drawannot { % <annot> drawannot - dup annotvisible { gsave dup dup /Subtype knownoget { dup //.PDFDrawAnnotType? exec { //drawannottypes exch .knownget { exec } { //true } ifelse { dup calc_annot_scale 2 copy mul 0 ne { 3 -1 roll drawwidget } { ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror }ifelse % Draw rejected annots as widgets } if % type known } { pop }ifelse } { pop ( **** Error: Ignoring /Annot dict without required /Subtype entry.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse grestore } if pop % annotvisible } bind executeonly def currentdict /drawannottypes undef % Draw an annotation. /loadannot { dup /AP .knownget { % <<Annot dict>> <<Appearance dictionary>> true | false oforce dup { % <<Annot dict>> <<Appearance dict>> /Key <</Key dict>> oforce % <<Annot dict>> <<Appearance dict>> /Key <<resolved /Key dict>> %% %% Check to see if the apperance key has a simple stream or a dictionary of states %% dup /Subtype known % <<Annot dict>> <<Appearance dict>> /Key <<resolved /Key dict>> bool { %% Simple appearance stream DoAppearance % <<Annot dict>> <<Appearance dict>> /Key 2 index % <<Annot dict>> <<Appearance dict>> /Key <<Annot dict>> /AP << % <<Annot dict>> <<Appearance dict>> /Key <<Annot dict>> /AP << 4 -1 roll MakeAppearanceName cvx cvn >> put % <<Annot dict>> <<Appearance dict>> } { %% dictionary of states <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> dup % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> <<appearance states dict>> { % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> /StateKey <<State dictionary>> oforce % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> /StateKey <<resolved State dictionary>> DoAppearance % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> /StateKey 1 index exch % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> <<appearance states dict>> /StateKey MakeAppearanceName cvx cvn % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> <<appearance states dict>> /StateKey {} put % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> } forall put % <<Annot dict>> <<Appearance dict>> /Key dup }ifelse } forall pop % <<Annot dict>> } if %% Parent (or /P) references will be incorrect. Remove them %% for now as they are optional. dup /Popup known {dup /Popup undef} if dup /IRT known {dup /IRT undef} if dup /RT known {dup /RT undef} if dup /P known {dup /P undef} if dup /Parent known {dup /Parent undef} if %% Resolve any indirect references. May need further work :-( { %% We know /AP doesn't need processing, we handled that above... 1 index /AP eq not { dup {oforce} stopped not {exch pop} if dup type /dicttype eq{ dup { dup {oforce} stopped not {exch pop} if 2 index 3 1 roll put } forall Removepdfobj# } if dup type /arraytype eq { 0 1 2 index length 1 sub{ dup 2 index exch get dup {oforce} stopped not {exch pop} if 2 index 3 1 roll put } for } if } if } forall } bind executeonly def /ApplyCTMToQuadPoints { %% Nasty hackery here really. We need to undo the HWResolution scaling which %% is done by pdfwrite. Default is 720 dpi, so 0.1. We also need to make %% sure that any translation of the page (because its been rotated for example) %% is also modified by the requisite amount. SO we ned to calculate a matrix %% which does the scaling and concatenate it with the current matrix. %% Do this inside a gsave/grestore pair to avoid side effects! gsave currentpagedevice /HWResolution get aload pop exch 72 exch div exch 72 exch div matrix 3 1 roll 2 index 3 3 -1 roll put 1 index 0 3 -1 roll put matrix currentmatrix exch matrix concatmatrix setmatrix oforce %% QuadPoints are given as 'n' sequences of 8 numbers. mark exch aload counttomark 1 roll counttomark 1 sub 2 div cvi { transform counttomark 1 sub 2 roll } repeat counttomark -1 roll astore exch pop % the mark grestore } bind executeonly def /preserveannottypes 20 dict begin /Circle {mark exch loadannot /ANN pdfmark //false} bind executeonly def /FileAttachment {mark exch loadannot /ANN pdfmark //false} bind executeonly def /FreeText {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Highlight { mark exch dup /QuadPoints .knownget { 1 index /QuadPoints 3 -1 roll ApplyCTMToQuadPoints put } if loadannot /ANN pdfmark //false } bind executeonly def /Ink {mark exch loadannot /ANN pdfmark //false} bind executeonly def /PolyLine {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Line {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Link { /NO_PDFMARK_DESTS where {pop NO_PDFMARK_DESTS not}{//true}ifelse { mark exch dup /BS knownoget { << exch { oforce } forall >> /BS exch 3 -1 roll } if dup /F knownoget { /F exch 3 -1 roll } if dup /C knownoget { /Color exch 3 -1 roll } if dup /Rect knownoget { /Rect exch 3 -1 roll } if dup /Border knownoget { dup type /arraytype eq { dup length 3 lt } { //true } ifelse { pop [ 0 0 0 ] % Following AR5 use invisible border. } if /Border exch 3 -1 roll } if dup /A knownoget { dup /URI known { /A mark 3 2 roll % <<>> /A [ <<action>> { oforce } forall .dicttomark 3 2 roll } { dup /S knownoget { %% Because we process GoTo Destinations into absolute references in the PDF file %% we need to resolve the /D or /Dest. However, we must *not* do this for %% GoToR Destinations because (obviously) those are in a different file and %% we cannot resolve them into absolute references. We don't need to anyway %% because that file must already have a named destination. dup /GoTo eq { pop dup /D knownoget { exch pop exch dup length dict copy dup /Dest 4 -1 roll put } if }{ dup /GoToR eq { pop /A mark % <<..action dict..>> /A [ 3 2 roll % /A [ <<..action dict..>> { oforce } forall .dicttomark 3 2 roll }{ dup /Launch eq { pop /A mark % <<..action dict..>> /A [ 3 2 roll % /A [ <<..action dict..>> { oforce } forall .dicttomark 3 2 roll }{ /Named eq { /N knownoget { namedactions exch .knownget { exec { pop ( **** Warning: Ignoring a named action pointing out of the document page range.\n) pdfformatwarning } { /Page exch 3 -1 roll } ifelse } if } if } if }ifelse } ifelse } ifelse } if } ifelse } if { linkdest } stopped { cleartomark ( **** Warning: Link annotation points out of the document page range.\n) pdfformatwarning } { pop { %% Need to remove any '/.gs.pdfobj# key/value pairs from any dictionaries counttomark array astore dup length 1 sub 0 1 3 -1 roll { dup 2 index exch get Removepdfobj# 2 index 3 1 roll put } for aload pop /LNK pdfmark } stopped {cleartomark} if } ifelse }{pop} ifelse //false } bind executeonly def %% We don't handle movies correctly, so don't try to preserve them %/Movie {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Popup {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Sound {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Square {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Stamp {mark exch loadannot /ANN pdfmark //false} bind executeonly def /StrikeOut { mark exch dup /QuadPoints .knownget { 1 index /QuadPoints 3 -1 roll ApplyCTMToQuadPoints put } if loadannot /ANN pdfmark //false } bind executeonly def /Squiggly { mark exch dup /QuadPoints .knownget { 1 index /QuadPoints 3 -1 roll ApplyCTMToQuadPoints put } if loadannot /ANN pdfmark //false } bind executeonly def /Text {mark exch loadannot /ANN pdfmark //false} bind executeonly def /TrapNet {mark exch loadannot /ANN pdfmark //false} bind executeonly def /Underline { mark exch dup /QuadPoints .knownget { 1 index /QuadPoints 3 -1 roll ApplyCTMToQuadPoints put } if loadannot /ANN pdfmark //false } bind executeonly def %% Widget annotations are only used with AcroForms, and since we don't preserve AcroForms %% we don't want to preserve widget annotations either, because the consumer of the new %% PDF won't know what values they should take. So we draw widget annotations instead. If we %% ever preserve AcroForms then we should alter this to preserve Widgets as well. %% simply chane "drawannot" to "mark exch loadannot /ANN pdfmark" /Widget {mark exch {drawannot} PDFSTOPONERROR {exec}{stopped {(Error: Ignoring invalid annotation, output may be incorrect.\n) pdfformaterror} if} ifelse cleartomark //false} bind executeonly def currentdict end readonly def /preserveannot { % <annot> preserveannot - dup /.gs.pdfobj# known { dup /.gs.pdfobj# undef } if gsave dup dup /Subtype knownoget { dup //.PDFPreserveAnnotType? exec { //preserveannottypes exch .knownget { exec } { //true } ifelse { dup annotvisible { dup calc_annot_scale 2 copy mul 0 ne { 3 -1 roll drawwidget } { ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror }ifelse % Draw rejected annots as widgets } { pop }ifelse } if } { % Not preserving this type of annotation % discard teh Subtype pop % copy the Annot dictionary and try drawing it instead dup drawannot } ifelse % type known } { pop ( **** Error: Ignoring /Annot dict without required /Subtype entry.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse grestore } bind executeonly def currentdict /preserveannottypes undef currentdict /.PDFDrawAnnotType? undef % ============================ AcroForm fields ============================ % % Get an attribure of the 0th annotation of a node /annot_oget { % <annot> /Name annot_oget <value> 1 index /Kids knownoget { 0 oget exch oget exch pop } { oget } ifelse } bind executeonly def % All procedures have the signature: % <acroform> <field> <annot|field> foo <acroform> <field> <annot|field> /draw_terminal_field_dict 4 dict begin /Btn { 1 index /Tf pget not { 0 } if dup 16#20000 and 0 ne { pop % Push button dup /AP known { 1 1 2 index drawwidget } { (Push button without appearance stream is not yet implemented) = } ifelse } { 16#10000 and 0 ne { % Radio button dup /AP known { 1 index /Kids oget { 1 1 3 -1 roll drawwidget } forall } { (Radio button without appearance stream is not yet implemented) = } ifelse } { % Checkbox dup /AP known { dup 1 1 3 -1 roll drawwidget } { (CkeckBox without appearance stream is not yet implemented) = } ifelse } ifelse } ifelse } bind executeonly def /Tx { dup /AP known { dup 1 1 3 -1 roll drawwidget } { %% If we don't have a NeedApperances, treat as true, because Acrobat %% always regenerates Appearances anyway. 2 index /NeedAppearances knownoget not { //true } if { dup /AP << /N 10 dict dup cvx begin >> put /Subtype /Form def /BBox [ 0 0 4 index /Rect oget { oforce } forall 3 -1 roll sub abs 3 1 roll sub abs exch ] def /Resources 3 index /DR pget not { 0 dict } if def /File 1000 string dup 3 1 roll def /Length 1000 def % <acroform> <field> <annot> (string) /NullEncode filter % <acroform> <field> <annot> file dup (BT ) writestring 2 index /DA pget not { () } if [ exch { token { dup /Tf eq { 2 index 0 eq { /BBox load 3 get 0.75 mul % empirical constant 4 -1 roll pop 3 1 roll } if } if exch } { exit } ifelse } loop ] { 1 index exch write== } forall dup 3 index /MaxLen pget not { 0 } if write= dup 3 index /V pget not { 3 index /DV pget not { () } if } if write== dup 3 index /Ff pget not { 0 } if write= dup 3 index /Q pget not { 0 } if write= dup (Tform ET) write= end closefile % <acroform> <field> <annot> dup 1 1 3 -1 roll drawwidget } if } ifelse } bind executeonly def /Ch { dup /AP known 3 index /NeedAppearances knownoget not { //true } if not and { dup 1 1 3 -1 roll drawwidget } { %% If we don't have a NeedApperances, treat as true, because Acrobat %% always regenerates Appearances anyway. 2 index /NeedAppearances knownoget not { //true } if { dup /AP << /N 10 dict dup cvx begin >> put /Subtype /Form def /BBox [ 0 0 4 index /Rect oget { oforce } forall 3 -1 roll sub abs 3 1 roll sub abs exch ] def /Resources 3 index /DR pget not { 0 dict } if def /File 1000 string dup 3 1 roll def /Length 1000 def % <acroform> <field> <annot> (string) /NullEncode filter % <acroform> <field> <annot> file dup (BT ) writestring 2 index /DA pget not { () } if [ exch { token { dup /Tf eq { 2 index 0 eq { /BBox load 3 get 0.75 mul % empirical constant 4 -1 roll pop 3 1 roll } if } if exch } { exit } ifelse } loop ] { 1 index exch write== } forall dup 3 index /MaxLen pget not { 0 } if write= dup 3 index /V pget not { 3 index /DV pget not { () } if } if write== dup 3 index /Ff pget not { 0 } if write= dup 3 index /Q pget not { 0 } if write= dup (Tform ET) write= end closefile % <acroform> <field> <annot> dup 1 1 3 -1 roll drawwidget } if } ifelse } bind executeonly def /Sig { (Sig is not yet implemened ) //== exec } bind executeonly def currentdict end def /draw_terminal_field { % <field> draw_terminal_field - dup /Kids knownoget { 0 oget } { dup } ifelse dup /P knownoget { /Page load eq { //draw_terminal_field_dict 2 index /FT pget not { 0 } if .knownget { exec } if } if } if pop pop } bind executeonly def % We distinguish 4 types of nodes on the form field tree: % - non-terminal field - has a kid that refers to the parent (or anywhere else) % - terminal field with separate widget annotations - has a kid that doesn't have a parent % - terminal field with a merged widget annotation - has no kids % - widget annotation - has /Subtype and /Rect % % The recursive enumeration of the form fields doesn't descend into widget annotations. /draw_form_field { % <field> draw_form_field - dup type /dicttyype eq { % File for Bug692447 has 'null' Fields entries % This matches what pdf_main process_trailer_attrs dup /Kids knownoget { % field [] dup length 0 gt { dup 0 oget /Parent knownoget { % field [] kid pop % mon-terminal field % field [] exch pop % [] { oforce draw_form_field } forall } { pop draw_terminal_field % separate annots % - } ifelse } { ( **** Error: Ignoring empty /Kids array in Form field.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror } ifelse } { draw_terminal_field % merged annotation % - } ifelse } if } bind executeonly def /draw_acro_form { % <form> draw_acro_form - dup /Fields knownoget { { oforce draw_form_field } forall } if pop } bind executeonly def currentdict /draw_terminal_field_dict undef end % pdfdict end % GS_PDF_ProcSet .setglobal
Save
cmd:
run