📄 gs_ttf.ps
字号:
% Copyright (C) 1996, 1997, 1998 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 $
% Support code for direct use of TrueType fonts.
% (Not needed for Type 42 fonts.)
% 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 { % only defined if DISKFONTS is recognized
pop /.scanfontheaders [ .scanfontheaders aload pop (\000\001\000\000*) ] 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 0 eq {
% 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 mark
/orgXUID 107 def % Aladdin Enterprises organization XUID
/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 mark
/.notdef /.null /CR
MacRomanEncoding 32 95 getinterval aload pop
MacRomanEncoding 128 45 getinterval aload pop
% 143
/notequal /AE
/Oslash /infinity /plusinus /lessequal /greaterequal
/yen /mu1 /partialdiff /summation /product
/pi /integral /ordfeminine /ordmasculine /Ohm
/ae /oslash /questiondown /exclamdown /logicalnot
/radical /florin /approxequal /increment /guillemotleft
/guillemotright /ellipsis /nbspace
MacRomanEncoding 203 12 getinterval aload pop
/lozenge
MacRomanEncoding 216 24 getinterval aload pop
/applelogo
MacRomanEncoding 241 7 getinterval aload pop
/overscore
MacRomanEncoding 249 7 getinterval aload pop
% 226
/Lslash /lslash /Scaron /scaron
/Zcaron /zcaron /brokenbar /Eth /eth
/Yacute /yacute /Thorn /thorn /minus
/multiply /onesuperior /twosuperior /threesuperior /onehalf
/onequarter /threequarters /franc /Gbreve /gbreve
/Idot /Scedilla /scedilla /Cacute /cacute
/Ccaron /ccaron /dmacron
/packedarray where
{ pop counttomark packedarray exch pop }
{ ] readonly }
ifelse def
% ---- Utilities ---- %
% <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:
% -mark- encodingtable <<proc>> -mark- glyphindices...
/cmapformats mark
0 % Apple standard 1-to-1 mapping.
{ 6 256 getinterval { } forall
} 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:
/firstcode startc 0 getu16 16#ff00 and dup 16#f000 ne { pop 0 } if def
pop /numcodes counttomark 1 sub 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 exch } 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 { } 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
} for
} ifelse
}
for
} bind
6 % Single interval lookup.
{ dup 6 getu16 { 0 exch } repeat
dup 8 getu16 0 exch 1 exch 1 sub
{ 2 mul 10 add 2 copy getu16 exch pop exch }
for pop
} bind
.dicttomark readonly def % cmapformats
% <cmaptab> cmaparray -mark- <glyphs> ...
/cmaparray {
mark exch dup 0 getu16 cmapformats exch .knownget {
exec
} {
(Can't handle format ) print 0 getu16 = flush
0 1 255 { } for
} ifelse
DEBUG {
([) print counttomark 1 sub -1 0 { index =only ( ) print } for (]) =
} if
} bind def
% Each procedure in this dictionary is called as follows:
% posttable <<proc>> glyphencoding
/postformats mark
16#00010000 { % 258 standard Macintosh glyphs.
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
(name) 1 index
(post) 1 index
(vhea) 1 index
% Big tables
(glyf) { .readbigtable }
(loca) 1 index
(hmtx) 1 index
(vmtx) 1 index
.dicttomark readonly 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -