% Copyright (C) 1990-2003 artofcode LLC. All rights reserved.% % This software is provided AS-IS with no warranty, either express or% implied.% % This software is distributed under license and may not be copied,% modified or distributed except as expressly authorized under the terms% of the license contained in the file LICENSE in this distribution.% % For more information about licensing, please refer to% http://www.ghostscript.com/licensing/. For information on% commercial licensing, go to http://www.artifex.com/licensing/ or% contact Artifex Software, Inc., 101 Lucas Valley Road #110,% San Rafael, CA 94903, U.S.A., +1(415)492-9861. % $Id: gs_fonts.ps,v 1.48 2004/11/24 20:09:01 ghostgum Exp $% Font initialization and management code. % Define the default font./defaultfontname /Courier def % Define the name of the font map file.% Note that the "%%Replace " comment below provides the font map file name% for compiling initialization files into executable. Most likely it should be% consistent with the one specified here./defaultfontmap (Fontmap) def /defaultfontmap_content 50 dict1 dict begin/; { 2 index 3 1 roll .growput } bind def%% Replace 0 (Fontmap)end def % ------ End of editable parameters ------ % % Define the UniqueIDs and organization XUID assigned to Aladdin.% UniqueIDs 5,066,501 - 5,066,580 are assigned as follows:% 01 and 02 for shareware Cyrillic% 33 through 67 for Type 1 versions of the Hershey fonts% UniqueIDs 5,115,501 - 5,115,600 are currently unassigned./AladdinEnterprisesXUID 107 def % If SUBSTFONT is defined, make it the default font./SUBSTFONT where { pop /defaultfontname /SUBSTFONT load def } if % Define a reliable way of accessing FontDirectory in systemdict./.FontDirectory{ /FontDirectory .systemvar} .bind odef % If DISKFONTS is true, we load individual CharStrings as they are needed.% (This is intended primarily for machines with very small memories.)% In this case, we define another dictionary, parallel to FontDirectory,% that retains an open file for every font loaded./FontFileDirectory 10 dict def % Define a temporary string for local use, since using =string% interferes with some PostScript programs./.fonttempstring 8192 string def % Split up a search path into individual directories or files./.pathlist % <path> .pathlist <dir1|file1> ... { { dup length 0 eq { pop exit } if .filenamelistseparator search not { exit } if exch pop exch } loop } bind def % Load a font name -> font file name map.userdict /Fontmap .FontDirectory maxlength dict put/.loadFontmap { % <file> .loadFontmap - % We would like to simply execute .definefontmap as we read, % but we have to maintain backward compatibility with an older % specification that makes later entries override earlier % ones within the same file. 50 dict exch .readFontmap { .definefontmap } forall} bind def/.readFontmap { % <dict> <file> .readFontmap <dict> { dup token not { closefile exit } if % stack: dict file fontname % This is a hack to get around the absurd habit of MS-DOS editors % of adding an EOF character at the end of the file. dup (\032) eq { pop closefile exit } if 1 index token not { (Fontmap entry for ) print dup =only ( has no associated file or alias name! Giving up.) = flush {.readFontmap} 0 get 1 .quit } if dup type dup /stringtype eq exch /nametype eq or not { (Fontmap entry for ) print 1 index =only ( has an invalid file or alias name! Giving up.) = flush {.readFontmap} 0 get 1 .quit } if % stack: dict file fontname filename|aliasname 1 index type /stringtype eq 1 index type /nametype eq and 1 index xcheck and 1 index /run eq 2 index /.runlibfile eq or and { % This is an inclusion entry. pop findlibfile { exch pop } { file } ifelse 2 index exch .readFontmap pop } { % This is a real entry. % Read and pop tokens until a semicolon. { 2 index token not { (Fontmap entry for ) print 1 index =only ( ends prematurely! Giving up.) = flush {.loadFontmap} 0 get 1 .quit } if dup /; eq { pop 3 index 3 1 roll .growput exit } if pop } loop } ifelse } loop} bind def% Add an entry in Fontmap. We redefine this if the Level 2% resource machinery is loaded./.definefontmap % <fontname> <file|alias> .definefontmap - { % Since Fontmap is global, make sure the values are storable. % If the fontname contains Unicode (first byte == \000) and % this is not an alias definition, define an alias using ASCII % (stripping out the high \000 bytes). Observed with some TT fonts. 1 index 100 string cvs 0 get 0 eq 1 index type /nametype ne and { 1 index 100 string cvs dup length 2 div cvi string true exch 0 1 2 index length 1 sub { % stack: fontname filename fontnamestring addflag newstring index dup 4 index exch 2 mul get 0 ne { % High byte of pair is not \000 pop pop false exch exit } if dup 4 index exch 2 mul 1 add get 2 index 3 1 roll put } for exch { DEBUG { (\nAdding alias for: ) print 1 index ==only ( as: ) print dup == flush } if cvn exch cvn .definefontmap % recurse with an alias } { pop pop % discard the name } ifelse } if .currentglobal 3 1 roll true .setglobal dup type /stringtype eq { dup .gcheck not { dup length string copy } if } if Fontmap 3 -1 roll 2 copy .knownget { % Add an element to the end of the existing value, % unless it's the same as the current last element. mark exch aload pop counttomark 4 add -1 roll 2 copy eq { cleartomark pop pop } { ] readonly .growput } ifelse } { % Make a new entry. mark 4 -1 roll ] readonly .growput } ifelse .setglobal } bind def % Parse a font file just enough to find the FontName or FontType./.findfontvalue { % <file> <key> .findfontvalue <value> true % <file> <key> .findfontvalue false % Closes the file in either case. exch dup read { 2 copy unread 16#80 eq { dup (xxxxxx) readstring pop pop % skip .PFB header } if { % Stack: key file % Protect ourselves against syntax errors here. dup { token } stopped { pop false exit } if not { false exit } if % end of file dup /eexec eq { pop false exit } if % reached eexec section dup /Subrs eq { pop false exit } if % Subrs without eexec dup /CharStrings eq { pop false exit } if % CharStrings without eexec dup 3 index eq { xcheck not { dup token exit } if } % found key { pop } ifelse } loop % Stack: key file value true (or) % Stack: key file false dup { 4 } { 3 } ifelse -2 roll closefile pop } { closefile pop false } ifelse} bind def/.findfontname { /FontName .findfontvalue } bind def % If there is no FONTPATH, try to get one from the environment.NOFONTPATH { /FONTPATH () def } if/FONTPATH where { pop } { /FONTPATH (GS_FONTPATH) getenv not { () } if def }ifelseFONTPATH length 0 eq { (%END FONTPATH) .skipeof } if/FONTPATH [ FONTPATH .pathlist ] def % Scan directories looking for plausible fonts. "Plausible" means that% the file begins with %!PS-AdobeFont or %!FontType1, or with \200\001% followed by four arbitrary bytes and then either of these strings.% To speed up the search, we skip any file whose name appears in% the Fontmap (with any extension and upper/lower case variation) already,% and any file whose extension definitely indicates it is not a font.%% NOTE: The current implementation of this procedure is somewhat Unix/DOS-% specific. It assumes that '/' and '\' are directory separators, and that% the part of a file name following the last '.' is the extension.%/.lowerstring % <string> .lowerstring <lowerstring> { 0 1 2 index length 1 sub { 2 copy get dup 65 ge exch 90 le and { 2 copy 2 copy get 32 add put } if pop } for } bind def/.splitfilename { % <dir.../base.extn> .basename <base> <extn> % Make the file name read-only to detect aliasing bugs. % We really don't like doing this, but we've had one % such bug already. readonly { (/) search { true } { (\\) search } ifelse { pop pop } { exit } ifelse } loop dup { (.) search { pop pop } { exit } ifelse } loop 2 copy eq { pop () } { exch dup length 2 index length 1 add sub 0 exch getinterval exch } ifelse} bind def/.scanfontdict 1 dict def % establish a binding/.scanfontbegin { % Construct the table of all file names already in Fontmap. currentglobal true setglobal .scanfontdict dup maxlength Fontmap length 2 add .max .setmaxlength Fontmap { exch pop { dup type /stringtype eq { .splitfilename pop .fonttempstring copy .lowerstring cvn .scanfontdict exch true put } { pop } ifelse } forall } forall setglobal } bind def/.scanfontskip mark % Strings are converted to names anyway, so.... /afm true /bat true /c true /cmd true /com true /dir true /dll true /doc true /drv true /exe true /fon true /fot true /h true /o true /obj true /pfm true /pss true % Adobe Multiple Master font instances /txt true.dicttomark def/.scan1fontstring 8192 string def% %%BeginFont: is not per Adobe documentation, but a few fonts have it./.scanfontheaders [(%!PS-Adobe*) (%!FontType*) (%%BeginFont:*)] def0 .scanfontheaders { length .max } forall 6 add % extra for PFB header/.scan1fontfirst exch string def/.scanfontdir % <dirname> .scanfontdir - { currentglobal exch true setglobal QUIET not { (Scanning ) print dup print ( for fonts...) print flush } if [ 1 index ] (*) .generate_dir_list_templates 0 0 0 4 -1 roll % found scanned files { % stack: <fontcount> <scancount> <filecount> <filename> exch 1 add exch % increment filecount dup .splitfilename .fonttempstring copy .lowerstring % stack: <fontcount> <scancount> <filecount+1> <filename> % <BASE> <ext> .scanfontskip exch known exch .scanfontdict exch known or { pop % stack: <fontcount> <scancount> <filecount+1> } { 3 -1 roll 1 add 3 1 roll % stack: <fontcount> <scancount+1> <filecount+1> <filename> dup (r) { file } .internalstopped { pop pop null () % stack: <fontcount> <scancount+1> <filecount+1> <filename> % null () } { % On some platforms, the file operator will open directories, % but an error will occur if we try to read from one. % Handle this possibility here. dup .scan1fontfirst { readstring } .internalstopped { pop pop () } { pop } ifelse % stack: <fontcount> <scancount+1> <filecount+1> % <filename> <file> <header> } ifelse % Check for PFB file header. dup (\200\001????*) .stringmatch { dup length 6 sub 6 exch getinterval } if % Check for font file headers. false .scanfontheaders { 2 index exch .stringmatch or } forall exch pop { % stack: <fontcount> <scancount+1> <filecount+1> <filename> % <file> dup 0 setfileposition .findfontname { dup Fontmap exch known { pop pop } { exch copystring exch DEBUG { ( ) print dup =only flush } if 1 index .definefontmap .splitfilename pop true .scanfontdict 3 1 roll .growput % Increment fontcount. 3 -1 roll 1 add 3 1 roll } ifelse } { pop } ifelse } % .findfontname will have done a closefile in the above case. { dup null eq { pop } { closefile } ifelse pop } ifelse } ifelse } .scan1fontstring filenameforall QUIET { pop pop pop } { ( ) print =only ( files, ) print =only ( scanned, ) print =only ( new fonts.) = flush } ifelse pop setglobal } bind def %END FONTPATH % Try to enumerate native fonts registered with the os% and add them to the fontmap. This relies on a custom% operator which calls platform-specific C code. It% returns an array of arrays, each containing a pair% of strings: what the system thinks is the ps name,% and the access path./.setnativefontmapbuilt { % set whether we've been run systemdict exch /.nativefontmapbuilt exch .forceput } .bind executeonly deffalse .setnativefontmapbuilt/.buildnativefontmap { % - .buildnativefontmap <bool> QUIET not { (Querying operating system for font files...\n) print flush } if .getnativefonts dup { exch { % stack: [ (name) (path) ] % verify the font name ourselves dup 1 get (r) { file } stopped { % skip the entry if we can't open the returned path pop pop pop }{ % we could open the font file .findfontname not { dup 0 get } if % stack: (newname) [ (name) (path) ] % DEBUG { ( found ) print dup print (\n) print flush } if % add entry to the fontmap 1 index exch 0 exch dup type /nametype ne {cvn} if put aload pop .definefontmap } ifelse } forall } if % record that we've been run true .setnativefontmapbuilt} bind def % Create the dictionary that registers the .buildfont procedure% (called by definefont) for each FontType./buildfontdict 20 dict def % Register Type 3 fonts, which are always supported, for definefont.buildfontdict 3 /.buildfont3 cvx put % Register Type 0 fonts if they are supported. Strictly speaking,% we should do this in its own file (gs_type0.ps), but since this is% the only thing that would be in that file, it's simpler to put it here./.buildfont0 where { pop buildfontdict 0 /.buildfont0 cvx put } if % Define definefont. This is a procedure built on a set of operators% that do all the error checking and key insertion./.growfontdict { % Grow the font dictionary, if necessary, to ensure room for an % added entry, making sure there is at least one slot left for FID. dup maxlength 1 index length sub 2 lt { dup dup wcheck { .growdict } { .growdictlength dict .copydict } ifelse } { dup wcheck not { dup maxlength dict .copydict } if } ifelse } bind def /.completefont { { % Check for disabled platform fonts. NOPLATFONTS { % Make sure we leave room for FID. .growfontdict dup /ExactSize 0 put } { % Hack: if the Encoding looks like it might be the % Symbol or Dingbats encoding, load those now (for the % benefit of platform font matching) just in case % the font didn't actually reference them. % Note that some types of font don't have an Encoding. dup /Encoding .knownget { dup length 65 ge { 64 get dup /congruent eq { SymbolEncoding pop } if /a9 eq { DingbatsEncoding pop } if } { pop } ifelse } if } ifelse dup /.OrigFont known not { dup dup /.OrigFont exch .growput } if true exch % If this is a CIDFont, CIDFontType takes precedence % over FontType. dup /CIDFontType known { /.buildcidfont where { pop exch not exch % true => false } if } if exch { dup /FontType get //buildfontdict exch get exec } { .buildcidfont } ifelse DISKFONTS { FontFileDirectory 2 index known { dup /FontFile FontFileDirectory 4 index get .growput } if } if systemdict /ProvideUnicode .knownget not { false } if { /FontEmulationProcs /ProcSet findresource /ProvideUnicodeDecoding get exec } if readonly % stack: name fontdict } stopped { /invalidfont signalerror } if} bind odef/definefont { .completefont % If the current allocation mode is global, also enter % the font in LocalFontDirectory. .currentglobal { //systemdict /LocalFontDirectory .knownget { 2 index 2 index .growput } if } if dup .FontDirectory 4 -2 roll .growput % If the font originated as a resource, register it. currentfile .currentresourcefile eq { dup .registerfont } if } odef % Define a procedure for defining aliased fonts.% We use this only for explicitly aliased fonts, not substituted fonts:% we think this matches the observed behavior of Adobe interpreters./.aliasfont % <name> <font> .aliasfont <newFont> { .currentglobal 3 1 roll dup .gcheck .setglobal % <bool> <name> <font> dup length 2 add dict % <bool> <name> <font> <dict> dup 3 -1 roll % <bool> <name> <dict> <dict> <font> { 1 index /FID eq { pop pop } { put dup } ifelse } forall % <bool> <name> <dict> <dict> % Stack: global fontname newfont newfont.Lines 1–500 of 1207. Load more
% Copyright (C) 1990-2003 artofcode LLC. All rights reserved. % % This software is provided AS-IS with no warranty, either express or % implied. % % This software is distributed under license and may not be copied, % modified or distributed except as expressly authorized under the terms % of the license contained in the file LICENSE in this distribution. % % For more information about licensing, please refer to % http://www.ghostscript.com/licensing/. For information on % commercial licensing, go to http://www.artifex.com/licensing/ or % contact Artifex Software, Inc., 101 Lucas Valley Road #110, % San Rafael, CA 94903, U.S.A., +1(415)492-9861. % $Id: gs_fonts.ps,v 1.48 2004/11/24 20:09:01 ghostgum Exp $ % Font initialization and management code. % Define the default font. /defaultfontname /Courier def % Define the name of the font map file. % Note that the "%%Replace " comment below provides the font map file name % for compiling initialization files into executable. Most likely it should be % consistent with the one specified here. /defaultfontmap (Fontmap) def /defaultfontmap_content 50 dict 1 dict begin /; { 2 index 3 1 roll .growput } bind def %% Replace 0 (Fontmap) end def % ------ End of editable parameters ------ % % Define the UniqueIDs and organization XUID assigned to Aladdin. % UniqueIDs 5,066,501 - 5,066,580 are assigned as follows: % 01 and 02 for shareware Cyrillic % 33 through 67 for Type 1 versions of the Hershey fonts % UniqueIDs 5,115,501 - 5,115,600 are currently unassigned. /AladdinEnterprisesXUID 107 def % If SUBSTFONT is defined, make it the default font. /SUBSTFONT where { pop /defaultfontname /SUBSTFONT load def } if % Define a reliable way of accessing FontDirectory in systemdict. /.FontDirectory { /FontDirectory .systemvar } .bind odef % If DISKFONTS is true, we load individual CharStrings as they are needed. % (This is intended primarily for machines with very small memories.) % In this case, we define another dictionary, parallel to FontDirectory, % that retains an open file for every font loaded. /FontFileDirectory 10 dict def % Define a temporary string for local use, since using =string % interferes with some PostScript programs. /.fonttempstring 8192 string def % Split up a search path into individual directories or files. /.pathlist % <path> .pathlist <dir1|file1> ... { { dup length 0 eq { pop exit } if .filenamelistseparator search not { exit } if exch pop exch } loop } bind def % Load a font name -> font file name map. userdict /Fontmap .FontDirectory maxlength dict put /.loadFontmap { % <file> .loadFontmap - % We would like to simply execute .definefontmap as we read, % but we have to maintain backward compatibility with an older % specification that makes later entries override earlier % ones within the same file. 50 dict exch .readFontmap { .definefontmap } forall } bind def /.readFontmap { % <dict> <file> .readFontmap <dict> { dup token not { closefile exit } if % stack: dict file fontname % This is a hack to get around the absurd habit of MS-DOS editors % of adding an EOF character at the end of the file. dup (\032) eq { pop closefile exit } if 1 index token not { (Fontmap entry for ) print dup =only ( has no associated file or alias name! Giving up.) = flush {.readFontmap} 0 get 1 .quit } if dup type dup /stringtype eq exch /nametype eq or not { (Fontmap entry for ) print 1 index =only ( has an invalid file or alias name! Giving up.) = flush {.readFontmap} 0 get 1 .quit } if % stack: dict file fontname filename|aliasname 1 index type /stringtype eq 1 index type /nametype eq and 1 index xcheck and 1 index /run eq 2 index /.runlibfile eq or and { % This is an inclusion entry. pop findlibfile { exch pop } { file } ifelse 2 index exch .readFontmap pop } { % This is a real entry. % Read and pop tokens until a semicolon. { 2 index token not { (Fontmap entry for ) print 1 index =only ( ends prematurely! Giving up.) = flush {.loadFontmap} 0 get 1 .quit } if dup /; eq { pop 3 index 3 1 roll .growput exit } if pop } loop } ifelse } loop } bind def % Add an entry in Fontmap. We redefine this if the Level 2 % resource machinery is loaded. /.definefontmap % <fontname> <file|alias> .definefontmap - { % Since Fontmap is global, make sure the values are storable. % If the fontname contains Unicode (first byte == \000) and % this is not an alias definition, define an alias using ASCII % (stripping out the high \000 bytes). Observed with some TT fonts. 1 index 100 string cvs 0 get 0 eq 1 index type /nametype ne and { 1 index 100 string cvs dup length 2 div cvi string true exch 0 1 2 index length 1 sub { % stack: fontname filename fontnamestring addflag newstring index dup 4 index exch 2 mul get 0 ne { % High byte of pair is not \000 pop pop false exch exit } if dup 4 index exch 2 mul 1 add get 2 index 3 1 roll put } for exch { DEBUG { (\nAdding alias for: ) print 1 index ==only ( as: ) print dup == flush } if cvn exch cvn .definefontmap % recurse with an alias } { pop pop % discard the name } ifelse } if .currentglobal 3 1 roll true .setglobal dup type /stringtype eq { dup .gcheck not { dup length string copy } if } if Fontmap 3 -1 roll 2 copy .knownget { % Add an element to the end of the existing value, % unless it's the same as the current last element. mark exch aload pop counttomark 4 add -1 roll 2 copy eq { cleartomark pop pop } { ] readonly .growput } ifelse } { % Make a new entry. mark 4 -1 roll ] readonly .growput } ifelse .setglobal } bind def % Parse a font file just enough to find the FontName or FontType. /.findfontvalue { % <file> <key> .findfontvalue <value> true % <file> <key> .findfontvalue false % Closes the file in either case. exch dup read { 2 copy unread 16#80 eq { dup (xxxxxx) readstring pop pop % skip .PFB header } if { % Stack: key file % Protect ourselves against syntax errors here. dup { token } stopped { pop false exit } if not { false exit } if % end of file dup /eexec eq { pop false exit } if % reached eexec section dup /Subrs eq { pop false exit } if % Subrs without eexec dup /CharStrings eq { pop false exit } if % CharStrings without eexec dup 3 index eq { xcheck not { dup token exit } if } % found key { pop } ifelse } loop % Stack: key file value true (or) % Stack: key file false dup { 4 } { 3 } ifelse -2 roll closefile pop } { closefile pop false } ifelse } bind def /.findfontname { /FontName .findfontvalue } bind def % If there is no FONTPATH, try to get one from the environment. NOFONTPATH { /FONTPATH () def } if /FONTPATH where { pop } { /FONTPATH (GS_FONTPATH) getenv not { () } if def } ifelse FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if /FONTPATH [ FONTPATH .pathlist ] def % Scan directories looking for plausible fonts. "Plausible" means that % the file begins with %!PS-AdobeFont or %!FontType1, or with \200\001 % followed by four arbitrary bytes and then either of these strings. % To speed up the search, we skip any file whose name appears in % the Fontmap (with any extension and upper/lower case variation) already, % and any file whose extension definitely indicates it is not a font. % % NOTE: The current implementation of this procedure is somewhat Unix/DOS- % specific. It assumes that '/' and '\' are directory separators, and that % the part of a file name following the last '.' is the extension. % /.lowerstring % <string> .lowerstring <lowerstring> { 0 1 2 index length 1 sub { 2 copy get dup 65 ge exch 90 le and { 2 copy 2 copy get 32 add put } if pop } for } bind def /.splitfilename { % <dir.../base.extn> .basename <base> <extn> % Make the file name read-only to detect aliasing bugs. % We really don't like doing this, but we've had one % such bug already. readonly { (/) search { true } { (\\) search } ifelse { pop pop } { exit } ifelse } loop dup { (.) search { pop pop } { exit } ifelse } loop 2 copy eq { pop () } { exch dup length 2 index length 1 add sub 0 exch getinterval exch } ifelse } bind def /.scanfontdict 1 dict def % establish a binding /.scanfontbegin { % Construct the table of all file names already in Fontmap. currentglobal true setglobal .scanfontdict dup maxlength Fontmap length 2 add .max .setmaxlength Fontmap { exch pop { dup type /stringtype eq { .splitfilename pop .fonttempstring copy .lowerstring cvn .scanfontdict exch true put } { pop } ifelse } forall } forall setglobal } bind def /.scanfontskip mark % Strings are converted to names anyway, so.... /afm true /bat true /c true /cmd true /com true /dir true /dll true /doc true /drv true /exe true /fon true /fot true /h true /o true /obj true /pfm true /pss true % Adobe Multiple Master font instances /txt true .dicttomark def /.scan1fontstring 8192 string def % %%BeginFont: is not per Adobe documentation, but a few fonts have it. /.scanfontheaders [(%!PS-Adobe*) (%!FontType*) (%%BeginFont:*)] def 0 .scanfontheaders { length .max } forall 6 add % extra for PFB header /.scan1fontfirst exch string def /.scanfontdir % <dirname> .scanfontdir - { currentglobal exch true setglobal QUIET not { (Scanning ) print dup print ( for fonts...) print flush } if [ 1 index ] (*) .generate_dir_list_templates 0 0 0 4 -1 roll % found scanned files { % stack: <fontcount> <scancount> <filecount> <filename> exch 1 add exch % increment filecount dup .splitfilename .fonttempstring copy .lowerstring % stack: <fontcount> <scancount> <filecount+1> <filename> % <BASE> <ext> .scanfontskip exch known exch .scanfontdict exch known or { pop % stack: <fontcount> <scancount> <filecount+1> } { 3 -1 roll 1 add 3 1 roll % stack: <fontcount> <scancount+1> <filecount+1> <filename> dup (r) { file } .internalstopped { pop pop null () % stack: <fontcount> <scancount+1> <filecount+1> <filename> % null () } { % On some platforms, the file operator will open directories, % but an error will occur if we try to read from one. % Handle this possibility here. dup .scan1fontfirst { readstring } .internalstopped { pop pop () } { pop } ifelse % stack: <fontcount> <scancount+1> <filecount+1> % <filename> <file> <header> } ifelse % Check for PFB file header. dup (\200\001????*) .stringmatch { dup length 6 sub 6 exch getinterval } if % Check for font file headers. false .scanfontheaders { 2 index exch .stringmatch or } forall exch pop { % stack: <fontcount> <scancount+1> <filecount+1> <filename> % <file> dup 0 setfileposition .findfontname { dup Fontmap exch known { pop pop } { exch copystring exch DEBUG { ( ) print dup =only flush } if 1 index .definefontmap .splitfilename pop true .scanfontdict 3 1 roll .growput % Increment fontcount. 3 -1 roll 1 add 3 1 roll } ifelse } { pop } ifelse } % .findfontname will have done a closefile in the above case. { dup null eq { pop } { closefile } ifelse pop } ifelse } ifelse } .scan1fontstring filenameforall QUIET { pop pop pop } { ( ) print =only ( files, ) print =only ( scanned, ) print =only ( new fonts.) = flush } ifelse pop setglobal } bind def %END FONTPATH % Try to enumerate native fonts registered with the os % and add them to the fontmap. This relies on a custom % operator which calls platform-specific C code. It % returns an array of arrays, each containing a pair % of strings: what the system thinks is the ps name, % and the access path. /.setnativefontmapbuilt { % set whether we've been run systemdict exch /.nativefontmapbuilt exch .forceput } .bind executeonly def false .setnativefontmapbuilt /.buildnativefontmap { % - .buildnativefontmap <bool> QUIET not { (Querying operating system for font files...\n) print flush } if .getnativefonts dup { exch { % stack: [ (name) (path) ] % verify the font name ourselves dup 1 get (r) { file } stopped { % skip the entry if we can't open the returned path pop pop pop }{ % we could open the font file .findfontname not { dup 0 get } if % stack: (newname) [ (name) (path) ] % DEBUG { ( found ) print dup print (\n) print flush } if % add entry to the fontmap 1 index exch 0 exch dup type /nametype ne {cvn} if put aload pop .definefontmap } ifelse } forall } if % record that we've been run true .setnativefontmapbuilt } bind def % Create the dictionary that registers the .buildfont procedure % (called by definefont) for each FontType. /buildfontdict 20 dict def % Register Type 3 fonts, which are always supported, for definefont. buildfontdict 3 /.buildfont3 cvx put % Register Type 0 fonts if they are supported. Strictly speaking, % we should do this in its own file (gs_type0.ps), but since this is % the only thing that would be in that file, it's simpler to put it here. /.buildfont0 where { pop buildfontdict 0 /.buildfont0 cvx put } if % Define definefont. This is a procedure built on a set of operators % that do all the error checking and key insertion. /.growfontdict { % Grow the font dictionary, if necessary, to ensure room for an % added entry, making sure there is at least one slot left for FID. dup maxlength 1 index length sub 2 lt { dup dup wcheck { .growdict } { .growdictlength dict .copydict } ifelse } { dup wcheck not { dup maxlength dict .copydict } if } ifelse } bind def /.completefont { { % Check for disabled platform fonts. NOPLATFONTS { % Make sure we leave room for FID. .growfontdict dup /ExactSize 0 put } { % Hack: if the Encoding looks like it might be the % Symbol or Dingbats encoding, load those now (for the % benefit of platform font matching) just in case % the font didn't actually reference them. % Note that some types of font don't have an Encoding. dup /Encoding .knownget { dup length 65 ge { 64 get dup /congruent eq { SymbolEncoding pop } if /a9 eq { DingbatsEncoding pop } if } { pop } ifelse } if } ifelse dup /.OrigFont known not { dup dup /.OrigFont exch .growput } if true exch % If this is a CIDFont, CIDFontType takes precedence % over FontType. dup /CIDFontType known { /.buildcidfont where { pop exch not exch % true => false } if } if exch { dup /FontType get //buildfontdict exch get exec } { .buildcidfont } ifelse DISKFONTS { FontFileDirectory 2 index known { dup /FontFile FontFileDirectory 4 index get .growput } if } if systemdict /ProvideUnicode .knownget not { false } if { /FontEmulationProcs /ProcSet findresource /ProvideUnicodeDecoding get exec } if readonly % stack: name fontdict } stopped { /invalidfont signalerror } if } bind odef /definefont { .completefont % If the current allocation mode is global, also enter % the font in LocalFontDirectory. .currentglobal { //systemdict /LocalFontDirectory .knownget { 2 index 2 index .growput } if } if dup .FontDirectory 4 -2 roll .growput % If the font originated as a resource, register it. currentfile .currentresourcefile eq { dup .registerfont } if } odef % Define a procedure for defining aliased fonts. % We use this only for explicitly aliased fonts, not substituted fonts: % we think this matches the observed behavior of Adobe interpreters. /.aliasfont % <name> <font> .aliasfont <newFont> { .currentglobal 3 1 roll dup .gcheck .setglobal % <bool> <name> <font> dup length 2 add dict % <bool> <name> <font> <dict> dup 3 -1 roll % <bool> <name> <dict> <dict> <font> { 1 index /FID eq { pop pop } { put dup } ifelse } forall % <bool> <name> <dict> <dict> % Stack: global fontname newfont newfont.