home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 September / PCWorld_2001-09_cd.bin / Software / Vyzkuste / rychlokurz / gs700w32.exe / gs7.00 / lib / gs_cidfn.ps < prev    next >
Text File  |  2000-12-08  |  13KB  |  394 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_cidfn.ps,v 1.18 2000/12/08 23:35:38 lpd Exp $
  16. % ProcSet for implementing CIDFont and CIDMap resources.
  17. % When this is run, systemdict is still writable.
  18.  
  19. % ---------------- Defining CIDFont resources ---------------- %
  20.  
  21. % Define a CIDFont resource.  This is the defineresource implementation for
  22. % the CIDFont resource category.
  23.  
  24. /.checkfonttype {    % <cidfont> <fonttype> .checkfonttype <cidfont> <new?>
  25.   1 index /FID known {
  26.     1 index /FontType get ne {
  27.       /definefont cvx /invalidfont signalerror
  28.     } if false
  29.   } {
  30.     1 index /FontType 3 -1 roll put true
  31.   } ifelse
  32. } bind def
  33.  
  34. /.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse
  35. .cidfonttypes
  36.  
  37. 30 dict begin
  38.  
  39. % The key in .cidfonttypes is the CIDFontType value;
  40. % the value is a procedure that takes a font name and the CIDFont dictionary
  41. % and replaces the latter with a real font.
  42.  
  43. % ------ CIDFontType 0 (FontType 9) ------ %
  44.  
  45. % We add the following entries to the CIDFont dictionary, in addition to
  46. % the ones documented by Adobe:
  47. %    SubrCache - dictionary for caching Subr arrays
  48. % For CIDFonts where we read the data from disk incrementally:
  49. %    GlyphData is 0 (arbitrary)
  50. %    DataSource - a ReusableStreamDecode filter for the data
  51. % We also add a FID entry, and possibly a Subrs entry, to each element of
  52. % FDArray.
  53.  
  54. dup 0 {
  55.   9 .checkfonttype {
  56.     /CIDInit /ProcSet findresource begin
  57.     .completefont9
  58.     end
  59.   } if
  60.   1 index exch .buildfont9 exch pop
  61. } bind put
  62.  
  63. % Add entries to a new CIDFontType 0 font per documentation (FontMatrix)
  64. % or for .buildfont9 (FDArray.Private.Subrs).
  65. /.completefont9 {    % <cidfont0> .completefont9 <cidfont0>
  66.   currentglobal 3 1 roll dup gcheck setglobal
  67.   dup /FontMatrix known not {
  68.     dup /FontMatrix [0.001 0 0 0.001 0 0] put
  69.     dup /FDArray get {
  70.       /FontMatrix get [1000 0 0 1000 0 0] 1 index concatmatrix pop
  71.     } forall
  72.   } if
  73.   dup /FDArray get {
  74.         % Read the Subrs if necessary.
  75.     dup /Private get dup /Subrs known not {
  76.       dup /SubrCount .knownget {
  77.         % Stack: font Private SubrCount
  78.     currentglobal 3 1 roll 1 index gcheck setglobal
  79.     array 1 index /Subrs 3 -1 roll put
  80.         % Stack: font global Private
  81.     2 index begin begin .loadsubrs end end
  82.     setglobal
  83.       } {
  84.     pop
  85.       } ifelse readonly pop
  86.     } {
  87.       pop pop
  88.     } ifelse
  89.   } forall
  90.   3 -1 roll setglobal
  91. } bind def
  92.  
  93. % Read some Subrs for the current Type 1 subfont.
  94. % The subfont's Private dict is currentdict; the CIDFont itself is the
  95. % next dictionary on the stack.
  96. /.readsubrs {        % <Subrs> <start> .readsubrs <Subrs>
  97.   1 SubrCount 1 sub {
  98.     dup SDBytes mul SubrMapOffset add
  99.     dup SDBytes .readint exch SDBytes add SDBytes .readint
  100.     1 index sub string ReadString 2 index 3 1 roll put
  101.   } for
  102. } bind def
  103.  
  104. % Ensure that all the Subrs for the current Type 1 subfont are loaded.
  105. % The subfont's Private dict is currentdict; the CIDFont itself is the
  106. % next dictionary on the stack.
  107. /.loadsubrs {
  108.   Subrs length 0 ne {
  109.     SubrCache SubrMapOffset .knownget {
  110.         % We've already loaded some Subrs at this offset.
  111.         % Make sure we've got as many as we need.
  112.       dup length SubrCount lt {
  113.         % We need to load more.
  114.     SubrCount array exch 1 index copy length .readsubrs
  115.     SubrCache SubrMapOffset 2 index put
  116.       } if
  117.     } {
  118.         % We haven't loaded any Subrs at this offset yet.
  119.       SubrCount array 0 .readsubrs
  120.       SubrCache SubrMapOffset 2 index put
  121.     } ifelse
  122.     Subrs copy pop
  123.   } if
  124. } bind def
  125.  
  126. % ------ CIDFontType 1 (FontType 10) ------ %
  127.  
  128. dup 1 {
  129.   10 .checkfonttype pop
  130.   1 index exch .buildfont10 exch pop
  131. } bind put
  132.  
  133. % ------ CIDFontType 2 (FontType 11) ------ %
  134.  
  135. dup 2 {
  136.   11 .checkfonttype pop
  137.   1 index exch .buildfont11 exch pop
  138. } bind put
  139.  
  140. pop        % .cidfonttypes
  141.  
  142. % ---------------- Reading CIDFontType 0 files ---------------- %
  143.  
  144. /StartData {        % <(Binary)|(Hex)> <datalength> StartData -
  145.             %   (currentdict is CID font dict)
  146.         % If we're loading a resource file and the data format is
  147.         % binary, we can just save a pointer to the data and load it
  148.         % incrementally.
  149.   mark {
  150.         % Previous versions of this code made provisions for
  151.         % reading hex-encoded data incrementally.  Since hex data
  152.         % doesn't seem to be used in practice, we no longer bother.
  153.     2 index (Binary) ne { stop } if
  154.     currentfile .currentresourcefile ne { stop } if
  155.         % Hack: the pdfwrite driver relies on finalization to write
  156.         % out fonts.  However, the font may be finalized after the
  157.         % resource file, in which case the resource file will be
  158.         % closed.  So if the current output device is pdfwrite,
  159.         % don't use incremental loading.
  160.     currentdevice .devicename /pdfwrite eq { stop } if
  161.     currentfile fileposition
  162.   } .internalstopped {
  163.         % File is not positionable, or uses hex data.
  164.         % Load the data now.
  165.     cleartomark exch (Hex) eq
  166.       { { currentfile exch readhexstring pop } }
  167.       { { currentfile exch readstring pop } }
  168.     ifelse exch
  169.         % Stack: readproc length
  170.     dup 65400 le {
  171.         % readstring with a 0-length string causes a rangecheck,
  172.         % but a data length of 0 is allowed.
  173.       string dup () ne { 1 index exec } if
  174.     } {
  175.       mark 3 1 roll {
  176.         % Stack: mark str ... readproc length
  177.     dup 0 eq { pop exit } if
  178.     dup 65400 min dup string 3 index exec
  179.         % Stack: mark str ... readproc length newstrlen newstr
  180.     4 1 roll sub
  181.       } loop
  182.       counttomark 1 add 1 roll ]
  183.     } ifelse
  184.     /GlyphData exch def
  185.         % If we were reading hex data, skip past the >.
  186.     2 get { readhexstring } 0 get eq {
  187.       currentfile 0 (>) .subfiledecode dup flushfile closefile
  188.     } if
  189.   } {
  190.         % File is positionable and binary, just save a pointer.
  191.         % Stack: (Binary) length -mark- pos
  192.     /GlyphData 0 def
  193.     exch pop 3 -1 roll pop exch
  194.         % Stack: pos length
  195.     /DataSource currentfile 2 index () .subfiledecode true .reusablestream def
  196.     currentfile 3 1 roll add setfileposition
  197.   } ifelse
  198.   /SubrCache 10 dict def
  199.   CIDFontName currentdict /CIDFont defineresource pop
  200.   end            % CID font dict
  201.   end            % resource category dict
  202. } bind def
  203.  
  204. % Some Adobe fonts include the line
  205. %   /Setup /cid_Setup load def
  206. % This is apparently included only to prevent proper, conforming PostScript
  207. % interpreters (as opposed to ATM or a special Adobe font loader) from
  208. % loading the font, since Setup is not referenced anywhere else in the file.
  209. /cid_Setup { } def
  210.  
  211. currentdict end
  212.  
  213. % ---------------- Rendering ---------------- %
  214.  
  215. % ------ Generic ------ %
  216.  
  217. % Read a string at a given offset in a "file" (binary file or
  218. % GlyphData in RAM).
  219. /ReadString {        % <pos> <string> ReadString <string>
  220.   GlyphData 0 eq {
  221.     % Read from the file.
  222.     DataSource 3 -1 roll setfileposition
  223.     DataSource exch readstring pop
  224.   } {
  225.     % Read from a string or an array of strings.
  226.     GlyphData .stringsreadstring
  227.   } ifelse
  228. } bind def
  229. /.stringsreadstring    % <pos> <string> <strings> .stringsreadstring
  230.             %   <vmstring>
  231. { dup type /stringtype eq
  232.    { 3 1 roll length getinterval
  233.    }
  234.    {  {        % Stack: pos string glyphdata
  235.     dup 0 get length dup 4 index gt { exit } if
  236.     4 -1 roll exch sub 3 1 roll
  237.     dup length 1 sub 1 exch getinterval
  238.       }
  239.      loop
  240.         % Stack: pos string glyphdata glyphdata[0]length
  241.         % We know no request can span more than 2 strings.
  242.      3 index 3 index length add 1 index le
  243.       {        % Request fits in a single string: just return a substring.
  244.     pop 0 get 3 1 roll length getinterval
  245.       }
  246.       {        % Request spans 2 strings.  Copy the first part.
  247.     1 index 0 get 4 index 3 -1 roll 1 index sub getinterval
  248.     2 index copy
  249.         % Copy the second part.
  250.         % Stack: pos str glyphdata str1
  251.     length exch 1 get 0 3 index length
  252.     3 index sub getinterval 2 index 3 1 roll putinterval
  253.     exch pop
  254.       }
  255.      ifelse
  256.    }
  257.   ifelse
  258. } bind def
  259.  
  260. % Interpret a byte string as a (big-endian) integer.
  261. /.cvbsi            % <bytes> .cvbsi <int>
  262. { 0 exch { exch 8 bitshift add } forall
  263. } bind def
  264.  
  265. % Read an integer from binary data.
  266. /.readint        % <pos> <nbytes> .readint <int>
  267. { string ReadString .cvbsi
  268. } bind def
  269.  
  270. % ------ CIDFontType 0 ------ %
  271.  
  272. /.readglyphdata {
  273.   currentfont exch .type9mapcid
  274.   FDArray exch get exch
  275. } bind def
  276.  
  277. % BuildGlyph procedure for CIDFontType 0.
  278. % The name %Type9BuildGlyph is known to the interpreter.
  279. /.cid0buildstring 10 string def
  280. (%Type9BuildGlyph) cvn {    % <cidfont> <cid> %Type9BuildGlyph -
  281.   .currentglobal 3 1 roll 1 index gcheck .setglobal
  282.   1 index begin
  283.   dup .readglyphdata dup null eq {
  284.         % Substitute CID 0. **** WRONG ****
  285.     pop pop 0 .readglyphdata
  286.   } if
  287.         % Stack: cidfont cid subfont charstring
  288.   dup null eq { pop pop pop pop } {    %**** WRONG ****
  289.     4 -1 roll pop
  290.     3 1 roll exch dup 4 -1 roll 0 0 moveto
  291.     3 index /FontType get 2 eq { .type2execchar } { .type1execchar } ifelse
  292.   } ifelse    %**** WRONG ****
  293.   end
  294.   .setglobal
  295. } bind def
  296.  
  297. % ------ CIDFontType 2 ------ %
  298.  
  299. % BuildGlyph procedure for CIDFontType 2.
  300. % The name %Type11BuildGlyph is known to the interpreter.
  301. (%Type11BuildGlyph) cvn {    % <cidfont> <cid> %Type11BuildGlyph -
  302.         % We must be prepared for out-of-range CIDs.
  303.   2 copy { .type11mapcid } .internalstopped {
  304.     pop /CharStrings get /.notdef get
  305.   } if
  306.             % Stack: cidfont cid glyphindex
  307.   1 index exch .type42execchar
  308. } bind def
  309.  
  310. % ---------------- Define resources ---------------- %
  311.  
  312. languagelevel exch 2 .setlanguagelevel
  313.  
  314. % Define the CIDInit ProcSet resource.
  315. % The ProcSet dictionary is still on the stack.
  316.  
  317. % We might have loaded CMap support already.  However, Adobe's
  318. % protected font downloader defines a CIDInit ProcSet that will be
  319. % loaded from the filesystem later, so we must check specifically
  320. % for the ProcSet being defined in VM.
  321. /CIDInit /ProcSet 2 copy resourcestatus { pop 0 eq } { false } ifelse {
  322.   pop pop findresource dup length 4 index length add dict .copydict
  323.   4 -1 roll exch .copydict
  324. } {
  325.   3 -1 roll
  326. } ifelse exch defineresource pop
  327.  
  328. % Define the CIDFont resource category.
  329. % We break out .buildcidfont because it appears that at least for
  330. % Type 32 (CIDFontType 4) fonts, the font can be registered in the Font
  331. % category with only a CIDFontType and no FontType.
  332. /.buildcidfont {        % <name> <fontdict> .buildcidfont
  333.                 %   <name> <cidfont>
  334.   dup /CIDFontType get //.cidfonttypes exch get exec
  335. } odef
  336.  
  337. /CIDFont /Generic /Category findresource dup length dict .copydict
  338. dup /InstanceType /dicttype put
  339. dup /DefineResource {
  340.   .buildcidfont
  341.   /Generic /Category findresource /DefineResource get exec
  342. } put
  343. % CIDFonts may be defined in CFF OpenType files.
  344. % Check for this here.
  345. /.loadcidfontresource {
  346.   dup .ResourceFile {
  347.     {.loadfont} .execasresource
  348.   } {
  349.     dup /undefinedresource signalerror
  350.   } ifelse
  351. } bind def
  352. dup /.LoadResource {
  353.   currentglobal {
  354.     .loadcidfontresource
  355.   } {
  356.     true setglobal {.loadcidfontresource} stopped false setglobal {stop} if
  357.   } ifelse
  358. } bind put
  359.  
  360. /Category defineresource pop
  361.  
  362. % Add the new FontType resources.
  363.  
  364. 9 1 11 { dup /FontType defineresource pop } for
  365.  
  366. % Add the new FMapType resource.
  367.  
  368. 9 dup /FMapType defineresource pop
  369.  
  370. % Define the CIDMap resource category.
  371. % These aren't documented, but it's clear what they are for:
  372. % to give names to CIDMaps for CIDFontType 2 fonts.
  373.  
  374. /CIDMap /Generic /Category findresource dup length dict .copydict
  375. dup /.CheckResource {
  376.     % Allow a string, an array of strings, or (as of Adobe release 3011)
  377.     % a dictionary.
  378.   dup type dup dup /stringtype eq exch /dicttype eq or {
  379.     pop true
  380.   } {
  381.     dup /arraytype eq exch /packedarraytype eq or {
  382.       true exch { type /stringtype eq and } forall
  383.     } {
  384.       false
  385.     } ifelse
  386.   } ifelse
  387. } bind put
  388. /Category defineresource pop
  389.  
  390. .setlanguagelevel
  391.