home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Updates / GhostScript / !GhostScr / 6_01 / lib / pdf_ops.ps < prev    next >
Text File  |  2000-03-29  |  13KB  |  414 lines

  1. %    Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % $Id: pdf_ops.ps,v 1.2 2000/03/10 03:57:03 lpd Exp $
  16. % Definitions for most of the PDF operators.
  17.  
  18. .currentglobal true .setglobal
  19.  
  20. % Define pdfmark.  Don't allow it to be bound in.
  21. % Also don't define it in systemdict, because this leads some Adobe code
  22. % to think this interpreter is a distiller.
  23. % (If this interpreter really is a distiller, don't do this.)
  24. systemdict /pdfmark known not
  25.  { userdict /pdfmark { cleartomark } bind put } if
  26.  
  27. userdict /GS_PDF_ProcSet 127 dict dup begin
  28.  
  29. % ---------------- Abbreviations ---------------- %
  30.  
  31. /bdef { bind def } bind def
  32.  
  33. % ---------------- Graphics state stack ---------------- %
  34.  
  35. % PDF adds a number of parameters to the graphics state.
  36. % We implement this by pushing and popping a dictionary
  37. % each time we do a PDF gsave or grestore.
  38. % The keys in this dictionary are as follows:
  39. %    self            % identifies the dictionary as one of ours
  40. %    Show
  41. %    TextSaveMatrix        % matrix at time of BT
  42. % (The following correspond directly to PDF state parameters.)
  43. %    FillColor
  44. %    FillColorSpace
  45. %    StrokeColor
  46. %    StrokeColorSpace
  47. %    TextSpacing
  48. %    TextHScaling
  49. %    Leading
  50. %    TextFont
  51. %    TextLineMatrix
  52. %    TextMatrix
  53. %    TextRise
  54. %    TextRenderingMode
  55. %    WordSpacing
  56.  
  57. /nodict 1 dict def
  58. nodict /self { //nodict } executeonly put
  59. nodict readonly pop
  60.  
  61. /beginpage
  62.  { //nodict 20 dict .copydict begin graphicsbeginpage textbeginpage
  63.  } bdef
  64. /endpage
  65.  { showpage end
  66.  } bdef
  67.  
  68. /graphicsbeginpage { initgraphics  0 g  0 G } bdef
  69.  
  70. /gput        % <value> <key> gput -
  71.  { exch currentdict //nodict eq { /self dup load end 5 dict begin def } if
  72.         % If we're in a Level 1 system, we need to grow the
  73.         % dictionary explicitly.
  74.    currentdict length currentdict maxlength ge %eq
  75.     { currentdict dup length 3 mul 2 idiv 1 add dict .copydict end begin 
  76.     }
  77.    if def
  78.  } bdef
  79.  
  80. /q {
  81.   gsave //nodict begin
  82. } bdef
  83. % Some PDF files have excess Q operators!
  84. /Q {
  85.   currentdict /self .knownget { exec //nodict eq { end grestore } if } if
  86. } bdef
  87.  
  88. % ---------------- Color setting ---------------- %
  89.  
  90. /fcput        % <color> <colorspace> fcput -
  91.  { /FillColorSpace gput /FillColor gput
  92.  } bdef
  93. /scput        % <color> <colorspace> scput -
  94.  { /StrokeColorSpace gput /StrokeColor gput
  95.  } bdef
  96.  
  97. /csdevgray [/DeviceGray] readonly def
  98. /csdevrgb [/DeviceRGB] readonly def
  99. /csdevcmyk [/DeviceCMYK] readonly def
  100. /cspattern [/Pattern] readonly def
  101. /nullpattern1 mark
  102.    /PatternType 1 /PaintType 1 /TilingType 3 /BBox [0 0 0 0]
  103.    /XStep 1 /YStep 1 /PaintProc { }
  104. .dicttomark readonly def
  105. /nullpattern2 nullpattern1 dup length dict copy readonly def
  106.  
  107. % Each entry in the color space dictionary is a procedure of the form
  108. %    <cspace> -proc- <cspace> <initial-color>
  109. /CSdict mark
  110.   /DeviceGray { pop //csdevgray 0 } bind
  111.   /DeviceRGB { pop //csdevrgb [0 0 0] cvx } bind
  112.   /DeviceCMYK { pop //csdevcmyk [0 0 0 1] cvx } bind
  113.   /CIEBasedA { 0 } bind
  114.   /CIEBasedABC { [0 0 0] cvx } bind
  115.   /Separation { 1 } bind
  116.   /DeviceN {    % What is the correct value??
  117.     [ 1 index 1 get length { 1 } repeat ] cvx
  118.   } bind
  119.   /Indexed { 0 } bind
  120.   /Pattern {
  121.     dup type /nametype eq 1 index length 1 eq or {
  122.       pop //cspattern //nullpattern1 matrix makepattern
  123.     } {
  124.       //nullpattern2 matrix makepattern 1 index 1 get csset
  125.         % Stack: patternspace nullpattern basecolor basespace
  126.       pop [ 3 1 roll dup type /arraytype eq { aload pop } if
  127.       counttomark -1 roll ] cvx
  128.     } ifelse
  129.   } bind
  130. .dicttomark readonly def
  131. /csset            % <cspace> csset <color> <cspace>
  132.  { dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch
  133.  } bdef
  134.  
  135. /g { //csdevgray fcput } bdef
  136. /G { //csdevgray scput } bdef
  137. /rg { 3 array astore cvx //csdevrgb fcput } bdef
  138. /RG { 3 array astore cvx //csdevrgb scput } bdef
  139. /k { 4 array astore cvx //csdevcmyk fcput } bdef
  140. /K { 4 array astore cvx //csdevcmyk scput } bdef
  141. /cs { csset fcput } bdef
  142. /CS { csset scput } bdef
  143. /ri { pop } bdef
  144. % We have to break up sc according to the number of operands.
  145. /sc1 { /FillColor gput } bdef
  146. /SC1 { /StrokeColor gput } bdef
  147. /sc* { /FillColor load astore pop } bdef
  148. /SC* { /StrokeColor load astore pop } bdef
  149.  
  150. % ---------------- Color installation ---------------- %
  151.  
  152. % Establish a given color (and color space) as current.
  153. /setfillcolor { FillColor FillColorSpace setgcolor } def
  154. /setstrokecolor { StrokeColor StrokeColorSpace setgcolor } def
  155. /Cdict 15 dict dup begin    % <color...> <colorspace> -proc- -
  156.   /DeviceGray { pop setgray } bdef
  157.   /DeviceRGB { pop setrgbcolor } bdef
  158.   /DeviceCMYK { pop setcmykcolor } bdef
  159.   /CIEBasedA
  160.    { dup currentcolorspace eq { pop } { setcolorspace } ifelse setcolor } bdef
  161.   /CIEBasedABC /CIEBasedA load def
  162.   /CIEBasedDEF /CIEBasedA load def
  163.   /CIEBasedDEFG /CIEBasedA load def
  164.   /Separation /CIEBasedA load def
  165.   /DeviceN /CIEBasedA load def
  166.   /Indexed /CIEBasedA load def
  167.   /Pattern
  168.    { dup currentcolorspace eq { pop } { setcolorspace } ifelse
  169.      dup /Matrix .knownget not { matrix } if makepattern setcolor
  170.    } bdef
  171. end def
  172. /setgcolor    % (null | <color...>) <colorspace> setgcolor -
  173.  { 1 index null eq
  174.     { pop pop }
  175.     { dup 0 get //Cdict exch get exec }
  176.    ifelse
  177.  } bdef
  178. /fsexec        % <fillop|strokeop> fsexec -
  179.  {        % Preserve the current point, if any.
  180.     { currentpoint } stopped
  181.     { $error /newerror false put   cvx exec }
  182.     { 3 -1 roll cvx exec moveto }
  183.    ifelse
  184.  } bdef
  185.  
  186. % ---------------- Path painting and clipping ---------------- %
  187.  
  188. /S { setstrokecolor /stroke fsexec } bdef
  189. /f { setfillcolor /fill fsexec } bdef
  190. /f* { setfillcolor /eofill fsexec } bdef
  191. /n { newpath } bdef        % don't allow n to get bound in
  192. /s { closepath S } bdef
  193. /B { gsave setfillcolor fill grestore S } bdef
  194. /b { closepath B } bdef
  195. /B* { gsave setfillcolor eofill grestore S } bdef
  196. /b* { closepath B* } bdef
  197.  
  198. % Clipping:
  199.  
  200. /Wdict 4 dict dup begin
  201. /S { gsave setstrokecolor stroke grestore n } bdef
  202. /f { gsave setfillcolor fill grestore n } bdef
  203. /f* { gsave setfillcolor eofill grestore n } bdef
  204. /n { end clip newpath } bdef
  205. end readonly def
  206. /W { //Wdict begin } bdef
  207. /W*dict 4 dict dup begin
  208. Wdict { def } forall
  209. /n { end eoclip newpath } bdef
  210. end readonly def
  211. /W* { //W*dict begin } bdef
  212.  
  213. % ---------------- Text control ---------------- %
  214.  
  215. /textbeginpage
  216.  { /TextSpacing 0 def        % 0 Tc
  217.    /TextLeading 0 def        % 0 TL
  218.    /TextRenderingMode 0 def    % 0 Tr
  219.    /TextRise 0 def        % 0 Ts
  220.    /WordSpacing 0 def        % 0 Tw
  221.    /TextHScaling 1.0 def    % 100 Tz
  222.    /TextFont null def
  223.    /Show { showfirst } def
  224.  } bdef
  225.  
  226. % Contrary to the statement in the PDF manual, BT and ET *can* be nested,
  227. % if the CharProc for a Type 3 font does a BT/ET itself.
  228. % Since we always call the CharProc inside a q/Q, we simply ensure that
  229. % the text state is saved and restored like the rest of the extended
  230. % graphics state.
  231.  
  232. /settextmatrix {
  233.   TextMatrix concat
  234.   TextHScaling 1 ne { TextHScaling 1 scale } if
  235.   TextRise 0 ne { 0 TextRise translate } if
  236.   TextFont dup null eq { pop } { setfont } ifelse
  237. } bdef
  238. /settextstate {
  239.   TextSaveMatrix setmatrix settextmatrix
  240. } bdef
  241. /settextposition {
  242.         % Update the TextMatrix translation.
  243.   gsave TextSaveMatrix setmatrix
  244.   currentpoint TextMatrix 4 2 getinterval astore pop
  245.   grestore currentpoint translate
  246. } bdef
  247.  
  248. /BT {
  249.   currentdict /TextLineMatrix .knownget
  250.     { identmatrix pop TextMatrix identmatrix pop }
  251.     { matrix /TextLineMatrix gput matrix /TextMatrix gput }
  252.   ifelse
  253.     { showfirst } /Show gput
  254.   currentdict /TextSaveMatrix .knownget not
  255.     { matrix dup /TextSaveMatrix gput }
  256.   if currentmatrix pop settextmatrix
  257. } bdef
  258. /ET {
  259.   TextSaveMatrix setmatrix
  260. } bdef
  261. /Tc { /TextSpacing gput { showfirst } /Show gput } bdef
  262. /TL { /TextLeading gput } bdef
  263. /Tr { /TextRenderingMode gput { showfirst } /Show gput } bdef
  264. /Ts { /TextRise gput settextstate } bdef
  265. /Tw { /WordSpacing gput { showfirst } /Show gput } bdef
  266. /Tz { 100 div /TextHScaling gput settextstate} bdef
  267.  
  268. % ---------------- Font control ---------------- %
  269.  
  270. /Tf {        % <font> <scale> Tf -
  271.   dup 1 eq { pop } { scalefont } ifelse
  272.   /TextFont gput settextstate
  273. } bdef
  274.  
  275. % Read a CFF font.
  276. /FRD        % <resdict> <file> FRD -
  277.  { /FontSetInit /ProcSet findresource begin ReadData
  278.  } bdef
  279.  
  280. % Copy a font, removing its FID.  If changed is true, also remove
  281. % the UniqueID and XUID, if any.  If the original dictionary doesn't have
  282. % the keys being removed, don't copy it.
  283. /.copyfontdict        % <font> <changed> .copyfontdict <dict>
  284.  { 1 index /FID known
  285.    1 index { 2 index /UniqueID known or 2 index /XUID known or } if
  286.     {        % We add 1 to the length just in case the original
  287.         % didn't have a FID.
  288.       exch dup length 1 add dict exch
  289.        {        % Stack: changed newfont key value
  290.      1 index /FID eq 4 index
  291.       { 2 index /UniqueID eq or 2 index /XUID eq or }
  292.      if not { 3 copy put } if pop pop
  293.        }
  294.       forall exch
  295.     }
  296.    if pop
  297.  } bdef
  298.  
  299. % Insert a new Encoding or Metrics into a font if necessary.
  300. % Return a possibly updated font, and a flag to indicate whether
  301. % the font was actually copied.
  302. /.updatefontmetrics {    % <font> <Metrics|null> .updatefontmetrics
  303.             %   <font'> <copied>
  304.   dup null ne {
  305.     exch true .copyfontdict dup /Metrics 4 -1 roll put true
  306.   } {
  307.     pop false
  308.   } ifelse
  309. } bdef
  310. /.updatefontencoding {    % <font> <Encoding|null> .updatefontencoding
  311.             %   <font'> <copied>
  312.   dup null ne { dup 2 index /Encoding get ne } { false } ifelse {
  313.     exch false .copyfontdict dup /Encoding 4 -1 roll put true
  314.   } {
  315.     pop false
  316.   } ifelse
  317. } bdef
  318. /.updatefont {        % <font> <Encoding|null> <Metrics|null> .updatefont
  319.             %   <font'> <copied>
  320.   3 -1 roll exch .updatefontmetrics
  321.             % Stack: enc|null font' copied
  322.   3 1 roll exch .updatefontencoding 3 -1 roll or
  323. } bdef
  324.  
  325. % ---------------- Text positioning ---------------- %
  326.  
  327. /Td {
  328.   TextLineMatrix transform TextLineMatrix 4 2 getinterval astore pop
  329.   TextLineMatrix TextMatrix copy pop settextstate
  330. } bdef
  331. /TD { dup neg /TextLeading gput Td } bdef
  332. /T* { 0 TextLeading neg Td } bdef
  333. /Tm {
  334.   TextLineMatrix astore TextMatrix copy pop settextstate
  335. } bdef
  336.  
  337. % ---------------- Text painting ---------------- %
  338.  
  339. /textrenderingprocs [        % (0 is handled specially)
  340.    { tf } { tS } { tB } { tn }
  341.     % We don't know what the clipping modes mean....
  342.    4 copy
  343. ] readonly def
  344. /setshowstate
  345.  { WordSpacing 0 eq TextSpacing 0 eq and
  346.     { TextRenderingMode 0 eq
  347.        { { setfillcolor show } }
  348.        { { false charpath textrenderingprocs TextRenderingMode get exec } }
  349.       ifelse
  350.     }
  351.     { TextRenderingMode 0 eq
  352.        { WordSpacing 0 eq
  353.           { { setfillcolor TextSpacing exch 0 exch ashow } }
  354.       { TextSpacing 0 eq
  355.          { { setfillcolor WordSpacing exch 0 exch 32 exch widthshow } }
  356.          { { setfillcolor WordSpacing exch TextSpacing exch 0 32 4 2 roll 0 exch awidthshow } }
  357.         ifelse
  358.       }
  359.      ifelse
  360.        }
  361.        { { WordSpacing TextSpacing
  362.             % Implement the combination of t3 and false charpath.
  363.             % Note that we must use cshow for this, because we
  364.             % can't parse multi-byte strings any other way.
  365.             % Stack: string xword xchar
  366.         { pop pop (x) dup 0 3 index put false charpath
  367.             % Stack: xword xchar ccode
  368.           3 copy 32 eq { add } { exch pop } ifelse 0 rmoveto pop
  369.         }
  370.        4 -1 roll cshow pop pop
  371.        textrenderingprocs TextRenderingMode get exec
  372.      }
  373.        }
  374.       ifelse
  375.     }
  376.    ifelse /Show gput
  377.  } bdef
  378. /showfirst { setshowstate Show } def
  379.  
  380. /Tj {
  381.   0 0 moveto Show settextposition
  382. } bdef
  383. /' { T* Tj } bdef
  384. /" { exch Tc exch Tw T* Tj } bdef
  385. /TJ {
  386.   0 0 moveto {
  387.     dup type /stringtype eq {
  388.       Show
  389.     } { -1000 div
  390.       currentfont /ScaleMatrix .knownget { 0 get mul } if
  391.       0 rmoveto
  392.     } ifelse
  393.   } forall settextposition
  394. } bdef
  395.  
  396. /tf { setfillcolor currentpoint fill moveto } bdef
  397. /tn { currentpoint newpath moveto } bdef
  398. % For stroking characters, temporarily restore the graphics CTM so that
  399. % the line width will be transformed properly.
  400. /Tmatrix matrix def
  401. /tS
  402.  { setstrokecolor
  403.    currentpoint //Tmatrix currentmatrix TextSaveMatrix setmatrix stroke
  404.    setmatrix moveto
  405.  } bdef
  406. /tB { gsave tf grestore tS } bdef
  407.  
  408. end readonly put        % GS_PDF_ProcSet
  409.  
  410. .setglobal
  411.