diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2023-09-13 23:30:15 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2023-09-13 23:30:15 +0000 |
commit | 9262fc101afe7733e74817d5d3e5917cf0143503 (patch) | |
tree | d53e8cfa6d589a695ef5554bfb69f5c0bf6c6b8e /Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps | |
parent | c167e0a5bb767292da0aeef68f0bc336fc06ec0f (diff) |
tlgs (gs-10.02.0)
git-svn-id: svn://tug.org/texlive/trunk@68272 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps')
-rw-r--r-- | Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps | 5896 |
1 files changed, 0 insertions, 5896 deletions
diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps deleted file mode 100644 index 117b362cfb9..00000000000 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps +++ /dev/null @@ -1,5896 +0,0 @@ -% Copyright (C) 2001-2022 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 signalerror - } if - exch token { - /rangecheck 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 - % If inside a BT/ET block, we need to undo the text matrix, then apply - % the cm, then re-apply the text matrix :-( Of course the spec says - % this isn't even legal. - currentdict /TextSaveMatrix .knownget { - pop - unsettextmatrix - } if - .getpath - exch concat - newpath { exec } forall - % If inside a BT/ET block, we need to update the TextSaveMatrix - currentdict /TextSaveMatrix .knownget { - settextmatrix - //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 cvx /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 - - % Check the object number of the pattern, from the pattern dictionary. Somehow - % there is a means to get here with no object number set, I have no idea how - % but this solves the immediate problem. Hopefully good enough until we drop - % this code. Fixes bug #704487 which is recursion caused by a pattern - % referenced via resolving a name from a Page as it is not defined in the Form - % which uses it. - 1 index /.gs.pdfobj# known { - 1 index /.gs.pdfobj# get - } - { - 0 - } ifelse - 3 1 roll - NestedPatterns 3 index known 3 index 0 ne and - { - PDFSTOPONERROR not { - ( **** Error: Attempting to run a Pattern while already executing that Pattern.\n Ignoring this pattern, output may be incorrect.\n) pdfformaterror - pop pop pop - } - { - /PaintProc cvx /circular_reference signalerror - } ifelse - } - { - % Store the currnet object number in the dictionary just so we can find it later. - NestedPatterns 3 index null put - 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 - NestedPatterns exch undef - }ifelse -} bind executeonly odef - -/.pdfpaintproc { - % Copy the pattern dictionary, we need it to rewind the /File if it is a file - % rather than a string, after we've run .actual_pdfpaintproc. If we don't reset - % the file position then if we try to run the PaintProc again we will already be - % at EOF and nothing will be executed. - 1 index 3 1 roll - - %% 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 - %% Unconditionally 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 - - % If the pattern dictionary has a /File (it should always but let's be safe) - % *and* the /File is a file object, not a string, then we need to set the - % position of that file (it's a subfiledecode filter) back to 0 so we can - % run the PaintProc again, should we need to. - % cf bug #704388 - /File .knownget { - dup type /filetype eq - { - 0 setfileposition - } - { - pop - } ifelse - } 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 - - % Regardless of whether we are using transparency, if we are doing Overprint - % simulation we still need to have the pattern code push the pdf14 compositor. - % We consider we are doing overprint simulation if: - % The current page device has /Overprint set to /simulate - % The current page device does NOT contain PageSpotColors (spot-capable devices can overprint) - % The current page device has a /PageUsesOverprint key (set by the interpreter) and it is set to true - % If all these conditions are true then we set /.pattern_uses_transparency, otherwise we leave it - % untouched as set above. - % - currentpagedevice dup - /Overprint .knownget {/simulate eq}{false} ifelse - 1 index /PageSpotColors known not and - exch /PageUsesOverprint .knownget not { //false } if - and - { - dup /.pattern_uses_transparency //true put - } if - - 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 type /dicttype ne 1 index type /arrratype ne and 1 index length 1 lt or { - 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. - %% - 1 dict begin - /.ImageDictStackDepth countdictstack def - /.ImageOpStackDepth count 2 sub def - { - 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 - } PDFSTOPONERROR {exec false}{stopped} ifelse - { - (\n **** Error: File encountered ') - $error /errorname get dup length string cvs concatstrings - (' error while processing an image.\n) concatstrings - ( Output may be incorrect.\n) concatstrings - pdfformaterror - } if - count .ImageOpStackDepth sub {pop} repeat - countdictstack .ImageDictStackDepth sub {end} repeat - end -} 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 { - oforce - /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 { - oforce - /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 - [ 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 - - % Set some sane defaults, in case the /DA does not. - 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 - - 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 - } if - - %% 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 |