home *** CD-ROM | disk | FTP | other *** search
/ jppd.dyndns.org / jppd.dyndns.org.tar / jppd.dyndns.org / QUERYPRO / Impressora_PDF / converter.exe / GPLGS / gs_cidcm.ps < prev    next >
Text File  |  2003-12-13  |  17KB  |  429 lines

  1. %    Copyright (C) 2000 artofcode LLC.  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: gs_cidcm.ps,v 1.10.2.1 2003/12/12 22:07:58 giles Exp $
  14. % Extending Font resource category with CIDFont-CMap fonts.
  15.  
  16. languagelevel 2 .setlanguagelevel currentglobal true setglobal
  17.  
  18.  
  19. % In the comments below, 'CSI' is an abbreviation/acronym for CIDSystemInfo.
  20. % We pre-scan resource files to retrieve the CSI from them.
  21. % First we define a hidden procset .prs_dict containing
  22. % necessary variables and procedures.
  23. % Then we redefine the old /Font category using this procset.
  24.  
  25. % We maintain internal caches for the CSI values retrieved from
  26. % resource files. This supposes that document doesn't uninstall
  27. % resource files. To disable caching, set enable_cache to false.
  28.  
  29. % We assume that names starting with '.prs' do not appear in resource files.
  30. % If this causes any problem, this prefix should be systematically changed
  31. % in this file.  ('prs' is an abbreviation for 'prescan'.)
  32.  
  33. 25 dict begin
  34.  
  35. % Define local variables :
  36.  
  37. /.prs_dict currentdict def       % self-reference (constant)
  38. /.prs_empty 0 dict readonly def  
  39. /path_buffer 8192 string def
  40. /name_buffer 1024 string def
  41. /minus (-) 0 get def             % character code constant for '-'
  42. /period (.) 0 get def            % character code constant for '.'
  43. /CMap 10 dict def                % CSI cache for CMaps
  44. /CIDFont 10 dict def             % CSI cache for CIDFonts
  45. /enable_cache true def           % set false to disable cache
  46.  
  47. % The folloving variables are just placeholders for ones to be set
  48. % dynamically :
  49. /.prsFile 0 def                   % file to prescan
  50. /.prsResult 0 def                 % result of prescan
  51. /.prsDictCount 0 def              % save the dictionary stack depth
  52.  
  53. % Define a dummy CIDInit procset to use while pre-scanning :
  54.  
  55. /DummyCIDInit 15 dict 
  56. begin
  57.  
  58.   /begincmap {} def
  59.   /usecmap {pop} bind def
  60.  
  61.   {stop} bind
  62.   [ /begincodespacerange /endcodespacerange /beginnotdefchar /endnotdefchar
  63.     /beginnotdefrange /endnotdefrange /begincidchar /endcidchar /begincidrange 
  64.     /endcidrange /endcmap /usefont /StartData
  65.   ] {
  66.     1 index def
  67.   } bind forall
  68.   pop
  69.  
  70. currentdict end def
  71.  
  72. % Define a local 'findresource' for pre-scanning :
  73. % (it returns the dummy CIDInit instead of the regular CIDInit ProcSet)
  74.  
  75. /findresource { % <InstName> <CatName> findresource <inst>
  76.   2 copy /ProcSet eq exch             % /InstName /CatName bool /InstName
  77.   /CIDInit eq and {
  78.     pop pop //DummyCIDInit
  79.   } {
  80.     //findresource exec
  81.   } ifelse
  82. } bind def
  83.  
  84. % Define procedures for pre-scanning :
  85.  
  86. /StopIfCSIDefined {   % - StopIfCSIDefined -
  87.   
  88.   % Check if the dictionary stack contains a dictionary containing /CIDSystemInfo. 
  89.   % The search is limited to the top .prsDictCount dictionaries in the stack.
  90.   % If so, retrieve the CSI, and execute stop to terminate the pre-scanning of the file.
  91.   % Otherwise, do nothing, so the pre-scanning continues.
  92.  
  93.   countdictstack //.prs_dict /.prsDictCount get sub dup {
  94.     currentdict /CIDSystemInfo .knownget {
  95.       //.prs_dict exch /.prsResult exch put
  96.       stop
  97.     } if
  98.     currentdict exch end
  99.   } repeat {
  100.     begin
  101.   } repeat
  102. } bind def
  103.  
  104. /PrescanFile {     % - PrescanFile -
  105.   { //.prs_dict /.prsFile get token {      
  106.       dup type                          % token type
  107.       dup /nametype eq exch /operatortype eq or {
  108.         dup xcheck {
  109.           exec
  110.           //StopIfCSIDefined exec
  111.         } if
  112.       } if
  113.     } {
  114.       stop
  115.     } ifelse
  116.   } loop
  117. } bind odef
  118.  
  119. /GetCIDSystemInfoFromFile { % <file> GetCIDSystemInfoFromFile <CSI>
  120.   
  121.   % This procedure reads resource files with 'token',
  122.   % executing the tokens untill /CIDSystemInfo appears to be defined.
  123.   % Normally the resource file creates a new dictionary on
  124.   % dictionary stack and defines /CIDSystemInfo in it.
  125.   %
  126.   % Returns an empty dictionary if no CIDSystemInfo is found.
  127.  
  128.   //.prs_dict begin
  129.   /.prsFile exch def
  130.   /.prsResult //.prs_empty def
  131.   /.prsDictCount countdictstack def
  132.   { //PrescanFile } stopped pop
  133.   //.prs_dict /.prsResult get
  134.   end
  135. } bind def
  136.  
  137. /GetCIDSystemInfo {     % <InstName> <CatName> GetCIDSystemInfo <CSI>
  138.   
  139.   % Retrieve CSI, using caches.
  140.  
  141.   /Category findresource begin                % /InstName
  142.   dup ResourceStatus 
  143.   {
  144.     pop 2 lt {
  145.       FindResource /CIDSystemInfo .knownget not {
  146.         //.prs_empty
  147.       } if                                    % CSI
  148.     } {                                       % /InstName
  149.       currentdict /GetCIDSystemInfoFromMap .knownget {
  150.         exec
  151.       } if
  152.       dup type /nametype eq
  153.       {
  154.         //.prs_dict Category get              % /InstName CSIs
  155.         dup 2 index known
  156.         //enable_cache and {
  157.           exch get                            % CSI
  158.         } {
  159.           exch                                % CSIs /InstName
  160.           dup //path_buffer ResourceFileName  % CSIs /InstName (path)
  161.           currentglobal exch true setglobal   % CSIs /InstName g (path)
  162.           mark exch                           % CSIs /InstName g [ (path)
  163.           { (r) file                          % CSIs /InstName g [ file
  164.             //GetCIDSystemInfoFromFile exec   % CSIs /InstName g [ CSI
  165.           } stopped {
  166.             cleartomark //.prs_empty             
  167.           } {
  168.             exch pop
  169.           } ifelse                            % CSIs /InstName g CSI
  170.           exch setglobal                      % CSIs /InstName CSI
  171.           dup 4 1 roll                        % CSI CSIs /InstName CSI
  172.           put                                 % CSI
  173.         } ifelse
  174.       } if
  175.     } ifelse
  176.   } {
  177.     pop //.prs_empty
  178.   } ifelse
  179.   end
  180. } bind def
  181.  
  182. /IsCompatibleCSI {  % <CSI-M> <CSI-F> IsCompatibleCSI <bool>
  183.   
  184.   % The CSI in a CIDFont may be an array, a dict, or null.
  185.   % If it is an array, it must be of 1 element, which is a dict.
  186.   % In this case the dict is used for testing the compatibility.
  187.   % Two dicts are compatible iff they contain same /Ordering and /Registry.
  188.  
  189.   exch                                  % CSI-F CSI-M
  190.   { dup type /arraytype eq {
  191.       dup length 1 ne {
  192.         pop pop false exit
  193.       } if
  194.       0 get
  195.     } if                                % CSI-F CSI-M
  196.     dup type /dicttype ne {
  197.       pop pop false exit
  198.     } if                                % CSI-F <<CSI-M>>
  199.     exch                                % <<CSI-M>> CSI-F
  200.     dup type /dicttype ne {
  201.       pop pop false exit
  202.     } if                                % <<CSI-M>> <<CSI-F>>
  203.     true                                % <<CSI-M>> <<CSI-F>> bEQ
  204.     [/Registry /Ordering] {                    
  205.       2 index 1 index .knownget not {
  206.         1234567
  207.       } if                              % <<CSI-M>> <<CSI-F>> bEQ /key vF
  208.       exch                              % <<CSI-M>> <<CSI-F>> bEQ vF /key
  209.       4 index exch .knownget not {
  210.         7654321
  211.       } if                              % <<CSI-M>> <<CSI-F>> bEQ vF vM
  212.       eq and                            % <<CSI-M>> <<CSI-F>> bEQ
  213.     } forall
  214.     exch pop exch pop                   % bEQ
  215.     exit
  216.   } loop
  217. } bind def
  218.  
  219. /IsWellComposed {     % <CIDFontName> <CMapName> IsWellComposed <bool>
  220.   
  221.   % Check if the given CIDFont and CMap have compatible CSIs.
  222.   exch                                  % /CMapName /CIDFontName
  223.   /CIDFont //GetCIDSystemInfo exec      % /CMapName CSI-F
  224.   dup type /dicttype eq {
  225.     dup length 0 ne {                          
  226.       exch                              % CSI-F /CMapName
  227.       /CMap //GetCIDSystemInfo exec     % CSI-F CSI-M
  228.       //IsCompatibleCSI exec            % bool
  229.     } {
  230.       pop pop false
  231.     } ifelse
  232.   } {
  233.     pop pop false
  234.   } ifelse
  235. } bind def
  236.  
  237. /IsComposedFont {   % <FontName> IsComposedFont <CIDFontName> <CMapName> true
  238.                     % <FontName> IsComposedFont false
  239.   
  240.   % Check if the given font name may be decomposed into CIDFont.CMap, CIDFont-CMap
  241.   % or into CIDFont--CMap, such that CIDFont and CMap have compatible CSIs.
  242.                                         % FontName
  243.   dup type /stringtype ne {
  244.     //name_buffer cvs
  245.   } if                                  % (FontName)
  246.   { dup length 2 sub -1 1 {
  247.                                         % (FontName) i
  248.       2 copy get dup //minus eq exch //period eq or {                
  249.         2 copy 2 copy                   % (FontName) i (FontName) i (FontName) i
  250.         2 copy get //minus eq {
  251.           2 copy 1 sub get //minus eq {
  252.             1 sub
  253.           } if
  254.         } if                            % (FontName) i (FontName) i (FontName) i0
  255.         0 exch getinterval cvn          % (FontName) i (FontName) i /CIDFontName
  256.         3 1 roll                        % (FontName) i /CIDFontName (FontName) i
  257.         1 add dup                       % (FontName) i /CIDFontName (FontName) i1 i1
  258.         5 index length                  % (FontName) i /CIDFontName (FontName) i1 i1 l
  259.         exch sub getinterval cvn        % (FontName) i /CIDFontName /CMapName
  260.         2 copy //IsWellComposed exec {  % (FontName) i /CIDFontName /CMapName 
  261.           4 2 roll pop pop              % /CIDFontName /CMapName
  262.           stop
  263.         } if
  264.         pop pop pop
  265.       } {
  266.         pop
  267.       } ifelse                          % (FontName)
  268.     } for
  269.     pop
  270.   } stopped
  271. } bind def
  272.  
  273. /ComposeName { % <CIDFont> <CMap> <scr> ComposeName <CIDFont-CMap>
  274.   dup dup 5 2 roll                        % (scr) (scr) /CIDFont /CMap (scr)
  275.   3 2 roll exch cvs length dup            % (scr) (scr) /CMap l0 l0
  276.   4 -1 roll exch //minus put              % (scr) /CMap l0
  277.   1 add dup                               % (scr) /CMap l1 l1
  278.   3 index dup length                      % (scr) /CMap l1 l1 (scr) L
  279.   2 index sub                             % (scr) /CMap l1 l1 (scr) LT
  280.   3 2 roll                                % (scr) /CMap l1 (scr) LT l1
  281.   exch getinterval                        % (scr) /CMap l1 (scrT)
  282.   3 2 roll exch cvs length                % (scr) l1 l2
  283.   add 0 exch getinterval                  % (CIDFont-CMap)
  284. } bind def
  285.  
  286. % Redefine the /Font category with CIDFont-CMap construction :
  287.  
  288. % The following code supposes that the following names are not
  289. % defined in the old /Font category dictionary :
  290. % /IsComposedFont, /IsWellComposed .
  291.  
  292.  
  293. /Font /Category findresource dup length dict copy begin
  294.  
  295. /FindResource {  % <InstName> FindResource <inst>
  296.   dup //ResourceStatus exec {
  297.     pop pop //FindResource exec
  298.   } {                                                
  299.     dup //IsComposedFont exec {          % /FontName /CIDFontName /CMapName 
  300.       exch [ exch ] composefont          % inst
  301.     } {
  302.       //FindResource exec
  303.     } ifelse
  304.   } ifelse
  305. } bind def
  306.  
  307. /ResourceStatus {  % <InstName> ResourceStatus <nStatus> <nSize> true
  308.                    % <InstName> ResourceStatus false
  309.   dup //ResourceStatus exec {                    
  310.     3 2 roll pop true                     % nStatus nSize true
  311.   } {
  312.     //IsComposedFont exec {               % /CIDFontName /CMapName 
  313.       /CMap resourcestatus {              % /CIDFontName nStatusM nSizeM 
  314.         exch pop exch                     % nSizeM /CIDFontName 
  315.         /CIDFont resourcestatus {         % nSizeM nStatusF nSizeF 
  316.           exch pop                        % nSizeF nSizeM
  317.           dup 0 ge {
  318.             exch dup 0 ge {
  319.               add
  320.             } {
  321.               exch pop
  322.             } ifelse
  323.           } {
  324.             pop
  325.           } ifelse                        % nSize
  326.           2 exch true                     % nStatus nSize true
  327.         } {                        
  328.           pop pop pop false  % work around buggy resource file
  329.         } ifelse
  330.       } {                            
  331.         pop pop pop false    % work around buggy resource file
  332.       } ifelse
  333.     } {
  334.       false
  335.     } ifelse
  336.   } ifelse
  337. } bind def
  338.  
  339. /ResourceForAll { % <template> <proc> <scratch> ResourceForAll - 
  340.  
  341.   % We suppose that the resourceforall procedure does not 
  342.   % define or install new fonts, CMaps, and/or CIDFonts.
  343.  
  344.   % First we create 3 temporary dictionaries to store temporary data
  345.   % about fonts, CMaps and CIDFonts.
  346.   % These dictionaries must be created dynamically, to allow for a possible 
  347.   % recursive call to resourceforall from the resourceforall procedure.
  348.   currentglobal false setglobal
  349.   20 dict 20 dict 20 dict
  350.  
  351.   4 -1 roll setglobal                     % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
  352.  
  353.   % Store resource identifiers into local dictionaries
  354.   % A resource instance can have a key that is not a name or a string. In this
  355.   % case, resourceforall passes the key directly to proc instead of copying it
  356.   % into the scratch string. This case can arise only for a resource instance
  357.   % defined in virtual memory by a previous defineresource
  358.  
  359.   % Discard non-string keys of CIDFont and CMap because <CIDFontName>- -<CMapName>
  360.   % is only defined for names.
  361.  
  362.   { /.DisableResourceOrdering pop % gs_resmp accesses this through execstack - don't remove !
  363.  
  364.     5 index [ 2 index {exch //null put} aload pop ] cvx bind 5 index //ResourceForAll exec
  365.  
  366.     (*) [ 3 index {exch dup type /stringtype eq { cvn dup put } { pop pop } ifelse } aload pop
  367.         ] cvx bind 5 index /CMap resourceforall
  368.  
  369.     (*) [ 4 index {exch dup type /stringtype eq { cvn dup put } { pop pop } ifelse } aload pop
  370.         ] cvx bind 5 index /CIDFont resourceforall
  371.  
  372.     exit
  373.   } loop % This loop is a pattern for execstack_lookup - don't remove !
  374.  
  375.   %% Make the list of fonts in the form (/Name status) :
  376.  
  377.                                           % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
  378.   dup {                                              
  379.     pop dup
  380.     //ResourceStatus exec {                        
  381.       pop 2 index                         % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>> /Name nStatus <<Font>>
  382.       3 1 roll put                        % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
  383.     } {
  384.       pop
  385.     } ifelse
  386.   } forall                                % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
  387.  
  388.   %% Add CIDFont-CMap to it (filtering duplicates) :
  389.  
  390.   3 2 roll  {                                        
  391.     3 index {                                        
  392.       3 1 roll                            % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /CIDFont /CMap
  393.       6 index //ComposeName exec          % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap (Font)
  394.       dup 8 index .stringmatch {              
  395.         cvn                               % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /Font
  396.         dup 4 index exch known {
  397.           pop pop
  398.         } {                                            
  399.           2 index                         % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /Font /CIDFont
  400.           4 2 roll                        % (templ) proc (scr) <<CMap>> <<Font>> /Font /CIDFont /CIDFont /CMap
  401.           //IsWellComposed exec {                
  402.             exch 2 index exch 2 put       % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont
  403.           } {
  404.             exch pop
  405.           } ifelse
  406.         } ifelse
  407.       } {
  408.         pop pop
  409.       } ifelse
  410.       dup                                 % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CIDFont
  411.     } forall
  412.     pop pop                               % (templ) proc (scr) <<CMap>> <<Font>>
  413.   } forall                                % (templ) proc (scr) <<CMap>> <<Font>>
  414.   exch pop                                % (templ) proc (scr) <<Font>>
  415.   4 3 roll pop                            % proc (scr) <<Font>>
  416.  
  417.   % Make the enumerator and apply it :
  418.   /MappedCategoryRedefiner /ProcSet findresource /MakeResourceEnumerator get exec exec
  419.  
  420. } bind def
  421.  
  422.  
  423. currentdict end /Font exch /Category defineresource pop
  424. end
  425. setglobal .setlanguagelevel
  426.