home *** CD-ROM | disk | FTP | other *** search
/ jppd.dyndns.org / jppd.dyndns.org.tar / jppd.dyndns.org / QUERYPRO / Impressora_PDF / converter.exe / GPLGS / pdf_ops.ps < prev    next >
Text File  |  2004-09-04  |  21KB  |  657 lines

  1. %    Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: pdf_ops.ps,v 1.27.2.3 2004/09/03 11:07:08 giles Exp $
  14. % Definitions for most of the PDF operators.
  15.  
  16. .currentglobal true .setglobal
  17.  
  18. % Define pdfmark.  Don't allow it to be bound in.
  19. % Also don't define it in systemdict, because this leads some Adobe code
  20. % to think this interpreter is a distiller.
  21. % (If this interpreter really is a distiller, don't do this.)
  22. systemdict /pdfmark known not
  23.  { userdict /pdfmark { cleartomark } bind put } if
  24.  
  25. userdict /GS_PDF_ProcSet 127 dict dup begin
  26.  
  27. % ---------------- Abbreviations ---------------- %
  28.  
  29. /bdef { bind def } bind def
  30.  
  31. % ---------------- Graphics state stack ---------------- %
  32.  
  33. % PDF adds a number of parameters to the graphics state.
  34. % We implement this by pushing and popping a dictionary
  35. % each time we do a PDF gsave or grestore.
  36. % The keys in this dictionary are as follows:
  37. %    self            % identifies the dictionary as one of ours
  38. %    ClipRect        % (optional)
  39. %    Show
  40. %    TextSaveMatrix        % matrix at time of BT (iff within BT/ET)
  41. % (The following correspond directly to PDF state parameters.)
  42. %    AlphaIsShape
  43. %    FillConstantAlpha
  44. %    FillColor
  45. %    FillColorSpace
  46. %    FillOverprint
  47. %    SoftMask
  48. %    StrokeConstantAlpha
  49. %    StrokeColor
  50. %    StrokeColorSpace
  51. %    StrokeOverprint
  52. %    TextSpacing
  53. %    TextHScaling
  54. %    Leading
  55. %    TextFont
  56. %    TextLineMatrix
  57. %    TextMatrix
  58. %    TextRise
  59. %    TextRenderingMode
  60. %    WordSpacing
  61.  
  62. /nodict 1 dict def
  63. nodict /self { //nodict } executeonly put
  64. nodict readonly pop
  65.  
  66. /dictbeginpage {    % <initialdict> dictbeginpage -
  67.   //nodict 20 dict .copydict begin { def } forall
  68.   graphicsbeginpage textbeginpage
  69. } bdef
  70. /endpage {    % - endpage -
  71.   showpage end
  72. } bdef
  73.  
  74. /graphicsbeginpage {
  75.   initgraphics
  76.   currentdict /ClipRect knownoget { aload pop rectclip } if
  77.   0 g  0 G  false op  false OP  0 OPM
  78.   1 ca  1 CA  null SMask  false AIS  /Compatible BM  true TK
  79. } bdef
  80.  
  81. /gput        % <value> <key> gput -
  82.  { exch currentdict //nodict eq { /self dup load end 5 dict begin def } if
  83.         % If we're in a Level 1 system, we need to grow the
  84.         % dictionary explicitly.
  85.    currentdict length currentdict maxlength ge %eq
  86.     { currentdict dup length 3 mul 2 idiv 1 add dict .copydict end begin 
  87.     }
  88.    if def
  89.  } bdef
  90.  
  91. % Restore graphics state, but do not modify path. Paths are not part
  92. % of the PDF graphics state; see 4.4.1 of PDF reference 3rd ed.
  93. /grestore_nopath {
  94.   % Collect the upath with an identity CTM
  95.   { matrix setmatrix //false upath } stopped {
  96.     pop grestore newpath
  97.   } {
  98.     % Save the CTM, set identity during the uappend, then set the CTM
  99.     grestore matrix currentmatrix matrix setmatrix
  100.     exch newpath uappend setmatrix
  101.   } ifelse
  102. } bdef
  103.  
  104. /q {
  105.   gsave //nodict begin
  106. } bdef
  107. % Some PDF files have excess Q operators!
  108. /Q {
  109.   currentdict /self .knownget {
  110.     exec //nodict eq { end grestore_nopath false } { true } ifelse
  111.   } {
  112.     true    % formaterror -- not a gsave dict
  113.   } ifelse
  114.   { (\n   **** File has imbalanced q/Q operators \(too many Q's\) ****\n)
  115.     pdfformaterror
  116.   } if
  117. } bdef
  118.  
  119. % Save PDF gstate
  120. /qstate {       % - qstate <qstate>
  121.   gstate
  122. } bdef
  123.  
  124. % Set PDF gstate
  125. /setqstate {    % <qstate> setqstate -
  126.   { matrix setmatrix //false upath } stopped {
  127.     pop setgstate newpath
  128.   } {
  129.     % Save the CTM, set identity during the uappend, then set the CTM
  130.     exch setgstate matrix currentmatrix matrix setmatrix
  131.     exch newpath uappend setmatrix
  132.   } ifelse
  133. } bdef
  134.  
  135. % ---------------- Color setting ---------------- %
  136.  
  137. /fcput        % <color> <colorspace> fcput -
  138.  { /FillColorSpace gput /FillColor gput
  139.  } bdef
  140. /scput        % <color> <colorspace> scput -
  141.  { /StrokeColorSpace gput /StrokeColor gput
  142.  } bdef
  143.  
  144. /csdevgray [/DeviceGray] readonly def
  145. /csdevrgb [/DeviceRGB] readonly def
  146. /csdevcmyk [/DeviceCMYK] readonly def
  147. /cspattern [/Pattern] readonly def
  148. /nullpattern1 mark
  149.    /PatternType 1 /PaintType 1 /TilingType 3 /BBox [0 0 0 0]
  150.    /XStep 1 /YStep 1 /PaintProc { }
  151. .dicttomark readonly def
  152. /nullpattern2 nullpattern1 dup length dict copy readonly def
  153.  
  154. % Each entry in the color space dictionary is a procedure of the form
  155. %    <cspace> -proc- <cspace> <initial-color>
  156. /CSdict mark
  157.   /DeviceGray { pop //csdevgray 0 } bind
  158.   /DeviceRGB { pop //csdevrgb [0 0 0] cvx } bind
  159.   /DeviceCMYK { pop //csdevcmyk [0 0 0 1] cvx } bind
  160.   /CIEBasedA { 0 } bind
  161.   /CIEBasedABC { [0 0 0] cvx } bind
  162.   /ICCBased { [ 1 index 1 oget /N get { 0 } repeat ] cvx } bind
  163.   /Separation { 1 } bind
  164.   /DeviceN {    % What is the correct value??
  165.     [ 1 index 1 get length { 1 } repeat ] cvx
  166.   } bind
  167.   /Indexed { 0 } bind
  168.   /Pattern {
  169.     dup type /nametype eq 1 index length 1 eq or {
  170.       pop //cspattern //nullpattern1 matrix makepattern
  171.     } {
  172.       //nullpattern2 matrix makepattern 1 index 1 get csset
  173.         % Stack: patternspace nullpattern basecolor basespace
  174.       pop [ 3 1 roll dup type /arraytype eq { aload pop } if
  175.       counttomark -1 roll ] cvx
  176.     } ifelse
  177.   } bind
  178. .dicttomark readonly def
  179. /csset            % <cspace> csset <color> <cspace>
  180.  { dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch
  181.  } bdef
  182.  
  183. /g { //csdevgray fcput } bdef
  184. /G { //csdevgray scput } bdef
  185. /rg { 3 array astore cvx //csdevrgb fcput } bdef
  186. /RG { 3 array astore cvx //csdevrgb scput } bdef
  187. /k { 4 array astore cvx //csdevcmyk fcput } bdef
  188. /K { 4 array astore cvx //csdevcmyk scput } bdef
  189. /cs { csset fcput } bdef
  190. /CS { csset scput } bdef
  191. /ri { pop } bdef
  192. % We have to break up sc according to the number of operands.
  193. /sc1 { /FillColor gput } bdef
  194. /SC1 { /StrokeColor gput } bdef
  195. % We have to avoid storing into a color array associated with an outer
  196. % gsave level, so we do a kind of "copy on write".
  197. /sc* {
  198.   currentdict /FillColor .knownget {
  199.     astore pop
  200.   } {
  201.     /FillColor load length array astore cvx /FillColor gput
  202.   } ifelse
  203. } bdef
  204. /SC* {
  205.   currentdict /StrokeColor .knownget {
  206.     astore pop
  207.   } {
  208.     /StrokeColor load length array astore cvx /StrokeColor gput
  209.   } ifelse
  210. } bdef
  211.  
  212. % ---------------- Overprint/transparency setting ---------------- %
  213.  
  214. /op { /FillOverprint gput } bdef
  215. /OP { /StrokeOverprint gput } bdef
  216. /OPM {
  217.   /.setoverprintmode where { pop .setoverprintmode } { pop } ifelse
  218. } bdef
  219. /ca { /FillConstantAlpha gput } bdef
  220. /CA { /StrokeConstantAlpha gput } bdef
  221. /SMask { /SoftMask gput } bdef
  222. /AIS { /AlphaIsShape gput } bdef
  223. /BM {
  224.   /.setblendmode where {
  225.     pop [ exch dup type /nametype ne { aload pop } if /Normal ] {
  226.       { .setblendmode } .internalstopped not { exit } if pop
  227.     } forall
  228.   } {
  229.     pop
  230.   } ifelse
  231. } bdef
  232. /TK {
  233.   /.settextknockout where { pop .settextknockout } { pop } ifelse
  234. } bdef
  235.  
  236. % ---------------- Color installation ---------------- %
  237.  
  238. % Establish a given color (and color space) as current.
  239. /.settransparencyparams {    % <alpha> <smask> .settransparencyparams -
  240.   /.begintransparencymask where {
  241.     pop AlphaIsShape {
  242.       1 .setopacityalpha 0 .inittransparencymask exch .setshapealpha 1
  243.     } {
  244.       1 .setshapealpha 1 .inittransparencymask exch .setopacityalpha 0
  245.     } ifelse
  246.     % Set the soft mask by rendering the XObject.  Doing this every time
  247.     % is obviously very inefficient; we'll improve it later.
  248.     .settransparencymask    
  249.   } {
  250.     pop pop
  251.   } ifelse
  252. } bdef
  253. /.settransparencymask {        % <paramdict> <masknum> .settransparencymask -
  254.   exch dup null eq {
  255.     pop .inittransparencymask
  256.   } {
  257.     dup /Draw get exec
  258.   } ifelse
  259. } bdef
  260. % (Non-mask) images must execute setfillblend.
  261. /setfillblend {
  262.   FillOverprint setoverprint
  263.   FillConstantAlpha SoftMask .settransparencyparams
  264. } def
  265. /setfillstate {
  266.   FillColor FillColorSpace setgcolor setfillblend
  267. } def
  268. /setstrokestate {
  269.   StrokeColor StrokeColorSpace setgcolor StrokeOverprint setoverprint
  270.   StrokeConstantAlpha SoftMask .settransparencyparams
  271. } def
  272. /Cdict 15 dict dup begin    % <color...> <colorspace> -proc- -
  273.   /DeviceGray { pop setgray } bdef
  274.   /DeviceRGB { pop setrgbcolor } bdef
  275.   /DeviceCMYK { pop setcmykcolor } bdef
  276.   /CIEBasedA { setgcolorspace setcolor } bdef
  277.   /CIEBasedABC /CIEBasedA load def
  278.   /CIEBasedDEF /CIEBasedA load def
  279.   /CIEBasedDEFG /CIEBasedA load def
  280.   /ICCBased /CIEBasedA load def
  281.   /Separation /CIEBasedA load def
  282.   /DeviceN /CIEBasedA load def
  283.   /Indexed /CIEBasedA load def
  284.   /Pattern
  285.    { setgcolorspace
  286.  
  287.      % Since multiple patterns may share
  288.      % same data stream, we need to ensure
  289.      % that the stream is at 0 position.
  290.      % Making this consistently with resolveshading,
  291.      % which applies ReusableStreamDecode filter
  292.      % to the PS stream, which represents the
  293.      % PDF stream in dynamics.
  294.  
  295.      dup /Shading knownoget {
  296.        dup /ShadingType oget 4 ge {
  297.          /DataSource knownoget {
  298.            dup type /filetype eq {
  299.              0 setfileposition
  300.            } {
  301.              pop
  302.            } ifelse
  303.          } if
  304.        } {
  305.         pop
  306.        } ifelse
  307.      } if
  308.  
  309.      dup /Matrix knownoget not { matrix } if
  310.      gsave DefaultQstate setqstate makepattern grestore setcolor
  311.    } bdef
  312. end def
  313. /setgcolor    % (null | <color...>) <colorspace> setgcolor -
  314.  { 1 index null eq
  315.     { pop pop }
  316.     { dup 0 get //Cdict exch get exec }
  317.    ifelse
  318.  } bdef
  319. % Compare the old and new color spaces in an attempt to avoid expensive
  320. % reloads of CIEBased color spaces.
  321. /PCSdict 15 dict dup begin    % <colorspace> -proc- <colorspace|pdfcspace>
  322.   /CIEBasedA { dup 1 get /PDFColorSpace .knownget { exch pop } if } bdef
  323.   /CIEBasedABC /CIEBasedA load def
  324.   /CIEBasedDEF /CIEBasedA load def
  325.   /CIEBasedDEFG /CIEBasedA load def
  326.   /Indexed {
  327.     dup 1 get dup pdfcolorspace 2 copy ne { 3 1 roll } if pop pop
  328.   } bdef
  329. end def
  330. /pdfcolorspace {    % <colorspace> pdfcolorspace <colorspace|pdfcspace>
  331.   dup type /arraytype eq {
  332.     //PCSdict 1 index 0 get .knownget { exec } if
  333.   } if
  334. } bdef
  335. /setgcolorspace {    % <colorspace> setgcolorspace -
  336.   dup pdfcolorspace currentcolorspace pdfcolorspace eq {
  337.     pop
  338.   } {
  339.     setcolorspace
  340.   } ifelse
  341. } bdef
  342. /fsexec        % <fillop|strokeop> fsexec -
  343.  {        % Preserve the current point, if any.
  344.     { currentpoint } stopped
  345.     { $error /newerror false put   cvx exec }
  346.     { 3 -1 roll cvx exec moveto }
  347.    ifelse
  348.  } bdef
  349.  
  350. % ---------------- Path painting and clipping ---------------- %
  351.  
  352. /S { setstrokestate /stroke fsexec } bdef
  353. /f { setfillstate /fill fsexec } bdef
  354. /f* { setfillstate /eofill fsexec } bdef
  355. /n { newpath } bdef        % don't allow n to get bound in
  356. /s { closepath S } bdef
  357. /B { gsave setfillstate fill grestore S } bdef
  358. /b { closepath B } bdef
  359. /B* { gsave setfillstate eofill grestore S } bdef
  360. /b* { closepath B* } bdef
  361.  
  362. % Clipping:
  363.  
  364. /Wdict 4 dict dup begin
  365. /S { gsave setstrokestate stroke grestore n } bdef
  366. /f { gsave setfillstate fill grestore n } bdef
  367. /f* { gsave setfillstate eofill grestore n } bdef
  368. % Adobe PDF Rendering doesn't change clipping if path is 0 area
  369. /n { end pathbbox 3 -1 roll sub abs 3 1 roll sub abs add 0 ne { clip } if newpath } bdef
  370. end readonly def
  371. /W { //Wdict begin } bdef
  372. /W*dict 4 dict dup begin
  373. Wdict { def } forall
  374. % Adobe PDF Rendering doesn't change clipping if path is 0 area
  375. /n { end pathbbox 3 -1 roll sub abs 3 1 roll sub abs add 0 ne { eoclip } if newpath } bdef
  376. end readonly def
  377. /W* { //W*dict begin } bdef
  378.  
  379. % ---------------- Text control ---------------- %
  380.  
  381. /textbeginpage
  382.  { /TextSpacing 0 def        % 0 Tc
  383.    /TextLeading 0 def        % 0 TL
  384.    /TextRenderingMode 0 def    % 0 Tr
  385.    /TextRise 0 def        % 0 Ts
  386.    /WordSpacing 0 def        % 0 Tw
  387.    /TextHScaling 1.0 def    % 100 Tz
  388.    /TextFont null def
  389.    /Show { showfirst } def
  390.  } bdef
  391.  
  392. % Contrary to the statement in the PDF manual, BT and ET *can* be nested,
  393. % if the CharProc for a Type 3 font does a BT/ET itself.
  394. % Since we always call the CharProc inside a q/Q, we simply ensure that
  395. % the text state is saved and restored like the rest of the extended
  396. % graphics state.
  397.  
  398. /settextmatrix {
  399.   TextMatrix concat
  400.   TextHScaling 1 ne { TextHScaling 1 scale } if
  401.   TextRise 0 ne { 0 TextRise translate } if
  402.   TextFont dup null eq { pop } { setfont } ifelse
  403. } bdef
  404. /settextstate {
  405.     % The text state can be set even outside BT/ET.
  406.   currentdict /TextSaveMatrix known {
  407.     TextSaveMatrix setmatrix settextmatrix
  408.   } if
  409. } bdef
  410. /settextposition {
  411.         % Update the TextMatrix translation.
  412.   gsave TextSaveMatrix setmatrix
  413.   currentpoint TextRise sub TextMatrix 4 2 getinterval astore pop
  414.         % We would like to do "grestore currentpoint translate"
  415.         % here, but some PDF files set a singular text matrix
  416.         % (0 0 0 0 <x> <y> Tm), so we can't do this.
  417.   TextTempMatrix identmatrix setmatrix currentpoint
  418.   grestore
  419.   TextTempMatrix currentmatrix 4 2 getinterval astore pop
  420.   TextTempMatrix setmatrix
  421. } bdef
  422.  
  423. /BT {
  424.   currentdict /TextLineMatrix .knownget
  425.     { identmatrix pop TextMatrix identmatrix pop }
  426.     { matrix /TextLineMatrix gput matrix /TextMatrix gput }
  427.   ifelse
  428.   { showfirst } /Show gput
  429.   currentdict /TextSaveMatrix .knownget not {
  430.     matrix dup /TextSaveMatrix gput
  431.   } if currentmatrix pop settextmatrix
  432.   matrix /TextTempMatrix gput        % see settextposition
  433. } bdef
  434. /ET {
  435.   TextRenderingMode 4 ge { clip newpath } if
  436.   TextSaveMatrix setmatrix
  437.   currentdict /TextSaveMatrix undef
  438. } bdef
  439. /Tc { /TextSpacing gput { showfirst } /Show gput } bdef
  440. /TL { /TextLeading gput } bdef
  441. /Tr { dup .settextrenderingmode /TextRenderingMode gput { showfirst } /Show gput } bdef
  442. /Ts { /TextRise gput settextstate } bdef
  443. /Tw { /WordSpacing gput { showfirst } /Show gput } bdef
  444. /Tz { 100 div /TextHScaling gput settextstate} bdef
  445.  
  446. % ---------------- Font control ---------------- %
  447.  
  448. /Tf {        % <font> <scale> Tf -
  449.   dup 0 eq {
  450.     (\n   **** Warning: Invalid 0.0 font scale given for Tf ****\n)
  451.     pdfformaterror
  452.     pop 0.00000001    % handle invalid scale by using a really small value
  453.   } if
  454.   dup 1 eq { pop } { scalefont } ifelse
  455.   /TextFont gput settextstate
  456. } bdef
  457.  
  458. % Read a CFF font.
  459. /FRD        % <resname> <file> FRD -
  460.  { /FontSetInit /ProcSet findresource begin //true ReadData
  461.  } bdef
  462.  
  463. % Copy a font, removing its FID.  If changed is true, also remove
  464. % the UniqueID and XUID, if any.  If the original dictionary doesn't have
  465. % the keys being removed, don't copy it.
  466. /.copyfontdict        % <font> <changed> .copyfontdict <dict>
  467.  { 1 index /FID known
  468.    1 index { 2 index /UniqueID known or 2 index /XUID known or } if
  469.     {        % We add 1 to the length just in case the original
  470.         % didn't have a FID.
  471.       exch dup length 1 add dict exch
  472.        {        % Stack: changed newfont key value
  473.      1 index /FID eq 4 index
  474.       { 2 index /UniqueID eq or 2 index /XUID eq or }
  475.      if not { 3 copy put } if pop pop
  476.        }
  477.       forall exch
  478.     }
  479.    if pop
  480.  } bdef
  481.  
  482. % Insert a new Encoding or Metrics into a font if necessary.
  483. % Return a possibly updated font, and a flag to indicate whether
  484. % the font was actually copied.
  485. /.updatefontmetrics {    % <font> <Metrics|null> .updatefontmetrics
  486.             %   <font'> <copied>
  487.   dup //null ne {
  488.     exch //true .copyfontdict dup /Metrics 4 -1 roll put //true
  489.   } {
  490.     pop //false
  491.   } ifelse
  492. } bdef
  493.  
  494. /.updatefontencoding {    % <font> <Encoding|null> .updatefontencoding
  495.             %   <font'> <copied>
  496.   dup //null ne { dup 2 index /Encoding get ne } { //false } ifelse {
  497.     exch //false .copyfontdict dup /Encoding 4 -1 roll put //true
  498.   } {
  499.     pop //false
  500.   } ifelse
  501. } bdef
  502.  
  503. % Duplicate keys in CharString dictionary according to GlyphMap: <</new_glyph /old_glyph>>
  504. % We have to do this because PDF fonts can associate multiple widths with the same glyph
  505. % but Metrics dictionary works by the glyph name.
  506. /.update_charstring {    % <font> <GlyphMap> .update_charstring  <font'> <copied>
  507.   dup //null ne {
  508.     exch //true .copyfontdict       % map font
  509.     dup dup /CharStrings get        % map font font cstr
  510.     dup length                      % map font font cstr len
  511.     4 index length add              % map font font cstr len+map_len
  512.     dict copy dup begin             % map font font cstr'
  513.     /CharStrings exch put           % map font
  514.     exch {                          % font /new /old
  515.       load def
  516.     } forall
  517.     end //true
  518.   } {
  519.     pop //false
  520.   } ifelse
  521. } bdef
  522.  
  523. /.updatefont {          % <font> <Encoding|null> <Metrics|null> <GlyphMap|null>
  524.                       %        .updatefont <font'> <copied>
  525.   4 2 roll            % <Metrics|null> <GlyphMap> <font> <Encoding|null>
  526.   .updatefontencoding % <Metrics|null> <GlyphMap> <font> bool
  527.   4 1 roll exch       % bool <Metrics|null> <font> <GlyphMap>
  528.   .update_charstring  % bool <Metrics|null> <font> bool
  529.   3 1 roll exch       % bool bool <font> <Metrics|null>
  530.   .updatefontmetrics  % bool bool <font> bool
  531.   4 2 roll or or      % <font> is_copied
  532. } bdef
  533.  
  534. % ---------------- Text positioning ---------------- %
  535.  
  536. /Td {
  537.   TextLineMatrix transform TextLineMatrix 4 2 getinterval astore pop
  538.   TextLineMatrix TextMatrix copy pop settextstate
  539. } bdef
  540. /TD { dup neg /TextLeading gput Td } bdef
  541. /T* { 0 TextLeading neg Td } bdef
  542. /Tm {
  543.   TextLineMatrix astore TextMatrix copy pop settextstate
  544. } bdef
  545.  
  546. % ---------------- Text painting ---------------- %
  547.  
  548. /Vexch {
  549.   rootfont /WMode knownoget { 1 eq { exch } if } if
  550. } bind def
  551.  
  552. /textrenderingprocs [        % (0 is handled specially)
  553.     % Painting-only modes
  554.    { tf } { tS } { tB } { tn }
  555.     % Clipping modes
  556.    { gsave tf grestore tW }
  557.    { gsave tS grestore tW }
  558.    { gsave tB grestore tW }
  559.    { tW }
  560. ] readonly def
  561. /setshowstate
  562.  { WordSpacing 0 eq TextSpacing 0 eq and
  563.     { TextRenderingMode 0 eq {
  564.         { setfillstate show }
  565.       } {
  566.         TextRenderingMode 3 eq {
  567.                 % Some PDF files execute 'tm' with a singular matrix,
  568.         % and then use the text rendering mode 3.
  569.         % The graphics library currently cannot handle text
  570.         % operations when the CTM is singular.
  571.         % Work around this here.
  572.       {    
  573.             matrix currentmatrix dup
  574.             dup 0 get 0 eq 1 index 1 get 0 eq and {
  575.               dup 0 1 put
  576.             } if
  577.             dup 2 get 0 eq 1 index 3 get 0 eq and {
  578.               dup 3 1 put
  579.             } if
  580.             setmatrix
  581.             exch setfillstate show % Tr was set to graphic state.
  582.             setmatrix 
  583.           }
  584.         } {
  585.           { false charpath textrenderingprocs TextRenderingMode get exec }
  586.         } ifelse
  587.       } ifelse
  588.     }
  589.     { TextRenderingMode 0 eq TextRenderingMode 3 eq or
  590.        % Tr was set to graphic state.
  591.        { WordSpacing 0 eq
  592.           { { setfillstate TextSpacing 0 Vexch 3 -1 roll ashow } }
  593.       { TextSpacing 0 eq
  594.             { { setfillstate WordSpacing 0 Vexch 32 4 -1 roll widthshow } }
  595.             { { setfillstate WordSpacing 0 Vexch 32
  596.                  TextSpacing 0 Vexch 6 -1 roll awidthshow } }
  597.         ifelse
  598.       }
  599.      ifelse
  600.        }
  601.        { { WordSpacing TextSpacing
  602.             % Implement the combination of t3 and false charpath.
  603.             % Note that we must use cshow for this, because we
  604.             % can't parse multi-byte strings any other way.
  605.             % Stack: string xword xchar
  606.         { pop pop (x) dup 0 3 index put false charpath
  607.             % Stack: xword xchar ccode
  608.              3 copy 32 eq { add } { exch pop } ifelse 0 Vexch rmoveto pop
  609.         }
  610.        4 -1 roll cshow pop pop
  611.        textrenderingprocs TextRenderingMode get exec
  612.      }
  613.        }
  614.       ifelse
  615.     }
  616.    ifelse /Show gput
  617.  } bdef
  618. /showfirst { setshowstate Show } def
  619.  
  620. /Tj {
  621.   0 0 moveto Show settextposition
  622. } bdef
  623. /' { T* Tj } bdef
  624. /" { exch Tc exch Tw T* Tj } bdef
  625. /TJ {
  626.   0 0 moveto {
  627.     dup type /stringtype eq {
  628.       Show
  629.     } { -1000 div
  630.       currentfont /ScaleMatrix .knownget { 0 get mul } if
  631.       0 Vexch rmoveto
  632.     } ifelse
  633.   } forall settextposition
  634. } bdef
  635.  
  636. /tf { setfillstate currentpoint fill moveto } bdef
  637. /tn { currentpoint newpath moveto } bdef % Obsolete, never used.
  638. % For stroking characters, temporarily restore the graphics CTM so that
  639. % the line width will be transformed properly.
  640. /Tmatrix matrix def
  641. /tS
  642.  { setstrokestate
  643.    currentpoint //Tmatrix currentmatrix TextSaveMatrix setmatrix stroke
  644.    setmatrix moveto
  645.  } bdef
  646. /tB { gsave tf grestore tS } bdef
  647. % This does the wrong thing if there have been multiple text operations
  648. % within a single BT/ET pair, but it's a start.
  649. /tW { } bdef
  650.  
  651. end readonly put        % GS_PDF_ProcSet
  652.  
  653. .setglobal
  654.