home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Updates / GhostScript / !GhostScr / 6_01 / lib / pdf_draw.ps < prev    next >
Text File  |  2000-03-29  |  25KB  |  865 lines

  1. %    Copyright (C) 1994, 1995, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % $Id: pdf_draw.ps,v 1.1 2000/03/09 08:40:40 lpd Exp $
  16. % pdf_draw.ps
  17. % PDF drawing operations (graphics, text, and images).
  18.  
  19. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  20. .currentglobal true .setglobal
  21. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  22. GS_PDF_ProcSet begin
  23. pdfdict begin
  24.  
  25. % For simplicity, we use a single interpretation dictionary for all
  26. % PDF graphics operations, even though this is too liberal.
  27. /drawopdict 100 dict def
  28.  
  29. % ================================ Graphics ================================ %
  30.  
  31. % ---------------- Functions ---------------- %
  32.  
  33. /fnrdict mark
  34.   0 { .resolvefn0 }
  35.   2 { }
  36.   3 { .resolvefn3 }
  37.   4 { .resolvefn4 }
  38. .dicttomark readonly def
  39.  
  40. /.pdfbuildfunction {
  41.   DEBUG { (%Function: ) print dup === flush } if
  42.   .buildfunction
  43. } bdef
  44.  
  45. /.resolvefn0 {
  46.         % Don't lose our place in PDFfile.
  47.   PDFfile fileposition exch
  48.   dup true resolvestream
  49.         % The stream isn't positionable, so read all the data now.
  50.         % Stack: filepos fndict stream
  51.   1 index /Range oget length 2 idiv 2 index /BitsPerSample oget mul
  52.   2 index /Size oget { mul } forall
  53.   7 add 8 idiv string
  54.   1 index exch readstring pop exch closefile
  55.         % Stack: filepos fndict data
  56.   exch dup length 1 add dict .copydict
  57.   dup /DataSource 4 -1 roll put
  58.   .pdfbuildfunction
  59.   exch PDFfile exch setfileposition
  60. } bdef
  61.  
  62. /.resolvefn3 {
  63.   dup length dict .copydict
  64.   dup /Functions 2 copy oget mark exch dup {
  65.     oforce resolvefunction
  66.   } forall
  67.   counttomark -1 roll astore exch pop put
  68. } bdef
  69.  
  70. /tfopdict mark
  71.   /true /.true load
  72.   /false /.false load
  73. .dicttomark readonly def
  74. /.resolvefn4 {
  75.   PDFfile fileposition exch
  76.   dup true resolvestream 
  77.         % Stack: filepos fndict stream
  78.   1 index /Length oget string readstring pop
  79.   exch dup length dict copy dup /Function undef
  80.   exch token not {
  81.     () /rangecheck cvx signalerror
  82.   } if
  83.   exch token {
  84.     /rangecheck cvx signalerror
  85.   } if
  86.         % Use .bind to avoid idiom recognition.
  87.         % Use tfopdict to bind true and false.
  88.   //tfopdict begin .bind end
  89.   1 index /Function 3 -1 roll put
  90.   .pdfbuildfunction
  91.   exch PDFfile exch setfileposition
  92. } bdef
  93. currentdict /tfopdict undef
  94.  
  95. /resolvefunction {    % <fndict> resolvefunction <function>
  96.   dup /FunctionType oget //fnrdict exch get exec
  97. } bdef
  98.  
  99. /resolveidfunction {
  100.   dup /Identity eq { pop { } } { resolvefunction } ifelse
  101. } bdef
  102.  
  103. /resolvedefaultfunction {    % <fndict> <default> resolved'f'n <function>
  104.   1 index /Default eq { exch pop } { pop resolveidfunction } ifelse
  105. } bdef
  106.  
  107. % ---------------- Shadings ---------------- %
  108.  
  109. /shrdict mark
  110.   /ColorSpace {
  111.     resolvecolorspace
  112.   }
  113.   /Function {
  114.     dup type /dicttype eq {
  115.       resolvefunction
  116.     } {
  117.       [ exch { resolvefunction } forall ]
  118.     } ifelse
  119.   }
  120. .dicttomark readonly def
  121.  
  122. /resolveshading {    % <shname> resolveshading <shading>
  123.   Page /Shading rget {
  124.     mark exch {
  125.       oforce //shrdict 2 index .knownget { exec } if
  126.     } forall .dicttomark
  127.     dup /ShadingType get 4 ge {
  128.       dup dup true resolvestream /DataSource exch put
  129.     } if
  130.   } {
  131.     null
  132.   } ifelse
  133. } bdef
  134.  
  135. % ---------------- Halftones ---------------- %
  136.  
  137. /spotfunctions mark
  138.   /Round {
  139.     abs exch abs 2 copy add 1 le {
  140.       dup mul exch dup mul add 1 exch sub 
  141.     } {
  142.       1 sub dup mul exch 1 sub dup mul add 1 sub
  143.     } ifelse
  144.   }
  145.   /Diamond {
  146.     abs exch abs 2 copy add .75 le {
  147.       dup mul exch dup mul add 1 exch sub
  148.     } {
  149.       2 copy add 1.23 le {
  150.     .85 mul add 1 exch sub
  151.       } {
  152.     1 sub dup mul exch 1 sub dup mul add 1 sub
  153.       } ifelse
  154.     } ifelse
  155.   }
  156.   /Ellipse {
  157.     abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt {
  158.       pop dup mul exch .75 div dup mul add 4 div 1 exch sub
  159.     } {
  160.       dup 1 gt {
  161.     pop 1 exch sub dup mul exch 1 exch sub
  162.     .75 div dup mul add 4 div 1 sub
  163.       } {
  164.     .5 exch sub exch pop exch pop
  165.       } ifelse
  166.     } ifelse
  167.   }
  168.   /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub }
  169.   /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub }
  170.   /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub }
  171.   /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub }
  172.   /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub }
  173.   /Line { exch pop abs neg }
  174.   /LineX { pop }
  175.   /LineY { exch pop }
  176.   /Square { abs exch abs 2 copy lt { exch } if pop neg }
  177.   /Cross { abs exch abs 2 copy gt { exch } if pop neg }
  178.   /Rhomboid { abs exch abs 0.9 mul add 2 div }
  179.   /DoubleDot { 2 {360 mul sin 2 div exch } repeat add }
  180.   /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg }
  181.   /SimpleDot { dup mul exch dup mul add 1 exch sub }
  182.   /InvertedSimpleDot { dup mul exch dup mul add 1 sub }
  183.   /CosineDot { 180 mul cos exch 180 mul cos add 2 div }
  184.   /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add }
  185.   /InvertedDouble {
  186.     exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg
  187.   }
  188. .dicttomark readonly def
  189.  
  190. /htrdict mark
  191.   1 { .resolveht1 }
  192.   5 { .resolveht5 }
  193.     % We don't support types 6, 10, or 16 yet.
  194. .dicttomark readonly def
  195.  
  196. /.resolveht1 {
  197.   mark exch {
  198.     oforce
  199.     1 index /SpotFunction eq {
  200.       dup type /nametype eq
  201.     { //spotfunctions exch get } { resolvefunction }
  202.       ifelse
  203.     } {
  204.       1 index /TransferFunction eq {
  205.     resolveidfunction
  206.       } if
  207.     } ifelse
  208.   } forall .dicttomark
  209. } bdef
  210.  
  211. /.resolveht5 {
  212.   mark exch {
  213.     oforce dup type /dicttype eq { resolvehalftone } if
  214.   } forall .dicttomark
  215. } bdef
  216.  
  217. /resolvehalftone {    % <dict> resolvehalftone <halftone>
  218.   dup /HalftoneType get //htrdict exch get exec
  219. } bdef
  220.  
  221. % ---------------- Graphics state management ---------------- %
  222.  
  223. /cmmatrix matrix def
  224. drawopdict begin
  225.             % Graphics state stack
  226.   /q { q } def
  227.   /Q { Q } def
  228.             % Graphics state setting
  229.   /cm { //cmmatrix astore concat } def
  230.   /i /setflat load def
  231.   /J /setlinecap load def
  232.   /d /setdash load def
  233.   /j /setlinejoin load def
  234.   /w /setlinewidth load def
  235.   /M /setmiterlimit load def
  236.   /gs { gs } def
  237. end
  238.  
  239. % Each entry in this dictionary is
  240. %    <gsres> <value> -proc- <gsres>
  241. /gsbg { /BGDefault load resolvedefaultfunction setblackgeneration } bdef
  242. /gsucr { /UCRDefault load resolvedefaultfunction setundercolorremoval } bdef
  243.     %****** DOESN'T IMPLEMENT THE ARRAY (colortransfer) CASE YET ******
  244. /gstr { /TRDefault load resolvedefaultfunction settransfer } bdef
  245. /gsparamdict mark
  246.   /SA { setstrokeadjust }
  247.   /op {
  248.     %****** STROKE OVERPRINT, NOT IMPLEMENTED YET ******
  249.     pop
  250.   }
  251.   /OP { setoverprint }
  252.   /OPM {
  253.     %****** OVERPRINT MODE, NOT IMPLEMENTED YET ******
  254.     pop
  255.   }
  256.     % The PDF 1.3 specification says that the name /Default is only
  257.     % recognized for {BG,UCR,TR}2.  However, PDF 1.3 files produced
  258.     % by Adobe Acrobat Distiller 4.0 for Windows use the name /Default
  259.     % with the older keys, so we have to implement this.
  260.   /BG { 1 index /BG2 known { pop } { gsbg } ifelse }
  261.   /BG2 { gsbg }
  262.   /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse }
  263.   /UCR2 { gsucr }
  264.   /TR { 1 index /TR2 known { pop } { gstr } ifelse }
  265.   /TR2 { gstr }
  266.   /HT {
  267.     dup /Default eq {
  268.       pop .setdefaultscreen
  269.     } {
  270.     %****** DOESN'T IMPLEMENT THE STREAM CASE YET ******
  271.       resolvehalftone sethalftone
  272.     } ifelse
  273.   }
  274.     % HTP may be present even if this isn't a DPS interpreter.
  275.   /HTP {
  276.     /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse
  277.   }
  278.     % SM may be present even if this is only a Level 2 interpreter.
  279.   /SM {
  280.     /setsmoothness where { pop setsmoothness } { pop } ifelse
  281.   }
  282.   /Font { aload pop Tf }
  283.   /LW { setlinewidth }
  284.   /LC { setlinecap }
  285.   /LJ { setlinejoin }
  286.   /ML { setmiterlimit }
  287.   /D { aload pop setdash }
  288.   /FL { setflat }
  289.   /RI { ri }
  290. .dicttomark readonly def
  291. /gs {            % <gsres> gs -
  292.   Page /ExtGState rget {
  293.     % We keep the dictionary on the stack during the forall so that
  294.     % keys that interact with each other have access to it.
  295.     dup {
  296.       oforce exch gsparamdict exch .knownget { exec } { pop } ifelse
  297.     } forall pop
  298.   } if
  299. } bdef
  300.  
  301. % ---------------- Color setting ---------------- %
  302.  
  303. /01_1 [0 1] readonly def
  304. /01_3 [0 1 0 1 0 1] readonly def
  305. /01_4 [0 1 0 1 0 1 0 1] readonly def
  306.  
  307. % The keys here are resolved (PostScript, not PDF) color space names.
  308. /csncompdict mark
  309.   /DeviceGray { pop 1 }
  310.   /DeviceRGB { pop 3 }
  311.   /DeviceCMYK { pop 4 }
  312.   /CIEBasedA { pop 1 }
  313.   /CIEBasedABC { pop 3 }
  314.   /Separation { pop 1 }
  315.   /DeviceN { 2 oget length }
  316. .dicttomark readonly def
  317.  
  318. % Perhaps some of the values in the following need to be modified
  319. % depending on the WhitePoint value....
  320. /cslabinit mark
  321.   /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind]
  322.   /MatrixABC [1 1 1 1 0 0 0 0 -1]
  323.   /DecodeLMN [
  324.     {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
  325.      0.9505 mul} bind
  326.     {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
  327.      } bind
  328.     {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
  329.      1.0890 mul} bind
  330.   ]
  331. .dicttomark readonly def
  332.  
  333. /csrdict mark
  334.   /DeviceGray {
  335.     /DefaultGray Page /ColorSpace rget { exch pop resolvecolorspace } if
  336.   }
  337.   /DeviceRGB {
  338.     /DefaultRGB Page /ColorSpace rget { exch pop resolvecolorspace } if
  339.   }
  340.   /DeviceCMYK { }
  341.   /CalGray {
  342.     1 oget 6 dict begin
  343.     dup /Gamma knownoget {
  344.       /exp load 2 packedarray cvx /DecodeA exch def
  345.     } if
  346.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  347.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  348.     pop [ /CIEBasedA currentdict end ]
  349.   }
  350.   /CalRGB {
  351.     1 oget 6 dict begin
  352.     dup /Gamma knownoget {
  353.       [ exch { /exp load 2 packedarray cvx } forall
  354.       ] /DecodeABC exch def
  355.     } if
  356.     dup /Matrix knownoget { /MatrixABC exch def } if
  357.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  358.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  359.     pop [ /CIEBasedABC currentdict end ]
  360.   }
  361.   /CalCMYK {
  362.     pop /DeviceCMYK        % not defined by Adobe
  363.   }
  364.   /Lab {
  365.     1 oget 6 dict begin
  366.     dup /Range knownoget not { [-100 100 -100 100] } if
  367.     [0 100 null null null null] dup 2 4 -1 roll putinterval
  368.     /RangeABC exch def
  369.     //cslabinit { def } forall
  370.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  371.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  372.     pop [ /CIEBasedABC currentdict end ]
  373.   }
  374.   /ICCBased {
  375.         % Since the PostScript interpreter doesn't support these yet,
  376.         % always substitute an alternate space.
  377.     1 oget dup /Alternate knownoget {
  378.       exch pop
  379.     } {
  380.       /N get { null /DeviceGray null /DeviceRGB /DeviceCMYK } exch get
  381.     } ifelse resolvecolorspace
  382.   }
  383.   /Separation {
  384.     aload pop exch oforce resolvecolorspace exch oforce resolvefunction
  385.     4 array astore
  386.   }
  387.   /DeviceN {
  388.     aload pop 3 -1 roll oforce
  389.     3 -1 roll oforce resolvecolorspace
  390.     3 -1 roll oforce resolvefunction
  391.     4 array astore
  392.   }
  393.   /Indexed {
  394.     aload pop 3 -1 roll oforce resolvecolorspace
  395.         % If the underlying space is a Lab space, we must scale
  396.         % the output of the lookup table as part of DecodeABC.
  397.     dup dup type /arraytype eq { 0 get } if /CIEBasedABC eq {
  398.       dup 1 get /DecodeLMN known {
  399.     1 get dup length dict copy
  400.     begin /DecodeABC [ 0 2 4 {
  401.       RangeABC 1 index 1 add get RangeABC 2 index get sub /mul load
  402.       RangeABC 3 index get /add load
  403.       DecodeABC 6 -1 roll 2 idiv get [ 6 1 roll aload pop ] cvx
  404.     } for ] def
  405.     /RangeABC //01_3 def
  406.     currentdict end /CIEBasedABC exch 2 array astore
  407.       } if
  408.     } if
  409.     3 1 roll
  410.     oforce dup type /stringtype ne {
  411.         % The color lookup table is a stream.
  412.         % Get its contents.  Don't lose our place in PDFfile.
  413.         % Stack: /Indexed basespace hival lookup
  414.     PDFfile fileposition 5 1 roll true resolvestream
  415.         % Stack: filepos /Indexed basespace hival lookupstream
  416.     1 index 1 add
  417.         % Stack: filepos /Indexed basespace hival lookupstream len
  418.     3 index
  419.       dup dup type /arraytype eq { 0 get } if
  420.       //csncompdict exch get exec mul
  421.     string readstring pop
  422.         % Stack: filepos /Indexed basespace hival table
  423.     5 -1 roll PDFfile exch setfileposition
  424.     }
  425.     if 4 array astore
  426.   }
  427.   /Pattern {
  428.     dup type /nametype ne {
  429.       dup length 1 gt {
  430.     1 oget resolvecolorspace
  431.     /Pattern exch 2 array astore
  432.       } if
  433.     } if
  434.   }
  435. .dicttomark readonly def
  436.  
  437. /cssubst {        % <csname> cssubst <cspace'> true
  438.             % <csname> cssubst false
  439.   dup resolvecolorspace
  440.   dup 1 index ne { exch pop true } { pop pop false } ifelse
  441. } bdef
  442.  
  443. /csnames mark
  444.   /DeviceGray dup  /DeviceRGB dup  /DeviceCMYK dup  /Pattern dup
  445. .dicttomark readonly def
  446. /csresolve {        % <csresourcename> csresolve <cspace>
  447.   dup Page /ColorSpace rget {
  448.     exch pop resolvecolorspace
  449.   } {
  450.     //csnames 1 index known not { /undefined cvx signalerror } if
  451.   } ifelse
  452. } bdef
  453. /resolvecolorspace {    % <cspace> resolvecolorspace <cspace'>
  454.   dup dup type /arraytype eq { 0 get } if
  455.   //csrdict exch .knownget {
  456.     exec dup type /nametype ne { dup length 1 eq { 0 get } if } if
  457.   } {
  458.     csresolve
  459.   } ifelse
  460. } bdef
  461.  
  462. /scresolve {    % <c0> ... scresolve <multi>
  463.         % We can't really make sc[n] and SC[N] work, because
  464.         % the color space information isn't available at
  465.         % conversion time; so we hack it by assuming that
  466.         % all the operands on the stack are used, and that
  467.         % if the top operand is a name, it's a Pattern resource.
  468.   dup type /nametype eq
  469.     { Page /Pattern rget { resolvepattern } { null } ifelse }
  470.   if
  471.   dup type /dicttype eq {
  472.         % Check the PaintType
  473.     dup /PaintType get 2 eq
  474.   } {
  475.     .pdfcount 1 gt
  476.   } ifelse
  477. } bdef
  478.  
  479. /.pdfpaintproc {         % <patdict> <resdict> .pdfpaintproc -
  480.   DEBUG { (%Begin PaintProc) = flush } if
  481.     % For uncolored patterns, we have to unbind the current
  482.     % color and color space before running the PaintProc.
  483.     % There's no harm in doing this for colored patterns,
  484.     % so for simplicity, we always do it.
  485.   q
  486.   null sc1 null SC1
  487.   exch false resolvestream pdfopdict .pdfruncontext
  488.   Q
  489.   DEBUG { (%End PaintProc) = flush } if
  490. } bdef
  491.  
  492. /resolvepattern {    % <patternstreamdict> resolvepattern <patterndict>
  493.         % Don't do the resolvestream now: just capture the data
  494.         % from the file if necessary.
  495.   dup length dict copy
  496.   dup /FilePosition .knownget {
  497.     1 index /File get dup fileposition 3 1 roll
  498.         % Stack: dict savepos pos file
  499.     dup 3 -1 roll setfileposition
  500.     dup 3 index /Length get string readstring pop
  501.         % Stack: dict savepos file string
  502.     3 1 roll exch setfileposition
  503.     1 index /File 3 -1 roll put
  504.     dup /FilePosition undef
  505.   } if
  506.   dup /PaintProc [
  507.         % Bind the resource dictionary into the PaintProc.
  508.     2 index /Resources knownoget { oforce } { 0 dict } ifelse
  509.     /.pdfpaintproc cvx
  510.   ] cvx put
  511.   DEBUG {
  512.     (%Pattern: ) print dup === flush
  513.   } if
  514. } bdef
  515.  
  516. drawopdict begin
  517.   /g { /DeviceGray cssubst { cs sc1 } { g } ifelse } bdef
  518.   /rg { /DeviceRGB cssubst { cs sc* } { rg } ifelse } bdef
  519.   /k { k } bdef
  520.   /cs { csresolve cs } bdef
  521.   /sc { scresolve { sc* } { sc1 } ifelse } bdef
  522.   /scn /sc load def
  523.   /G { /DeviceGray cssubst { CS SC1 } { G } ifelse } bdef
  524.   /RG { /DeviceRGB cssubst { CS SC* } { RG } ifelse } bdef
  525.   /K { K } bdef
  526.   /CS { csresolve CS } bdef
  527.   /ri { ri } bdef
  528.   /SC { scresolve { SC* } { SC1 } ifelse } bdef
  529.   /SCN /SC load def
  530. end
  531.  
  532. % ---------------- Paths ---------------- %
  533.  
  534. drawopdict begin
  535.             % Path construction
  536.   /m /moveto load def
  537.   /l /lineto load def
  538.   /c /curveto load def
  539.   /v { currentpoint 6 2 roll curveto } def
  540.   /y { 2 copy curveto } def
  541.   /re {
  542.    4 2 roll moveto  exch dup 0 rlineto  0 3 -1 roll rlineto  neg 0 rlineto
  543.    closepath
  544.   } def
  545.   /h /closepath load def
  546.             % Path painting and clipping
  547.   /n { n } def
  548.   /S { S } def
  549.   /s { s } def
  550.   /f { f } def
  551.   /f* { f* } def
  552.   /B { B } def
  553.   /b { b } def
  554.   /B* { B* } def
  555.   /b* { b* } def
  556.   /W { W } def
  557.   /W* { W* } def
  558.   /sh { resolveshading shfill } def
  559. end
  560.  
  561. % ---------------- XObjects ---------------- %
  562.  
  563. /xobjectprocs mark        % <dict> -proc- -
  564.   /Image { DoImage }
  565.   /Form { DoForm }
  566.   /PS { DoPS }
  567. .dicttomark readonly def
  568.  
  569. % Note that the keys in defaultdecodedict are resolved (PostScript, not PDF)
  570. % color space names.
  571. /defaultdecodedict mark
  572.   /DeviceGray { pop //01_1 }
  573.   /DeviceRGB { pop //01_3 }
  574.   /DeviceCMYK { pop //01_4 }
  575.   /CIEBasedA { 1 get /RangeA .knownget not { //01_1 } if }
  576.   /CIEBasedABC { 1 get /RangeABC .knownget not { //01_3 } if }
  577.   /Separation { pop //01_1 }
  578.   /DeviceN {
  579.     dup 1 oget length [ exch {0 1} repeat ] readonly
  580.   }
  581.   /Indexed {
  582.     pop [ 0 1 BitsPerComponent bitshift 1 sub ]
  583.   }
  584. .dicttomark readonly def
  585.  
  586. /checkaltimage {    % <resdict> checkaltimage <resdict[']>
  587.   /UsePrinterImages where {
  588.     pop UsePrinterImages {
  589.       dup /Alternates knownoget {
  590.     {
  591.       dup /DefaultForPrinting knownoget {
  592.         {
  593.           /Image oget exch pop exit
  594.         } {
  595.           pop
  596.         } ifelse
  597.       } {
  598.         pop
  599.       } ifelse
  600.     } forall
  601.       } if
  602.     } if
  603.   } if
  604. } bdef
  605.  
  606. /makeimagedict {    % <resdict> <newdict> makeimagedict -
  607.             % On return, newdict' is currentdict
  608.   begin
  609.   /Width 2 copy oget def
  610.   /Height 2 copy oget def
  611.   /BitsPerComponent 2 copy oget def
  612.   /Interpolate 2 copy knownoget { def } { pop } ifelse
  613.   makeimagekeys
  614. } bdef
  615. /makeimagekeys {    % <resdict> makeimagekeys <imagemask>
  616.         % newdict is currentdict
  617.         % Assumes Width, Height, BPC, Interpolate already copied.
  618.   /ImageType 1 def
  619.   /ImageMatrix Width 0 0
  620.         % Handle 0-height images specially.
  621.     Height dup 0 eq { pop 1 } if neg 0 1 index neg
  622.     6 array astore def
  623.   dup /ImageMask knownoget dup { and } if {
  624.         % Image mask
  625.         % Decode is required for the PostScript image operators.
  626.     /Decode 2 copy knownoget not { //01_1 } if def
  627.         % BitsPerComponent may be missing for masks.
  628.         % The spec requires it, but some producers omit it, and
  629.         % Acrobat Reader doesn't care.
  630.     /BitsPerComponent 2 copy known { pop } { 1 def } ifelse
  631.     true
  632.   } {
  633.         % Opaque image
  634.     dup /ColorSpace oget resolvecolorspace /ColorSpace exch def
  635.         % Decode is required for the PostScript image operators.
  636.     /Decode 2 copy knownoget not {
  637.       ColorSpace //defaultdecodedict
  638.       ColorSpace dup type /arraytype eq { 0 get } if get exec
  639.     } if def
  640.     false
  641.   } ifelse
  642.         % Even though we're going to read data,
  643.         % pass false to resolvestream so that
  644.         % it doesn't try to use Length (which may not be present).
  645.   exch false resolvestream /DataSource exch def
  646. } bdef
  647.  
  648. /DoImage {
  649.   checkaltimage dup length 6 add dict makeimagedict doimage
  650. } bdef
  651. /doimage {    % <imagemask> doimage -
  652.         % imagedict is currentdict, gets popped from dstack
  653.   DataSource exch
  654.   currentdict /Mask knownoget {
  655.     dup type /arraytype eq {
  656.       /ImageType 4 def
  657.       /MaskColor exch def
  658.     } {
  659.         % Mask is a stream, another Image XObject.
  660.       dup length dict makeimagedict
  661.       currentdict end currentdict end
  662.       4 dict begin
  663.       /ImageType 3 def
  664.       /InterleaveType 3 def
  665.       /MaskDict exch def
  666.       /DataDict exch def
  667.     } ifelse
  668.   } if
  669.         % Stack: datasource imagemask
  670.    { currentdict end setfillcolor imagemask }
  671.    { ColorSpace setcolorspace currentdict end image }
  672.   ifelse
  673.         % Close the input stream, unless it is PDFfile or
  674.         % PDFsource.
  675.   dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse
  676. } bdef
  677.  
  678. /DoForm {
  679.   dup length dict copy
  680.   dup [ /pop load 2 index /Resources knownoget { oforce } { 0 dict } ifelse
  681.   3 index false /resolvestream cvx
  682.   pdfopdict /.pdfruncontext cvx
  683.   ] cvx /PaintProc exch put
  684.   execform
  685. } bdef
  686.  
  687. /DoPS {
  688.   true resolvestream cvx exec
  689. } bdef
  690.  
  691. drawopdict begin
  692.   /Do
  693.     { PDFfile fileposition exch
  694.       dup Page /XObject rget not { /undefined cvx signalerror } if
  695.       exch pop dup /Subtype get xobjectprocs exch get
  696.         % Don't leave extra objects on the stack while executing
  697.         % the definition of the form.
  698.       3 -1 roll 2 .execn
  699.       PDFfile exch setfileposition
  700.     } bdef
  701. end
  702.  
  703. % ---------------- In-line images ---------------- %
  704.  
  705. % Undo the abbreviations in an in-line image dictionary.
  706. % Note that we must look inside array values.
  707. % /I is context-dependent.
  708. /unabbrevkeydict mark
  709.   /BPC /BitsPerComponent  /CS /ColorSpace  /D /Decode  /DP /DecodeParms
  710.   /F /Filter  /H /Height  /I /Interpolate  /IM /ImageMask  /W /Width
  711. .dicttomark readonly def
  712. /unabbrevvaluedict mark
  713.   /AHx /ASCIIHexDecode  /A85 /ASCII85Decode  /CC /CalCMYK
  714.   /CCF /CCITTFaxDecode  /CG /CalGray  /CR /CalRGB
  715.   /DCT /DCTDecode  /CMYK /DeviceCMYK  /Fl /FlateDecode
  716.   /G /DeviceGray  /RGB /DeviceRGB
  717.   /I /Indexed  /LZW /LZWDecode  /RL /RunLengthDecode
  718. .dicttomark readonly def
  719. /unabbrevtypedict mark
  720.   /nametype {
  721.     //unabbrevvaluedict 1 index .knownget { exch pop } if
  722.   }
  723.   /arraytype {
  724.     dup 0 1 2 index length 1 sub {
  725.       2 copy get unabbrevvalue put dup
  726.     } for pop
  727.   }
  728. .dicttomark readonly def
  729. /unabbrevvalue {    % <obj> unabbrevvalue <obj'>
  730.   oforce //unabbrevtypedict 1 index type .knownget { exec } if
  731. } bdef
  732.  
  733. drawopdict begin
  734.   /BI { mark } bdef
  735.   /ID {
  736.     counttomark 2 idiv dup 6 add dict begin {
  737.       exch //unabbrevkeydict 1 index .knownget { exch pop } if
  738.       exch unabbrevvalue def
  739.     } repeat pop
  740.     /File PDFsource def
  741.     currentdict makeimagekeys doimage
  742.     PDFsource token pop /EI ne { /ID cvx /syntaxerror signalerror } if
  743.   } bdef
  744. end
  745.  
  746. % ================================ Text ================================ %
  747.  
  748. drawopdict begin
  749.             % Text control
  750.   /BT { BT } def
  751.   /ET { ET } def
  752.   /Tc { Tc } def
  753.   /TL { TL } def
  754.   /Tr { Tr } def
  755.   /Ts { Ts } def
  756.   /Tw { Tw } def
  757.   /Tz { Tz } def
  758.             % Text positioning
  759.   /Td { Td } def
  760.   /TD { TD } def
  761.   /Tm { Tm } def
  762.   /T* { T* } def
  763.             % Text painting
  764.   /Tj { Tj } def
  765.   /' { ' } def
  766.   /" { " } def
  767.   /TJ { TJ } def
  768. end
  769.  
  770. % ============================== Annotations ============================== %
  771.  
  772.  
  773.  
  774. % Get and normalize an annotation's rectangle.
  775. /annotrect {        % <annot> annotrect <x> <y> <w> <h>
  776.   /Rect get aload pop
  777.   exch 3 index sub dup 0 lt { dup 5 -1 roll add 4 1 roll neg } if
  778.   exch 2 index sub dup 0 lt { dup 4 -1 roll add 3 1 roll neg } if
  779. } bdef
  780.  
  781. % Set an annotation color.
  782. /annotsetcolor {    % <annot> annotsetcolor -
  783.   /C knownoget { setrgbcolor } { 0 setgray } ifelse
  784. } bdef
  785.  
  786. % Draw the border.  Currently, we ignore requests for beveling, and we
  787. % don't round the corners of rectangles.
  788. /strokeborder {        % <annot> <width> <dash> strokeborder -
  789.   gsave
  790.   2 index annotsetcolor
  791.   0 setdash dup setlinewidth
  792.   exch annotrect
  793.   2 { 4 index sub 4 1 roll } repeat
  794.   2 { 4 index 0.5 mul add 4 1 roll } repeat
  795.   rectstroke pop
  796.   grestore
  797. } bdef
  798.  
  799. % Draw an annotation border.
  800. /drawborder {        % <annot> drawborder -
  801.   gsave
  802.   dup /BS knownoget {
  803.     dup /W knownoget not { 1 } if
  804.     [] 2 index /S knownoget {
  805.       /D eq { 2 index /D knownoget not { [3] } if exch pop } if
  806.     } if 3 -1 roll pop strokeborder
  807.   } {
  808.     dup /Border knownoget {
  809.       dup 2 get
  810.       exch dup length 3 gt { 3 get } { pop [] } ifelse
  811.       strokeborder
  812.     } {
  813.       pop
  814.     } ifelse
  815.   } ifelse
  816.   grestore
  817. } bdef
  818.  
  819. % Draw an annotation.
  820. /drawannot {        % <annot> drawannot -
  821.   gsave
  822.   dup /Subtype get /Widget eq
  823.   1 index /F knownoget not { 0 } if 2 and 0 eq and {
  824.     dup drawborder
  825.     dup /AP knownoget {
  826.     % Always use the Normal appearance.
  827.       /N oget
  828.         % Acrobat Distiller produces files in which this Form
  829.         % XObject lacks Type and Subtype keys.  This is illegal,
  830.         % but Acrobat Reader accepts it.  The only way we can
  831.         % tell whether this is a Form or a set of sub-appearances
  832.         % is by testing for the stream Length key.
  833.       dup /Length known not {
  834.     1 index /AS knownoget not { () } if
  835.         % Stack: annot Ndict AS
  836.     2 copy knownoget {
  837.       exch pop exch pop
  838.     } {
  839.         % Pick any one.
  840.       pop { exch pop oforce exit } forall
  841.     } ifelse
  842.       } if
  843.         % Acrobat Distiller produces files in which this Form
  844.         % XObject lack FormType and Matrix keys.  This is illegal,
  845.         % but Acrobat Reader accepts it.  Patch this up now.
  846.       dup /FormType known not  {
  847.     dup length 1 add dict copy dup /FormType 1 put
  848.       } if
  849.       dup /Matrix known not  {
  850.     dup length 1 add dict copy dup /Matrix matrix put
  851.       } if
  852.       gsave 1 index annotrect pop pop translate
  853.       DoForm
  854.     } if
  855.   } if pop
  856.   grestore
  857. } bdef
  858.  
  859. end            % pdfdict
  860. end            % GS_PDF_ProcSet
  861. .setglobal
  862.