home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / ghostscript / 8.64 / Resource / Init / gs_cidcm.ps < prev    next >
Encoding:
Text File  |  2009-04-17  |  17.0 KB  |  453 lines

  1. %    Copyright (C) 2000 Artifex Software, Inc.  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 9164 2008-10-17 13:44:34Z alexcher $
  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.   RESMPDEBUG { (cidcm GetCIDSystemInfoFromFile beg) = } if
  129.   //.prs_dict begin
  130.   /.prsFile exch def
  131.   /.prsResult //.prs_empty def
  132.   /.prsDictCount countdictstack def
  133.   RESMPDEBUG { (cidcm GetCIDSystemInfoFromFile will PrescanFile.) = } if
  134.   { //PrescanFile } stopped pop
  135.   //.prs_dict /.prsResult get
  136.   end
  137.   RESMPDEBUG { (cidcm GetCIDSystemInfoFromFile end) = } if
  138. } bind def
  139.  
  140. /GetCIDSystemInfo {     % <InstName> <CatName> GetCIDSystemInfo <CSI>
  141.   
  142.   % Retrieve CSI, using caches.
  143.  
  144.   RESMPDEBUG { (cidcm GetCIDSystemInfo beg) = } if
  145.   /Category findresource begin                % /InstName
  146.   dup ResourceStatus 
  147.   {
  148.     pop 2 lt {
  149.       FindResource /CIDSystemInfo .knownget not {
  150.         //.prs_empty
  151.       } if                                    % CSI
  152.     } {                                       % /InstName
  153.       currentdict /GetCIDSystemInfoFromMap .knownget {
  154.         exec
  155.       } if
  156.       dup type /nametype eq
  157.       {
  158.         RESMPDEBUG { (cidcm GetCIDSystemInfo got a name.) = } if
  159.         //.prs_dict Category get              % /InstName CSIs
  160.         dup 2 index known
  161.         //enable_cache and {
  162.           RESMPDEBUG { (cidcm GetCIDSystemInfo from cache.) = } if
  163.           exch get                            % CSI
  164.         } {
  165.           RESMPDEBUG { (cidcm GetCIDSystemInfo from file.) = } if
  166.           exch                                % CSIs /InstName
  167.           dup //path_buffer ResourceFileName  % CSIs /InstName (path)
  168.           RESMPDEBUG { (cidcm GetCIDSystemInfo from file ) print dup = } if
  169.           currentglobal exch true setglobal   % CSIs /InstName g (path)
  170.           mark exch                           % CSIs /InstName g [ (path)
  171.           { (r) file } stopped {
  172.             cleartomark //.prs_empty
  173.           } {
  174.             exch 1 index                      % CSIs /InstName g file [ file
  175.             //GetCIDSystemInfoFromFile stopped {
  176.               cleartomark closefile //.prs_empty
  177.             } {
  178.               exch pop exch closefile
  179.             } ifelse
  180.           } ifelse                            % CSIs /InstName g CSI
  181.           exch setglobal                      % CSIs /InstName CSI
  182.           dup 4 1 roll                        % CSI CSIs /InstName CSI
  183.           put                                 % CSI
  184.           RESMPDEBUG {
  185.             (cidcm GetCIDSystemInfo got from file : <<) print
  186.             dup { exch //=string cvs print ( ) print
  187.                        //=string cvs print ( ) print
  188.             } forall
  189.             (>>) =
  190.           } if
  191.         } ifelse
  192.       } if
  193.     } ifelse
  194.   } {
  195.     pop //.prs_empty
  196.   } ifelse
  197.   end
  198.   RESMPDEBUG { (cidcm GetCIDSystemInfo end) = } if
  199. } bind def
  200.  
  201. /IsCompatibleCSI {  % <CSI-M> <CSI-F> IsCompatibleCSI <bool>
  202.   
  203.   % The CSI in a CIDFont may be an array, a dict, or null.
  204.   % If it is an array, it must be of 1 element, which is a dict.
  205.   % In this case the dict is used for testing the compatibility.
  206.   % Two dicts are compatible iff they contain same /Ordering and /Registry.
  207.   % Identity CMap is compatible with any CIDFont.
  208.  
  209.   exch                                  % CSI-F CSI-M
  210.   { dup type /arraytype eq {
  211.       dup length 1 ne {
  212.         pop pop //false exit
  213.       } if
  214.       0 get
  215.     } if                                % CSI-F CSI-M
  216.     dup type /dicttype ne {
  217.       pop pop //false exit
  218.     } if                                % CSI-F <<CSI-M>>
  219.     exch                                % <<CSI-M>> CSI-F
  220.     dup type /dicttype ne {
  221.       pop pop //false exit
  222.     } if                                % <<CSI-M>> <<CSI-F>>
  223.     dup /Ordering .knownget {
  224.       /Identity eq {
  225.         pop pop //true exit
  226.       } if
  227.     } if
  228.     //true                              % <<CSI-M>> <<CSI-F>> bEQ
  229.     [/Registry /Ordering] {                    
  230.       2 index 1 index .knownget not {
  231.         1234567
  232.       } if                              % <<CSI-M>> <<CSI-F>> bEQ /key vF
  233.       exch                              % <<CSI-M>> <<CSI-F>> bEQ vF /key
  234.       4 index exch .knownget not {
  235.         7654321
  236.       } if                              % <<CSI-M>> <<CSI-F>> bEQ vF vM
  237.       eq and                            % <<CSI-M>> <<CSI-F>> bEQ
  238.     } forall
  239.     exch pop exch pop                   % bEQ
  240.     exit
  241.   } loop
  242. } bind def
  243.  
  244. /IsWellComposed {     % <CIDFontName> <CMapName> IsWellComposed <bool>
  245.   
  246.   % Check if the given CIDFont and CMap have compatible CSIs.
  247.   exch                                  % /CMapName /CIDFontName
  248.   /CIDFont //GetCIDSystemInfo exec      % /CMapName CSI-F
  249.   dup type /dicttype eq {
  250.     dup length 0 ne {                          
  251.       exch                              % CSI-F /CMapName
  252.       /CMap //GetCIDSystemInfo exec     % CSI-F CSI-M
  253.       //IsCompatibleCSI exec            % bool
  254.     } {
  255.       pop pop false
  256.     } ifelse
  257.   } {
  258.     pop pop false
  259.   } ifelse
  260. } bind def
  261.  
  262. /IsComposedFont {   % <FontName> IsComposedFont <CIDFontName> <CMapName> true
  263.                     % <FontName> IsComposedFont false
  264.   
  265.   % Check if the given font name may be decomposed into CIDFont.CMap, CIDFont-CMap
  266.   % or into CIDFont--CMap, such that CIDFont and CMap have compatible CSIs.
  267.                                         % FontName
  268.   dup type /stringtype ne {
  269.     //name_buffer cvs
  270.   } if                                  % (FontName)
  271.   { dup length 2 sub -1 1 {
  272.                                         % (FontName) i
  273.       2 copy get dup //minus eq exch //period eq or {                
  274.         2 copy 2 copy                   % (FontName) i (FontName) i (FontName) i
  275.         2 copy get //minus eq {
  276.           2 copy 1 sub get //minus eq {
  277.             1 sub
  278.           } if
  279.         } if                            % (FontName) i (FontName) i (FontName) i0
  280.         0 exch getinterval cvn          % (FontName) i (FontName) i /CIDFontName
  281.         3 1 roll                        % (FontName) i /CIDFontName (FontName) i
  282.         1 add dup                       % (FontName) i /CIDFontName (FontName) i1 i1
  283.         5 index length                  % (FontName) i /CIDFontName (FontName) i1 i1 l
  284.         exch sub getinterval cvn        % (FontName) i /CIDFontName /CMapName
  285.         2 copy //IsWellComposed exec {  % (FontName) i /CIDFontName /CMapName 
  286.           4 2 roll pop pop              % /CIDFontName /CMapName
  287.           stop
  288.         } if
  289.         pop pop pop
  290.       } {
  291.         pop
  292.       } ifelse                          % (FontName)
  293.     } for
  294.     pop
  295.   } stopped
  296. } bind def
  297.  
  298. /ComposeName { % <CIDFont> <CMap> <scr> ComposeName <CIDFont-CMap>
  299.   dup dup 5 2 roll                        % (scr) (scr) /CIDFont /CMap (scr)
  300.   3 2 roll exch cvs length dup            % (scr) (scr) /CMap l0 l0
  301.   4 -1 roll exch //minus put              % (scr) /CMap l0
  302.   1 add dup                               % (scr) /CMap l1 l1
  303.   3 index dup length                      % (scr) /CMap l1 l1 (scr) L
  304.   2 index sub                             % (scr) /CMap l1 l1 (scr) LT
  305.   3 2 roll                                % (scr) /CMap l1 (scr) LT l1
  306.   exch getinterval                        % (scr) /CMap l1 (scrT)
  307.   3 2 roll exch cvs length                % (scr) l1 l2
  308.   add 0 exch getinterval                  % (CIDFont-CMap)
  309. } bind def
  310.  
  311. % Redefine the /Font category with CIDFont-CMap construction :
  312.  
  313. % The following code supposes that the following names are not
  314. % defined in the old /Font category dictionary :
  315. % /IsComposedFont, /IsWellComposed .
  316.  
  317.  
  318. /Font /Category findresource dup length dict copy begin
  319.  
  320. /FindResource {  % <InstName> FindResource <inst>
  321.   dup //ResourceStatus exec {
  322.     pop pop //FindResource exec
  323.   } {                                                
  324.     dup //IsComposedFont exec {          % /FontName /CIDFontName /CMapName 
  325.       exch [ exch ] composefont          % inst
  326.     } {
  327.       //FindResource exec
  328.     } ifelse
  329.   } ifelse
  330. } bind def
  331.  
  332. /ResourceStatus {  % <InstName> ResourceStatus <nStatus> <nSize> true
  333.                    % <InstName> ResourceStatus false
  334.   dup //ResourceStatus exec {                    
  335.     3 2 roll pop true                     % nStatus nSize true
  336.   } {
  337.     //IsComposedFont exec {               % /CIDFontName /CMapName 
  338.       /CMap resourcestatus {              % /CIDFontName nStatusM nSizeM 
  339.         exch pop exch                     % nSizeM /CIDFontName 
  340.         /CIDFont resourcestatus {         % nSizeM nStatusF nSizeF 
  341.           exch pop                        % nSizeF nSizeM
  342.           dup 0 ge {
  343.             exch dup 0 ge {
  344.               add
  345.             } {
  346.               exch pop
  347.             } ifelse
  348.           } {
  349.             pop
  350.           } ifelse                        % nSize
  351.           2 exch true                     % nStatus nSize true
  352.         } {                        
  353.           pop pop pop false  % work around buggy resource file
  354.         } ifelse
  355.       } {                            
  356.         pop pop pop false    % work around buggy resource file
  357.       } ifelse
  358.     } {
  359.       false
  360.     } ifelse
  361.   } ifelse
  362. } bind def
  363.  
  364. /ResourceForAll { % <template> <proc> <scratch> ResourceForAll - 
  365.  
  366.   % We suppose that the resourceforall procedure does not 
  367.   % define or install new fonts, CMaps, and/or CIDFonts.
  368.  
  369.   % First we create 3 temporary dictionaries to store temporary data
  370.   % about fonts, CMaps and CIDFonts.
  371.   % These dictionaries must be created dynamically, to allow for a possible 
  372.   % recursive call to resourceforall from the resourceforall procedure.
  373.   currentglobal false setglobal
  374.   20 dict 20 dict 20 dict                  % (templ) proc (scr) g <<CIDFont>> <<CMap>> <<Fonts>>
  375.   
  376.  
  377.   % Store resource identifiers into local dictionaries
  378.   % A resource instance can have a key that is not a name or a string. In this
  379.   % case, resourceforall passes the key directly to proc instead of copying it
  380.   % into the scratch string. This case can arise only for a resource instance
  381.   % defined in virtual memory by a previous defineresource
  382.  
  383.   % Discard non-string keys of CIDFont and CMap because <CIDFontName>-<CMapName>
  384.   % is only defined for names.
  385.  
  386.   { /.DisableResourceOrdering pop % gs_resmp accesses this through execstack - don't remove !
  387.  
  388.     6 index [ 2 index {exch //null put} aload pop ] cvx bind 6 index //ResourceForAll exec
  389.  
  390.     (*) [ 3 index {exch dup type /stringtype eq { cvn dup put } { pop pop } ifelse } aload pop
  391.         ] cvx bind 6 index /CMap resourceforall
  392.  
  393.     (*) [ 4 index {exch dup type /stringtype eq { cvn dup put } { pop pop } ifelse } aload pop
  394.         ] cvx bind 6 index /CIDFont resourceforall
  395.  
  396.     exit
  397.   } loop % This loop is a pattern for execstack_lookup - don't remove !
  398.   4 -1 roll setglobal                     % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
  399.  
  400.   %% Make the list of fonts in the form (/Name status) :
  401.  
  402.                                           % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
  403.   dup {                                              
  404.     pop dup
  405.     //ResourceStatus exec {                        
  406.       pop 2 index                         % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>> /Name nStatus <<Font>>
  407.       3 1 roll put                        % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
  408.     } {
  409.       pop
  410.     } ifelse
  411.   } forall                                % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
  412.  
  413.   %% Add CIDFont-CMap to it (filtering duplicates) :
  414.  
  415.   3 2 roll  {                                        
  416.     3 index {                                        
  417.       3 1 roll                            % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /CIDFont /CMap
  418.       6 index //ComposeName exec          % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap (Font)
  419.       dup 8 index .stringmatch {              
  420.         cvn                               % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /Font
  421.         dup 4 index exch known {
  422.           pop pop
  423.         } {                                            
  424.           2 index                         % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /Font /CIDFont
  425.           4 2 roll                        % (templ) proc (scr) <<CMap>> <<Font>> /Font /CIDFont /CIDFont /CMap
  426.           //IsWellComposed exec {                
  427.             exch 2 index exch 2 put       % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont
  428.           } {
  429.             exch pop
  430.           } ifelse
  431.         } ifelse
  432.       } {
  433.         pop pop
  434.       } ifelse
  435.       dup                                 % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CIDFont
  436.     } forall
  437.     pop pop                               % (templ) proc (scr) <<CMap>> <<Font>>
  438.   } forall                                % (templ) proc (scr) <<CMap>> <<Font>>
  439.   exch pop                                % (templ) proc (scr) <<Font>>
  440.   4 3 roll pop                            % proc (scr) <<Font>>
  441.  
  442.   % Make the enumerator and apply it :
  443.   /MappedCategoryRedefiner /ProcSet findresource /MakeResourceEnumerator get exec exec
  444. } bind def
  445.  
  446.  
  447. currentdict end /Font exch /Category defineresource pop
  448. end
  449. setglobal .setlanguagelevel
  450.