home *** CD-ROM | disk | FTP | other *** search
/ jppd.dyndns.org / jppd.dyndns.org.tar / jppd.dyndns.org / QUERYPRO / Impressora_PDF / converter.exe / GPLGS / pdf_draw.ps < prev    next >
Text File  |  2004-09-14  |  41KB  |  1,308 lines

  1. %    Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: pdf_draw.ps,v 1.66.2.5 2004/09/13 22:16:17 ray Exp $
  14. % pdf_draw.ps
  15. % PDF drawing operations (graphics, text, and images).
  16.  
  17. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  18. .currentglobal true .setglobal
  19. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  20. GS_PDF_ProcSet begin
  21. pdfdict begin
  22.  
  23. % For simplicity, we use a single interpretation dictionary for all
  24. % PDF graphics operations, even though this is too liberal.
  25. /drawopdict 100 dict def
  26.  
  27. % ================================ Graphics ================================ %
  28.  
  29. % ---------------- Functions ---------------- %
  30.  
  31. % Note that resolvefunction converts a PDF Function to a PostScript Function;
  32. % resolve*fnproc converts a PDF function to a PostScript procedure.
  33. % We need to process all required and optional parameters to resolve any
  34. % use of indirect references.
  35.  
  36. /fnrdict mark
  37.   0 { .resolvefn0 }
  38.   2 { .resolvefn2 }
  39.   3 { .resolvefn3 }
  40.   4 { .resolvefn4 }
  41. .dicttomark readonly def
  42.  
  43. /.resolvefn0 {
  44.   dup length 1 add dict .copydict    % make room for DataSource
  45.   % now resolve any indirect references
  46.   dup /Size 2 copy knownoget { put } { pop pop } ifelse
  47.   dup /BitsPerSample 2 copy knownoget { put } { pop pop } ifelse
  48.   dup /Order 2 copy knownoget { put } { pop pop } ifelse
  49.   dup /Encode 2 copy knownoget { put } { pop pop } ifelse
  50.   dup /Decode 2 copy knownoget { put } { pop pop } ifelse
  51.   
  52.         % Don't lose our place in PDFfile.
  53.   PDFfile fileposition exch
  54.   dup true resolvestream
  55.         % The stream isn't positionable, so read all the data now.
  56.         % Stack: filepos fndict stream
  57.   1 index /Range get length 2 idiv 2 index /BitsPerSample get mul
  58.   2 index /Size get { mul } forall
  59.   7 add 8 idiv string
  60.   1 index exch readstring pop exch closefile
  61.         % Stack: filepos fndict data
  62.   exch dup /DataSource 4 -1 roll put
  63.   exch PDFfile exch setfileposition
  64. } bdef
  65.  
  66. /.resolvefn2 {
  67.   dup length dict .copydict
  68.   dup /C0 2 copy knownoget { put } { pop pop } ifelse
  69.   dup /C1 2 copy knownoget { put } { pop pop } ifelse
  70.   dup /N 2 copy knownoget { put } { pop pop } ifelse
  71. } bdef
  72.  
  73. /.resolvefn3 {
  74.   dup length dict .copydict
  75.   dup /Bounds 2 copy knownoget { put } { pop pop } ifelse
  76.   dup /Encode 2 copy knownoget { put } { pop pop } ifelse
  77.   dup /Functions 2 copy oget mark exch dup {
  78.     oforce .resolvefn
  79.   } forall
  80.   counttomark -1 roll astore exch pop put
  81. } bdef
  82.  
  83. /.resolvefn4 {
  84.   PDFfile fileposition exch             % filepos fndict
  85.   dup true resolvestream                % filepos fndict stream
  86.   exch dup length dict copy             % filepos stream fndict2
  87.   dup /Function undef                   % filepos stream fndict2
  88.   exch dup token not {
  89.     () /rangecheck cvx signalerror
  90.   } if
  91.   exch token {
  92.     /rangecheck cvx signalerror
  93.   } if
  94.         % Use .bind to avoid idiom recognition.
  95.   .bind
  96.   1 index /Function 3 -1 roll put
  97.   exch PDFfile exch setfileposition
  98. } bdef
  99.  
  100. /.resolvefn {        % <fndict> .resolvefn <fndict'>
  101.   dup length dict .copydict
  102.   dup /Domain 2 copy knownoget { put } { pop pop } ifelse
  103.   dup /Range 2 copy knownoget { put } { pop pop } ifelse
  104.   dup /FunctionType oget //fnrdict exch get exec
  105. } bdef
  106.  
  107. /resolvefunction {    % <fndict> resolvefunction <function>
  108.   .resolvefn
  109.   PDFDEBUG { (%Function: ) print dup === flush } if
  110. } bdef
  111.  
  112. /resolvefnproc {    % <fndict> resolvefnproc <proc>
  113.   resolvefunction .buildfunction
  114. } bdef
  115.  
  116. /resolveidfnproc {    % <fndict> resolveidfnproc <proc>
  117.   dup /Identity eq { pop { } } { resolvefnproc } ifelse
  118. } bdef
  119.  
  120. /resolvedefaultfnproc {    % <fndict> <default> resolved'fnproc <proc>
  121.   1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse
  122. } bdef
  123.  
  124. % ---------------- Shadings ---------------- %
  125.  
  126. /shrdict mark
  127.   /ColorSpace {
  128.     resolvecolorspace
  129.   }
  130.   /Function {
  131.     dup type /dicttype eq {
  132.       resolvefunction
  133.     } {
  134.       [ exch { oforce resolvefunction } forall ]
  135.     } ifelse
  136.   }
  137. .dicttomark readonly def
  138.  
  139. /resolveshading {    % <shadingstream> resolveshading <shading>
  140.   PDFfile fileposition exch
  141.   mark exch {
  142.     oforce //shrdict 2 index .knownget { exec } if
  143.   } forall .dicttomark
  144.   dup /ShadingType get 4 ge {
  145.     dup dup true resolvestream
  146.         % Make a reusable stream so that the shading doesn't
  147.         % reposition PDFfile at unexpected times.
  148.     /ReusableStreamDecode filter /DataSource exch put
  149.   } if exch PDFfile exch setfileposition
  150. } bdef
  151. /resolvesh {        % <shname> resolveshading <shading>
  152.   Page /Shading rget {
  153.     resolveshading
  154.   } {
  155.     null
  156.   }ifelse
  157. } bdef
  158.  
  159. % ---------------- Halftones ---------------- %
  160.  
  161. /spotfunctions mark
  162.   /Round {
  163.     abs exch abs 2 copy add 1 le {
  164.       dup mul exch dup mul add 1 exch sub 
  165.     } {
  166.       1 sub dup mul exch 1 sub dup mul add 1 sub
  167.     } ifelse
  168.   }
  169.   /Diamond {
  170.     abs exch abs 2 copy add .75 le {
  171.       dup mul exch dup mul add 1 exch sub
  172.     } {
  173.       2 copy add 1.23 le {
  174.     .85 mul add 1 exch sub
  175.       } {
  176.     1 sub dup mul exch 1 sub dup mul add 1 sub
  177.       } ifelse
  178.     } ifelse
  179.   }
  180.   /Ellipse {
  181.     abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt {
  182.       pop dup mul exch .75 div dup mul add 4 div 1 exch sub
  183.     } {
  184.       dup 1 gt {
  185.     pop 1 exch sub dup mul exch 1 exch sub
  186.     .75 div dup mul add 4 div 1 sub
  187.       } {
  188.     .5 exch sub exch pop exch pop
  189.       } ifelse
  190.     } ifelse
  191.   }
  192.   /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub }
  193.   /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub }
  194.   /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub }
  195.   /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub }
  196.   /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub }
  197.   /Line { exch pop abs neg }
  198.   /LineX { pop }
  199.   /LineY { exch pop }
  200.   /Square { abs exch abs 2 copy lt { exch } if pop neg }
  201.   /Cross { abs exch abs 2 copy gt { exch } if pop neg }
  202.   /Rhomboid { abs exch abs 0.9 mul add 2 div }
  203.   /DoubleDot { 2 {360 mul sin 2 div exch } repeat add }
  204.   /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg }
  205.   /SimpleDot { dup mul exch dup mul add 1 exch sub }
  206.   /InvertedSimpleDot { dup mul exch dup mul add 1 sub }
  207.   /CosineDot { 180 mul cos exch 180 mul cos add 2 div }
  208.   /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add }
  209.   /InvertedDouble {
  210.     exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg
  211.   }
  212. .dicttomark readonly def
  213.  
  214. /htrdict mark
  215.   1 { .resolveht1 }
  216.   5 { .resolveht5 }
  217.     % We don't support types 6, 10, or 16 yet.
  218. .dicttomark readonly def
  219.  
  220. /.resolveht1 {
  221.   mark exch {
  222.     oforce
  223.     1 index /SpotFunction eq {
  224.       dup type /nametype eq
  225.     { //spotfunctions exch get } { resolvefnproc }
  226.       ifelse
  227.     } {
  228.       1 index /TransferFunction eq {
  229.     resolveidfnproc
  230.       } if
  231.     } ifelse
  232.   } forall .dicttomark
  233. } bdef
  234.  
  235. /.resolveht5 {
  236.   mark exch {
  237.     oforce dup type /dicttype eq { resolvehalftone } if
  238.   } forall .dicttomark
  239. } bdef
  240.  
  241. /resolvehalftone {    % <dict> resolvehalftone <halftone>
  242.   dup /HalftoneType get
  243.   dup //htrdict exch .knownget {
  244.     exch pop exec
  245.   } {
  246.     (\n\n   **** Unsupported HalftoneType ) pdfformaterror
  247.     =string cvs pdfformaterror (. ***\n\n) pdfformaterror
  248.     /resolvehalftone cvx /unregistered signalerror
  249.   } ifelse
  250. } bdef
  251.  
  252. % ---------------- Graphics state management ---------------- %
  253.  
  254. /cmmatrix matrix def
  255. drawopdict begin
  256.             % Graphics state stack
  257.   /q { q } def
  258.   /Q { Q } def
  259.             % Graphics state setting
  260.   /cm { //cmmatrix astore concat } def
  261.   /i { 1 .min setflat } def
  262.   /J /setlinecap load def
  263.   /d /setdash load def
  264.   /j /setlinejoin load def
  265.   /w /setlinewidth load def
  266.   /M /setmiterlimit load def
  267.   /gs { gs } def
  268. end
  269.  
  270. % Each entry in this dictionary is
  271. %    <gsres> <value> -proc- <gsres>
  272. /gsbg {
  273.   /BGDefault load resolvedefaultfnproc setblackgeneration
  274. } bdef
  275. /gsucr {
  276.   /UCRDefault load resolvedefaultfnproc setundercolorremoval
  277. } bdef
  278. /gstr {
  279.   dup type /arraytype eq {
  280.     { oforce /TRDefault load resolvedefaultfnproc } forall
  281.     setcolortransfer
  282.   } {
  283.     /TRDefault load resolvedefaultfnproc settransfer
  284.   } ifelse
  285. } bdef
  286. /gsparamdict mark
  287.   /SA { setstrokeadjust }
  288.   /OP { 1 index /op known not { dup op } if OP }
  289.     % The PDF 1.3 specification says that the name /Default is only
  290.     % recognized for {BG,UCR,TR}2.  However, PDF 1.3 files produced
  291.     % by Adobe Acrobat Distiller 4.0 for Windows use the name /Default
  292.     % with the older keys, so we have to implement this.
  293.   /BG { 1 index /BG2 known { pop } { gsbg } ifelse }
  294.   /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse }
  295.   /TR { 1 index /TR2 known { pop } { gstr } ifelse }
  296.   /HT {
  297.     dup /Default eq {
  298.       pop .setdefaulthalftone
  299.     } {
  300.     %****** DOESN'T IMPLEMENT THE STREAM CASE YET ******
  301.       resolvehalftone sethalftone
  302.     } ifelse
  303.     % the transfer function may dependent on the halftone, so make sure
  304.     % it is set if included in the graphic state (otherwise this is
  305.     % subject to order of a dictionary forall, which is unpredictable)
  306.     dup /TR2 .knownget {
  307.       dup /Default eq { oforce gsparamdict /TR2 get exec } { pop } ifelse
  308.     } {
  309.       dup /TR .knownget {
  310.         /dup /Default eq { oforce gsparamdict /TR get exec } { pop } ifelse
  311.       } if
  312.     } ifelse
  313.   }
  314.   /HTP {
  315.     % HTP may be present even if this isn't a DPS interpreter.
  316.     /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse
  317.   }
  318.     % PDF 1.3
  319.   /Font { aload pop Tf }
  320.   /LW { setlinewidth }
  321.   /LC { setlinecap }
  322.   /LJ { setlinejoin }
  323.   /ML { setmiterlimit }
  324.   /D { aload pop setdash }
  325.   /RI { ri }
  326.   /op { op }
  327.   /OPM { OPM }
  328.   /BG2 { gsbg }
  329.   /UCR2 { gsucr }
  330.   /TR2 { gstr }
  331.   /FL { 1 .min setflat }
  332.   /SM {
  333.     % SM may be present even if this is only a Level 2 interpreter.
  334.     /setsmoothness where { pop setsmoothness } { pop } ifelse
  335.   }
  336.     % PDF 1.4
  337.     % All of these require the "transparency" feature in the interpreter.
  338.   /ca { ca }
  339.   /CA { CA }
  340.   /SMask { gssmask }
  341.   /AIS { AIS }
  342.   /BM { BM }
  343.   /TK { TK }
  344. .dicttomark readonly def
  345. /gs {            % <gsres> gs -
  346.   Page /ExtGState rget {
  347.     % We keep the dictionary on the stack during the forall so that
  348.     % keys that interact with each other have access to it.
  349.     dup {
  350.       oforce exch gsparamdict exch .knownget { exec } { pop } ifelse
  351.     } forall pop
  352.   } if
  353. } bdef
  354.  
  355. % ------ Transparency support ------ %
  356.  
  357. /gssmask {
  358.   dup /None eq PDFusingtransparency not or {
  359.     pop null
  360.   } {
  361.     % Preprocess the SMask value into a parameter dictionary for
  362.     % .begintransparencymask, with added /BBox and /Draw keys.
  363.     mark exch        % Stack: mark smaskdict
  364.     dup /S oget /Subtype exch 3 2 roll
  365.             % Stack: mark ... smaskdict
  366.     dup /BC knownoget {
  367.       gsave
  368.         1 index /G oget /Group oget /CS knownoget {
  369.       csresolve setgcolorspace
  370.     } if
  371.         aload pop setcolor [ currentgray ]
  372.       grestore
  373.       /Background exch 3 2 roll
  374.     } if
  375.     dup /TR knownoget {
  376.       resolveidfnproc /TransferFunction exch 3 2 roll
  377.     } if    
  378.     dup /G oget dup /BBox oget /BBox exch 4 2 roll
  379.     /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll
  380.     pop .dicttomark
  381.   } ifelse SMask
  382. } bdef
  383.  
  384. % This procedure is called to actually render the soft mask.
  385. /.execmaskgroup {    % <masknum> <paramdict> <formdict> .execmaskgroup -
  386.     % Save our place in PDFfile, and do a gsave to avoid resetting
  387.     % the color space.
  388.   gsave PDFfile fileposition 4 1 roll
  389.     % We have to select the group's color space so that the
  390.     % background color will be interpreted correctly.
  391.   dup /Group oget /CS knownoget { csresolve setgcolorspace } if
  392.   exch dup /BBox get aload pop .begintransparencymask {
  393.     dup /Resources knownoget { oforce } { 0 dict } ifelse
  394.     exch false resolvestream
  395.     .execgroup .endtransparencymask
  396.   } .internalstopped {
  397.     .discardtransparencymask stop
  398.   } if
  399.   PDFfile exch setfileposition grestore
  400. } bdef
  401. % Paint a Form+Group XObject, either for a transparency mask or for a Do.
  402. /.execgroup {        % <resdict> <stream> .execgroup -
  403.   gsave //nodict begin
  404.   null SMask
  405.   1 .setopacityalpha 1 .setshapealpha
  406.   0 .inittransparencymask 1 .inittransparencymask
  407.   /Compatible .setblendmode
  408.     % Execute the body of the Form, similar to DoForm.
  409.   pdfopdict .pdfruncontext
  410.   end grestore
  411. } bdef
  412.  
  413. /.beginformgroup {    % groupdict bbox .beginformgroup -
  414.   exch mark exch            % bbox mark groupdict
  415.   dup /CS knownoget { csresolve setgcolorspace } if
  416.   dup /I knownoget { /Isolated exch 3 2 roll } if
  417.   dup /K knownoget { /Knockout exch 3 2 roll } if
  418.   pop .dicttomark
  419.         % Stack: bbox paramdict
  420.   exch aload pop
  421.   .begintransparencygroup
  422. } bdef
  423.  
  424. % .paintgroupform implements the Form PaintProc in the case where the
  425. % Form XObject dictionary includes a Group key.  See .paintform below.
  426. /.paintgroupform {    % <resdict> <stream> <formdict> .paintgroupform -
  427.   dup /Group oget exch /BBox oget
  428.         % Stack: resdict stream groupdict bbox
  429.   .beginformgroup {
  430.     .execgroup
  431.   } .internalstopped {
  432.     .discardtransparencygroup stop
  433.   } if .endtransparencygroup
  434. } bdef
  435.  
  436. % Make an ImageType 103 (soft-masked) image.
  437. /makesoftmaskimage {    % <datasource> <imagemask> <SMask> makesoftmaskimage
  438.             %   <datasource> <imagemask>, updates currentdict =
  439.             %   imagedict
  440.         % See the ImageType 3 case of makemaskimage below.
  441.         % SMask is a stream, another Image XObject.
  442.         % Stack: datasource imagemask(false) smaskstreamdict
  443.   PDFfile fileposition exch
  444.   dup /Matte knownoget { /Matte exch def } if
  445.   dup length dict makeimagedict pop
  446.         % In order to prevent the two data sources from being
  447.         % aliased, we need to make at least one a reusable stream.
  448.         % We pick the mask, since it's smaller (in case we need to
  449.         % read all its data now).
  450.         % Stack: datasource imagemask(false) savedpos
  451.         % maskdict is currentdict
  452.   /DataSource DataSource mark
  453.     /Intent 1
  454.     /AsyncRead true
  455.   .dicttomark .reusablestreamdecode def
  456.   PDFfile exch setfileposition
  457.   currentdict end currentdict end
  458.   5 dict begin
  459.   /ImageType 103 def
  460.   /DataDict exch def
  461.   dup /InterleaveType 3 put
  462.   DataDict /Matte knownoget {
  463.     /Matte exch def
  464.   } if
  465.   AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def
  466.   /ColorSpace DataDict /ColorSpace get def
  467. } bdef
  468.  
  469. % ---------------- Color setting ---------------- %
  470.  
  471. /01_1 [0 1] readonly def
  472. /01_3 [0 1 0 1 0 1] readonly def
  473. /01_4 [0 1 0 1 0 1 0 1] readonly def
  474.  
  475. % The keys here are resolved (PostScript, not PDF) color space names.
  476. /csncompdict mark
  477.   /DeviceGray { pop 1 }
  478.   /DeviceRGB { pop 3 }
  479.   /DeviceCMYK { pop 4 }
  480.   /CIEBasedA { pop 1 }
  481.   /CIEBasedABC { pop 3 }
  482.   /ICCBased { 1 oget /N oget }
  483.   /Separation { pop 1 }
  484.   /DeviceN { 1 oget length }
  485. .dicttomark readonly def
  486.  
  487. /csrdict mark
  488.   /DeviceGray { }
  489.   /DeviceRGB { }
  490.   /DeviceCMYK { }
  491.   /CalGray {
  492.     1 oget 6 dict begin
  493.     dup /Gamma knownoget {
  494.       /exp load 2 packedarray cvx /DecodeA exch def
  495.     } if
  496.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  497.     dup /WhitePoint knownoget {
  498.       dup /WhitePoint exch def
  499.       dup /MatrixA exch def
  500.       /RangeLMN [ 3 2 roll { 0 exch } forall ] def
  501.     } if
  502.     /PDFColorSpace exch def [ /CIEBasedA currentdict end ]
  503.   }
  504.   /CalRGB {
  505.     1 oget 6 dict begin
  506.     dup /Gamma knownoget {
  507.       [ exch { /exp load 2 packedarray cvx } forall
  508.       ] /DecodeABC exch def
  509.     } if
  510.     dup /Matrix knownoget { /MatrixABC exch def } if
  511.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  512.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  513.     /PDFColorSpace exch def [ /CIEBasedABC currentdict end ]
  514.   }
  515.   /CalCMYK {
  516.     pop /DeviceCMYK        % not defined by Adobe
  517.   }
  518.   /Lab {
  519.     1 oget 6 dict begin
  520.     dup /Range knownoget not { [-100 100 -100 100] } if
  521.     [0 100 null null null null] dup 2 4 -1 roll putinterval
  522.     /RangeABC exch def
  523.     /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind] def
  524.     /MatrixABC [1 1 1 1 0 0 0 0 -1] def
  525.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  526.     dup /WhitePoint knownoget { /WhitePoint exch def } {
  527.       (   **** Warning: Lab colorspace is missing WhitePoint.\n)
  528.       pdfformaterror
  529.       /WhitePoint [0.9505 1 1.089] def
  530.     } ifelse
  531.     % scaling function g() for DecodeLMN construction
  532.     { dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse }
  533.     /DecodeLMN [
  534.       % Store white point implicitly inside procedures.
  535.       [ 3 index aload pop WhitePoint 0 get /mul .systemvar ] cvx bind
  536.       [ 4 index aload pop WhitePoint 1 get /mul .systemvar ] cvx bind
  537.       [ 5 index aload pop WhitePoint 2 get /mul .systemvar ] cvx bind
  538.     ] def pop
  539.     /PDFColorSpace exch def [ /CIEBasedABC currentdict end ]
  540.   }
  541.   /ICCBased {
  542.     PDFfile fileposition exch
  543.     dup dup 1 oget
  544.     mark exch { oforce } forall .dicttomark
  545.     dup dup true resolvestream
  546.     /ReusableStreamDecode filter /DataSource exch put
  547.     1 exch put
  548.     exch PDFfile exch setfileposition
  549.     % Resolve alternate color space
  550.     dup 1 get            % Get colorspace dictionary
  551.     dup /Alternate .knownget    % Check for alternate color space
  552.     { oforce resolvecolorspace /Alternate exch put }    % resolve and replace
  553.     { pop }            % remove colorspace dictionary
  554.     ifelse
  555.   } bind
  556.   /Separation {
  557.     aload pop exch oforce resolvecolorspace
  558.                 % Contrary to PDF manuals up to v.1.5, Acrobat Distiller 3.01
  559.                 % can use /Identity name here instead of a function.
  560.     exch oforce resolveidfnproc
  561.     4 array astore
  562.   }
  563.   /DeviceN {
  564.     0 4 getinterval                    % ignore attributes
  565.     aload pop 3 -1 roll oforce           % resolve names array
  566.     [ exch { oforce } forall ]           % resolve each of the names
  567.     3 -1 roll oforce resolvecolorspace
  568.     3 -1 roll oforce resolvefnproc
  569.     4 array astore
  570.   }
  571.   /Indexed {
  572.     aload pop 3 -1 roll oforce resolvecolorspace
  573.         % Stack: /Indexed hival lookup basespace
  574.         % If the underlying space is a Lab space, we must scale
  575.         % the output of the lookup table as part of DecodeABC.
  576.     dup dup type /arraytype eq { 0 get } if /CIEBasedABC eq {
  577.       dup 1 get /DecodeLMN known {
  578.     1 get dup length dict copy
  579.     begin /DecodeABC [ 0 2 4 {
  580.       RangeABC 1 index 1 add get RangeABC 2 index get sub /mul load
  581.       RangeABC 3 index get /add load
  582.       DecodeABC 6 -1 roll 2 idiv get [ 6 1 roll aload pop ] cvx
  583.     } for ] def
  584.     /RangeABC //01_3 def
  585.     currentdict end /CIEBasedABC exch 2 array astore
  586.       } if
  587.     } if
  588.     3 1 roll
  589.     oforce dup type /stringtype ne {
  590.         % The color lookup table is a stream.
  591.         % Get its contents.  Don't lose our place in PDFfile.
  592.         % Stack: /Indexed basespace hival lookup
  593.     PDFfile fileposition 5 1 roll true resolvestream
  594.         % Stack: filepos /Indexed basespace hival lookupstream
  595.     1 index 1 add
  596.         % Stack: filepos /Indexed basespace hival lookupstream len
  597.     3 index
  598.       dup dup type /arraytype eq { 0 get } if
  599.       //csncompdict exch get exec mul
  600.     string readstring pop
  601.         % Stack: filepos /Indexed basespace hival table
  602.     5 -1 roll PDFfile exch setfileposition
  603.     }
  604.     if 4 array astore
  605.         % Replace the PDFColorSpace with the Indexed space if needed.
  606.     dup 1 get
  607.     dup type /arraytype eq {
  608.       dup length 2 ge {
  609.     dup 1 get type /dicttype eq {
  610.       dup 1 get /PDFColorSpace known {
  611.         dup 1 get /PDFColorSpace 3 index put
  612.       } if
  613.     } if
  614.       } if
  615.     } if pop
  616.   }
  617.   /Pattern {
  618.     dup type /nametype ne {
  619.       dup length 1 gt {
  620.     1 oget resolvecolorspace
  621.     /Pattern exch 2 array astore
  622.       } if
  623.     } if
  624.   }
  625. .dicttomark readonly def
  626.  
  627. /cssubst {        % <csname> cssubst <cspace'> true
  628.             % <csname> cssubst false
  629.   dup resolvecolorspace
  630.   dup 1 index ne { exch pop true } { pop pop false } ifelse
  631. } bdef
  632.  
  633. /csnames mark
  634.   /DeviceGray dup  /DeviceRGB dup  /DeviceCMYK dup  /Pattern dup
  635. .dicttomark readonly def
  636. /csresolve {        % <csresourcename> csresolve <cspace>
  637.   dup type /nametype ne {
  638.     (\n   **** Warning: CS/cs (setcolorspace) operand not a name: ) pdfformaterror
  639.     dup stderrfile dup 3 -1 roll write==only flushfile
  640.     ( ****\n) pdfformaterror
  641.     dup type /arraytype eq {    % Adobe InDesign + PDF Library has array
  642.       resolvecolorspace
  643.     } if
  644.   } {
  645.   dup Page /ColorSpace rget {
  646.     exch pop resolvecolorspace
  647.   } {
  648.     //csnames 1 index known not { /undefined cvx signalerror } if
  649.     } ifelse
  650.   } ifelse
  651. } bdef
  652. /resolvecolorspace {    % <cspace> resolvecolorspace <cspace'>
  653.   dup dup type /arraytype eq { 0 get } if
  654.   //csrdict exch .knownget {
  655.     exec dup type /nametype ne { dup length 1 eq { 0 get } if } if
  656.   } {
  657.     csresolve
  658.   } ifelse
  659. } bdef
  660.  
  661. /scresolve {    % <c0> ... scresolve <multi>
  662.         % We can't really make sc[n] and SC[N] work, because
  663.         % the color space information isn't available at
  664.         % conversion time; so we hack it by assuming that
  665.         % all the operands on the stack are used, and that
  666.         % if the top operand is a name, it's a Pattern resource.
  667.   dup type /nametype eq
  668.     { Page /Pattern rget { resolvepattern } { null } ifelse }
  669.   if
  670.   dup type /dicttype eq {
  671.         % Check the PaintType, if any (shading patterns don't
  672.         % have one).
  673.     dup /PaintType knownoget { 2 eq } { false } ifelse
  674.   } {
  675.     .pdfcount 1 gt
  676.   } ifelse
  677. } bdef
  678.  
  679. /.pdfpaintproc {         % <patdict> <resdict> .pdfpaintproc -
  680.   PDFDEBUG { (%Begin PaintProc) = flush } if
  681.     % For uncolored patterns, we have to unbind the current
  682.     % color and color space before running the PaintProc.
  683.     % There's no harm in doing this for colored patterns,
  684.     % so for simplicity, we always do it.
  685.   PDFfile fileposition 3 1 roll
  686.   q
  687.   null sc1 null SC1
  688.  
  689.   % save old value of pdfemptycount on opstack, set to new value
  690.   pdfemptycount /pdfemptycount count 3 sub def 3 1 roll
  691.   exch false resolvestream pdfopdict .pdfruncontext
  692.   % restore pdfemptycount
  693.   /pdfemptycount exch def
  694.  
  695.   Q
  696.   PDFDEBUG { (%End PaintProc) = flush } if
  697.   PDFfile exch setfileposition
  698. } bdef
  699.  
  700. /resolvepattern {    % <patternstreamdict> resolvepattern <patterndict>
  701.         % Don't do the resolvestream now: just capture the data
  702.         % from the file if necessary.
  703.   dup length dict copy
  704.   dup /FilePosition .knownget {
  705.     1 index /File get dup fileposition 3 1 roll
  706.         % Stack: dict savepos pos file
  707.     dup 3 -1 roll setfileposition
  708.     dup 3 index /Length oget
  709.  
  710.     dup 65535 le {
  711.       string readstring pop
  712.     } {
  713.       () /SubFileDecode filter /ReusableStreamDecode filter
  714.     } ifelse
  715.         % Stack: dict savepos file string
  716.     3 1 roll exch setfileposition
  717.     1 index /File 3 -1 roll put
  718.     dup /FilePosition undef
  719.   } if
  720.   dup /Shading knownoget {
  721.     resolveshading 1 index /Shading 3 -1 roll put
  722.   } if
  723.   dup /PaintProc [
  724.         % Bind the resource dictionary into the PaintProc.
  725.     2 index /Resources knownoget { oforce } { 0 dict } ifelse
  726.     /.pdfpaintproc cvx
  727.   ] cvx put
  728.   PDFDEBUG {
  729.     (%Pattern: ) print dup === flush
  730.   } if
  731. } bdef
  732.  
  733. drawopdict begin
  734.   /g { /DeviceGray cssubst { cs sc1 } { g } ifelse } bdef
  735.   /rg { /DeviceRGB cssubst { cs sc* } { rg } ifelse } bdef
  736.   /k { k } bdef
  737.   /cs { csresolve cs } bdef
  738.   /sc { scresolve { sc* } { sc1 } ifelse } bdef
  739.   /scn /sc load def
  740.   /G { /DeviceGray cssubst { CS SC1 } { G } ifelse } bdef
  741.   /RG { /DeviceRGB cssubst { CS SC* } { RG } ifelse } bdef
  742.   /K { K } bdef
  743.   /CS { csresolve CS } bdef
  744.   /ri { ri } bdef
  745.   /SC { scresolve { SC* } { SC1 } ifelse } bdef
  746.   /SCN /SC load def
  747. end
  748.  
  749. % ---------------- Paths ---------------- %
  750.  
  751. drawopdict begin
  752.             % Path construction
  753.   /m /moveto load def
  754.   /l /lineto load def
  755.   /c /curveto load def
  756.   /v { currentpoint 6 2 roll curveto } def
  757.   /y { 2 copy curveto } def
  758.   /re {
  759.    4 2 roll moveto  exch dup 0 rlineto  0 3 -1 roll rlineto  neg 0 rlineto
  760.    closepath
  761.   } def
  762.   /h /closepath load def
  763.             % Path painting and clipping
  764.   /n { n } def
  765.   /S { S } def
  766.   /s { s } def
  767.   /f { f } def
  768.   /f* { f* } def
  769.   /B { B } def
  770.   /b { b } def
  771.   /B* { B* } def
  772.   /b* { b* } def
  773.   /W { W } def
  774.   /W* { W* } def
  775.   /sh { setfillstate resolvesh shfill } def
  776. end
  777.  
  778. % ---------------- XObjects ---------------- %
  779.  
  780. /xobjectprocs mark        % <dict> -proc- -
  781.   /Image { DoImage }
  782.   /Form { DoForm }
  783.   /PS { DoPS }
  784. .dicttomark readonly def
  785.  
  786. % Note that the keys in defaultdecodedict are resolved (PostScript, not PDF)
  787. % color space names.
  788. /defaultdecodedict mark
  789.   /DeviceGray { pop //01_1 } bind
  790.   /DeviceRGB { pop //01_3 } bind
  791.   /DeviceCMYK { pop //01_4 } bind
  792.   /CIEBasedA { 1 get /RangeA knownoget not { //01_1 } if } bind
  793.   /CIEBasedABC { 1 get /RangeABC knownoget not { //01_3 } if } bind
  794.   /ICCBased {
  795.      1 oget dup /Range knownoget {
  796.        exch pop
  797.      }{
  798.        /N get [ exch {0 1} repeat ] readonly
  799.      } ifelse
  800.   } bind
  801.   /Separation { pop //01_1 } bind
  802.   /DeviceN {
  803.     1 oget length [ exch {0 1} repeat ] readonly
  804.   } bind
  805.   /Indexed {
  806.     pop [ 0 1 BitsPerComponent bitshift 1 sub ]
  807.   } bind
  808. .dicttomark readonly def
  809.  
  810. /checkaltimage {    % <resdict> checkaltimage <resdict[']>
  811.   Printed {
  812.     dup /Alternates knownoget {
  813.       {
  814.     dup /DefaultForPrinting knownoget {
  815.       {
  816.         /Image oget exch pop exit
  817.       } {
  818.         pop
  819.       } ifelse
  820.     } {
  821.       pop
  822.     } ifelse
  823.       } forall
  824.     } if
  825.   } if
  826. } bdef
  827.  
  828. /makeimagedict {    % <resdict> <newdict> makeimagedict <imagemask>
  829.             % On return, newdict' is currentdict
  830.   begin
  831.   /Width 2 copy oget def
  832.   /Height 2 copy oget def
  833.         % Handle missing BitsPerComponent later.
  834.   /BitsPerComponent 2 copy knownoget { def } { pop } ifelse
  835.   /Interpolate 2 copy knownoget { def } { pop } ifelse
  836.   makeimagekeys
  837. } bdef
  838. /makeimagekeys {    % <resdict> makeimagekeys <imagemask>
  839.         % newdict is currentdict
  840.         % Assumes Width, Height, BPC, Interpolate already copied.
  841.   /ImageType 1 def
  842.   /ImageMatrix Width 0 0
  843.         % Handle 0-height images specially.
  844.     Height dup 0 eq { pop 1 } if neg 0 1 index neg
  845.     6 array astore def
  846.   dup /ImageMask knownoget dup { and } if {
  847.         % Image mask
  848.         % Decode is required for the PostScript image operators.
  849.                 % AI8 writes bogus decode array [0 1 0 0 0 0 0 0]
  850.     /Decode 2 copy knownoget { 0 2 getinterval } { //01_1 } ifelse def
  851.         % BitsPerComponent is optional for masks.
  852.     /BitsPerComponent 2 copy known { pop } { 1 def } ifelse
  853.     true
  854.   } {
  855.         % Opaque image
  856.     dup /ColorSpace oget resolvecolorspace /ColorSpace exch def
  857.         % Decode is required for the PostScript image operators.
  858.     /Decode 2 copy knownoget not {
  859.       ColorSpace //defaultdecodedict
  860.       ColorSpace dup type /arraytype eq { 0 get } if get exec
  861.     } if def
  862.     false
  863.   } ifelse
  864.         % Even though we're going to read data,
  865.         % pass false to resolvestream so that
  866.         % it doesn't try to use Length (which may not be present).
  867.   exch false resolvestream /DataSource exch def
  868. } bdef
  869.  
  870. /DoImage {
  871.   checkaltimage dup length 6 add dict
  872.   1 index /SMask knownoget { 1 index exch /SMask exch put } if
  873.   1 index /Mask knownoget { 1 index exch /Mask exch put } if
  874.   makeimagedict doimagesmask
  875. } bdef
  876. /makemaskimage {    % <datasource> <imagemask> <Mask> makemaskimage
  877.             %   <datasource> <imagemask>, updates currentdict =
  878.             %   imagedict
  879.   dup type /arraytype eq {
  880.     /ImageType 4 def
  881.                 % Check that every element of the Mask is an integer.
  882.     //false 1 index {
  883.       type /integertype ne or
  884.     } forall {
  885.       (\n   **** Warning: Some elements of Mask array are not integers.\n)
  886.       pdfformaterror
  887.       [ exch { 0.5 add cvi } forall ]  % following AR4, 5, 6 implementation
  888.     } if
  889.     /MaskColor exch def
  890.   } {
  891.         % Mask is a stream, another Image XObject.
  892.         % Stack: datasource imagemask(false) maskstreamdict
  893.     PDFfile fileposition exch
  894.     dup length dict makeimagedict pop
  895.         % In order to prevent the two data sources from being
  896.         % aliased, we need to make at least one a reusable stream.
  897.         % We pick the mask, since it's smaller (in case we need to
  898.         % read all its data now).
  899.         % Stack: datasource imagemask(false) savedpos
  900.         % maskdict is currentdict
  901.     /DataSource DataSource mark
  902.       /Intent 1
  903.       /AsyncRead true
  904.     .dicttomark .reusablestreamdecode def
  905.     PDFfile exch setfileposition
  906.     currentdict end currentdict end
  907.     5 dict begin
  908.     /ImageType 3 def
  909.     /InterleaveType 3 def
  910.     /DataDict exch def
  911.     /MaskDict exch def
  912.     /ColorSpace DataDict /ColorSpace get def
  913.   } ifelse
  914. } bdef
  915. /doimagesmask { % <imagemask> doimagesmask -
  916.   PDFusingtransparency { currentdict /SMask knownoget } { false } ifelse {
  917.     << /Subtype /Luminosity >> 0 0 0 0 .begintransparencymask
  918.     PDFfile fileposition exch
  919.     gsave //nodict begin
  920.     null /SoftMask gput
  921.     1 .setopacityalpha 1 .setshapealpha
  922.     0 .inittransparencymask 1 .inittransparencymask
  923.     /Compatible .setblendmode
  924.     DoImage
  925.     end grestore
  926.     PDFfile exch setfileposition
  927.     0 .endtransparencymask
  928.     << /Subtype /Group /Isolated true >> 0 0 0 0 .begintransparencygroup
  929.     doimage
  930.     .endtransparencygroup
  931.   } {
  932.     doimage
  933.   } ifelse
  934. } bdef
  935. /doimage {    % <imagemask> doimage -
  936.         % imagedict is currentdict, gets popped from dstack
  937.   DataSource exch
  938.   PDFusingtransparency {
  939.     currentdict /SMask knownoget
  940.   } {
  941.     false
  942.   } ifelse {
  943.     makesoftmaskimage
  944.   } {
  945.     currentdict /Mask knownoget {
  946.       makemaskimage
  947.     } if
  948.   } ifelse
  949.         % Stack: datasource imagemask
  950.    % image and imagemask can be redefined in gs_init.ps to tweak interpolation
  951.    % after device-specific files are run. Don't bind them here.
  952.    { currentdict end setfillstate /imagemask }
  953.    { ColorSpace setgcolorspace currentdict end setfillblend /image }
  954.   ifelse
  955.   .systemvar stopped {
  956.     pop
  957.     $error /errorname get dup /ioerror eq {
  958.       pop (\n   **** Warning: File has insufficient data for an image.\n)
  959.       pdfformaterror
  960.     } {
  961.       (\n   **** Warning: File encountered ')
  962.       exch 40 string cvs concatstrings
  963.       (' error while processing an image.\n) concatstrings
  964.       pdfformaterror
  965.     } ifelse
  966.   } if
  967.         % Close the input stream, unless it is PDFfile or
  968.         % PDFsource.
  969.   dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse
  970. } bdef
  971.  
  972. /.paintform {    % <formdict> <resdict> <stream> .paintform -
  973.   3 -1 roll dup /Group known PDFusingtransparency and {
  974.     .paintgroupform
  975.   } {
  976.     pop pdfopdict .pdfruncontext
  977.   } ifelse
  978. } bdef
  979.  
  980. /DoForm {
  981.     % Adobe 2nd edition of the PDF 1.3 spec makes /FormType
  982.     % and /Matrix keys optional. Cope with the missing keys.
  983.   begin <<
  984.   currentdict /FormType known not { /FormType 1 } if
  985.   currentdict /Matrix   known not { /Matrix { 1 0 0 1 0 0 } cvlit } if
  986.   currentdict end { oforce } forall
  987.   >>
  988.   dup [ 2 index /Resources knownoget { oforce } { 0 dict } ifelse
  989.   3 index false /resolvestream cvx
  990.   /.paintform cvx
  991.   ] cvx /PaintProc exch put
  992.     % Adjust pdfemptycount since we have an extra dictionary on the stack
  993.   pdfemptycount exch
  994.   /pdfemptycount where pop count 2 sub /pdfemptycount exch put
  995.   q execform Q                 % gsave / grestore around the Form
  996.     % Restore pdfemptycount
  997.   /pdfemptycount where pop exch /pdfemptycount exch put
  998. } bdef
  999.  
  1000. /_dops_save 1 array def
  1001.  
  1002. /DoPS {
  1003.   DOPS
  1004.    {
  1005.      //_dops_save 0 save put
  1006.      true resolvestream cvx exec
  1007.      //_dops_save 0 get restore
  1008.    }
  1009.    { pop }
  1010.   ifelse
  1011. } bdef
  1012.  
  1013. currentdict /_dops_save undef
  1014.  
  1015. drawopdict begin
  1016.   /Do {
  1017.     setfillblend
  1018.     PDFfile fileposition exch
  1019.     dup Page /XObject rget { 
  1020.       exch pop dup /Subtype get xobjectprocs exch get
  1021.         % Don't leave extra objects on the stack while executing
  1022.         % the definition of the form.
  1023.       3 -1 roll 2 .execn
  1024.     } {
  1025.         % This should cause an error, but Acrobat Reader can
  1026.         % continue, so we do too.
  1027.       (   **** Undefined XObject resource: ) 
  1028.       exch =string cvs concatstrings (\n) concatstrings
  1029.       pdfformaterror
  1030.     } ifelse
  1031.     PDFfile exch setfileposition
  1032.   } bdef
  1033. end
  1034.  
  1035. % ---------------- In-line images ---------------- %
  1036.  
  1037. % Undo the abbreviations in an in-line image dictionary.
  1038. % Note that we must look inside array values.
  1039. % /I is context-dependent.
  1040. /unabbrevkeydict mark
  1041.   /BPC /BitsPerComponent  /CS /ColorSpace  /D /Decode  /DP /DecodeParms
  1042.   /F /Filter  /H /Height  /I /Interpolate  /IM /ImageMask  /W /Width
  1043. .dicttomark readonly def
  1044. /unabbrevvaluedict mark
  1045.   /AHx /ASCIIHexDecode  /A85 /ASCII85Decode  /CC /CalCMYK
  1046.   /CCF /CCITTFaxDecode  /CG /CalGray  /CR /CalRGB
  1047.   /DCT /DCTDecode  /CMYK /DeviceCMYK  /Fl /FlateDecode
  1048.   /G /DeviceGray  /RGB /DeviceRGB
  1049.   /I /Indexed  /LZW /LZWDecode  /RL /RunLengthDecode
  1050. .dicttomark readonly def
  1051. /unabbrevtypedict mark
  1052.   /nametype {
  1053.     //unabbrevvaluedict 1 index .knownget { exch pop } if
  1054.   }
  1055.   /arraytype {
  1056.     dup 0 1 2 index length 1 sub {
  1057.       2 copy get unabbrevvalue put dup
  1058.     } for pop
  1059.   }
  1060. .dicttomark readonly def
  1061. /unabbrevvalue {    % <obj> unabbrevvalue <obj'>
  1062.   oforce //unabbrevtypedict 1 index type .knownget { exec } if
  1063. } bdef
  1064.  
  1065. drawopdict begin
  1066.   /BI { mark } bdef
  1067.   /ID {
  1068.     counttomark 2 idiv dup 7 add dict begin {
  1069.       exch //unabbrevkeydict 1 index .knownget { exch pop } if
  1070.       exch unabbrevvalue def
  1071.     } repeat pop
  1072.     /IDFlag true def  % flag for stream processing.
  1073.     /File PDFsource def
  1074.     currentdict makeimagekeys doimage    
  1075.     % The Adobe documentation says that the data following ID
  1076.     % consists of "lines", and some PDF files (specifically, some files
  1077.     % produced by PCL2PDF from Visual Software) contain garbage bytes
  1078.     % between the last byte of valid data and an EOL.
  1079.         % Some files (PDFOUT v3.8d by GenText) have EI immediately following
  1080.         % the stream. Some have no EOL and garbage bytes.
  1081.         % Therefore, we skip all bytes before EI or EOL 
  1082.     0
  1083.       { PDFsource read not { //true exit } if
  1084.         dup 10 eq 1 index 13 eq or
  1085.           { pop PDFsource token pop /EI ne exit
  1086.           }
  1087.         if
  1088.         exch 69 eq 1 index 73 eq and { //false exit } if  % 'EI'
  1089.       }
  1090.     loop
  1091.     exch pop
  1092.       { /ID cvx /syntaxerror signalerror
  1093.       }
  1094.     if
  1095.   } bdef
  1096. end
  1097.  
  1098. % ================================ Text ================================ %
  1099.  
  1100. drawopdict begin
  1101.             % Text control
  1102.   /BT { BT } def
  1103.   /ET { ET } def
  1104.   /Tc { Tc } def
  1105.   /TL { TL } def
  1106.   /Tr { Tr } def
  1107.   /Ts { Ts } def
  1108.   /Tw { Tw } def
  1109.   /Tz { Tz } def
  1110.             % Text positioning
  1111.   /Td { Td } def
  1112.   /TD { TD } def
  1113.   /Tm { Tm } def
  1114.   /T* { T* } def
  1115.             % Text painting
  1116.   /Tj { Tj } def
  1117.   /' { ' } def
  1118.   /" { " } def
  1119.   /TJ { TJ } def
  1120. end
  1121.  
  1122. % ============================== Annotations ============================== %
  1123.  
  1124.  
  1125.  
  1126. % Get and normalize an annotation's rectangle.
  1127. /annotrect {        % <annot> annotrect <x> <y> <w> <h>
  1128.   /Rect get aload pop
  1129.   exch 3 index sub dup 0 lt { dup 5 -1 roll add 4 1 roll neg } if
  1130.   exch 2 index sub dup 0 lt { dup 4 -1 roll add 3 1 roll neg } if
  1131. } bdef
  1132.  
  1133. % Set an annotation color.
  1134. /annotsetcolor {    % <annot> annotsetcolor -
  1135.   /C knownoget { aload pop setrgbcolor } { 0 setgray } ifelse
  1136. } bdef
  1137.  
  1138. % Draw the border.  Currently, we ignore requests for beveling, and we
  1139. % don't round the corners of rectangles.
  1140. /strokeborder {        % <annot> <width> <dash> strokeborder -
  1141.   1 index 0 ne {    % do not draw if border width is 0
  1142.     gsave
  1143.     2 index annotsetcolor
  1144.     0 setdash dup setlinewidth
  1145.     exch annotrect
  1146.     2 { 4 index sub 4 1 roll } repeat
  1147.     2 { 4 index 0.5 mul add 4 1 roll } repeat
  1148.     rectstroke pop
  1149.     grestore
  1150.   } {
  1151.     pop pop pop
  1152.   } ifelse
  1153. } bdef
  1154.  
  1155. % Draw an annotation border.
  1156. /drawborder {        % <annot> drawborder -
  1157.   gsave
  1158.   dup /BS knownoget {
  1159.     dup /W knownoget not { 1 } if
  1160.     [] 2 index /S knownoget {
  1161.       /D eq { 2 index /D knownoget not { [3] } if exch pop } if
  1162.     } if 3 -1 roll pop strokeborder
  1163.   } {
  1164.     dup /Border knownoget {
  1165.       dup 2 get
  1166.       exch dup length 3 gt { 3 get } { pop [] } ifelse
  1167.       strokeborder
  1168.     } {
  1169.       1 [] strokeborder
  1170.     } ifelse
  1171.   } ifelse
  1172.   grestore
  1173. } bdef
  1174.  
  1175. %
  1176. %   The PDF annotation F (flags) integer is bit encoded.
  1177. %   Bit 1 (LSB) Invisible:  1 --> Do not display if no handler.
  1178. %         Note:  We have no handlers but we ignore this bit.
  1179. %   Bit 2 Hidden:  1 --> Do not display.  We will not display if this bit is set.
  1180. %   Bit 3 Print:  1 --> Display if printing.  We will display if this bit set
  1181. %         (and not hidden) and Printed is true
  1182. %   Bit 4 NoZoom:  1 --> Do not zoom annotation even if image is zoomed.
  1183. %   Bit 5 NoRotate:  1 --> Do not rotate annotation even if image is rotated.
  1184. %   Bit 6 NoView:  0 --> Display if this is a 'viewer'.  We will display
  1185. %         if this bit is not set (and not hidden) and Printed is false
  1186. %   Bit 7 Read Only - 1 --> No interaction.  We ignore this bit
  1187. %
  1188. /annotvisible {            % <annot> annotvisible <visible>
  1189.   /F knownoget not { 0 } if         % Get flag value
  1190.   dup 2 and 0 eq              % Check hidden flag
  1191.   exch dup 4 and 0 ne Printed and    % Check print flag
  1192.   exch 32 and 0 eq Printed not and    % Check noview flag
  1193.   or                    % Combine print and view
  1194.   and                     % Combine with 'hidden' flag test
  1195. } bdef
  1196.  
  1197. /drawwidget {            % <scalefactor> <annot> drawwidget -
  1198.   dup /AP knownoget {
  1199.     false
  1200.     [/N /R /D] {
  1201.     % stack: scale annot appearance false key
  1202.       dup 3 index exch known {
  1203.     exch pop true exit 
  1204.       } if
  1205.       pop
  1206.     } forall
  1207.     % stack: scale annot appearance key true
  1208.     % stack: scale annot appearance false
  1209.     dup {
  1210.       pop
  1211.       oget
  1212.         % Acrobat Distiller produces files in which this Form
  1213.         % XObject lacks Type and Subtype keys.  This is illegal,
  1214.         % but Acrobat Reader accepts it.  The only way we can
  1215.         % tell whether this is a Form or a set of sub-appearances
  1216.         % is by testing for the stream Length key.
  1217.       dup /Length known {
  1218.               % If this is a form then simply use it
  1219.         true
  1220.       } {
  1221.         1 index /AS knownoget not {
  1222.               % If we do not have AS then use any appearance
  1223.         { exch pop oforce exit } forall true
  1224.         } { 
  1225.         % Stack: annot Ndict AS
  1226.         % Get the specified appearance.  If no appearance, then
  1227.         % display nothing - set stack = false.
  1228.       knownoget
  1229.         } ifelse
  1230.       } ifelse
  1231.     } {
  1232.       exch pop    % discard useless AP dictionary
  1233.     } ifelse
  1234.  
  1235.         % Stack: scale annot appearance true
  1236.         % Stack: scale annot false
  1237.     {
  1238.               % Draw appearance
  1239.                 % Initialize graphic following "7.4.4 Appearance Streams"
  1240.       q graphicsbeginpage textbeginpage
  1241.       1 index annotrect pop pop translate
  1242.       2 index dup scale        % Apply scale factor
  1243.       DoForm Q
  1244.     } if
  1245.   } if pop pop
  1246. } bdef
  1247.  
  1248. %  For stamp object we have to determine the size of the output rectangle
  1249. %  and the size of the BBox for the stamp image.  From these we calculate
  1250. %  a scale factor for drawing the stamp.
  1251. /calcstampscale {        % <annot> calcstampscale scale
  1252.   dup /Rect known {
  1253.   dup annotrect 4 -2 roll pop pop     % get width height size in user space
  1254.   3 -1 roll /AP knownoget {
  1255.     /N knownoget {
  1256.       dup /Matrix knownoget {
  1257.     % transform /Annot /Rect xwidth to Form space
  1258.     4 -2 roll 3 -1 roll dtransform 3 -1 roll
  1259.       } if
  1260.       /BBox knownoget {
  1261.         exch pop    % discard y height
  1262.         aload pop pop exch pop sub    % BBox width
  1263.     div        % scale x widths
  1264.     dup 0 lt { neg } if        % get magnitude
  1265.       } {
  1266.         pop pop 1        % default to unity scaling
  1267.       } ifelse            % if we have /BBox
  1268.     } {
  1269.       pop pop 1
  1270.     } ifelse            % if we have /N
  1271.   } {
  1272.     pop pop 1
  1273.   } ifelse            % if we have /AP
  1274.   } {
  1275.     (   **** Warning: /Annot dict is missing required /Rect entry.\n)
  1276.     pdfformaterror
  1277.     pop 1
  1278.   } ifelse
  1279. } bdef
  1280.  
  1281. /drawlink {            % <annot> drawlink -
  1282.   dup drawborder dup calcstampscale exch drawwidget
  1283. } bdef
  1284.  
  1285. % Draw an annotation.
  1286. /drawannottypes mark
  1287.   /Link { drawlink } bind
  1288. .dicttomark readonly def
  1289. /drawannot {        % <annot> drawannot -
  1290.   dup annotvisible {
  1291.     gsave
  1292.     dup dup /Subtype get //drawannottypes exch .knownget {
  1293.       exec
  1294.     } {
  1295.       dup calcstampscale exch drawwidget    % Use drawwidget for everything else
  1296.     } ifelse            % type known
  1297.     grestore
  1298.   } if pop            % annotvisible
  1299. } bdef
  1300. currentdict /drawannottypes undef
  1301.  
  1302. end            % pdfdict
  1303. end            % GS_PDF_ProcSet
  1304. .setglobal
  1305.