464 lines
14 KiB
PostScript
464 lines
14 KiB
PostScript
% Copyright (C) 1990, 1992 Aladdin Enterprises. All rights reserved.
|
|
% Distributed by Free Software Foundation, Inc.
|
|
%
|
|
% This file is part of Ghostscript.
|
|
%
|
|
% Ghostscript is distributed in the hope that it will be useful, but
|
|
% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
|
|
% to anyone for the consequences of using it or for whether it serves any
|
|
% particular purpose or works at all, unless he says so in writing. Refer
|
|
% to the Ghostscript General Public License for full details.
|
|
%
|
|
% Everyone is granted permission to copy, modify and redistribute
|
|
% Ghostscript, but only under the conditions described in the Ghostscript
|
|
% General Public License. A copy of this license is supposed to have been
|
|
% given to you along with Ghostscript so you can know your rights and
|
|
% responsibilities. It should be in a file named COPYING. Among other
|
|
% things, the copyright notice and this notice must be preserved on all
|
|
% copies.
|
|
|
|
% Font initialization for Ghostscript.
|
|
|
|
% Ghostscript fonts have essentially the same contents as Adobe Type 1 fonts,
|
|
% except that the external form doesn't use eexec encryption.
|
|
% Someday there may be GNU documentation that describes this format.
|
|
% Until then, you'll have to either get a copy of Adobe's book, or read
|
|
% the Ghostscript code. The interpreter for Type 1 fonts, which reveals
|
|
% most of their structure, is in the file gstype1.c.
|
|
|
|
|
|
% Define the default font.
|
|
/defaultfontname /Ugly def
|
|
|
|
% Load the font name -> font file name map.
|
|
FontDirectory maxlength dict
|
|
2 dict begin
|
|
mark 1 index
|
|
/;
|
|
{ % The stack contains a mark, the dictionary, the font name,
|
|
% the file or alias name, and possibly additional information
|
|
% about the font.
|
|
counttomark 3 sub { pop } repeat put
|
|
1 index
|
|
} bind def
|
|
(Fontmap) run
|
|
end
|
|
pop pop % pop the mark and the copy of the dictionary
|
|
userdict exch /Fontmap exch put
|
|
|
|
|
|
% Ghostscript optionally can load individual CharStrings as they are needed.
|
|
% (This is intended primarily for machines with very small memories.)
|
|
% This happens if DISKFONTS is true. In this case, we define another
|
|
% dictionary parallel to FontDirectory that retains an open file
|
|
% for every font loaded.
|
|
DISKFONTS
|
|
{ /FontFileDirectory FontDirectory maxlength dict def
|
|
}
|
|
if
|
|
|
|
|
|
% Define an augmented version of .buildfont1 that inserts UnderlinePosition
|
|
% and UnderlineThickness entries in FontInfo if they aren't there already.
|
|
% (This works around the incorrect assumption, made by many word processors,
|
|
% that these entries are present in the built-in fonts.)
|
|
/.buildfont1x
|
|
{ dup /FontInfo known not
|
|
{ dup /FontInfo 2 dict put }
|
|
if
|
|
dup dup /FontInfo get dup dup
|
|
/UnderlinePosition known exch /UnderlineThickness known and
|
|
{ pop pop % entries already present
|
|
}
|
|
{ dup length 2 add dict copy
|
|
dup /UnderlinePosition known not
|
|
{ dup /UnderlinePosition 3 index /FontBBox get
|
|
1 get 2 div put % 1/2 the font descent
|
|
}
|
|
if
|
|
dup /UnderlineThickness known not
|
|
{ dup /UnderlineThickness 3 index /FontBBox get
|
|
dup 3 get exch 1 get sub 20 div put % 1/20 the font height
|
|
}
|
|
if
|
|
1 index /FontInfo get wcheck not { readonly } if
|
|
/FontInfo exch put
|
|
}
|
|
ifelse .buildfont1
|
|
} bind def
|
|
% Define definefont. This is a procedure built on an operator that
|
|
% does all the error checking and key insertion.
|
|
/.buildfontdict 3 dict
|
|
/.buildfont0 where { pop dup 0 /.buildfont0 load put } if
|
|
/.buildfont1 where { pop dup 1 /.buildfont1x load put } if
|
|
/.buildfont3 where { pop dup 3 /.buildfont3 load put } if
|
|
def
|
|
/definefont
|
|
{ 1 dict begin count /d exch def % save stack depth in case of error
|
|
{ dup /FontType get .buildfontdict exch get exec
|
|
DISKFONTS
|
|
{ FontFileDirectory 2 index known
|
|
{ dup /FontFile FontFileDirectory 4 index get put
|
|
}
|
|
if
|
|
}
|
|
if
|
|
readonly
|
|
}
|
|
stopped
|
|
{ count d sub { pop } repeat end /invalidfont signalerror }
|
|
{ end dup FontDirectory 4 2 roll put }
|
|
ifelse
|
|
} odef
|
|
|
|
|
|
% Ghostscript optionally can load individual CharStrings as they are needed.
|
|
% (This is intended primarily for machines with very small memories.)
|
|
% Initially, the character definition is the file position of the definition;
|
|
% this gets replaced with the actual CharString.
|
|
% Note that if we are loading characters lazily, CharStrings is writable.
|
|
|
|
% _Cstring must be long enough to hold the longest CharString for
|
|
% a character defined using seac. This is lenIV + 4 * 5 (for the operands
|
|
% of sbw, assuming div is not used) + 2 (for sbw) + 3 * 5 (for the operands
|
|
% of seac other than the character codes) + 2 * 2 (for the character codes)
|
|
% + 2 (for seac), i.e., lenIV + 43.
|
|
|
|
/_Cstring 60 string def
|
|
|
|
% When we initially load the font, we call
|
|
% <index|charname> <length> /readstring|/readhexstring skip_C
|
|
% to skip over each character definition and return the file position instead.
|
|
% This substitutes for the procedure
|
|
% <length> string currentfile exch read[hex]string pop
|
|
% What we actually store is fileposition * 1000 + length,
|
|
% negated if the string is stored in binary form.
|
|
|
|
/skip_C
|
|
{ load exch dup 1000 ge 3 index type /nametype ne or
|
|
{ % This is a Subrs string, or the string is so long we can't represent
|
|
% its length. Load it now.
|
|
currentfile 3 1 roll string exch exec pop
|
|
}
|
|
{ % Record the position and length, and skip the string.
|
|
dup currentfile fileposition 1000 mul add
|
|
2 index /readstring load eq { neg } if
|
|
3 1 roll
|
|
dup _Cstring length idiv
|
|
{ currentfile _Cstring 3 index exec pop pop
|
|
} repeat
|
|
_Cstring length mod _Cstring exch 0 exch getinterval
|
|
currentfile exch 3 -1 roll exec pop pop
|
|
}
|
|
ifelse
|
|
} bind def
|
|
|
|
% Type1BuildChar calls load_C to actually load the character definition.
|
|
|
|
/load_C % charindex fileposandlength ->
|
|
{ exch Encoding exch get exch
|
|
read_C type1addpath
|
|
} bind def
|
|
|
|
/read_C % charname fileposandlength -> charstring
|
|
{ dup abs 1000 idiv FontFile exch setfileposition
|
|
CharStrings 3 1 roll
|
|
dup 0 lt
|
|
{ neg 1000 mod string FontFile exch readstring }
|
|
{ 1000 mod string FontFile exch readhexstring }
|
|
ifelse pop
|
|
dup 4 1 roll put
|
|
% If the character is defined with seac, load its components now.
|
|
dup mark exch seac_C
|
|
counttomark
|
|
{ StandardEncoding exch get dup CharStrings exch get
|
|
dup type /integertype eq { read_C } { pop } ifelse pop
|
|
} repeat
|
|
pop % the mark
|
|
} bind def
|
|
|
|
/seac_C % charstring -> achar bchar ..or nothing..
|
|
{ dup length _Cstring length le
|
|
{ 4330 exch _Cstring type1decrypt exch pop
|
|
dup dup length 2 sub 2 getinterval <0c06> eq % seac
|
|
{ dup length
|
|
Private /lenIV known { Private /lenIV get } { 4 } ifelse
|
|
exch 1 index sub getinterval
|
|
% Parse the string just enough to extract the seac information.
|
|
% We assume that the only possible operators are hsbw, sbw, and seac,
|
|
% and that there are no 5-byte numbers.
|
|
mark 0 3 -1 roll
|
|
{ exch
|
|
{ { dup 32 lt
|
|
{ pop 0 }
|
|
{ dup 247 lt
|
|
{ 139 sub 0 }
|
|
{ dup 251 lt
|
|
{ 247 sub 256 mul 108 add 1 1 }
|
|
{ 251 sub -256 mul -108 add -1 1 }
|
|
ifelse
|
|
}
|
|
ifelse
|
|
}
|
|
ifelse
|
|
} % 0
|
|
{ mul add 0 } % 1
|
|
}
|
|
exch get exec
|
|
}
|
|
forall pop
|
|
counttomark 1 add 2 roll cleartomark % pop all but achar bchar
|
|
}
|
|
{ pop % not seac
|
|
}
|
|
ifelse
|
|
}
|
|
{ pop % punt
|
|
}
|
|
ifelse
|
|
} bind def
|
|
|
|
% Define an auxiliary procedure for loading a font.
|
|
% If DISKFONTS is true:
|
|
% - Prevent the CharStrings from being made read-only.
|
|
% - Substitute a different CharString-reading procedure.
|
|
% If the body of the font is encrypted with eexec, this is disabled,
|
|
% because the implicit 'systemdict begin' hides the redefinitions.
|
|
% We assume that:
|
|
% - The magic procedures (-|, -!, |-, and |) are defined with
|
|
% executeonly or readonly;
|
|
% - The contents of the reading procedures are as defined in bdftops.ps;
|
|
% - The font ends with
|
|
% <font> <Private> <CharStrings>
|
|
% readonly put noaccess|readonly put
|
|
4 dict begin
|
|
/dict % leave room for FontFile
|
|
{ 1 add dict
|
|
} bind def
|
|
/executeonly % for reading procedures
|
|
{ readonly
|
|
} def
|
|
/noaccess % for Subrs strings and Private dictionary
|
|
{ readonly
|
|
} def
|
|
/readonly % for procedures and CharStrings dictionary
|
|
{ % We want to take the following non-standard actions here:
|
|
% - If the operand is the CharStrings dictionary, do nothing;
|
|
% - If the operand is a number (a file position replacing the
|
|
% actual CharString), do nothing;
|
|
% - If the operand is either of the reading procedures (-| or -!),
|
|
% substitute a different one.
|
|
dup type /dicttype eq % CharStrings or Private
|
|
{ 1 index /CharStrings ne { readonly } if }
|
|
{ dup type /arraytype eq % procedure or data array
|
|
{ dup length 5 eq 1 index xcheck and
|
|
{ dup 0 get /string eq
|
|
1 index 1 get /currentfile eq and
|
|
1 index 2 get /exch eq and
|
|
1 index 3 get dup /readstring eq exch /readhexstring eq or and
|
|
1 index 4 get /pop eq and
|
|
{ 3 get cvlit /skip_C cvx 2 packedarray cvx
|
|
}
|
|
{ readonly
|
|
}
|
|
ifelse
|
|
}
|
|
{ readonly
|
|
}
|
|
ifelse
|
|
}
|
|
{ dup type /stringtype eq % must be a Subr string
|
|
{ readonly }
|
|
if
|
|
}
|
|
ifelse
|
|
}
|
|
ifelse
|
|
} bind def
|
|
currentdict end /.loadfontdict exch def
|
|
/.loadfont % <file> .loadfont ->
|
|
{ mark exch systemdict begin
|
|
% We really would just like systemdict on the stack,
|
|
% but fonts produced by Fontographer require a writable dictionary....
|
|
userdict begin
|
|
DISKFONTS { .loadfontdict begin } if
|
|
% We can't just use `run', because we want to check for
|
|
% .PFB files. We can't save the packing status anywhere,
|
|
% so we need two separate control paths.
|
|
% Also, we would like to use `false /PFBDecode filter',
|
|
% but this occasionally produces a whitespace character as
|
|
% the first of an eexec section, so we can't do it.
|
|
currentpacking
|
|
{ false setpacking
|
|
{ dup read not { -1 } if
|
|
2 copy unread 16#80 eq { true /PFBDecode filter } if
|
|
cvx exec
|
|
} stopped % split up `execute'
|
|
true setpacking
|
|
$error /newerror get and {handleerror} if
|
|
}
|
|
{ { dup read not { -1 } if
|
|
2 copy unread 16#80 eq { true /PFBDecode filter } if
|
|
cvx exec
|
|
} execute
|
|
}
|
|
ifelse
|
|
DISKFONTS { end } if
|
|
end end cleartomark
|
|
} bind def
|
|
|
|
% Define findfont so it tries to load a font if it's not found.
|
|
/findfont
|
|
{ % Since PostScript has no concept of goto, or even blocks with
|
|
% exits, we use a loop as a way to get an exitable scope.
|
|
% The loop is never executed more than twice.
|
|
{
|
|
dup type /nametype ne % Convert the key to a name for lookup.
|
|
{ cvn } if
|
|
|
|
dup FontDirectory exch known % Already loaded?
|
|
{ FontDirectory exch get exit }
|
|
if
|
|
|
|
dup Fontmap exch known not % Unknown font name.
|
|
{ dup defaultfontname eq
|
|
{ (Default font ) print cvx =only
|
|
( not found in Fontmap! Giving up.\n) print flush
|
|
1 .quit
|
|
} if
|
|
QUIET not
|
|
{ (Substituting ) print defaultfontname cvx =only
|
|
( for unknown font ) print dup == flush
|
|
} if
|
|
pop defaultfontname findfont exit
|
|
}
|
|
if
|
|
|
|
dup Fontmap exch get
|
|
|
|
% Check for a font alias.
|
|
dup type /nametype eq
|
|
{ findfont
|
|
FontDirectory 2 index 2 index put
|
|
exch pop exit
|
|
}
|
|
if
|
|
|
|
% If we can't find the file, substitute for the font.
|
|
findlibfile
|
|
{ % Stack: fontname fontfilename fontfile
|
|
DISKFONTS
|
|
{ 1 index (r) file
|
|
FontFileDirectory exch 4 index exch put
|
|
}
|
|
if
|
|
QUIET not
|
|
{ (Loading ) print 2 index =only
|
|
( font from ) print exch print (... ) print flush }
|
|
{ exch pop }
|
|
ifelse
|
|
.loadfont
|
|
QUIET not
|
|
{ vmstatus 3 { =only ( ) print } repeat
|
|
(done.\n) print flush
|
|
} if
|
|
% Check to make sure the font was actually loaded.
|
|
dup FontDirectory exch known { findfont exit } if
|
|
|
|
(Loading ) print cvx =only
|
|
( font failed, substituting ) print defaultfontname cvx =only
|
|
(.\n) print flush
|
|
defaultfontname findfont exit
|
|
}
|
|
if
|
|
|
|
% findlibfile failed, substitute the default font.
|
|
% Stack: fontname fontfilename
|
|
(Can't find font file ) print print
|
|
dup defaultfontname eq
|
|
{ ( for default font \() print cvx =only
|
|
(\)! Giving up.\n) print flush 1 .quit
|
|
}
|
|
{ ( for font ) print cvx =only
|
|
(, substituting ) print defaultfontname cvx =only
|
|
(.\n) print flush
|
|
defaultfontname findfont
|
|
}
|
|
ifelse
|
|
exit
|
|
|
|
} loop % end of loop
|
|
|
|
} odef % bind def
|
|
|
|
|
|
% The CharStrings for a Ghostscript font are a dictionary in which
|
|
% the key is the character name, and the value is a compressed
|
|
% representation of a path, as produced by type1imagepath.
|
|
% For detailed information, see the book
|
|
% "Adobe Type 1 Font Format", published by Adobe Systems Inc.
|
|
|
|
% Here is the BuildChar implementation
|
|
% for Type 1 (Ghostscript standard) fonts.
|
|
% The name Type1BuildChar is known to the interpreter.
|
|
|
|
/Type1BuildChar
|
|
{ exch begin
|
|
dup Encoding exch get
|
|
dup CharStrings exch known not
|
|
{ QUIET not
|
|
{ (Substituting .notdef for ) print = flush
|
|
} { pop } ifelse
|
|
/.notdef
|
|
} if
|
|
currentdict /Metrics known
|
|
{ dup Metrics exch known
|
|
{ dup Metrics exch get .setmetrics } if
|
|
} if
|
|
CharStrings exch get
|
|
PaintType 0 ne
|
|
{ 1 setmiterlimit 1 setlinejoin 1 setlinecap
|
|
currentdict /StrokeWidth known { StrokeWidth } { 0 } ifelse
|
|
setlinewidth
|
|
} if
|
|
dup type /stringtype eq % encoded outline
|
|
{ type1addpath pop } % does a fill or stroke
|
|
{ dup type /integertype eq % file position for lazy loading
|
|
{ load_C
|
|
}
|
|
{ currentdict end systemdict begin begin
|
|
exec
|
|
end
|
|
}
|
|
ifelse
|
|
}
|
|
ifelse
|
|
end
|
|
} bind def
|
|
|
|
% Find all the precompiled font operators in systemdict.
|
|
systemdict
|
|
{ exch =string cvs (.font_) anchorsearch
|
|
{ pop pop exec % execute the operator, returns the font dictionary
|
|
dup begin
|
|
Encoding type /stringtype eq
|
|
{ Encoding cvn cvx exec /Encoding exch def
|
|
}
|
|
if
|
|
FontName exch
|
|
end definefont pop
|
|
}
|
|
{ pop pop
|
|
}
|
|
ifelse
|
|
}
|
|
forall
|
|
|
|
|
|
|
|
% Define a procedure to load all known fonts.
|
|
% This isn't likely to be very useful.
|
|
/loadallfonts
|
|
{ Fontmap { pop findfont pop } forall
|
|
} bind def
|