📄 bdftops.ps
字号:
% Copyright (C) 1990, 1995, 1996 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: bdftops.ps $
% bdftops.ps
% Convert a BDF file (possibly with (an) associated AFM file(s))
% to a PostScript Type 1 font (without eexec encryption).
% The resulting font will work with any PostScript language interpreter,
% but not with ATM or other font rasterizers lacking a complete interpreter.
/envBDF 120 dict def
envBDF begin
% "Import" the image-to-path package.
% This also brings in the Type 1 opcodes (type1ops.ps).
(impath.ps) runlibfile
% "Import" the font-writing package.
(wrfont.ps) runlibfile
wrfont_dict begin
/binary_CharStrings false def
/binary_tokens false def
/encrypt_CharStrings true def
/standard_only true def
end
/lenIV 0 def
% Invert the StandardEncoding vector.
256 dict dup begin
0 1 255 { dup StandardEncoding exch get exch def } for
end /StandardDecoding exch def
% Define the properties copied to FontInfo.
mark
(COPYRIGHT) /Notice
(FAMILY_NAME) /FamilyName
(FULL_NAME) /FullName
(WEIGHT_NAME) /Weight
.dicttomark /properties exch def
% Define the character sequences for synthesizing missing composite
% characters in the standard encoding.
mark
/AE [/A /E]
/OE [/O /E]
/ae [/a /e]
/ellipsis [/period /period /period]
/emdash [/hyphen /hyphen /hyphen]
/endash [/hyphen /hyphen]
/fi [/f /i]
/fl [/f /l]
/germandbls [/s /s]
/guillemotleft [/less /less]
/guillemotright [/greater /greater]
/oe [/o /e]
/quotedblbase [/comma /comma]
.dicttomark /composites exch def
% Define the procedure for synthesizing composites.
% This must not be bound.
/compose
{ exch pop
FontMatrix Private /composematrix get invertmatrix concat
0 0 moveto
dup gsave false charpath pathbbox currentpoint grestore
6 2 roll setcachedevice show
} def
% Define the CharString procedure that calls compose, with the string
% on the stack. This too must remain unbound.
/compose_proc
{ Private /compose get exec
} def
% Define aliases for missing characters similarly.
mark
/acute /quoteright
/bullet /asterisk
/cedilla /comma
/circumflex /asciicircum
/dieresis /quotedbl
/dotlessi /i
/exclamdown /exclam
/florin /f
/fraction /slash
/grave /quoteleft
/guilsinglleft /less
/guilsinglright /greater
/hungarumlaut /quotedbl
/periodcentered /asterisk
/questiondown /question
/quotedblleft /quotedbl
/quotedblright /quotedbl
/quotesinglbase /comma
/quotesingle /quoteright
/tilde /asciitilde
.dicttomark /aliases exch def
% Define overstruck characters that can be synthesized with seac.
mark
[ /Aacute /Acircumflex /Adieresis /Agrave /Aring /Atilde
/Ccedilla
/Eacute /Ecircumflex /Edieresis /Egrave
/Iacute /Icircumflex /Idieresis /Igrave
/Lslash
/Ntilde
/Oacute /Ocircumflex /Odieresis /Ograve /Otilde
/Scaron
/Uacute /Ucircumflex /Udieresis /Ugrave
/Yacute /Ydieresis
/Zcaron
/aacute /acircumflex /adieresis /agrave /aring /atilde
/ccedilla
/eacute /ecircumflex /edieresis /egrave
/iacute /icircumflex /idieresis /igrave
/lslash
/ntilde
/oacute /ocircumflex /odieresis /ograve /otilde
/scaron
/uacute /ucircumflex /udieresis /ugrave
/yacute /ydieresis
/zcaron
]
{ dup =string cvs
[ exch dup 0 1 getinterval cvn
exch dup length 1 sub 1 exch getinterval cvn
]
} forall
/cent [/c /slash]
/daggerdbl [/bar /equal]
/divide [/colon /hyphen]
/sterling [/L /hyphen]
/yen [/Y /equal]
.dicttomark /accentedchars exch def
% ------ Output utilities ------ %
/ws {psfile exch writestring} bind def
/wl {ws (\n) ws} bind def
/wt {=string cvs ws ( ) ws} bind def
% ------ BDF file parsing utilities ------ %
% Define a buffer for reading the BDF file.
/buffer 400 string def
% Read a line from the BDF file into the buffer.
% Ignore empty (zero-length) lines.
% Define /keyword as the first word on the line.
% Define /args as the remainder of the line.
% If the keyword is equal to commentword, skip the line.
% (If commentword is equal to a space, never skip.)
/nextline
{ { bdfile buffer readline not
{ (Premature EOF\n) print stop } if
dup length 0 ne { exit } if pop
}
loop
( ) search
{ /keyword exch def pop }
{ /keyword exch def () }
ifelse
/args exch def
keyword commentword eq { nextline } if
} bind def
% Get a word argument from args. We do *not* copy the string.
/warg % warg -> string
{ args ( ) search
{ exch pop exch }
{ () }
ifelse /args exch def
} bind def
% Get an integer argument from args.
/iarg % iarg -> int
{ warg cvi
} bind def
% Get a numeric argument from args.
/narg % narg -> int|real
{ warg cvr
dup dup cvi eq { cvi } if
} bind def
% Convert the remainder of args into a string.
/remarg % remarg -> string
{ args copystring
} bind def
% Get a string argument that occupies the remainder of args.
/sarg % sarg -> string
{ args (") anchorsearch
{ pop /args exch def } { pop } ifelse
args args length 1 sub get (") 0 get eq
{ args 0 args length 1 sub getinterval /args exch def } if
args copystring
} bind def
% Check that the keyword is the expected one.
/checkline % (EXPECTED-KEYWORD) checkline ->
{ dup keyword ne
{ (Expected ) print =
(Line=) print keyword print ( ) print args print (\n) print stop
} if
pop
} bind def
% Read a line and check its keyword.
/getline % (EXPECTED-KEYWORD) getline ->
{ nextline checkline
} bind def
% Find the first/last non-zero bit of a non-zero byte.
/fnzb
{ 0 { exch dup 128 ge { pop exit } { dup add exch 1 add } ifelse }
loop
} bind def
/lnzb
{ 7 { exch dup 1 and 0 ne { pop exit } { -1 bitshift exch 1 sub } ifelse }
loop
} bind def
% ------ Type 1 encoding utilities ------ %
% Parse the side bearing and width information that begins a CharString.
% Arguments: charstring. Result: sbx sby wx wy substring.
/parsesbw
{ mark exch lenIV
{ % stack: mark ... string dropcount
dup 2 index length exch sub getinterval
dup 0 get dup 32 lt { pop exit } if
dup 246 le
{ 139 sub exch 1 }
{ dup 250 le
{ 247 sub 8 bitshift 108 add 1 index 1 get add exch 2 }
{ dup 254 le
{ 251 sub 8 bitshift 108 add 1 index 1 get add neg exch 2 }
{ pop dup 1 get 128 xor 128 sub
8 bitshift 1 index 2 get add
8 bitshift 1 index 3 get add
8 bitshift 1 index 4 get add exch 5
} ifelse
} ifelse
} ifelse
} loop
counttomark 3 eq { 0 3 1 roll 0 exch } if
6 -1 roll pop
} bind def
% Find the side bearing and width information that begins a CharString.
% Arguments: charstring. Result: charstring sizethroughsbw.
/findsbw
{ dup parsesbw 4 { exch pop } repeat skipsbw
} bind def
/skipsbw % charstring sbwprefix -> sizethroughsbw
{ length 1 index length exch sub
2 copy get 12 eq { 2 } { 1 } ifelse add
} bind def
% Encode a number, and append it to a string.
% Arguments: str num. Result: newstr.
/concatnum
{ dup dup -107 ge exch 107 le and
{ 139 add 1 string dup 0 3 index put }
{ dup dup -1131 ge exch 1131 le and
{ dup 0 ge { 16#f694 } { neg 16#fa94 } ifelse add
2 string dup 0 3 index -8 bitshift put
dup 1 3 index 255 and put
}
{ 5 string dup 0 255 put exch
2 copy 1 exch -24 bitshift 255 and put
2 copy 2 exch -16 bitshift 255 and put
2 copy 3 exch -8 bitshift 255 and put
2 copy 4 exch 255 and put
exch
}
ifelse
}
ifelse exch pop concatstrings
} bind def
% ------ Point arithmetic utilities ------ %
/ptadd { exch 4 -1 roll add 3 1 roll add } bind def
/ptexch { 4 2 roll } bind def
/ptneg { neg exch neg exch } bind def
/ptpop { pop pop } bind def
/ptsub { ptneg ptadd } bind def
% ------ The main program ------ %
/readBDF % <infilename> <outfilename> <fontname>
% <encodingname> <uniqueID> <xuid> readBDF -> <font>
{ /xuid exch def % may be null
/uniqueID exch def % may be -1
/encodingname exch def
/encoding encodingname cvx exec def
/fontname exch def
/psname exch def
/bdfname exch def
gsave % so we can set the CTM to the font matrix
% Open the input files. We don't open the output file until
% we've done a minimal validity check on the input.
bdfname (r) file /bdfile exch def
/commentword ( ) def
% Check for the STARTFONT.
(STARTFONT) getline
args (2.1) ne { (Not version 2.1\n) print stop } if
% Initialize the font.
/Font 20 dict def
Font begin
/FontName fontname def
/PaintType 0 def
/FontType 1 def
uniqueID 0 gt { /UniqueID uniqueID def } if
xuid null ne { /XUID xuid def } if
/Encoding encoding def
/FontInfo 20 dict def
/Private 20 dict def
currentdict end currentdict end
exch begin begin % insert font above environment
% Initialize the Private dictionary in the font.
Private begin
/-! {string currentfile exch readhexstring pop} readonly def
/-| {string currentfile exch readstring pop} readonly def
/|- {readonly def} readonly def
/| {readonly put} readonly def
/BlueValues [] def
/lenIV lenIV def
/MinFeature {16 16} def
/password 5839 def
/UniqueID uniqueID def
end % Private
% Invert the Encoding, for synthesizing composite characters.
/decoding encoding length dict def
0 1 encoding length 1 sub
{ dup encoding exch get exch decoding 3 1 roll put }
for
% Now open the output file.
psname (w) file /psfile exch def
% Put out a header compatible with the Adobe "standard".
(%!FontType1-1.0: ) ws fontname wt (000.000) wl
(% This is a font description converted from ) ws
bdfname wl
(% by bdftops running on ) ws
statusdict /product get ws ( revision ) ws
revision =string cvs ws (.) wl
% Copy the initial comments, up to FONT.
true
{ nextline
keyword (COMMENT) ne {exit} if
{ (% Here are the initial comments from the BDF file:\n%) wl
} if false
(%) ws remarg wl
} loop pop
() wl
/commentword (COMMENT) def % do skip comments from now on
% Read and process the FONT, SIZE, and FONTBOUNDINGBOX.
% If we cared about FONT, we'd use it here. If the BDF files
% from MIT had PostScript names rather than X names, we would
% care; but what's there is unusable, so we discard FONT.
% The FONTBOUNDINGBOX may not be reliable, so we discard it too.
(FONT) checkline
(SIZE) getline
/pointsize iarg def /xres iarg def /yres iarg def
(FONTBOUNDINGBOX) getline
nextline
% Initialize the font bounding box bookeeping.
/fbbxo 1000 def
/fbbyo 1000 def
/fbbxe -1000 def
/fbbye -1000 def
% Read and process the properties. We only care about a few of them.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -