henesyinit from p9fd787fda5 years agoHistory
766 lines · 22.4 KB · Text
RawDownload
%    Copyright (C) 1996, 2000 Aladdin Enterprises.  All rights reserved.%% This file is part of Aladdin Ghostscript.%% Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author% or distributor accepts any responsibility for the consequences of using it,% or for whether it serves any particular purpose or works at all, unless he% or she says so in writing.  Refer to the Aladdin Ghostscript Free Public% License (the "License") for full details.%% Every copy of Aladdin Ghostscript must include a copy of the License,% normally in a plain ASCII text file named PUBLIC.  The License grants you% the right to copy, modify and redistribute Aladdin Ghostscript, but only% under certain conditions described in the License.  Among other things, the% License requires that the copyright notice and this notice be preserved on% all copies. % $Id: gs_ttf.ps,v 1.3 2000/03/16 07:38:07 lpd Exp $% Support code for direct use of TrueType fonts.% (Not needed for Type 42 fonts.) % Note that if you want to use this file without including the ttfont.dev% option when you built Ghostscript, you will need to load the following% files before this one:%	lib/gs_mgl_e.ps%	lib/gs_mro_e.ps%	lib/gs_wan_e.ps % Thanks to B. Jackowski and GUST (the Polish TeX Users' Group) for% the glyf-splitting code. % ---------------- Font loading machinery ---------------- % % Augment the FONTPATH machinery so it recognizes TrueType fonts. /.scanfontheaders where {  pop /.scanfontheaders [   .scanfontheaders aload pop (\000\001\000\000*) (true*)  ] def} if % <file> <key> .findfontvalue <value> true% <file> <key> .findfontvalue false% Closes the file in either case./.findnonttfontvalue /.findfontvalue load def/.findfontvalue {  1 index read pop 2 index 1 index unread  dup 0 eq exch (t) 0 get eq or {		% If this is a font at all, it's a TrueType font.    dup /FontType eq {      pop closefile 42 true    } {      dup /FontName eq { pop .findttfontname } { pop closefile false } ifelse    } ifelse  } {		% Not a TrueType font.    .findnonttfontvalue  } ifelse} bind def % <file> .findttfontname <fname> true% <file> .findttfontname false% Closes the file in either case./.findttfontname {  .loadttfonttables  tabdict /name .knownget {    dup 8 getu32 f exch setfileposition    12 getu32 string f exch readstring pop    6 findname  } {    false  } ifelse  f closefile end end} bind def % Load a font file that might be a TrueType font. % <file> .loadfontfile -/.loadnonttfontfile /.loadfontfile load def/.loadfontfile {  dup read pop 2 copy unread 0 eq {		% If this is a font at all, it's a TrueType font.    .loadttfont pop  } {		% Not a TrueType font.    .loadnonttfontfile  } ifelse} bind def % ---------------- Automatic Type 42 generation ---------------- % % Load a TrueType font from a file as a Type 42 PostScript font.% The thing that makes this really messy is the handling of encodings.% There are 2 interacting tables that affect the encoding:%       'cmap' provides multiple maps from character codes to glyph indices%       'post' maps glyph indices to glyph names (if present)% What we need to get out of this is:%       Encoding mapping character codes to glyph names%         (the composition of cmap and post)%       CharStrings mapping glyph names to glyph indices%         (the inverse of post)% If the post table is missing, we have to take a guess based on the cmap% table. /.loadttfontdict 50 dict dup begin /orgXUID AladdinEnterprisesXUID def/maxstring 32000 def    % half the maximum length of a PostScript string,			% must be a multiple of 4 (for hmtx / loca / vmtx) % Define the Macintosh standard mapping from characters to glyph indices./MacRomanEncoding dup .findencoding def/MacGlyphEncoding dup .findencoding def % ---- Utilities ---- % % Define a serial number for creating unique XUIDs for TrueType fonts.% We used to use the checkSumAdjustment value from the font, but this is% not reliable, since some fonts don't set it correctly.% Note that we must do this in a string to make it immune to save/restore./xuidstring <80000000> def/curxuid {		% - curxuid <int>  0 xuidstring { exch 8 bitshift exch add } forall} bind def/nextxuid {		% - nextxuid -  3 -1 0 {    xuidstring 1 index 2 copy get dup 255 ne {      1 add put pop exit    } if pop 0 put pop  } for} bind def % <string> <index> getu16 <integer>/getu16 {  2 copy get 8 bitshift 3 1 roll 1 add get add} bind def % <string> <index> gets16 <integer>/gets16 {  getu16 16#8000 xor 16#8000 sub} bind def % <string> <index> getu32 <integer>/getu32 {  2 copy getu16 16 bitshift 3 1 roll 2 add getu16 add} bind def % <string> <index> gets32 <integer>/gets32 {  2 copy gets16 16 bitshift 3 1 roll 2 add getu16 add} bind def % <string> <index> <integer> putu16 -/putu16 {  3 copy -8 bitshift put  exch 1 add exch 16#ff and put} bind def % <string> <index> <integer> putu32 -/putu32 {  3 copy -16 bitshift putu16  exch 2 add exch 16#ffff and putu16} bind def % <nametable> <nameid> findname <string> true% <nametable> <nameid> findname false/findname {  false 3 1 roll 0 1 3 index 2 getu16 1 sub {		% Stack: false table id index    12 mul 6 add 2 index exch 12 getinterval    dup 6 getu16 2 index eq {		% We found the name we want.      exch pop		% Stack: false table record      dup 10 getu16 2 index 4 getu16 add      1 index 8 getu16 4 -1 roll 3 1 roll getinterval exch		% Stack: false string record		% Check for 8- vs. 16-bit characters.      is2byte { string2to1 } if true null 4 -1 roll exit    } if pop  } for pop pop} bind def % <namerecord> is2byte <bool>/is2byte {  dup 0 getu16 {    { pop true }		% Apple Unicode    { pop false }		% Macintosh Script manager    { 1 getu16 1 eq }		% ISO    { 1 getu16 1 eq }		% Microsoft  } exch get exec} bind def % <string2> string2to1 <string>/string2to1 {  dup length 2 idiv string dup  0 1 3 index length 1 sub {    3 index 1 index 2 mul 1 add get put dup  } for pop exch pop} bind def % <array> <lt-proc> sort <array>/sort {  1 index length 1 sub -1 1 {    2 index exch 2 copy get 3 copy	% arr proc arr i arr[i] arr i arr[i]    0 1 3 index 1 sub {      3 index 1 index get	% arr proc arr i arr[i] arr imax amax j arr[j]      2 index 1 index 10 index exec {	% ... amax < arr[j]	4 2 roll      } if pop pop    } for			% arr proc arr i arr[i] arr imax amax    4 -1 roll exch 4 1 roll put put  } for pop} def % Each procedure in this dictionary is called as follows:%       <encodingtable> proc <glypharray>/cmapformats mark  0 {		% Apple standard 1-to-1 mapping.    6 256 getinterval { } forall 256 packedarray  } bind  4 {		% Microsoft/Adobe segmented mapping.    /etab exch def    /nseg2 etab 6 getu16 def    14 /endc etab 2 index nseg2 getinterval def		% The Apple TrueType documentation omits the 2-byte		% 'reserved pad' that follows the endCount vector!    2 add    nseg2 add /startc etab 2 index nseg2 getinterval def    nseg2 add /iddelta etab 2 index nseg2 getinterval def    nseg2 add /idroff etab 2 index nseg2 getinterval def		% The following hack allows us to properly handle		% idiosyncratic fonts that start at 0xf000:    pop    /firstcode startc 0 getu16 16#ff00 and dup 16#f000 ne { pop 0 } if def    /putglyph {      glyphs code 3 -1 roll put /code code 1 add def    } bind def		% Do a first pass to compute the size of the glyphs array.    /numcodes 0 def /glyphs 0 0 2 nseg2 3 sub {		% Stack: /glyphs numglyphs i2      /i2 exch def      /scode startc i2 getu16 def      /ecode endc i2 getu16 def      numcodes scode firstcode sub		% Hack for fonts that have only 0x0000 and 0xf000 ranges      dup 16#e000 ge { 255 and } if      exch sub 0 max ecode scode sub 1 add add      exch 1 index add exch      numcodes add /numcodes exch def    } for array def		% Now fill in the array.    /numcodes 0 def /code 0 def    0 2 nseg2 3 sub {      /i2 exch def      /scode startc i2 getu16 def      /ecode endc i2 getu16 def      numcodes scode firstcode sub		% Hack for fonts that have only 0x0000 and 0xf000 ranges      dup 16#e000 ge { 255 and } if      exch sub 0 max dup { 0 putglyph } repeat      ecode scode sub 1 add add numcodes add /numcodes exch def      /delta iddelta i2 gets16 def      DEBUG {	(scode=) print scode =only	( ecode=) print ecode =only	( delta=) print delta =only	( droff=) print idroff i2 getu16 =      } if      idroff i2 getu16 dup 0 eq {	pop scode delta add 65535 and 1 ecode delta add 65535 and	{ putglyph } for      } {	% The +2 is for the 'reserved pad'.        /gloff exch 14 nseg2 3 mul add 2 add i2 add add def        0 1 ecode scode sub {	  2 mul gloff add etab exch getu16	  dup 0 ne { delta add 65535 and } if putglyph	} for      } ifelse    } for glyphs /glyphs null def	% for GC  } bind  6 {		% Single interval lookup.    dup 6 getu16 /firstcode exch def dup 8 getu16 /ng exch def    firstcode ng add array		% Stack: tab array		% Fill elements 0 .. firstcode-1 with 0    0 1 firstcode 1 sub { 2 copy 0 put pop } for    dup firstcode ng getinterval		% Stack: tab array subarray		% Fill elements firstcode .. firstcode+nvalue-1 with glyph values    0 1 ng 1 sub {      dup 2 mul 10 add 3 index exch getu16 3 copy put pop pop    } for pop exch pop  } bind.dicttomark readonly def                % cmapformats % <cmaptab> cmaparray <glypharray>/cmaparray {  dup 0 getu16 cmapformats exch .knownget {    DEBUG {      (cmap: format ) print 1 index 0 getu16 = flush    } if exec  } {    (Can't handle format ) print 0 getu16 = flush    0 1 255 { } for 256 packedarray  } ifelse  DEBUG {    (cmap: length=) print dup length = dup ==  } if} bind def % Each procedure in this dictionary is called as follows:%       posttable <<proc>> glyphencoding/postformats mark  16#00010000  {	% 258 standard Macintosh glyphs.    pop MacGlyphEncoding  }  16#00020000  {	% Detailed map, required by Microsoft fonts.    /postglyphs exch def      postglyphs 32 getu16 /numglyphs exch def      /glyphnames numglyphs 2 mul 34 add def      [ 0 1 numglyphs 1 sub {	2 mul 34 add postglyphs exch getu16	dup 258 lt {	  MacGlyphEncoding exch get	} {	  258 sub glyphnames exch {	    postglyphs 1 index get 1 add add	  } repeat	  1 add postglyphs exch 2 copy 1 sub get getinterval cvn	} ifelse      } for ]  } bind  16#00030000  {	% No map.    pop [ ]  } bind.dicttomark readonly def                % postformats % Each procedure in this dictionary is called as follows:%	<file> <length> -proc- <string|array_of_strings>% Note that each table must have an even length, because of a strange% Adobe requirement that each sfnts entry have even length./readtables mark	% Ordinary tables  (cmap) { .readtable }  (head) 1 index  (hhea) 1 index  (maxp) 1 index  (name) 1 index  (OS/2) 1 index  (post) 1 index  (vhea) 1 index	% Big tables  (glyf) { .readbigtable }  (loca) 1 index  (hmtx) 1 index  (vmtx) 1 index	% Tables only needed for embedding in PDF files  (cvt ) { .readtable }  (fpgm) 1 index  (prep) 1 index.dicttomark% Normally there would be a 'readonly' here, but the ttf2pf utility wants% to include the 'kern' table as well, so we leave the readtables dictionary% writable.def                % readtables % Read a table as a single string.% <file> <length> .readtable <string>/.readtable {  dup dup 1 and add string		% Stack: f len str  dup 0 4 -1 roll getinterval		% Stack: f str str1  3 -1 roll exch readstring pop pop} bind def % Read a big table (one that may exceed 64K).% <file> <length> .readbigtable <string[s]>/.readbigtable {  dup 65400 lt {    .readtable  } {    currentuserparams /VMReclaim get -2 vmreclaim    [ 4 2 roll {		% Stack: mark ... f left      dup maxstring le { exit } if      1 index maxstring string readstring pop 3 1 roll maxstring sub    } loop .readtable ]    exch vmreclaim  } ifelse} bind def end readonly def                % .loadttfontdict % <tab> .printtab -/.printtab {  dup 0 4 getinterval print ( ) print  dup 8 getu32 =only ( ) print  12 getu32 =} bind def % <file> .loadttfonttables -% Pushes .loadttfontdict & scratch dict on d-stack.% Defines f, offsets, tables, tabdict, tabs./.loadttfonttables {  .loadttfontdict begin  40 dict begin  /f exch def  /offsets f 12 string readstring pop def  /tables f offsets 4 getu16 16 mul string readstring pop def  /tabdict tables length 16 idiv dict def	% tabs = tables we want to keep, sorted by file position.  /tabs [ 0 16 tables length 1 sub {    tables exch 16 getinterval    DEBUG { dup .printtab } if    dup 0 4 getinterval readtables 1 index known {      tabdict exch 2 index put    } {      pop pop    } ifelse  } for ] {    exch 8 getu32 exch 8 getu32 lt  } sort def	% In certain malformed TrueType fonts, tables overlap.	% Truncate tables if necessary.  0 1 tabs length 2 sub {    dup tabs exch get exch 1 add tabs exch get    1 index 8 getu32 2 index 12 getu32 add    1 index 8 getu32 gt {      (**** Warning: ) print 1 index 0 4 getinterval print      ( overlaps ) print dup 0 4 getinterval print      (, truncating.) = flush      dup 8 getu32 2 index 8 getu32 sub      2 index 12 3 -1 roll putu32    } if pop pop  } for} bind def % - .readttdata -% Read data.  Updates offsets, tabs; stores data in tabdict./.readttdata {  /fpos offsets length tables length add def  /sfpos offsets length tabs length 16 mul add def  offsets 4 tabs length putu16  tabs {    dup 0 4 getinterval /tname exch def    dup 8 getu32 /tpos exch def    dup 12 getu32 /tlen exch def    8 sfpos putu32	% Skip data between the end of the previous table and	% the beginning of this one, if any.    tpos fpos gt {      f tpos fpos sub () /SubFileDecode filter dup flushfile closefile      /fpos tpos def    } if    f tlen readtables tname get exec    tabdict tname 3 -1 roll put    /fpos fpos tlen add def	% Round up the table length to an even value.    /sfpos sfpos tlen dup 1 and add add def  } forall} bind def % Find the string in a list of strings that includes a given index.% <strings> <index> .findseg <string> <index'>/.findseg {  exch {    dup length 2 index gt { exch exit } if    length sub  } forall} bind def % - .makesfnts -% Defines checksum, getloca, head, locatable, numloca, post, sfnts, upem/.makesfnts {  .readttdata  /head tabdict /head get def  /locatable tabdict /loca get def  /post tabdict /post .knownget not { null } if def  /numloca    locatable dup type /stringtype eq     { length }     { 0 exch { length add } forall }    ifelse	% no def yet  locatable type /stringtype eq {    /.indexloca {} def  } {    /.indexloca /.findseg load def  } ifelse  head 50 getu16 0 ne {    /getloca {      2 bitshift locatable exch .indexloca getu32    } def    4 idiv 1 sub  } {    /getloca {      dup add locatable exch .indexloca getu16 dup add    } def    2 idiv 1 sub

Lines 1–500 of 766.