home *** CD-ROM | disk | FTP | other *** search
/ Mixa 155: Dogs / MIXA 155: Dogs.iso / pc / Viewer / BROWSER(W) / フィルタ / PDF / LIB / pdf_draw.ps < prev    next >
Encoding:
Text File  |  2002-10-29  |  33.5 KB  |  1,134 lines

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