home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / Vyzkuste / gs / gs650w32.exe / gs6.50 / lib / gs_cmap.ps < prev    next >
Text File  |  2000-12-05  |  12KB  |  377 lines

  1. %    Copyright (C) 1995, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of AFPL Ghostscript.
  3. % AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  4. % distributor accepts any responsibility for the consequences of using it, or
  5. % for whether it serves any particular purpose or works at all, unless he or
  6. % she says so in writing.  Refer to the Aladdin Free Public License (the
  7. % "License") for full details.
  8. % Every copy of AFPL Ghostscript must include a copy of the License, normally
  9. % in a plain ASCII text file named PUBLIC.  The License grants you the right
  10. % to copy, modify and redistribute AFPL Ghostscript, but only under certain
  11. % conditions described in the License.  Among other things, the License
  12. % requires that the copyright notice and this notice be preserved on all
  13. % copies.
  14.  
  15. % $Id: gs_cmap.ps,v 1.6.2.1 2000/10/17 15:54:50 rayjj 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
  36.     } {
  37.       /Font
  38.     } ifelse findresource
  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 /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 .CodeMapData structure closely mirrors the structures
  59. % defined in gxfcmap.h (q.v.).  () indicate a string, [] indicate an array,
  60. % ? indicates a Boolean, # indicates an integer, {} for grouping.
  61. %    [[(first) (last) ...]        % code space ranges
  62. %     [(prefix) (key_size,?is_range,value_type,value_size) (keys...)
  63. %       {(values...) | [value ...]} #font_index    % code mappings
  64. %      ...]
  65. %     <<same>>        % notdef mappings
  66. %    ]
  67. % FontMatrices is the array of matrices defined by begin/endusematrix.
  68. % All of the arrays and strings are read-only after they have been built.
  69. %
  70. % Note that the code in zfcmap.c that constructs the C structures from
  71. % the PostScript structures has intimate knowledge of the above format.
  72.  
  73. % ****** NOTE: The code currently only handles "well-behaved" CMaps:
  74. %    - CID values only (no bfchars), 16-bit
  75. %    - Entries (both code space and map) must be sorted
  76. %    - Only the last byte must vary in each map range, except for
  77. %    the identity mapping
  78.  
  79. % ------ Font-level operators ------ %
  80.  
  81. /begincmap {        % - begincmap -
  82.   /.CodeMapData [[] [] []] def
  83.   /FontMatrices [] def
  84.   /.FontIndex 0 def
  85.   /.TempMaps [20 dict 50 dict 50 dict] def
  86.   /CodeMap null def        % for .buildcmap
  87. } bind def
  88. /endcmap {        % - endcmap -
  89.   10 dict begin 0 1 2 {
  90.     /i exch def
  91.         % Append data from .TempMaps to .CodeMapData.
  92.     /t .TempMaps i get def
  93.     .CodeMapData i get length t { exch pop length add } forall
  94.     array /a exch def
  95.     a 0 .CodeMapData i get .putmore
  96.     0 1 t length 1 sub {
  97.       t exch get .putmore
  98.     } for pop pop
  99.     .CodeMapData i a put
  100.   } for end
  101.   currentdict /.TempMaps undef
  102.   /.CodeMapData .CodeMapData .endmap def
  103.   /FontMatrices FontMatrices .endmap def
  104. } bind def
  105.  
  106. /.putmore {        % <array> <i> <array2> .putmore <array> <i+len(array2)>
  107.   3 copy putinterval length add
  108. } bind def
  109.  
  110. /.endmap {        % <map> .endmap <map>
  111.   dup type /arraytype eq {
  112.     % This might be a shared read-only array inherited via usecmap.
  113.     % Don't try to update its elements if this is the case.
  114.     dup wcheck {
  115.       0 1 2 index length 1 sub {
  116.     2 copy 2 copy get .endmap put pop
  117.       } for readonly
  118.     } if
  119.   } {
  120.     dup type /stringtype eq { readonly } if
  121.   } ifelse
  122. } bind def
  123.  
  124. /.appendmap {        % -mark- <elt> ... <array#> .appendmap -
  125.   .TempMaps exch get counttomark 1 add 1 roll
  126.   ] 1 index length exch put
  127. } bind def
  128.  
  129. /begincodespacerange {    % <count> begincodespacerange -
  130.   pop mark
  131. } bind def
  132. /endcodespacerange {    % <code_lo> <code_hi> ... endcodespacerange -
  133.   0 .appendmap
  134. } bind def
  135.  
  136. /usecmap {        % <CMap_name> usecmap -
  137.   /CMap findresource dup
  138.         % Copy the top level of .CodeMapData
  139.   /.CodeMapData exch /.CodeMapData get copyarray def
  140.   /FontMatrices exch /FontMatrices get copyarray def
  141. } bind def
  142.  
  143. /usefont {        % <fontID> usefont -
  144.   /.FontIndex exch def
  145. } bind def
  146.  
  147. /beginusematrix {    % <fontID> beginusematrix -
  148.   FontMatrices wcheck not FontMatrices length 2 index le or {
  149.     FontMatrices length 1 index 1 add .max array
  150.     dup 0 FontMatrices putinterval
  151.     /FontMatrices exch def
  152.   } if
  153. } bind def
  154. /endusematrix {        % <matrix> endusematrix -
  155.   FontMatrices 3 1 roll put
  156. } bind def
  157.  
  158. % ------ Rearranged font operators ------ %
  159.  
  160. /beginrearrangedfont {    % <font_name> <font*> beginrearrangedfont -
  161.   10 dict begin
  162.   /.FontNames exch def
  163.   /.FontName exch def
  164.   begincmap
  165. } bind def
  166. /endrearrangedfont {    % - endrearrangedfont -
  167.   (REARRANGED FONTS NOT IMPLEMENTED YET.) = flush
  168.   FontName .FontNames 0 get findfont end definefont pop
  169. } bind def
  170.  
  171. % ------ Character name/code selector operators ------ %
  172.  
  173. /beginbfchar {        % <count> beginbfchar -
  174.   pop mark
  175. } bind def
  176. /endbfchar {        % <code> <to_code|charname> ... endbfchar
  177.   counttomark 2 idiv {
  178.     counttomark -2 roll        % process in correct order
  179.     .addbfchar
  180.   } repeat 1 .appendmap
  181. } bind def
  182.  
  183. /beginbfrange {        % <count> beginbfrange -
  184.   pop mark
  185. } bind def
  186. /endbfrange {        % <code_lo> <code_hi> <to_code|(charname*)> ...
  187.             %   endbfrange -
  188.   counttomark 3 idiv {
  189.     counttomark -3 roll        % process in correct order
  190.     dup type dup /arraytype eq exch /packedarraytype eq or {
  191.             % Array value, split up.
  192.       exch pop {
  193.             % Stack: code to_code|charname
  194.     1 index exch .addbfchar
  195.             % Increment the code.  As noted above, we require
  196.             % that only the last byte vary, but we still must
  197.             % mask it after incrementing, in case the last
  198.             % value was 0xff.
  199.             % Stack: code prefix params key value fontindex
  200.     6 -1 roll dup length string copy
  201.     dup dup length 1 sub 2 copy get 1 add 255 and put
  202.       } forall pop
  203.     } {
  204.             % Single value, handle directly.
  205.       .addbfrange
  206.     } ifelse
  207.   } repeat 1 .appendmap
  208. } bind def
  209.  
  210. /.addbfchar {        % <code> <to_code|charname> .addbfchar
  211.             %   <prefix> <params> <key> <value> <font_index>
  212.   1 index exch .addbfrange
  213. } bind def
  214. /.addbfrange {        % <code_lo> <code_hi> <to_code|charname>
  215.             %   .addbfrange <<same as .addbfchar>>
  216.   4 string dup 3
  217.   3 index type /nametype eq {
  218.     2 index 2 1 put
  219.     4 -1 roll 1 array astore 4 1 roll 4
  220.   } {
  221.     2 index 2 2 put
  222.     3 index length
  223.   } ifelse put
  224.             % Stack: code_lo code_hi value params
  225.   3 index 3 index eq {
  226.             % Single value.
  227.     3 -1 roll pop exch () exch
  228.   } {
  229.             % Range.
  230.     dup 0 1 put dup 1 1 put
  231.     4 2 roll
  232.     dup dup length 1 sub 0 exch getinterval 5 1 roll    % prefix
  233.             % Stack: prefix value params code_lo code_hi
  234.     2 { exch dup length 1 sub 1 getinterval } repeat concatstrings
  235.     3 -1 roll
  236.   } ifelse
  237.   .FontIndex
  238. } bind def
  239.  
  240. % ------ CID selector operators ------ %
  241.  
  242. /begincidchar {        % <count> begincidchar -
  243.   pop mark
  244. } bind def
  245. /endcidchar {        % <code> <cid> ... endcidchar -
  246.   1 .endmapchars
  247. } bind def
  248.  
  249. /begincidrange {    % <count> begincidrange -
  250.   pop mark
  251. } bind def
  252. /endcidrange {        % <code_lo> <code_hi> <cid_base> ... endcidrange -
  253.   1 .endmapranges
  254. } bind def
  255.  
  256. /.endmapchars {        % -mark- <code> <cid> ... <map#> .endmapchars -
  257.   counttomark 1 add 1 roll
  258.   counttomark 2 idiv {
  259.     counttomark -2 roll        % process in correct order
  260.         % Construct prefix, params, key, value, font_index
  261.     <00 00 00 02> ()    % params, key
  262.     3 -1 roll .endmapvalue
  263.   } repeat
  264.   counttomark 2 add -1 roll .appendmap
  265. } bind def
  266.  
  267. /.endmapranges {    % -mark- <code_lo> <code_hi> <cid_base> ... <map#>
  268.             %   .endmapranges -
  269.   2 dict begin /merge false def
  270.   counttomark 1 add 1 roll
  271.   counttomark 3 idiv {
  272.     counttomark -3 roll        % process in correct order
  273.         % Construct prefix, params, key_lo, key_hi, value, font_index
  274.     3 1 roll dup length 1 eq {
  275.       exch 0 get exch 0 get 1 exch {
  276.         % Stack: cid code
  277.     1 string dup 0 4 -1 roll put    % prefix
  278.     <00 00 00 02> ()    % params, keys
  279.     3 index .endmapvalue
  280.     6 -1 roll 1 add
  281.       } for pop
  282.       /merge false def
  283.     } {
  284.         % Hack: handle 16-bit single-range mappings specially.
  285.       counttomark 3 eq 1 index length 2 eq and {
  286.     () 3 1 roll    % prefix
  287.     <02 01 00 02>    % params
  288.     3 1 roll    % keys
  289.     concatstrings 4 -1 roll .endmapvalue
  290.     /merge false def
  291.       } {
  292.     exch dup dup length 1 sub 0 exch getinterval    % prefix
  293.     <01 01 00 02>    % params
  294.     3 -1 roll dup length 1 sub 1 getinterval    % key_lo
  295.     4 -1 roll dup length 1 sub 1 getinterval    % key_hi
  296.     concatstrings 4 -1 roll .endmapvalue
  297.         % See if we can merge with the previous value.
  298.         % Stack: prefix params keys value fontindex
  299.     merge {
  300.       4 index 10 index eq 1 index 7 index eq and {
  301.         pop 4 2 roll pop pop
  302.         % Stack: prefix params keys value fontindex keys2 value2
  303.         5 -1 roll 3 -1 roll concatstrings
  304.         % Stack: prefix params value fontindex value2 keys'
  305.         4 -1 roll 3 -1 roll concatstrings
  306.         % Stack: prefix params fontindex keys' values'
  307.         3 -1 roll
  308.       } if
  309.     } if
  310.     /merge true def
  311.       } ifelse
  312.     } ifelse
  313.   } repeat
  314.   counttomark 2 add -1 roll .appendmap end
  315. } bind def
  316.  
  317. /.endmapvalue {        % <cid> .endmapvalue (hi,lo) .FontIndex
  318.   2 string dup 0 3 index -8 bitshift put    % value
  319.   dup 1 4 -1 roll 255 and put
  320.   .FontIndex        % font_index
  321. } bind def
  322.  
  323. % ------ notdef operators ------ %
  324.  
  325. /beginnotdefchar {    % <count> beginnotdefchar -
  326.   pop mark
  327. } bind def
  328. /endnotdefchar {    % <code> <cid> ... endnotdefchar -
  329.   2 .endmapchars
  330. } bind def
  331.  
  332. /beginnotdefrange {    % <count> beginnotdefrange -
  333.   pop mark
  334. } bind def
  335. /endnotdefrange {    % <code_lo> <code_hi> <cid> ... endnotdefrange -
  336.   2 .endmapranges
  337. } bind def
  338.  
  339. % ---------------- Resource category definition ---------------- %
  340.  
  341. currentdict end
  342.  
  343. languagelevel exch 2 .setlanguagelevel
  344.  
  345. /CMap /Generic /Category findresource dup length dict .copydict
  346. dup /InstanceType /dicttype put
  347. dup /DefineResource {
  348.         % The AdobePS5 Windows driver emits code that attempts to
  349.         % create CMaps without the require CMapName entry.
  350.         % Work around this here.
  351.   dup /CMapName known not {
  352.     dup wcheck not {
  353.       .currentglobal exch dup wcheck .setglobal
  354.       dup length dict .copydict exch .setglobal
  355.     } if
  356.     dup gcheck 2 index gcheck not and {
  357.       exch .currentglobal exch true .setglobal
  358.       dup length string copy exch .setglobal exch
  359.     } if dup /CMapName 3 index put
  360.   } if
  361.   dup /CodeMap get null eq { .buildcmap } if
  362.   /Generic /Category findresource /DefineResource get exec
  363. } put
  364. /Category defineresource pop
  365.     % We might have loaded CID font support already.
  366. /CIDInit /ProcSet 2 copy { findresource } .internalstopped
  367.     % An interior `stopped' might have reset VM allocation to local.
  368. true .setglobal
  369.  { pop pop 3 -1 roll }
  370.  { dup length 4 index length add dict .copydict 4 -1 roll exch .copydict }
  371. ifelse exch defineresource pop
  372.  
  373. .setlanguagelevel
  374.