home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 October / Chip_2002-10_cd1.bin / zkuste / pdf / download / gs704w32.exe / gs7.04 / lib / gs_cmap.ps < prev    next >
Encoding:
Text File  |  2002-01-31  |  14.6 KB  |  456 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.11 2001/06/16 19:02:31 igorm 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. /.rewriteTempMapsNotDef {
  24.   DEBUG { (rewriting TempMapsNotDef\n) print flush } if
  25.   .TempMaps 2 get
  26.   dup length 0 gt {
  27.     0 get
  28.     DEBUG { (...original...\n) print flush } if
  29.     1 5 2 index length 1 sub {
  30.       { 1 index exch get 2 3 put } stopped
  31.       { DEBUG { (cannot rewrite\n) print flush } if }
  32.       { DEBUG { (rewrite\n) print flush } if } ifelse
  33.     } for
  34.   } if
  35.   pop
  36.   DEBUG { (...FINISHED...\n) print } if
  37. } bind def
  38.  
  39. % composefont doesn't appear in CMap files -- it's documented in
  40. % the "PostScript Language Reference Manual Supplement".
  41. /composefont {        % <name> <cmap|cmapname> <fonts> composefont <font>
  42.   10 dict begin
  43.     /CMap 2 index dup type /dicttype ne { /CMap findresource } if def
  44.     /FDepVector 1 index cvlit def    % temporarily
  45.     /Encoding [ 0 1 FDepVector length 1 sub { } for ] def
  46.     /FDepVector [ 0 1 FDepVector length 1 sub {
  47.         % Stack: name cmap[name] fonts /FDepVector [ fonts... i
  48.       FDepVector 1 index get
  49.       dup type /dicttype ne {
  50.     dup /CIDFont resourcestatus {
  51.       pop pop /CIDFont
  52.     } {
  53.       /Font
  54.     } ifelse findresource
  55.       } if
  56.       exch CMap /FontMatrices get dup length 2 index gt {
  57.     exch get dup null eq { pop } { makefont } ifelse
  58.       } {
  59.     pop pop
  60.       } ifelse
  61.     } for ] readonly def
  62.     /FMapType 9 def
  63.     /FontMatrix matrix def
  64.     /FontName 3 index def
  65.     CMap /WMode .knownget { /WMode exch def } if
  66.     /FontType 0 def
  67.   pop pop currentdict end /Font defineresource
  68. } bind odef
  69.  
  70. % ---------------- CMap operators ---------------- %
  71.  
  72. 40 dict begin
  73.  
  74. % Our internal .CodeMapData structure closely mirrors the structures
  75. % defined in gxfcmap.h (q.v.).  () indicate a string, [] indicate an array,
  76. % ? indicates a Boolean, # indicates an integer, {} for grouping.
  77. %    [[(first) (last) ...]        % code space ranges
  78. %     [(prefix) (key_size,?is_range,value_type,value_size) (keys...)
  79. %       {(values...) | [value ...]} #font_index    % code mappings
  80. %      ...]
  81. %     <<same>>        % notdef mappings
  82. %    ]
  83. % FontMatrices is the array of matrices defined by begin/endusematrix.
  84. % All of the arrays and strings are read-only after they have been built.
  85. %
  86. % Note that the code in zfcmap.c that constructs the C structures from
  87. % the PostScript structures has intimate knowledge of the above format.
  88.  
  89. % ****** NOTE: The code currently only handles "well-behaved" CMaps:
  90. %    - CID values only (no bfchars), 16-bit
  91. %    - Entries (both code space and map) must be sorted
  92. %    - Only the last byte must vary in each map range, except for
  93. %    the identity mapping
  94.  
  95. % ------ Font-level operators ------ %
  96.  
  97. /begincmap {        % - begincmap -
  98.   /.CodeMapData [[] [] []] def
  99.   /FontMatrices [] def
  100.   /.FontIndex 0 def
  101.   /.TempMaps [20 dict 50 dict 50 dict] def
  102.   /CodeMap null def        % for .buildcmap
  103. } bind def
  104. /endcmap {        % - endcmap -
  105.   .rewriteTempMapsNotDef
  106.   DEBUG {
  107.     (*** defined charmap ***\n) print
  108.     .TempMaps 1 get {exch == (\t) print ==} forall
  109.     (*** undefined charmap ***\n) print
  110.     .TempMaps 2 get {exch == (\t) print ==} forall
  111.   } if
  112.   10 dict begin 0 1 2 {
  113.     /i exch def
  114.         % Append data from .TempMaps to .CodeMapData.
  115.     /t .TempMaps i get def
  116.     .CodeMapData i get length t { exch pop length add } forall
  117.     DEBUG { (requested array size ) print dup == } if
  118.     array /a exch def
  119.     a 0 .CodeMapData i get .putmore
  120.     0 1 t length 1 sub {
  121.       t exch get .putmore
  122.     } for pop pop
  123.     .CodeMapData i a put
  124.   } for end
  125.   currentdict /.TempMaps undef
  126.   /.CodeMapData .CodeMapData .endmap def
  127.   /FontMatrices FontMatrices .endmap def
  128. } bind def
  129.  
  130. /.putmore {        % <array> <i> <array2> .putmore <array> <i+len(array2)>
  131.   3 copy putinterval length add
  132. } bind def
  133.  
  134. /.endmap {        % <map> .endmap <map>
  135.   dup type /arraytype eq {
  136.     % This might be a shared read-only array inherited via usecmap.
  137.     % Don't try to update its elements if this is the case.
  138.     dup wcheck {
  139.       0 1 2 index length 1 sub {
  140.     2 copy 2 copy get .endmap put pop
  141.       } for readonly
  142.     } if
  143.   } {
  144.     dup type /stringtype eq { readonly } if
  145.   } ifelse
  146. } bind def
  147.  
  148. /.appendmap {        % -mark- <elt> ... <array#> .appendmap -
  149.   .TempMaps exch get counttomark 1 add 1 roll
  150.   ] 1 index length exch put
  151. } bind def
  152.  
  153. /begincodespacerange {    % <count> begincodespacerange -
  154.   pop mark
  155. } bind def
  156. /endcodespacerange {    % <code_lo> <code_hi> ... endcodespacerange -
  157.   0 .appendmap
  158. } bind def
  159.  
  160. /usecmap {        % <CMap_name> usecmap -
  161.   /CMap findresource dup
  162.         % Copy the top level of .CodeMapData
  163.   /.CodeMapData exch /.CodeMapData get copyarray def
  164.   /FontMatrices exch /FontMatrices get copyarray def
  165. } bind def
  166.  
  167. /usefont {        % <fontID> usefont -
  168.   /.FontIndex exch def
  169. } bind def
  170.  
  171. /beginusematrix {    % <fontID> beginusematrix -
  172.   FontMatrices wcheck not FontMatrices length 2 index le or {
  173.     FontMatrices length 1 index 1 add .max array
  174.     dup 0 FontMatrices putinterval
  175.     /FontMatrices exch def
  176.   } if
  177. } bind def
  178. /endusematrix {        % <matrix> endusematrix -
  179.   FontMatrices 3 1 roll put
  180. } bind def
  181.  
  182. % ------ Rearranged font operators ------ %
  183.  
  184. /beginrearrangedfont {    % <font_name> <font*> beginrearrangedfont -
  185.   10 dict begin
  186.   /.FontNames exch def
  187.   /.FontName exch def
  188.   begincmap
  189. } bind def
  190. /endrearrangedfont {    % - endrearrangedfont -
  191.   (REARRANGED FONTS NOT IMPLEMENTED YET.) = flush
  192.   FontName .FontNames 0 get findfont end definefont pop
  193. } bind def
  194.  
  195. % ------ Character name/code selector operators ------ %
  196.  
  197. /beginbfchar {        % <count> beginbfchar -
  198.   pop mark
  199. } bind def
  200. /endbfchar {        % <code> <to_code|charname> ... endbfchar
  201.   counttomark 2 idiv {
  202.     counttomark -2 roll        % process in correct order
  203.     .addbfchar
  204.   } repeat 1 .appendmap
  205. } bind def
  206.  
  207. /beginbfrange {        % <count> beginbfrange -
  208.   pop mark
  209. } bind def
  210. /endbfrange {        % <code_lo> <code_hi> <to_code|(charname*)> ...
  211.             %   endbfrange -
  212.   counttomark 3 idiv {
  213.     counttomark -3 roll        % process in correct order
  214.     dup type dup /arraytype eq exch /packedarraytype eq or {
  215.             % Array value, split up.
  216.       exch pop {
  217.             % Stack: code to_code|charname
  218.     1 index exch .addbfchar
  219.             % Increment the code.  As noted above, we require
  220.             % that only the last byte vary, but we still must
  221.             % mask it after incrementing, in case the last
  222.             % value was 0xff.
  223.             % Stack: code prefix params key value fontindex
  224.     6 -1 roll dup length string copy
  225.     dup dup length 1 sub 2 copy get 1 add 255 and put
  226.       } forall pop
  227.     } {
  228.             % Single value, handle directly.
  229.       .addbfrange
  230.     } ifelse
  231.   } repeat 1 .appendmap
  232. } bind def
  233.  
  234. /.addbfchar {        % <code> <to_code|charname> .addbfchar
  235.             %   <prefix> <params> <key> <value> <font_index>
  236.   1 index exch .addbfrange
  237. } bind def
  238. /.addbfrange {        % <code_lo> <code_hi> <to_code|charname>
  239.             %   .addbfrange <<same as .addbfchar>>
  240.   4 string dup 3
  241.   3 index type /nametype eq {
  242.     2 index 2 1 put
  243.     4 -1 roll 1 array astore 4 1 roll 4
  244.   } {
  245.     2 index 2 2 put
  246.     3 index length
  247.   } ifelse put
  248.             % Stack: code_lo code_hi value params
  249.   3 index 3 index eq {
  250.             % Single value.
  251.     3 -1 roll pop exch () exch
  252.   } {
  253.             % Range.
  254.     dup 0 1 put dup 1 1 put
  255.     4 2 roll
  256.     dup dup length 1 sub 0 exch getinterval 5 1 roll    % prefix
  257.             % Stack: prefix value params code_lo code_hi
  258.     2 { exch dup length 1 sub 1 getinterval } repeat concatstrings
  259.     3 -1 roll
  260.   } ifelse
  261.   .FontIndex
  262. } bind def
  263.  
  264. % ------ CID selector operators ------ %
  265.  
  266. /begincidchar {        % <count> begincidchar -
  267.   pop mark
  268. } bind def
  269. /endcidchar {        % <code> <cid> ... endcidchar -
  270.   1 .endmapchars
  271. } bind def
  272.  
  273. /begincidrange {    % <count> begincidrange -
  274.   pop mark
  275. } bind def
  276. /endcidrange {        % <code_lo> <code_hi> <cid_base> ... endcidrange -
  277.   1 .endmapranges
  278. } bind def
  279.  
  280. /.endmapchars {        % -mark- <code> <cid> ... <map#> .endmapchars -
  281.   counttomark 1 add 1 roll
  282.   counttomark 2 idiv {
  283.     counttomark -2 roll        % process in correct order
  284.         % Construct prefix, params, key, value, font_index
  285.     <00 00 00 02> ()    % params, key
  286.     3 -1 roll .endmapvalue
  287.   } repeat
  288.   counttomark 2 add -1 roll .appendmap
  289. } bind def
  290.  
  291. /.endmapranges {    % -mark- <code_lo> <code_hi> <cid_base> ... <map#>
  292.             %   .endmapranges -
  293.   counttomark 1 add 1 roll
  294.   counttomark 3 idiv {
  295.     counttomark -3 roll        % process in correct order
  296.         % Construct prefix, params, key_lo, key_hi, value, font_index
  297.     3 1 roll    % <cid_base> <code_lo> <code_hi>
  298.         %        prefix    key
  299.         % 1-byte code:    ()    .
  300.         % 1-byte range:    ()    .
  301.         % N-byte code:    .    (*)
  302.         % N-byte range:    (*)    (*)
  303.     dup 2 index eq {    % <code_lo> == <code_hi>
  304.                    % 0: prefix_len for 1-byte code
  305.                    % 1: prefix_len for N-byte code
  306.        dup length 1 eq { 0 } { 1 } ifelse
  307.     } {            % <code_lo> != <code_hi>
  308.                  % calculate prefix_len for *-byte range
  309.        dup length 1 sub % <cid_base> <code_lo> <code_hi> <code_len-1>
  310.        0        % initial value for N
  311.        {        % <cid_base> <code_lo> <code_hi> (code_len-1)  N
  312.            dup 2 index ge { exit } if % if (N >= len - 1) exit
  313.            3 index 1 index get    % N-th byte of code_lo
  314.            3 index 2 index get    % N-th byte of code_hi
  315.            eq { 1 add } { exit } ifelse
  316.        } loop
  317.        exch pop     % discard <code_len-1>
  318.     } ifelse
  319.                 % cid_base code_lo code_hi prefix_len
  320.  
  321.     % Althogh Adobe CPSI with native CID/CMap support accept
  322.     % multi-dimensional range specification in notdef & cidrange
  323.     % (and CID is calculated as relative position in multi-dimensional
  324.     % range), but older CPSI & ATM cannot handle it.
  325.     % 
  326.     % GS accepts such specification, but it's recommended to keep
  327.     % from using this feature for notdef & cidrange.
  328.     % Following is a disabler of this feature.
  329.     % -------------------------------------------------------------
  330.     % counttomark 1 add index     % get map#
  331.     % 0 ne {            % if not codespacerange
  332.     %   1 index length         % get code length
  333.     %   1 index             % get prefix length
  334.     %   sub            % calculate key length
  335.     %   1 gt {            % if (key_len > 1),
  336.     %      (.endmapranges error) = flush
  337.     %      (multi-dimensional range specification is used out of codespacerange)
  338.     %      = flush
  339.     %      (/) =only
  340.     %      CMapName CMapName length string cvs =only
  341.     %      (: <) =only
  342.     %      2 index (%stdout) (w) file exch writehexstring
  343.     %      (> <) =only
  344.     %      1 index (%stdout) (w) file exch writehexstring
  345.     %      (>\n) =only flush
  346.     %      quit
  347.     %   } if
  348.     % } if
  349.     % -------------------------------------------------------------
  350.  
  351.     1 index exch 0 exch getinterval
  352.                 % cid_base code_lo code_hi prefix
  353.     dup length 3 index length exch sub
  354.                 % cid_base code_lo code_hi prefix range_len
  355.     dup 255 gt {
  356.        (too long coderange specification for current GS\n) print stop
  357.     } if
  358.     <00 01 00 02> 4 string copy    % create initialized param
  359.     dup 0 4 -1 roll put        % put range_len into param
  360.  
  361.     % get key_hi
  362.     3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval
  363.  
  364.     % get key_lo
  365.     4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval
  366.  
  367.     % make "keys" (concatenated key_lo + key_hi)
  368.     exch concatstrings
  369.  
  370.     % 
  371.     4 -1 roll
  372.     .endmapvalue
  373.  
  374.         % See if we can merge with the previous value.
  375.         % The prefix, params, and font index must match.
  376.     % prefix params keys value fontindex
  377.     counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item)
  378.        4 index 10 index eq    % compare prefix
  379.        4 index 10 index eq and    % compare params
  380.        1 index 7 index eq and    % compare fontindex
  381.     {
  382.           DEBUG { (merge!\n) print } if
  383.       pop 4 2 roll pop pop
  384.            % prefix params keys value fontindex keys2 value2
  385.       5 -1 roll 3 -1 roll concatstrings
  386.            % prefix params value fontindex value2 keys'
  387.       4 -1 roll 3 -1 roll concatstrings
  388.            % prefix params fontindex keys' values'
  389.       3 -1 roll
  390.     } if
  391.      } if % end of 2 (or more) ranges
  392.   } repeat
  393.   counttomark 2 add -1 roll .appendmap
  394. } bind def
  395.  
  396. /.endmapvalue {        % <cid> .endmapvalue (hi,lo) .FontIndex
  397.   2 string dup 0 3 index -8 bitshift put    % value
  398.   dup 1 4 -1 roll 255 and put
  399.   .FontIndex        % font_index
  400. } bind def
  401.  
  402. % ------ notdef operators ------ %
  403.  
  404. /beginnotdefchar {    % <count> beginnotdefchar -
  405.   pop mark
  406. } bind def
  407. /endnotdefchar {    % <code> <cid> ... endnotdefchar -
  408.   2 .endmapchars
  409. } bind def
  410.  
  411. /beginnotdefrange {    % <count> beginnotdefrange -
  412.   pop mark
  413. } bind def
  414. /endnotdefrange {    % <code_lo> <code_hi> <cid> ... endnotdefrange -
  415.   2 .endmapranges
  416. } bind def
  417.  
  418. % ---------------- Resource category definition ---------------- %
  419.  
  420. currentdict end
  421.  
  422. languagelevel exch 2 .setlanguagelevel
  423.  
  424. /CMap /Generic /Category findresource dup length dict .copydict
  425. dup /InstanceType /dicttype put
  426. dup /DefineResource {
  427.         % The AdobePS5 Windows driver emits code that attempts to
  428.         % create CMaps without the required CMapName entry.
  429.         % Work around this here.
  430.   dup /CMapName known not {
  431.     dup wcheck not {
  432.       .currentglobal exch dup wcheck .setglobal
  433.       dup length dict .copydict exch .setglobal
  434.     } if
  435.     dup gcheck 2 index gcheck not and {
  436.       exch .currentglobal exch true .setglobal
  437.       dup length string copy exch .setglobal exch
  438.     } if dup /CMapName 3 index put
  439.   } if
  440.   dup /CodeMap get null eq { .buildcmap } if
  441.   /Generic /Category findresource /DefineResource get exec
  442. } put
  443. /Category defineresource pop
  444.     % We might have loaded CID font support already.
  445. /CIDInit /ProcSet 2 copy { findresource } .internalstopped
  446.     % An interior `stopped' might have reset VM allocation to local.
  447. true .setglobal
  448.  { pop pop 3 -1 roll }
  449.  { dup length 4 index length add dict .copydict 4 -1 roll exch .copydict }
  450. ifelse exch defineresource pop
  451.  
  452. .setlanguagelevel
  453.