home *** CD-ROM | disk | FTP | other *** search
- % Copyright (C) 1990, 1995, 1996, 1997 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.
-
- % Font initialization and management code.
-
- % Define the default font.
- /defaultfontname /Courier def
-
- % Define the name of the font map file.
- /defaultfontmap (Fontmap) def
-
- % ------ End of editable parameters ------ %
-
- % 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
- { //systemdict /FontDirectory get
- } 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 128 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.
- 50 dict exch
- { dup token not { closefile exit } if
- % stack: <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.\n) print flush
- {.loadFontmap} 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.\n) print flush
- {.loadFontmap} 0 get 1 .quit
- } if
- % stack: dict file fontname filename|aliasname
- % Read and pop tokens until a semicolon.
- { 2 index token not
- { (Fontmap entry for ) print 1 index =only
- ( ends prematurely! Giving up.\n) print flush
- {.loadFontmap} 0 get 1 .quit
- } if
- dup /; eq { pop 3 index 3 1 roll .growput exit } if
- pop
- } loop
- } loop
- { .definefontmap } forall
- } 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.
- .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 not { -1 } if
- 2 copy unread 16#80 eq
- { dup (xxxxxx) readstring pop pop } % skip .PFB header
- if
- % Stack: key file
- { dup token 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
- } 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>
- { { (/) 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
- % Following is debugging code.
- % (*** Split => ) print 2 copy exch ==only ( ) print ==only
- % ( ***\n) print flush
- } 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
- /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 128 string def
- /.scanfontheaders [(%!PS-Adobe*) (%!FontType*)] 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
- (*) 2 copy .filenamedirseparator
- dup (\\) eq { pop (\\\\) } if % double \ for pattern match
- exch concatstrings concatstrings
- 0 0 0 4 -1 roll % found scanned files
- { % stack: <fontcount> <scancount> <filecount> <filename>
- exch 1 add exch % increment filecount
- dup .splitfilename .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 } 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.\n) print flush
- }
- ifelse
- setglobal
- } bind def
-
- %END FONTPATH
-
- % 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.
- dup /Encoding get length 65 ge
- { dup /Encoding get 64 get
- dup /congruent eq { SymbolEncoding pop } if
- /a9 eq { DingbatsEncoding pop } if
- }
- if
- }
- ifelse
- dup /FontType get //buildfontdict exch get exec
- DISKFONTS
- { FontFileDirectory 2 index known
- { dup /FontFile FontFileDirectory 4 index get .growput
- }
- if
- }
- 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
- } odef
-
- % Define a procedure for defining aliased fonts.
- % We can't just copy the font (or even use the same font unchanged),
- % because a significant number of PostScript files assume that
- % the FontName of a font is the same as the font resource name or
- % the key in [Shared]FontDirectory; on the other hand, some Adobe files
- % rely on the FontName of a substituted font *not* being the same as
- % the requested resource name. We address this issue heuristically:
- % we substitute the new name iff the font name doesn't have MM in it.
- /.aliasfont % <name> <font> .aliasfont <newFont>
- { .currentglobal 3 1 roll dup .gcheck .setglobal
- dup length 2 add dict
- dup 3 -1 roll { 1 index /FID eq { pop pop } { put dup } ifelse } forall
- % Stack: global fontname newfont newfont.
- % We might be defining a global font whose FontName
- % is a local string. This is weird, but legal,
- % and doesn't cause problems anywhere else:
- % to avoid any possible problems in this case, do a cvn.
- % We might also be defining (as an alias) a global font
- % whose FontName is a local non-string, if someone passed a
- % garbage value to findfont. In this case, just don't
- % call definefont at all.
- 2 index dup type /stringtype eq exch .gcheck or 1 index .gcheck not or
- { 2 index .fonttempstring cvs (MM) search
- { pop pop pop pop
- }
- { /FontName exch dup type /stringtype eq { cvn } if put
- }
- ifelse
- % Don't bind in definefont, since Level 2 redefines it.
- //systemdict /definefont get exec
- }
- { .completefont pop exch pop
- }
- ifelse exch .setglobal
- } odef % so findfont will bind it
-
- % Define .loadfontfile for loading a font. If we recognize Type 1 and/or
- % TrueType fonts, gs_type1.ps and/or gs_ttf.ps will redefine this.
- /.loadfontfile { cvx exec } bind def
- /.loadfont
- { % Some buggy fonts leave extra junk on the stack,
- % so we have to make a closure that records the stack depth
- % in a fail-safe way.
- /.loadfontfile cvx count 1 sub 2 packedarray cvx exec
- count exch sub { pop } repeat
- } bind def
-
- % Find an alternate font to substitute for an unknown one.
- % We go to some trouble to parse the font name and extract
- % properties from it. Later entries take priority over earlier.
- /.substitutefaces [
- % Guess at suitable substitutions for random unknown fonts.
- [(Grot) /Times]
- [(Roman) /Times]
- [(Book) /NewCenturySchlbk]
- % If the family name appears in the font name,
- % use a font from that family.
- [(Arial) /Helvetica]
- [(Avant) /AvantGarde]
- [(Bookman) /Bookman]
- [(Century) /NewCenturySchlbk]
- [(Cour) /Courier]
- [(Geneva) /Helvetica]
- [(Helv) /Helvetica]
- [(NewYork) /Times]
- [(Pala) /Palatino]
- [(Sans) /Helvetica]
- [(Schlbk) /NewCenturySchlbk]
- [(Serif) /Times]
- [(Swiss) /Helvetica]
- [(Times) /Times]
- [(Univers) /Helvetica]
- % Substitute for Adobe Multiple Master fonts.
- [(Minion) /Times]
- [(Myriad) /Helvetica]
- [(MyriadPkg) /Helvetica-Narrow]
- % Condensed or narrow fonts map to the only narrow family we have.
- [(Cond) /Helvetica-Narrow]
- [(Narrow) /Helvetica-Narrow]
- % If the font wants to be monospace, use Courier.
- [(Monospace) /Courier]
- [(Typewriter) /Courier]
- ] readonly def
- /.substituteproperties [
- [(It) 1] [(Oblique) 1]
- [(Bd) 2] [(Bold) 2] [(bold) 2] [(Demi) 2] [(Heavy) 2] [(Sb) 2]
- ] readonly def
- /.substitutefamilies mark
- /AvantGarde
- {/AvantGarde-Book /AvantGarde-BookOblique
- /AvantGarde-Demi /AvantGarde-DemiOblique}
- /Bookman
- {/Bookman-Demi /Bookman-DemiItalic /Bookman-Light /Bookman-LightItalic}
- /Courier
- {/Courier /Courier-Oblique /Courier-Bold /Courier-BoldOblique}
- /Helvetica
- {/Helvetica /Helvetica-Oblique /Helvetica-Bold /Helvetica-BoldOblique}
- /Helvetica-Narrow
- {/Helvetica-Narrow /Helvetica-Narrow-Oblique
- /Helvetica-Narrow-Bold /Helvetica-Narrow-BoldOblique}
- /NewCenturySchlbk
- {/NewCenturySchlbk-Roman /NewCenturySchlbk-Italic
- /NewCenturySchlbk-Bold /NewCenturySchlbk-BoldItalic}
- /Palatino
- {/Palatino-Roman /Palatino-Italic /Palatino-Bold /Palatino-BoldItalic}
- /Times
- {/Times-Roman /Times-Italic /Times-Bold /Times-BoldItalic}
- .dicttomark readonly def
- /.substitutefont % <fontname> .substitutefont <altname>
- { % Look for properties and/or a face name in the font name.
- % If we find any, use Helvetica as the base font;
- % otherwise, use the default font.
- % Note that the "substituted" font name may be the same as
- % the requested one; the caller must check this.
- dup type dup /stringtype eq exch /nametype eq or
- { dup length string cvs } { () } ifelse
- {defaultfontname /Helvetica-Oblique /Helvetica-Bold /Helvetica-BoldOblique}
- exch 0 exch % stack: fontname facelist properties fontname
- % Look for a face name.
- .substitutefaces
- { 2 copy 0 get search
- { pop pop pop 1 get .substitutefamilies exch get
- 4 -1 roll pop 3 1 roll
- }
- { pop pop
- }
- ifelse
- }
- forall
- .substituteproperties
- { 2 copy 0 get search
- { pop pop pop 1 get 3 -1 roll or exch }
- { pop pop }
- ifelse
- }
- forall pop get exec
- % Only accept fonts known in the Fontmap.
- Fontmap 1 index known not { pop defaultfontname } if
- } bind def
-
- % If requested, make (and recognize) fake entries in FontDirectory for fonts
- % present in Fontmap but not actually loaded. Thanks to Ray Johnston for
- % the idea behind this code.
- FAKEFONTS not { (%END FAKEFONTS) .skipeof } if
-
- % We use the presence or absence of the FontMatrix key to indicate whether
- % a font is real or fake. We must pop the arguments at the very end,
- % so that stack protection will be effective.
-
- /definefont { % <name> <font> definefont <font>
- dup /FontMatrix known {
- //definefont
- } {
- 2 copy /FontName get findfont //definefont exch pop exch pop
- } ifelse
- } bind odef
-
- /scalefont { % <font> <scale> scalefont <font>
- 1 index /FontMatrix known {
- //scalefont
- } {
- 1 index /FontName get findfont 1 index //scalefont
- exch pop exch pop
- } ifelse
- } bind odef
-
- /makefont { % <font> <matrix> makefont <font>
- 1 index /FontMatrix known {
- //makefont
- } {
- 1 index /FontName get findfont 1 index //makefont
- exch pop exch pop
- } ifelse
- } bind odef
-
- /setfont { % <font> setfont -
- dup /FontMatrix known {
- //setfont
- } {
- dup /FontName get findfont //setfont pop
- } ifelse
- } bind odef
-
- %END FAKEFONTS
-
- % Define findfont so it tries to load a font if it's not found.
- % The Red Book requires that findfont be a procedure, not an operator,
- % but it still needs to restore the stacks reliably if it fails,
- % so we do all the work in an operator.
- /.findfont {
- mark 1 index
- //systemdict begin .dofindfont
- % Define any needed aliases.
- counttomark 1 sub { .aliasfont } repeat end
- exch pop exch pop
- } odef
- /findfont {
- .findfont
- } bind def
- % Check whether the font name we are about to look for is already on the list
- % of aliases we're accumulating; if so, cause an error.
- /.checkalias % -mark- <alias1> ... <name> .checkalias <<same>>
- { counttomark 1 sub -1 1
- { index 1 index eq
- { pop QUIET not
- { (Unable to substitute for font.\n) print flush
- } if
- /findfont cvx /invalidfont signalerror
- }
- if
- }
- for
- } bind def
- % Get a (non-fake) font if present in a FontDirectory.
- /.fontknownget % <fontdir> <fontname> .fontknownget <font> true
- % <fontdir> <fontname> .fontknownget false
- { .knownget
- { FAKEFONTS
- { dup /FontMatrix known { true } { pop false } ifelse }
- { true }
- ifelse
- }
- { false
- }
- ifelse
- } bind def
- % Do the work of findfont, including substitution, defaulting, and
- % scanning of FONTPATH.
- /.dofindfont % <fontname> .dofindfont <font>
- { { .tryfindfont { exit } if
- % We didn't find the font. If we haven't scanned
- % all the directories in FONTPATH, scan the next one now,
- % and look for the font again.
- null 0 1 FONTPATH length 1 sub
- { FONTPATH 1 index get null ne { exch pop exit } if pop
- }
- for dup null ne
- { dup 0 eq { .scanfontbegin } if
- FONTPATH 1 index get .scanfontdir
- FONTPATH exch null put
- % Start over with an empty alias list.
- counttomark 1 sub { pop } repeat
- .dofindfont exit
- }
- if pop
- % No luck. Make sure we're not already
- % looking for the default font.
- dup defaultfontname eq
- { QUIET not
- { (Unable to load default font ) print
- dup =only (! Giving up.\n) print flush
- }
- if /findfont cvx /invalidfont signalerror
- }
- if
- % Substitute for the font.
- % If SUBSTFONT is defined, don't alias.
- /SUBSTFONT where {
- pop QUIET not {
- (Substituting for font ) print dup =only
- (.\n) print flush
- } if
- cleartomark mark defaultfontname
- } {
- dup .substitutefont
- 2 copy eq { pop defaultfontname } if
- .checkalias
- QUIET not {
- (Substituting font ) print dup =only ( for ) print
- 1 index =only (.\n) print flush
- } if
- } ifelse
- }
- loop
- } bind def
- % Try to find a font using only the present contents of Fontmap.
- /.tryfindfont % <fontname> .tryfindfont <font> true
- % <fontname> .tryfindfont false
- { .FontDirectory 1 index .fontknownget
- { % Already loaded
- exch pop true
- }
- { dup Fontmap exch .knownget not
- { % Unknown font name. Look for a file with the
- % same name as the requested font.
- dup dup type /nametype eq { .namestring } if .loadfontloop
- }
- { % Try each element of the Fontmap in turn.
- false exch % (in case we exhaust the list)
- % Stack: fontname false fontmaplist
- { exch pop
- dup type /nametype eq
- { % Font alias
- .checkalias .tryfindfont exit
- }
- { dup dup type dup /arraytype eq exch /packedarraytype eq or exch xcheck and
- { % Font with a procedural definition
- exec % The procedure will load the font.
- % Check to make sure this really happened.
- .FontDirectory 1 index .knownget
- { exch pop true exit }
- if
- }
- { % Font file name
- .loadfontloop { true exit } if
- }
- ifelse
- }
- ifelse false
- }
- forall
- % Stack: font true -or- fontname false
- { true
- }
- { % None of the Fontmap entries worked.
- % Try loading a file with the same name
- % as the requested font.
- dup dup type /nametype eq { .namestring } if .loadfontloop
- }
- ifelse
- }
- ifelse
- }
- ifelse
- } bind def
- % Attempt to load a font from a file.
- /.loadfontloop % <filename> .loadfontloop <font> true
- % <filename> .loadfontloop false
- { % See above regarding the use of 'loop'.
-
- {
- % Is the font name a string?
- dup type /stringtype ne
- { QUIET not
- { (Can't find font with non-string name: ) print dup =only (.\n) print flush
- }
- if pop false exit
- }
- if
- % Can we open the file?
- findlibfile not
- { QUIET not
- { (Can't find \(or can't open\) font file ) print dup print
- (.\n) print flush
- }
- if pop false exit
- }
- if
-
- % Stack: fontname fontfilename fontfile
- DISKFONTS
- { .currentglobal true .setglobal
- 2 index (r) file
- FontFileDirectory exch 5 index exch .growput
- .setglobal
- }
- if
- QUIET not
- { (Loading ) print 2 index =only
- ( font from ) print 1 index print (... ) print flush
- }
- if
- % If LOCALFONTS isn't set, load the font into local or global
- % VM according to FontType; if LOCALFONTS is set, load the font
- % into the current VM, which is what Adobe printers (but not
- % DPS or CPSI) do.
- LOCALFONTS { false } { /setglobal where } ifelse
- { pop /FontType .findfontvalue { 1 eq } { false } ifelse
- % .setglobal, like setglobal, aliases FontDirectory to
- % GlobalFontDirectory if appropriate. However, we mustn't
- % allow the current version of .setglobal to be bound in,
- % because it's different depending on language level.
- .currentglobal exch /.setglobal load exec
- % Remove the fake definition, if any.
- .FontDirectory 3 index .undef
- 1 index (r) file .loadfont .FontDirectory exch
- /.setglobal load exec
- }
- { .loadfont .FontDirectory
- }
- ifelse
- % Stack: fontname fontfilename fontdirectory
- QUIET not
- { //systemdict /level2dict known
- { .currentglobal false .setglobal vmstatus
- true .setglobal vmstatus 3 -1 roll pop
- 6 -1 roll .setglobal 5
- }
- { vmstatus 3
- }
- ifelse { =only ( ) print } repeat
- (done.\n) print flush
- } if
-
- % Check to make sure the font was actually loaded.
- dup 3 index .fontknownget
- { 4 1 roll pop pop pop true exit } if
-
- % Maybe the file had a different FontName.
- % See if we can get a FontName from the file, and if so,
- % whether a font by that name exists now.
- exch (r) file .findfontname
- { 2 copy .fontknownget
- { % Yes. Stack: origfontname fontdirectory filefontname fontdict
- 3 -1 roll pop exch
- QUIET
- { pop
- }
- { (Using ) print =only
- ( font for ) print 1 index =only
- (.\n) print flush
- }
- ifelse true exit
- }
- if pop
- }
- if pop
-
- % The font definitely did not load correctly.
- QUIET not
- { (Loading ) print dup =only
- ( font failed.\n) print flush
- } if
- false exit
-
- } loop % end of loop
-
- } bind def
-
- % Define a procedure to load all known fonts.
- % This isn't likely to be very useful.
- /loadallfonts
- { Fontmap { pop findfont pop } forall
- } bind def
-
- % If requested, load all the fonts defined in the Fontmap into FontDirectory
- % as "fake" fonts i.e., font dicts with only FontName and FontType defined.
- % (We define FontType only to for the sake of some questionable code in the
- % Apple Printer Utility 2.0 font inquiry code.) We must ensure that this
- % happens in both global and local directories.
- /.definefakefonts
- {
- }
- { (gs_fonts FAKEFONTS) VMDEBUG
- 2
- { .currentglobal not .setglobal
- Fontmap
- { pop dup type /stringtype eq { cvn } if
- .FontDirectory 1 index known not
- { 2 dict dup /FontName 3 index put
- dup /FontType 1 put
- .FontDirectory 3 1 roll put
- }
- { pop
- }
- ifelse
- }
- forall
- }
- repeat
- }
- FAKEFONTS { exch } if pop def % don't bind, .current/setglobal get redefined
-
- % Install initial fonts from Fontmap.
- /.loadinitialfonts
- { NOFONTMAP not
- { /FONTMAP where
- { pop [ FONTMAP .pathlist ]
- { dup VMDEBUG findlibfile
- { exch pop .loadFontmap }
- { /undefinedfilename signalerror }
- ifelse
- }
- }
- { LIBPATH
- { defaultfontmap 2 copy .filenamedirseparator
- exch concatstrings concatstrings dup VMDEBUG
- (r) { file } .internalstopped
- { pop pop } { .loadFontmap } ifelse
- }
- }
- ifelse forall
- }
- if
- .definefakefonts
- } def % don't bind, .current/setglobal get redefined
-
- % ---------------- Synthetic font support ---------------- %
-
- % Create a new font by modifying an existing one. paramdict contains
- % entries with the same keys as the ones found in a Type 1 font;
- % it should also contain enough empty entries to allow adding the
- % corresponding non-overridden entries from the original font dictionary,
- % including FID. If paramdict includes a FontInfo entry, this will
- % also override the original font's FontInfo, entry by entry;
- % again, it must contain enough empty entries.
-
- % Note that this procedure does not perform a definefont.
-
- /.makemodifiedfont % <fontdict> <paramdict> .makemodifiedfont <fontdict'>
- { exch
- { % Stack: destdict key value
- 1 index /FID ne
- { 2 index 2 index known
- { % Skip fontdict entry supplied in paramdict, but
- % handle FontInfo specially.
- 1 index /FontInfo eq
- { 2 index 2 index get % new FontInfo
- 1 index % old FontInfo
- { % Stack: destdict key value destinfo key value
- 2 index 2 index known
- { pop pop }
- { 2 index 3 1 roll put }
- ifelse
- }
- forall pop
- }
- if
- }
- { % No override, copy the fontdict entry.
- 2 index 3 1 roll put
- dup dup % to match pop pop below
- }
- ifelse
- }
- if
- pop pop
- } forall
- } bind def
-
- % Make a modified font and define it. Note that unlike definefont,
- % this does not leave the font on the operand stack.
-
- /.definemodifiedfont % <fontdict> <paramdict> .definemodifiedfont -
- { .makemodifiedfont
- dup /FontName get exch definefont pop
- } bind def
-