home *** CD-ROM | disk | FTP | other *** search
/ swCHIP 1991 January / swCHIP_95-1.bin / utility / gs333ini / gs3.33 / pdf_draw.ps < prev    next >
Text File  |  1995-12-09  |  12KB  |  447 lines

  1. %    Copyright (C) 1994, 1995 Aladdin Enterprises.  All rights reserved.
  2.  
  3. % pdf_draw.ps
  4. % PDF drawing operations (graphics, text, and images).
  5.  
  6. % We don't handle the following PDF elements yet (identified by
  7. % page number in the reference manual):
  8. %    style strings (63-64), except in a few known fonts
  9. %    font descriptor resources (71-75), except for MissingWidth
  10. %    text clipping modes (104)
  11. %        What do these mean??
  12.  
  13. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  14. .currentglobal true .setglobal
  15. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  16. GS_PDF_ProcSet begin
  17. pdfdict begin
  18.  
  19. % For simplicity, we use a single interpretation dictionary for all
  20. % PDF graphics operations, even though this is too liberal.
  21. /drawopdict 100 dict def
  22.  
  23. % ================================ Graphics ================================ %
  24.  
  25. % PDF adds a number of parameters to the graphics state.
  26. % We implement this by pushing and popping a dictionary
  27. % each time we do a PDF gsave or grestore.
  28. % The keys in this dictionary are as follows:
  29. %    Show
  30. %    TextOrigin        % origin of current line, in text space
  31. % (The following correspond directly to PDF state parameters.)
  32. %    FillColor
  33. %    StrokeColor
  34. %    TextSpacing
  35. %    TextHScaling
  36. %    Leading
  37. %    TextFont
  38. %    TextMatrix
  39. %    TextRise
  40. %    TextRenderingMode
  41. %    WordSpacing
  42.  
  43. % ---------------- Graphics state management ---------------- %
  44.  
  45. /nodict 0 dict def
  46. /gput        % <value> <key> gput -
  47.  { currentdict //nodict eq { end 2 dict begin } if
  48.    exch def
  49.  } bdef
  50. /beginpage
  51.  { 2 dict dup begin /BottomDict exch def graphicsbeginpage textbeginpage
  52.  } bdef
  53. /endpage { end } bdef
  54.  
  55. /pdfgsave { gsave //nodict begin } bdef
  56. /pdfgrestore { currentdict BottomDict ne { end grestore } if } bdef
  57. drawopdict begin
  58.   /q { q //nodict begin } bdef
  59.   /Q { currentdict BottomDict ne { end Q } if } bdef
  60. end
  61.  
  62. % ---------------- Graphics state setting ---------------- %
  63.  
  64. /graphicsbeginpage
  65.  { initgraphics
  66.    0 /FillColor gput
  67.    0 /StrokeColor gput
  68.  } bdef
  69. % Patch around a bug in setdash (it won't accept packed arrays).
  70. /setdash
  71.  { 1 index type /packedarraytype eq { exch copyarray exch } if setdash
  72.  } bdef
  73.  
  74. /cmmatrix matrix def
  75. /cm#
  76.  {    % See if we can represent the transformation as
  77.     % a translation and/or scale operation.
  78.    4 index 0 eq 4 index 0 eq and
  79.     {        % a 0 0 d e f
  80.       dup 0 eq 2 index 0 eq and { pop pop } { ct } ifelse
  81.       exch pop exch pop
  82.       dup 1 eq 2 index 1 eq and { pop pop } { cs } ifelse
  83.     }
  84.     { //cmmatrix astore cvx cm
  85.     }
  86.    ifelse
  87.  } bdef
  88. drawopdict begin
  89.   /cm { cm# } bdef
  90.   /i { dup currentflat eq { pop } { i } ifelse } def
  91.   /J { dup currentlinecap eq { pop } { J } ifelse } def
  92.   /d { d } def
  93.   /j { dup currentlinejoin eq { pop } { j } ifelse } def
  94.   /w { dup currentlinewidth eq { pop } { w } ifelse } def
  95.   /M { dup currentmiterlimit eq { pop } { M } ifelse } def
  96.   /g { /FillColor gput } bdef
  97.   /rg { 3 packedarray /FillColor gput } bdef
  98.   /k { 4 packedarray /FillColor gput } bdef
  99.   /G { /StrokeColor gput } bdef
  100.   /RG { 3 packedarray /StrokeColor gput } bdef
  101.   /K { 4 packedarray /StrokeColor gput } bdef
  102. end
  103.  
  104. % ---------------- Paths ---------------- %
  105.  
  106. drawopdict begin
  107.   /m { m } def
  108.   /l { l } def
  109.   /c { c } def
  110.   /v { v } def
  111.   /y { y } def
  112.   /re { re } def
  113.   /h { h } def
  114. end
  115.  
  116. /setfillcolor { FillColor setgcolor } def
  117. /setstrokecolor { StrokeColor setgcolor } def
  118. /setgcolor    % (null | <gray> | [<r><g><b>/rg] | [<c><m><y><k>/k]) setgcolor -
  119.  { dup type /packedarraytype ne
  120.     { dup null eq
  121.        { pop
  122.        }
  123.        { currentcolorspace 0 get /DeviceGray eq currentgray 2 index eq and
  124.       { pop }
  125.       { g }
  126.      ifelse
  127.        }
  128.       ifelse
  129.     }
  130.     { dup length 3 eq
  131.        { aload pop currentcolorspace 0 get /DeviceRGB ne
  132.       { rg }
  133.       { currentrgbcolor 3 index eq exch 4 index eq and exch 4 index eq and
  134.          { pop pop pop }
  135.          { rg }
  136.         ifelse
  137.       }
  138.      ifelse
  139.        }
  140.        { aload pop currentcolorspace 0 get /DeviceCMYK ne
  141.       { k }
  142.       { currentcmykcolor 4 index eq exch 5 index eq and
  143.         exch 5 index eq and exch 5 index eq and
  144.          { pop pop pop pop }
  145.          { k }
  146.         ifelse
  147.       }
  148.      ifelse
  149.        }
  150.       ifelse
  151.     }
  152.    ifelse
  153.  } bdef
  154. /fs        % <fillop|strokeop> fs -
  155.  {        % Preserve the current point, if any.
  156.     { currentpoint } stopped
  157.     { cvx exec }
  158.     { pop pop p 3 -1 roll cvx exec m }
  159.    ifelse
  160.  } bdef
  161. /fillstroke    % <fillop> <strokeop> <fillstrokeop> fillstroke -
  162.  { FillColor StrokeColor eq
  163.     { fs pop pop }
  164.     { pop q setfillcolor exch 0 # Q fs }
  165.    ifelse
  166.  } bdef
  167.  
  168. drawopdict begin
  169.   /n { n } def
  170.   /S { setstrokecolor /S fs } def
  171.   /s { setstrokecolor /s fs } def
  172.   /f { setfillcolor /f fs } def
  173.   /f* { setfillcolor /f* fs } def
  174.   /B { /fill /S /B fillstroke } def
  175.   /b { /fill /s /b fillstroke } def
  176.   /B* { /eofill /S /B* fillstroke } def
  177.   /b* { /eofill /s /b* fillstroke } def
  178. % Clipping is done after the next painting operator.
  179. % The ProcSet handles this.
  180.   /W { W } def
  181.   /W* { W* } def
  182. end
  183.  
  184. % ---------------- XObjects ---------------- %
  185.  
  186. /xobjectprocs mark        % <dict> -proc- -
  187.   /Image { DoImage }
  188.   /Form { DoForm }
  189. .dicttomark readonly def
  190.  
  191. /ncompdict mark
  192.   /DeviceGray 1
  193.   /DeviceRGB 3
  194.   /DeviceCMYK 4
  195. .dicttomark readonly def
  196. /resolvecolorspace    % <cspace> resolvecolorspace <cspace>
  197.  { dup type /arraytype eq
  198.     { dup 0 get /Indexed eq
  199.        { dup 3 oget dup type /stringtype eq
  200.       { pop
  201.       }
  202.       {    % The color lookup table is a stream.
  203.         % Get its contents.
  204.         true resolvestream
  205.         1 index 2 get 1 add
  206.         ncompdict 3 index 1 get get mul
  207.         string readstring pop
  208.         1 index 3 3 -1 roll put
  209.       }
  210.      ifelse
  211.        }
  212.       if
  213.     }
  214.    if
  215.  } bdef
  216. /DoImage
  217.  { dup /ColorSpace knownoget
  218.     { resolvecolorspace
  219.       dup type /arraytype eq { dup length 1 eq { 0 get } if } if
  220.       exch
  221.     } if
  222.    dup length 1 sub dict begin
  223.    /ImageType 1 def
  224.         % Always define ImageMask appropriately.
  225.    dup /ImageMask knownoget dup { and } if
  226.      /ImageMask exch def
  227.    /Width 2 copy oget def
  228.    /Height 2 copy oget def
  229.    /BitsPerComponent 2 copy oget def
  230.    /Decode 2 copy knownoget not
  231.     {        % Decode is required for the PostScript image operators.
  232.       ImageMask
  233.        { [0 1]
  234.        }
  235.        { 2 index dup type /arraytype eq { 0 get } if dup /Indexed eq
  236.       { pop 2 index 2 get 0 exch 2 array astore }
  237.       { ncompdict exch get [ exch {0 1} repeat ] }
  238.      ifelse
  239.        }
  240.       ifelse
  241.     }
  242.    if def
  243.    /Interpolate 2 copy knownoget { def } { pop } ifelse
  244.    /ImageMatrix Width 0 0 Height neg 0 Height 6 array astore def
  245.         % Define DataSource as the width of the row buffer,
  246.         % which is what is needed if we're writing PostScript.
  247.    /DataSource 
  248.      Width BitsPerComponent mul
  249.      mark currentcolor counttomark dup 2 add 1 roll cleartomark mul
  250.      7 add 8 idiv
  251.    def
  252.         % Even though we're going to read data,
  253.         % pass false to resolvestream so that
  254.         % it doesn't try to use Length (which may not be present).
  255.    false resolvestream /Is_stream exch store
  256.    ImageMask currentdict end
  257.    exch { Im } { I } ifelse
  258.  } bdef
  259. % Rebind Is, which constructs the data source for the image,
  260. % to retrieve the stream.
  261. userdict /Is_stream null put
  262. /Is
  263.  { Is_stream
  264.  } bdef
  265.  
  266. /DoForm
  267.  { dup [ /pop load 2 index
  268.     { false resolvestream pdfopdict pdfrun }
  269.    aload pop ] cvx /PaintProc exch put
  270.    execform
  271.  } bdef
  272.  
  273. drawopdict begin
  274.   /Do
  275.     { PDFfile fileposition exch
  276.       Page /Resources oget /XObject oget exch oget
  277.       dup /Subtype get xobjectprocs exch get exec
  278.       PDFfile exch setfileposition
  279.     } bdef
  280. end
  281.  
  282. % ---------------- In-line images ---------------- %
  283.  
  284. % Undo the abbreviations in an in-line image dictionary.
  285. % Note that these can appear as keys, values, or members of array values.
  286. % /I is ambiguous; we check specially for it below.
  287. /unabbrevdict mark
  288.     % Top-level dictionary keys
  289.   /BPC /BitsPerComponent  /CS /ColorSpace  /D /Decode  /DP /DecodeParms
  290.   /F /Filter  /H /Height  /IM /ImageMask  /W /Width
  291.     % Values
  292.   /AHx /ASCIIHexDecode  /A85 /ASCII85Decode  /CCF /CCITTFaxDecode
  293.   /DCT /DCTDecode  /CMYK /DeviceCMYK  /G /DeviceGray  /RGB /DeviceRGB
  294.   /I /Indexed  /LZW /LZWDecode  /RL /RunLengthDecode
  295. .dicttomark readonly def
  296. /unabbrev        % <obj> unabbrev <obj'>
  297.  { dup type /nametype eq
  298.     { unabbrevdict 1 index .knownget { exch pop } if
  299.     }
  300.     { dup type /arraytype eq
  301.        { dup 0 1 2 index length 1 sub
  302.       { 2 copy get unabbrev put dup
  303.       }
  304.      for pop
  305.        }
  306.       if
  307.     }
  308.    ifelse
  309.  } bdef
  310.  
  311. drawopdict begin
  312.   /BI { mark } bdef
  313.   /ID
  314.     { counttomark
  315.        { counttomark 1 roll
  316.      dup /I eq { pop /Interpolate } { unabbrev } ifelse
  317.        }
  318.       repeat
  319.       /File PDFsource
  320.       .dicttomark DoImage
  321.       PDFsource token pop /EI ne { /ID cvx /syntaxerror signalerror } if
  322.     } bdef
  323. end
  324.  
  325. % ================================ Text ================================ %
  326.  
  327. % ---------------- Text state ---------------- %
  328.  
  329. /textbeginpage
  330.  { /TextSpacing 0 def        % 0 Tc
  331.    /TextLeading 0 def        % 0 TL
  332.    /TextRenderingMode 0 def    % 0 Tr
  333.    /TextRise 0 def        % 0 Ts
  334.    /WordSpacing 0 def        % 0 Tw
  335.    /TextHScaling 1.0 def    % 100 Tz
  336.    /TextFont NullFont def
  337.    /Show { showfirst } def
  338.  } bdef
  339. /textrenderingprocs [
  340.    { setfillcolor tf }        % handled specially
  341.    { setstrokecolor tS }
  342.    { /tf /tS /tB fillstroke }
  343.    { tn }
  344.     % We don't know what the clipping modes mean....
  345.    4 copy
  346. ] readonly def
  347. /setshowstate
  348.  { /Show WordSpacing 0 eq TextSpacing 0 eq and
  349.     { TextRenderingMode 0 eq
  350.        { { setfillcolor t } }
  351.        { { T textrenderingprocs TextRenderingMode get exec } }
  352.       ifelse
  353.     }
  354.     { TextRenderingMode 0 eq
  355.        { WordSpacing 0 eq
  356.           { { setfillcolor TextSpacing exch t1 } }
  357.       { TextSpacing 0 eq
  358.          { { setfillcolor WordSpacing exch t2 } }
  359.          { { setfillcolor WordSpacing exch TextSpacing exch t3 } }
  360.         ifelse
  361.       }
  362.      ifelse
  363.        }
  364.        { { WordSpacing TextSpacing 2 index T3
  365.        textrenderingprocs TextRenderingMode get exec
  366.      }
  367.        }
  368.       ifelse
  369.     }
  370.    ifelse def
  371.  } bdef
  372. /showfirst { setshowstate Show } def
  373. /settextmatrix
  374.  { TextMatrix aload pop cm#
  375.    TextHScaling 1 ne { TextHScaling 1 cs } if
  376.    TextRise 0 ne { 0 TextRise ct } if
  377.  } bdef
  378. /settextstate { ti settextmatrix } bdef
  379. /begintext
  380.  { currentdict /TextMatrix .knownget
  381.     { identmatrix pop }
  382.     { matrix /TextMatrix gput }
  383.    ifelse
  384.    currentdict /TextOrigin .knownget
  385.     { dup 0 0 put 1 0 put }
  386.     { [0 0] cvx /TextOrigin gput }
  387.    ifelse
  388.    /Show { showfirst } def
  389.    BT settextmatrix TextFont setfont 0 0 moveto
  390.  } bdef
  391. /endtext
  392.  { ET
  393.  } bdef
  394.  
  395. /Tc { /TextSpacing gput /Show { showfirst } def } bdef
  396. /Tw { /WordSpacing gput /Show { showfirst } def } bdef
  397. drawopdict begin
  398.   /BT /begintext load def
  399.   /ET /endtext load def
  400.   /Tc /Tc load def
  401.   /TL { /TextLeading gput } bdef
  402.   /Tr { /TextRenderingMode gput /Show { showfirst } def } bdef
  403.   /Ts { /TextRise gput settextstate } bdef
  404.   /Tw /Tw load def
  405.   /Tz { 100 div /TextHScaling gput settextstate } bdef
  406. end
  407.  
  408. % ---------------- Text positioning ---------------- %
  409.  
  410. /Td
  411.  { TextOrigin exch 4 -1 roll add 3 1 roll add
  412.    2 copy /TextOrigin load astore pop m
  413.  } bdef
  414. /T*
  415.  { 0 TextLeading neg Td
  416.  } bdef
  417. drawopdict begin
  418.   /Td /Td load def
  419.   /TD { dup neg /TextLeading gput Td } bdef
  420.   /Tm
  421.    { TextMatrix astore pop settextstate
  422.      0 0 /TextOrigin load astore pop
  423.      z
  424.    } bdef
  425.   /T* /T* load def
  426. end
  427.  
  428. % ---------------- Text painting ---------------- %
  429.  
  430. drawopdict begin
  431.   /Tj /Show cvx def
  432.   /' { T* Show } bdef
  433.   /" { exch Tc exch Tw T* Show } bdef
  434.   /TJ
  435.    {  { dup type /stringtype eq
  436.      { Show }
  437.      { neg 1000 div x }    % probably wrong
  438.     ifelse
  439.       }
  440.      forall
  441.    } bdef
  442. end
  443.  
  444. end            % pdfdict
  445. end            % GS_PDF_ProcSet
  446. .setglobal
  447.