home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 October / Chip_2002-10_cd1.bin / zkuste / pdf / download / gs704w32.exe / gs7.04 / lib / pdf_draw.ps < prev    next >
Encoding:
Text File  |  2002-01-31  |  34.5 KB  |  1,153 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.36 2001/10/16 22:20:31 dancoby 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             % filepos fndict
  71.   dup true resolvestream                % filepos fndict stream
  72.   exch dup length dict copy             % filepos stream fndict2
  73.   dup /Function undef                   % filepos stream fndict2
  74.   exch dup token not {
  75.     () /rangecheck cvx signalerror
  76.   } if
  77.   exch token {
  78.     /rangecheck cvx signalerror
  79.   } if
  80.         % Use .bind to avoid idiom recognition.
  81.   .bind
  82.   1 index /Function 3 -1 roll put
  83.   exch PDFfile exch setfileposition
  84. } bdef
  85. currentdict /tfopdict undef
  86.  
  87. /.resolvefn {        % <fndict> .resolvefn <fndict'>
  88.   dup /FunctionType oget //fnrdict exch get exec
  89. } bdef
  90.  
  91. /resolvefunction {    % <fndict> resolvefunction <function>
  92.   .resolvefn
  93.   DEBUG { (%Function: ) print dup === flush } if
  94. } bdef
  95.  
  96. /resolvefnproc {    % <fndict> resolvefnproc <proc>
  97.   resolvefunction .buildfunction
  98. } bdef
  99.  
  100. /resolveidfnproc {    % <fndict> resolveidfnproc <proc>
  101.   dup /Identity eq { pop { } } { resolvefnproc } ifelse
  102. } bdef
  103.  
  104. /resolvedefaultfnproc {    % <fndict> <default> resolved'fnproc <proc>
  105.   1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse
  106. } bdef
  107.  
  108. % ---------------- Shadings ---------------- %
  109.  
  110. /shrdict mark
  111.   /ColorSpace {
  112.     resolvecolorspace
  113.   }
  114.   /Function {
  115.     dup type /dicttype eq {
  116.       resolvefunction
  117.     } {
  118.       [ exch { oforce resolvefunction } forall ]
  119.     } ifelse
  120.   }
  121. .dicttomark readonly def
  122.  
  123. /resolveshading {    % <shadingstream> resolveshading <shading>
  124.   PDFfile fileposition exch
  125.   mark exch {
  126.     oforce //shrdict 2 index .knownget { exec } if
  127.   } forall .dicttomark
  128.   dup /ShadingType get 4 ge {
  129.     dup dup true resolvestream
  130.         % Make a reusable stream so that the shading doesn't
  131.         % reposition PDFfile at unexpected times.
  132.     /ReusableStreamDecode filter /DataSource exch put
  133.   } if exch PDFfile exch setfileposition
  134. } bdef
  135. /resolvesh {        % <shname> resolveshading <shading>
  136.   Page /Shading rget {
  137.     resolveshading
  138.   } {
  139.     null
  140.   }ifelse
  141. } bdef
  142.  
  143. % ---------------- Halftones ---------------- %
  144.  
  145. /spotfunctions mark
  146.   /Round {
  147.     abs exch abs 2 copy add 1 le {
  148.       dup mul exch dup mul add 1 exch sub 
  149.     } {
  150.       1 sub dup mul exch 1 sub dup mul add 1 sub
  151.     } ifelse
  152.   }
  153.   /Diamond {
  154.     abs exch abs 2 copy add .75 le {
  155.       dup mul exch dup mul add 1 exch sub
  156.     } {
  157.       2 copy add 1.23 le {
  158.     .85 mul add 1 exch sub
  159.       } {
  160.     1 sub dup mul exch 1 sub dup mul add 1 sub
  161.       } ifelse
  162.     } ifelse
  163.   }
  164.   /Ellipse {
  165.     abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt {
  166.       pop dup mul exch .75 div dup mul add 4 div 1 exch sub
  167.     } {
  168.       dup 1 gt {
  169.     pop 1 exch sub dup mul exch 1 exch sub
  170.     .75 div dup mul add 4 div 1 sub
  171.       } {
  172.     .5 exch sub exch pop exch pop
  173.       } ifelse
  174.     } ifelse
  175.   }
  176.   /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub }
  177.   /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub }
  178.   /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub }
  179.   /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub }
  180.   /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub }
  181.   /Line { exch pop abs neg }
  182.   /LineX { pop }
  183.   /LineY { exch pop }
  184.   /Square { abs exch abs 2 copy lt { exch } if pop neg }
  185.   /Cross { abs exch abs 2 copy gt { exch } if pop neg }
  186.   /Rhomboid { abs exch abs 0.9 mul add 2 div }
  187.   /DoubleDot { 2 {360 mul sin 2 div exch } repeat add }
  188.   /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg }
  189.   /SimpleDot { dup mul exch dup mul add 1 exch sub }
  190.   /InvertedSimpleDot { dup mul exch dup mul add 1 sub }
  191.   /CosineDot { 180 mul cos exch 180 mul cos add 2 div }
  192.   /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add }
  193.   /InvertedDouble {
  194.     exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg
  195.   }
  196. .dicttomark readonly def
  197.  
  198. /htrdict mark
  199.   1 { .resolveht1 }
  200.   5 { .resolveht5 }
  201.     % We don't support types 6, 10, or 16 yet.
  202. .dicttomark readonly def
  203.  
  204. /.resolveht1 {
  205.   mark exch {
  206.     oforce
  207.     1 index /SpotFunction eq {
  208.       dup type /nametype eq
  209.     { //spotfunctions exch get } { resolvefnproc }
  210.       ifelse
  211.     } {
  212.       1 index /TransferFunction eq {
  213.     resolveidfnproc
  214.       } if
  215.     } ifelse
  216.   } forall .dicttomark
  217. } bdef
  218.  
  219. /.resolveht5 {
  220.   mark exch {
  221.     oforce dup type /dicttype eq { resolvehalftone } if
  222.   } forall .dicttomark
  223. } bdef
  224.  
  225. /resolvehalftone {    % <dict> resolvehalftone <halftone>
  226.   dup /HalftoneType get //htrdict exch get exec
  227. } bdef
  228.  
  229. % ---------------- Graphics state management ---------------- %
  230.  
  231. /cmmatrix matrix def
  232. drawopdict begin
  233.             % Graphics state stack
  234.   /q { q } def
  235.   /Q { Q } def
  236.             % Graphics state setting
  237.   /cm { //cmmatrix astore concat } def
  238.   /i /setflat load def
  239.   /J /setlinecap load def
  240.   /d /setdash load def
  241.   /j /setlinejoin load def
  242.   /w /setlinewidth load def
  243.   /M /setmiterlimit load def
  244.   /gs { gs } def
  245. end
  246.  
  247. % Each entry in this dictionary is
  248. %    <gsres> <value> -proc- <gsres>
  249. /gsbg {
  250.   /BGDefault load resolvedefaultfnproc setblackgeneration
  251. } bdef
  252. /gsucr {
  253.   /UCRDefault load resolvedefaultfnproc setundercolorremoval
  254. } bdef
  255. /gstr {
  256.   dup type /arraytype eq {
  257.     { oforce /TRDefault load resolvedefaultfnproc } forall
  258.     setcolortransfer
  259.   } {
  260.     /TRDefault load resolvedefaultfnproc settransfer
  261.   } ifelse
  262. } bdef
  263. /gsparamdict mark
  264.   /SA { setstrokeadjust }
  265.   /OP { 1 index /op known not { dup op } if OP }
  266.     % The PDF 1.3 specification says that the name /Default is only
  267.     % recognized for {BG,UCR,TR}2.  However, PDF 1.3 files produced
  268.     % by Adobe Acrobat Distiller 4.0 for Windows use the name /Default
  269.     % with the older keys, so we have to implement this.
  270.   /BG { 1 index /BG2 known { pop } { gsbg } ifelse }
  271.   /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse }
  272.   /TR { 1 index /TR2 known { pop } { gstr } ifelse }
  273.   /HT {
  274.     dup /Default eq {
  275.       pop .setdefaultscreen
  276.     } {
  277.     %****** DOESN'T IMPLEMENT THE STREAM CASE YET ******
  278.       resolvehalftone sethalftone
  279.     } ifelse
  280.   }
  281.   /HTP {
  282.     % HTP may be present even if this isn't a DPS interpreter.
  283.     /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse
  284.   }
  285.     % PDF 1.3
  286.   /Font { aload pop Tf }
  287.   /LW { setlinewidth }
  288.   /LC { setlinecap }
  289.   /LJ { setlinejoin }
  290.   /ML { setmiterlimit }
  291.   /D { aload pop setdash }
  292.   /RI { ri }
  293.   /op { op }
  294.   /OPM { OPM }
  295.   /BG2 { gsbg }
  296.   /UCR2 { gsucr }
  297.   /TR2 { gstr }
  298.   /FL { setflat }
  299.   /SM {
  300.     % SM may be present even if this is only a Level 2 interpreter.
  301.     /setsmoothness where { pop setsmoothness } { pop } ifelse
  302.   }
  303.     % PDF 1.4
  304.     % All of these require the "transparency" feature in the interpreter.
  305.   /ca { ca }
  306.   /CA { CA }
  307.   /SMask { gssmask }
  308.   /AIS { AIS }
  309.   /BM { BM }
  310.   /TK { TK }
  311. .dicttomark readonly def
  312. /gs {            % <gsres> gs -
  313.   Page /ExtGState rget {
  314.     % We keep the dictionary on the stack during the forall so that
  315.     % keys that interact with each other have access to it.
  316.     dup {
  317.       oforce exch gsparamdict exch .knownget { exec } { pop } ifelse
  318.     } forall pop
  319.   } if
  320. } bdef
  321.  
  322. % ------ Transparency support ------ %
  323.  
  324. /gssmask {
  325.   dup /None eq {
  326.     pop null
  327.   } {
  328.     % Preprocess the SMask value into a parameter dictionary for
  329.     % .begintransparencymask, with added /BBox and /Draw keys.
  330.     mark exch        % Stack: mark smaskdict
  331.     dup /S oget /Subtype exch 3 2 roll
  332.             % Stack: mark ... smaskdict
  333.     dup /BC knownoget { /Background exch 3 2 roll } if
  334.     dup /TR knownoget {
  335.       resolveidfnproc /TransferFunction exch 3 2 roll
  336.     } if    
  337.     dup /G oget dup /BBox oget /BBox exch 4 2 roll
  338.     /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll
  339.     pop .dicttomark
  340.   } ifelse SMask
  341. } bdef
  342.  
  343. % This procedure is called to actually render the soft mask.
  344. /.execmaskgroup {    % <masknum> <paramdict> <formdict> .execmaskgroup -
  345.     % Save our place in PDFfile, and do a gsave to avoid resetting
  346.     % the color space.
  347.   gsave PDFfile fileposition 4 1 roll
  348.     % We have to select the group's color space so that the
  349.     % background color will be interpreted correctly.
  350.   dup /Group oget /CS knownoget { csresolve setcolorspace } if
  351.   exch dup /BBox get aload pop .begintransparencymask {
  352.     dup /Resources knownoget { oforce } { 0 dict } ifelse
  353.     exch false resolvestream
  354.     .execgroup .endtransparencymask
  355.   } .internalstopped {
  356.     .discardtransparencymask stop
  357.   } if
  358.   PDFfile exch setfileposition grestore
  359. } bdef
  360. % Paint a Form+Group XObject, either for a transparency mask or for a Do.
  361. /.execgroup {        % <resdict> <stream> .execgroup -
  362.   gsave
  363.   1 .setopacityalpha 1 .setshapealpha
  364.   0 .inittransparencymask 1 .inittransparencymask
  365.   /Compatible .setblendmode
  366.     % Execute the body of the Form, similar to DoForm.
  367.   pdfopdict .pdfruncontext
  368.   grestore
  369. } bdef
  370.  
  371. /.beginformgroup {    % groupdict bbox .beginformgroup -
  372.   exch mark exch            % bbox mark groupdict
  373.   dup /CS knownoget { csresolve setcolorspace } if
  374.   dup /I knownoget { /Isolated exch 3 2 roll } if
  375.   dup /K knownoget { /Knockout exch 3 2 roll } if
  376.   pop .dicttomark
  377.         % Stack: bbox paramdict
  378.   exch aload pop
  379.   .begintransparencygroup
  380. } bdef
  381.  
  382. % .paintgroupform implements the Form PaintProc in the case where the
  383. % Form XObject dictionary includes a Group key.  See .paintform below.
  384. /.paintgroupform {    % <resdict> <stream> <formdict> .paintgroupform -
  385.   dup /Group oget exch /BBox oget
  386.         % Stack: resdict stream groupdict bbox
  387.   .beginformgroup {
  388.     .execgroup
  389.   } .internalstopped {
  390.     .discardtransparencygroup stop
  391.   } if .endtransparencygroup
  392. } bdef
  393.  
  394. % Make an ImageType 103 (soft-masked) image.
  395. /makesoftmaskimage {    % <datasource> <imagemask> <SMask> makesoftmaskimage
  396.             %   <datasource> <imagemask>, updates currentdict =
  397.             %   imagedict
  398.         % See the ImageType 3 case of makemaskimage below.
  399.         % SMask is a stream, another Image XObject.
  400.         % Stack: datasource imagemask(false) smaskstreamdict
  401.   PDFfile fileposition exch
  402.   dup /Matte knownoget { /Matte exch def } if
  403.   dup length dict makeimagedict pop
  404.         % In order to prevent the two data sources from being
  405.         % aliased, we need to make at least one a reusable stream.
  406.         % We pick the mask, since it's smaller (in case we need to
  407.         % read all its data now).
  408.         % Stack: datasource imagemask(false) savedpos
  409.         % maskdict is currentdict
  410.   /DataSource DataSource mark
  411.     /Intent 1
  412.     /AsyncRead true
  413.   .dicttomark .reusablestreamdecode def
  414.   PDFfile exch setfileposition
  415.   currentdict end currentdict end
  416.   5 dict begin
  417.   /ImageType 103 def
  418.   /DataDict exch def
  419.   dup /InterleaveType 3 put
  420.   DataDict /Matte .knownget {
  421.     /Matte exch def
  422.   } if
  423.   AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def
  424.   /ColorSpace DataDict /ColorSpace get def
  425. } bdef
  426.  
  427. % ---------------- Color setting ---------------- %
  428.  
  429. /01_1 [0 1] readonly def
  430. /01_3 [0 1 0 1 0 1] readonly def
  431. /01_4 [0 1 0 1 0 1 0 1] readonly def
  432.  
  433. % The keys here are resolved (PostScript, not PDF) color space names.
  434. /csncompdict mark
  435.   /DeviceGray { pop 1 }
  436.   /DeviceRGB { pop 3 }
  437.   /DeviceCMYK { pop 4 }
  438.   /CIEBasedA { pop 1 }
  439.   /CIEBasedABC { pop 3 }
  440.   /ICCBased { 1 oget /N oget }
  441.   /Separation { pop 1 }
  442.   /DeviceN { 1 oget length }
  443. .dicttomark readonly def
  444.  
  445. % Perhaps some of the values in the following need to be modified
  446. % depending on the WhitePoint value....
  447. /cslabinit mark
  448.   /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind]
  449.   /MatrixABC [1 1 1 1 0 0 0 0 -1]
  450.   /DecodeLMN [
  451.     {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
  452.      0.9505 mul} bind
  453.     {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
  454.      } bind
  455.     {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
  456.      1.0890 mul} bind
  457.   ]
  458. .dicttomark readonly def
  459.  
  460. /csrdict mark
  461.   /DeviceGray {
  462.     /DefaultGray Page /ColorSpace rget { exch pop resolvecolorspace } if
  463.   }
  464.   /DeviceRGB {
  465.     /DefaultRGB Page /ColorSpace rget { exch pop resolvecolorspace } if
  466.   }
  467.   /DeviceCMYK { }
  468.   /CalGray {
  469.     1 oget 6 dict begin
  470.     dup /Gamma knownoget {
  471.       /exp load 2 packedarray cvx /DecodeA exch def
  472.     } if
  473.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  474.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  475.     pop [ /CIEBasedA currentdict end ]
  476.   }
  477.   /CalRGB {
  478.     1 oget 6 dict begin
  479.     dup /Gamma knownoget {
  480.       [ exch { /exp load 2 packedarray cvx } forall
  481.       ] /DecodeABC exch def
  482.     } if
  483.     dup /Matrix knownoget { /MatrixABC exch def } if
  484.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  485.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  486.     pop [ /CIEBasedABC currentdict end ]
  487.   }
  488.   /CalCMYK {
  489.     pop /DeviceCMYK        % not defined by Adobe
  490.   }
  491.   /Lab {
  492.     1 oget 6 dict begin
  493.     dup /Range knownoget not { [-100 100 -100 100] } if
  494.     [0 100 null null null null] dup 2 4 -1 roll putinterval
  495.     /RangeABC exch def
  496.     //cslabinit { def } forall
  497.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  498.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  499.     pop [ /CIEBasedABC currentdict end ]
  500.   }
  501.   /ICCBased {
  502.     PDFfile fileposition exch
  503.     dup dup 1 oget
  504.     mark exch { oforce } forall .dicttomark
  505.     dup dup true resolvestream
  506.     /ReusableStreamDecode filter /DataSource exch put
  507.     1 exch put
  508.     exch PDFfile exch setfileposition
  509.   } bind
  510.   /Separation {
  511.     aload pop exch oforce resolvecolorspace exch oforce resolvefnproc
  512.     4 array astore
  513.   }
  514.   /DeviceN {
  515.     0 4 getinterval                    % ignore attributes
  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.     % Adobe 2nd edition of the PDF 1.3 spec makes /FormType
  858.     % and /Matrix keys optional. Cope with the missing keys.
  859.   dup length
  860.   1 index /Matrix known
  861.     { dict
  862.     }
  863.     { 1 add dict
  864.       dup /Matrix { 1 0 0 1 0 0 } cvlit put
  865.     }
  866.   ifelse
  867.   copy
  868.   dup /FormType known not {
  869.     dup length 1 add dict copy dup /FormType 1 put
  870.   } if
  871.  
  872.   dup [ 2 index /Resources knownoget { oforce } { 0 dict } ifelse
  873.   3 index false /resolvestream cvx
  874.   /.paintform cvx
  875.   ] cvx /PaintProc exch put
  876.   execform
  877. } bdef
  878.  
  879. /DoPS {
  880.   true resolvestream cvx exec
  881. } bdef
  882.  
  883. drawopdict begin
  884.   /Do {
  885.     setfillblend
  886.     PDFfile fileposition exch
  887.     dup Page /XObject rget { 
  888.       exch pop dup /Subtype get xobjectprocs exch get
  889.         % Don't leave extra objects on the stack while executing
  890.         % the definition of the form.
  891.       3 -1 roll 2 .execn
  892.     } {
  893.         % This should cause an error, but Acrobat Reader can
  894.         % continue, so we do too.
  895.       (%stderr) (w) file
  896.       dup (****************Undefined XObject resource: ) writestring 
  897.       dup 3 -1 roll write===
  898.       flushfile
  899.     } ifelse
  900.     PDFfile exch setfileposition
  901.   } bdef
  902. end
  903.  
  904. % ---------------- In-line images ---------------- %
  905.  
  906. % Undo the abbreviations in an in-line image dictionary.
  907. % Note that we must look inside array values.
  908. % /I is context-dependent.
  909. /unabbrevkeydict mark
  910.   /BPC /BitsPerComponent  /CS /ColorSpace  /D /Decode  /DP /DecodeParms
  911.   /F /Filter  /H /Height  /I /Interpolate  /IM /ImageMask  /W /Width
  912. .dicttomark readonly def
  913. /unabbrevvaluedict mark
  914.   /AHx /ASCIIHexDecode  /A85 /ASCII85Decode  /CC /CalCMYK
  915.   /CCF /CCITTFaxDecode  /CG /CalGray  /CR /CalRGB
  916.   /DCT /DCTDecode  /CMYK /DeviceCMYK  /Fl /FlateDecode
  917.   /G /DeviceGray  /RGB /DeviceRGB
  918.   /I /Indexed  /LZW /LZWDecode  /RL /RunLengthDecode
  919. .dicttomark readonly def
  920. /unabbrevtypedict mark
  921.   /nametype {
  922.     //unabbrevvaluedict 1 index .knownget { exch pop } if
  923.   }
  924.   /arraytype {
  925.     dup 0 1 2 index length 1 sub {
  926.       2 copy get unabbrevvalue put dup
  927.     } for pop
  928.   }
  929. .dicttomark readonly def
  930. /unabbrevvalue {    % <obj> unabbrevvalue <obj'>
  931.   oforce //unabbrevtypedict 1 index type .knownget { exec } if
  932. } bdef
  933.  
  934. drawopdict begin
  935.   /BI { mark } bdef
  936.   /ID {
  937.     counttomark 2 idiv dup 6 add dict begin {
  938.       exch //unabbrevkeydict 1 index .knownget { exch pop } if
  939.       exch unabbrevvalue def
  940.     } repeat pop
  941.     /File PDFsource def
  942.     currentdict makeimagekeys doimage    
  943.     % The Adobe documentation says that the data following ID
  944.     % consists of "lines", and some PDF files (specifically, some files
  945.     % produced by PCL2PDF from Visual Software) contain garbage bytes
  946.     % between the last byte of valid data and an EOL.
  947.         % Some files (PDFOUT v3.8d by GenText) have EI immediately following
  948.         % the stream. Some have no EOL and garbage bytes.
  949.         % Therefore, we skip all bytes before EI or EOL 
  950.     0
  951.       { PDFsource read not { //true exit } if
  952.         dup 10 eq 1 index 13 eq or
  953.           { pop PDFsource token pop /EI ne exit
  954.           }
  955.         if
  956.         exch 69 eq 1 index 73 eq and { //false exit } if  % 'EI'
  957.       }
  958.     loop
  959.     exch pop
  960.       { /ID cvx /syntaxerror signalerror
  961.       }
  962.     if
  963.   } bdef
  964. end
  965.  
  966. % ================================ Text ================================ %
  967.  
  968. drawopdict begin
  969.             % Text control
  970.   /BT { BT } def
  971.   /ET { ET } def
  972.   /Tc { Tc } def
  973.   /TL { TL } def
  974.   /Tr { Tr } def
  975.   /Ts { Ts } def
  976.   /Tw { Tw } def
  977.   /Tz { Tz } def
  978.             % Text positioning
  979.   /Td { Td } def
  980.   /TD { TD } def
  981.   /Tm { Tm } def
  982.   /T* { T* } def
  983.             % Text painting
  984.   /Tj { Tj } def
  985.   /' { ' } def
  986.   /" { " } def
  987.   /TJ { TJ } def
  988. end
  989.  
  990. % ============================== Annotations ============================== %
  991.  
  992.  
  993.  
  994. % Get and normalize an annotation's rectangle.
  995. /annotrect {        % <annot> annotrect <x> <y> <w> <h>
  996.   /Rect get aload pop
  997.   exch 3 index sub dup 0 lt { dup 5 -1 roll add 4 1 roll neg } if
  998.   exch 2 index sub dup 0 lt { dup 4 -1 roll add 3 1 roll neg } if
  999. } bdef
  1000.  
  1001. % Set an annotation color.
  1002. /annotsetcolor {    % <annot> annotsetcolor -
  1003.   /C knownoget { aload pop setrgbcolor } { 0 setgray } ifelse
  1004. } bdef
  1005.  
  1006. % Draw the border.  Currently, we ignore requests for beveling, and we
  1007. % don't round the corners of rectangles.
  1008. /strokeborder {        % <annot> <width> <dash> strokeborder -
  1009.   1 index 0 ne {    % do not draw if border width is 0
  1010.     gsave
  1011.     2 index annotsetcolor
  1012.     0 setdash dup setlinewidth
  1013.     exch annotrect
  1014.     2 { 4 index sub 4 1 roll } repeat
  1015.     2 { 4 index 0.5 mul add 4 1 roll } repeat
  1016.     rectstroke pop
  1017.     grestore
  1018.   } {
  1019.     pop pop pop
  1020.   } ifelse
  1021. } bdef
  1022.  
  1023. % Draw an annotation border.
  1024. /drawborder {        % <annot> drawborder -
  1025.   gsave
  1026.   dup /BS knownoget {
  1027.     dup /W knownoget not { 1 } if
  1028.     [] 2 index /S knownoget {
  1029.       /D eq { 2 index /D knownoget not { [3] } if exch pop } if
  1030.     } if 3 -1 roll pop strokeborder
  1031.   } {
  1032.     dup /Border knownoget {
  1033.       dup 2 get
  1034.       exch dup length 3 gt { 3 get } { pop [] } ifelse
  1035.       strokeborder
  1036.     } {
  1037.       pop
  1038.     } ifelse
  1039.   } ifelse
  1040.   grestore
  1041. } bdef
  1042.  
  1043. %
  1044. %   The PDF annotation F (flags) integer is bit encoded.
  1045. %   Bit 1 (LSB) Invisible:  1 --> Do not display if no handler.
  1046. %         Note:  We have no handlers but we ignore this bit.
  1047. %   Bit 2 Hidden:  1 --> Do not display.  We will not display if this bit is set.
  1048. %   Bit 3 Print:  1 --> Display if printing.  We will display if this bit set
  1049. %         (and not hidden) and Printed is true
  1050. %   Bit 4 NoZoom:  1 --> Do not zoom annotation even if image is zoomed.
  1051. %   Bit 5 NoRotate:  1 --> Do not rotate annotation even if image is rotated.
  1052. %   Bit 6 NoView:  0 --> Display if this is a 'viewer'.  We will display
  1053. %         if this bit is not set (and not hidden) and Printed is false
  1054. %   Bit 7 Read Only - 1 --> No interaction.  We ignore this bit
  1055. %
  1056. /annotvisible {            % <annot> annotvisible <visible>
  1057.   /F knownoget not { 0 } if         % Get flag value
  1058.   dup 2 and 0 eq              % Check hidden flag
  1059.   exch dup 4 and 0 ne Printed and    % Check print flag
  1060.   exch 64 and 0 eq Printed not and    % Check noview flag
  1061.   or                    % Combine print and view
  1062.   and                     % Combine with 'hidden' flag test
  1063. } bdef
  1064.  
  1065. /drawwidget {            % <scalefactor> <annot> drawwidget -
  1066.   dup /AP knownoget {
  1067.     % Always use the Normal appearance.
  1068.     /N oget
  1069.         % Acrobat Distiller produces files in which this Form
  1070.         % XObject lacks Type and Subtype keys.  This is illegal,
  1071.         % but Acrobat Reader accepts it.  The only way we can
  1072.         % tell whether this is a Form or a set of sub-appearances
  1073.         % is by testing for the stream Length key.
  1074.     dup /Length known {
  1075.               % If this is a form then simply use it
  1076.       true
  1077.     } {
  1078.       1 index /AS knownoget not {
  1079.               % If we do not have AS then use any appearance
  1080.     { exch pop oforce exit } forall true
  1081.       } { 
  1082.         % Stack: annot Ndict AS
  1083.         % Get the specified appearance.  If no appearance, then
  1084.         % display nothing - set stack = false.
  1085.     knownoget
  1086.       } ifelse
  1087.     } ifelse
  1088.  
  1089.         % Stack: scale annot appearance true
  1090.         % Stack: scale annot false
  1091.     {
  1092.               % Draw appearance
  1093.       1 index annotrect pop pop translate
  1094.       2 index dup scale        % Apply scale factor
  1095.       DoForm
  1096.     } if
  1097.   } if pop pop
  1098. } bdef
  1099.  
  1100. %
  1101. %  For stamp object we have to determine the size of the output rectangle
  1102. %  and the size of the BBox for the stamp image.  From these we calculate
  1103. %  a scale factor for drawing the stamp.
  1104. %
  1105. /calcstampscale {        % <annot> calcstampscale scale
  1106.   dup annotrect 4 -2 roll pop pop pop    % get x width
  1107.   dup 0 lt { neg } if        % get magnitude
  1108.   exch /AP knownoget {
  1109.     /N knownoget {
  1110.       /BBox knownoget {
  1111.          aload pop 4 -2 roll pop pop pop
  1112.          div
  1113.       } {
  1114.         pop 1            % default to unity scaling
  1115.       } ifelse            % if we have /BBox
  1116.     } {
  1117.       pop 1
  1118.     } ifelse            % if we have /N
  1119.   } {
  1120.     pop 1
  1121.   } ifelse            % if we have /AP
  1122. } bdef
  1123.  
  1124. /drawlink {            % <annot> drawlink -
  1125.   dup drawborder
  1126.   1 exch drawwidget
  1127. } bdef
  1128.  
  1129. % Draw an annotation.
  1130. /drawannottypes mark
  1131.   /Link { drawlink } bind
  1132.   /Stamp { dup calcstampscale exch drawwidget } bind
  1133. .dicttomark readonly def
  1134. /drawannot {        % <annot> drawannot -
  1135.   dup annotvisible {
  1136.     gsave
  1137.     dup dup /Subtype get //drawannottypes exch .knownget {
  1138.       exec
  1139.     } {
  1140.       1 exch drawwidget        % Use drawwidget for everything else
  1141.     } ifelse            % type known
  1142.     grestore
  1143.   } if pop            % annotvisible
  1144. } bdef
  1145. currentdict /drawannottypes undef
  1146.  
  1147. end            % pdfdict
  1148. end            % GS_PDF_ProcSet
  1149. .setglobal
  1150.