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

  1. %    Copyright (C) 1995, 1996, 1997, 1998, 1999 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: gs_cmap.ps,v 1.1 2000/03/09 08:40:39 lpd Exp $
  16. % ProcSet for implementing CMap resources.
  17. % When this is run, systemdict is still writable.
  18.  
  19. % NOTE: Rearranged fonts are not implemented yet.
  20.  
  21. % ---------------- Public operators ---------------- %
  22.  
  23. % composefont doesn't appear in CMap files -- it's documented in
  24. % the "PostScript Language Reference Manual Supplement".
  25. /composefont {        % <name> <cmap|cmapname> <fonts> composefont <font>
  26.   10 dict begin
  27.     /CMap 2 index dup type /dicttype ne { /CMap findresource } if def
  28.     /FDepVector 1 index cvlit def    % temporarily
  29.     /Encoding [ 0 1 FDepVector length 1 sub { } for ] def
  30.     /FDepVector [ 0 1 FDepVector length 1 sub {
  31.         % Stack: name cmap[name] fonts /FDepVector [ fonts... i
  32.       FDepVector 1 index get
  33.       dup type /dicttype ne {
  34.     dup /CIDFont resourcestatus {
  35.       pop pop /CIDFont findresource
  36.     } {
  37.       /Font findresource
  38.     } ifelse
  39.       } if
  40.       exch CMap /FontMatrices get dup length 2 index gt {
  41.     exch get dup null eq { pop } { makefont } ifelse
  42.       } {
  43.     pop pop
  44.       } ifelse
  45.     } for ] readonly def
  46.     /FMapType 9 def
  47.     /FontMatrix matrix def
  48.     /FontName 3 index def
  49.     /CMap load /WMode .knownget { /WMode exch def } if
  50.     /FontType 0 def
  51.   pop pop currentdict end /Font defineresource
  52. } bind odef
  53.  
  54. % ---------------- CMap operators ---------------- %
  55.  
  56. 40 dict begin
  57.  
  58. % Our internal .CodeMaps structure is an array of two arrays: array 0
  59. % is the map for defined characters, array 1 is the map for notdefs.
  60. % Both are multi-level arrays indexed by the successive bytes of the
  61. % character code.  Each value is either a sub-array, null, a character name,
  62. % a CID (an integer), or a character code (expressed as a byte string).
  63. % .FontIndices is a similar array holding the corresponding usefont values,
  64. % except that if the only font index is 0, the .FontIndices element is 0.
  65. % FontMatrices is the array of matrices defined by begin/endusematrix.
  66. % All of the arrays and strings are read-only after they have been built.
  67. %
  68. % Note that the code in zfcmap.c that constructs the C structures from
  69. % the PostScript structures has intimate knowledge of the above format.
  70.  
  71. % ------ Font-level operators ------ %
  72.  
  73. /begincmap {        % - begincmap -
  74.   /.CodeMaps [256 array 256 array] def
  75.   /.FontIndices [0 0] def
  76.   /FontMatrices [] def
  77.   /.FontIndex 0 def
  78. } bind def
  79. /endcmap {        % - endcmap -
  80.   /.CodeMaps .CodeMaps .endmap def
  81.   /.FontIndices .FontIndices .endmap def
  82.   /FontMatrices FontMatrices .endmap def
  83.   /CodeMap null def        % for .buildcmap
  84.   currentdict end .buildcmap begin
  85. } bind def
  86.  
  87. /begincodespacerange {    % <count> begincodespacerange -
  88.   pop mark
  89. } bind def
  90. /endcodespacerange {    % <code_lo> <code_hi> ... endcodespacerange -
  91.   counttomark 2 idiv {
  92.     .CodeMaps { 3 copy .addcodespacerange pop } forall pop pop
  93.   } repeat pop
  94. } bind def
  95.  
  96. /.addcodespacerange {    % <code_lo> <code_hi> <map> .addcodespacerange -
  97.   2 index length 1 eq
  98.     { 2 { 3 -1 roll 0 get } repeat 1 exch
  99.        { 2 copy 0 put pop } for pop
  100.     }
  101.     { 2 index 0 get 1 3 index 0 get
  102.       6 -2 roll
  103.       2 { 1 1 index length 1 sub getinterval 6 1 roll } repeat
  104.         % Stack: lo hi map lo0 1 hi0
  105.        { 2 copy get null eq { 2 copy 256 array put } if
  106.          4 copy get .addcodespacerange pop
  107.        }
  108.       for pop pop pop
  109.     }
  110.   ifelse
  111. } bind def
  112. /.endmap {        % <map> .endmap <map>
  113.   dup type /arraytype eq {
  114.     % This might be a shared read-only array inherited via usecmap.
  115.     % Don't try to update its elements if this is the case.
  116.     dup wcheck {
  117.       dup { .endmap exch } forall astore readonly
  118.     } if
  119.   } {
  120.     dup type /stringtype eq { readonly } if
  121.   } ifelse
  122. } bind def
  123.  
  124. /usecmap {        % <CMap_name> usecmap -
  125.   /CMap findresource
  126.   dup /.CodeMaps get dup length array copy /.CodeMaps exch def
  127.   /.FontIndices get /.FontIndices exch def
  128. } bind def
  129.  
  130. /usefont {        % <fontID> usefont -
  131.   /.FontIndex exch def
  132. } bind def
  133.  
  134. /beginusematrix {    % <fontID> beginusematrix -
  135.   FontMatrices wcheck not FontMatrices length 2 index le or {
  136.     FontMatrices length 1 index 1 add .max array
  137.     dup 0 FontMatrices putinterval
  138.     /FontMatrices exch def
  139.   } if
  140. } bind def
  141. /endusematrix {        % <matrix> endusematrix -
  142.   FontMatrices 3 1 roll put
  143. } bind def
  144.  
  145. % ------ Rearranged font operators ------ %
  146.  
  147. /beginrearrangedfont {    % <font_name> <font*> beginrearrangedfont -
  148.   10 dict begin
  149.   /.FontNames exch def
  150.   /.FontName exch def
  151.   begincmap
  152. } bind def
  153. /endrearrangedfont {    % - endrearrangedfont -
  154.   (REARRANGED FONTS NOT IMPLEMENTED YET.) = flush
  155.   FontName .FontNames 0 get findfont end definefont pop
  156. } bind def
  157.  
  158. % ------ Character name/code selector operators ------ %
  159.  
  160. /beginbfchar {        % <count> beginbfchar -
  161.   pop mark
  162. } bind def
  163. /endbfchar {        % <code> <to_code|charname> ... endbfchar
  164.   .endmapchar
  165. } bind def
  166.  
  167. /beginbfrange {        % <count> beginbfrange -
  168.   pop mark
  169. } bind def
  170. /endbfrange {        % <code_lo> <code_hi> <to_code|(charname*)> ...
  171.             %   endbfrange -
  172.   counttomark 3 idiv {
  173.     counttomark -3 roll        % process in correct order
  174.     .addbfrange
  175.   } repeat pop
  176. } bind def
  177.  
  178. /.addbfrange {        % <code_lo> <code_hi> <to_code|(charname*)>
  179.             %   .addbfrange
  180.   dup type /stringtype eq {
  181.     { dup length string copy dup dup length 1 sub 2 copy get 1 add put }
  182.     .addcharrange
  183.   } {
  184.     2 dict begin /codes 1 index def 0 get
  185.     { pop codes dup dup length 1 sub 1 exch getinterval /codes exch def
  186.       dup length 0 gt { 0 get } if
  187.     }
  188.     .addcharrange end
  189.   } ifelse
  190. } bind def
  191.  
  192. % ------ CID selector operators ------ %
  193.  
  194. /begincidchar {        % <count> begincidchar -
  195.   pop mark
  196. } bind def
  197. /endcidchar {        % <code> <cid> ... endcidchar -
  198.   .endmapchar
  199. } bind def
  200.  
  201. /begincidrange {    % <count> begincidrange -
  202.   pop mark
  203. } bind def
  204. /endcidrange {        % <code_lo> <code_hi> <cid_base> ... endcidrange -
  205.   counttomark 3 idiv {
  206.     counttomark -3 roll        % process in correct order
  207.     { 1 add } .addcharrange
  208.   } repeat pop
  209. } bind def
  210.  
  211. /.endmapchar {        % -mark- <code> <value> ... .endmapchar -
  212.   counttomark 2 idiv {
  213.     counttomark -2 roll        % process in correct order
  214.     1 index exch { } .addcharrange
  215.   } repeat pop
  216. } bind def
  217.  
  218. /.addcharrange {    % <code_lo> <code_hi> <value_base> <next_proc>
  219.             %   .addcharrange -
  220.   0 .putmaprange
  221. } bind def
  222.  
  223. /.putmaprange     {    % <code_lo> <code_hi> <value_base> <next_proc> <0|1>
  224.             %   .putmaprange -
  225.   5 1 roll
  226.         % Most CMaps don't involve multiple fonts.
  227.         % For this reason, we create .FontIndices lazily.
  228.   .FontIndices 5 index get 0 eq .FontIndex 0 ne and {
  229.         % Create .FontIndices now.
  230.     .CodeMaps 5 index get .makecodespace
  231.       .FontIndices 6 index 3 -1 roll put
  232.   } if
  233.   .FontIndices 5 index get 0 ne {
  234.     3 index 3 index .FontIndex { } .FontIndices 9 index get .addmaprange
  235.       .FontIndices 7 index 3 -1 roll put pop
  236.   } if
  237.   .CodeMaps 5 index get .addmaprange
  238.     .CodeMaps 3 index 3 -1 roll put pop
  239.   pop
  240. } bind def
  241. /.makecodespace {    % <array|other> .makecodespace -
  242.   dup type /arraytype eq {
  243.     [ exch { .makecodespace } forall ]
  244.   } {
  245.     pop 0
  246.   } ifelse
  247. } bind def
  248.  
  249. /.addmaprange {        % <code_lo> <code_hi> <value_base> <next_proc> <map>
  250.             %   .addmaprange <value_next> <map>
  251.     % We may be updating a (partly) read-only map from another CMap.
  252.     % If so, implement copy-on-write.
  253.    dup wcheck not { dup length array copy } if
  254.    4 index length 1 eq
  255.     { 2 { 5 -1 roll 0 get } repeat 1 exch
  256.        {    % Stack: value proc map code
  257.      2 copy 5 index put pop
  258.      3 -1 roll 2 index exec 3 1 roll
  259.        } for
  260.     }
  261.     { 4 index 0 get 1 5 index 0 get
  262.       8 -2 roll
  263.       2 { 1 1 index length 1 sub getinterval 8 1 roll } repeat
  264.         % Stack: lo hi next proc map lo0 1 hi0
  265.        { 6 copy get .addmaprange
  266.         % Stack: lo hi oldnext proc map i next submap
  267.      exch 6 1 roll 5 -1 roll pop
  268.         % Stack: lo hi next proc map i submap
  269.      3 copy put pop pop
  270.        }
  271.       for 5 -2 roll pop pop
  272.     }
  273.    ifelse exch pop
  274. } bind def
  275.  
  276. % ------ notdef operators ------ %
  277.  
  278. /beginnotdefchar {    % <count> beginnotdefchar -
  279.   pop mark
  280. } bind def
  281. /endnotdefchar {    % <code> <cid> ... endnotdefchar -
  282.   counttomark 2 idiv {
  283.     counttomark -2 roll        % process in correct order
  284.     1 index exch .addnotdefrange
  285.   } repeat pop
  286. } bind def
  287.  
  288. /beginnotdefrange {    % <count> beginnotdefrange -
  289.   pop mark
  290. } bind def
  291. /endnotdefrange {    % <code_lo> <code_hi> <cid> ... endnotdefrange -
  292.   counttomark 3 idiv {
  293.     counttomark -3 roll        % process in correct order
  294.     .addnotdefrange
  295.   } repeat pop
  296. } bind def
  297.  
  298. /.addnotdefrange {    % <code_lo> <code_hi> <cid_base> .addnotdefrange -
  299.   { } 1 .putmaprange
  300. } bind def
  301.  
  302. % ---------------- Resource category definition ---------------- %
  303.  
  304. currentdict end
  305.  
  306. languagelevel exch 2 .setlanguagelevel
  307.  
  308. /CMap /Generic /Category findresource dup length dict .copydict
  309. /Category defineresource pop
  310.     % We might have loaded CID font support already.
  311. /CIDInit /ProcSet 2 copy { findresource } .internalstopped
  312.     % An interior `stopped' might have reset VM allocation to local.
  313. true .setglobal
  314.  { pop pop 3 -1 roll }
  315.  { dup length 4 index length add dict .copydict 4 -1 roll exch .copydict }
  316. ifelse exch defineresource pop
  317.  
  318. .setlanguagelevel
  319.