home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 September / PCWorld_2001-09_cd.bin / Software / Vyzkuste / rychlokurz / gs700w32.exe / gs7.00 / lib / pdf_draw.ps < prev    next >
Text File  |  2001-04-06  |  35KB  |  1,146 lines

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