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