diff options
author | Reinhard Kotucha <reinhard.kotucha@web.de> | 2010-05-12 19:25:45 +0000 |
---|---|---|
committer | Reinhard Kotucha <reinhard.kotucha@web.de> | 2010-05-12 19:25:45 +0000 |
commit | dc55d4f5cde421a3704c183bc6ceb3fcdb6b0653 (patch) | |
tree | db0890c2f5f2714d527a42ad3fb7955ac5b1f545 /Master/tlpkg/tlgs/lib/pf2afm.ps | |
parent | 053ead4487e776b05721ec15b941fe0bc1b7d513 (diff) |
tlgs: 8.70 => 8.71
git-svn-id: svn://tug.org/texlive/trunk@18215 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/tlgs/lib/pf2afm.ps')
-rw-r--r--[-rwxr-xr-x] | Master/tlpkg/tlgs/lib/pf2afm.ps | 1078 |
1 files changed, 539 insertions, 539 deletions
diff --git a/Master/tlpkg/tlgs/lib/pf2afm.ps b/Master/tlpkg/tlgs/lib/pf2afm.ps index 3eb26f092d1..a79cb5b97cd 100755..100644 --- a/Master/tlpkg/tlgs/lib/pf2afm.ps +++ b/Master/tlpkg/tlgs/lib/pf2afm.ps @@ -1,539 +1,539 @@ -%!
-% This is a PostScript program for making an AFM file from
-% PFB / PFA and (optionally) PFM files.
-%
-% Written in BOP s.c., Gda\'nsk, Poland
-% e-mail contact: B.Jackowski@GUST.ORG.PL
-% version 0.5 (18 XII 1997)
-% version 0.55 (11 III 1998) -- unlimited number of chars in a font
-% version 1.00 (27 III 1998) -- scanning PFM subdirectory added,
-% code improved; version sent to LPD
-% version 1.01 (1 II 2000) -- message changed
-
-% Usage:
-% gs [-dNODISPLAY] -- pf2afm.ps disk_font_name
-%
-% The result is written to the file disk_font_name.afm, provided such
-% a file does not exist; otherwise program quits.
-%
-% The font can be either *.pfa or *.pfb; if no extension is supplied,
-% first disk_font_name.pfb is examined, then disk_font_name.pfa.
-% Moreover, if there is a *.pfm file in the same directory or in the
-% subdirectory PFM, i.e., disk_font_name.pfm or PFM/disk_font_name.pfm,
-% kern pairs from it are extracted, as well as additional font
-% parameters, usually absent from Type 1 fonts.
-
-% Tribute:
-% $Id: pf2afm.ps 9792 2009-06-13 14:33:18Z alexcher $
-% The program is based on James Clark's <jjc@jclark.uucp> printafm.ps
-% (with alterations by d.love@dl.ac.uk and L. Peter Deutsch) from
-% Ghostscript 5.10 distribution.
-
-/onechar 1 string def
-/edef {exch def} def
-/WinAnsiEncoding dup /Encoding findresource def
-
-% charnumber print-charname -
-% prints the name of the encoded character
-/print-charname {
- PFMCharSet 0 eq {
- WinAnsiEncoding
- } {
- PFBencoding
- } ifelse
- exch get =string cvs dup
- (.notdef) eq {
- /was.notdef true def
- } if
- print.to.ofi ( ) print.to.ofi
-} def
-
-/printquit {print flush quit} def
-
-% redirecting GS output to ``ofi'' file
-/eolch (\r\n) def
-/=only.to.ofi {ofi exch write=only} def % replaces GS's `=only'
-/print.to.ofi {ofi exch writestring} def % replaces `print'
-/=to.ofi { =only.to.ofi eolch print.to.ofi } def % replaces `='
-
-% read and skip: byte, short, word, double and long
-/readb-p {currPFMfile read not {(Unexpected EOF\n) printquit} if} def
-/readw-p {readb-p readb-p 256 mul add} def
-/reads-p {readw-p dup 32768 ge {65536 sub} if} def
-/readd-p {readb-p readb-p readb-p readb-p 256 mul add 256 mul add 256 mul add} def
-/readl-p /readd-p load def % double word is, in fact, long integer in GS
-/skipb-p {readb-p pop} def
-/skipw-p {skipb-p skipb-p} def
-/skips-p /skipw-p load def
-/skipd-p {skipb-p skipb-p skipb-p skipb-p} def
-/skipl-p /skipd-p load def
-/skipa-p { {skipb-p} repeat} def
-
-% PFMfile readPFMheader -
-% defines currPFMfile, PFMExtMetricOffset, PFMPairKernTableOffset
-
-/readPFMheader {
- currPFMfile bytesavailable
- % ---------------
- % PFM MAIN HEADER
- % ---------------
- skipw-p % PFM: version
- readd-p % PFM: size (size is dword, not word as the documentation says)
- ne {(Wrong file size\n) printquit} if
- 60 skipa-p % PFM: copyright
- skipw-p % PFM: Type
- skipw-p % PFM: Points
- skipw-p % PFM: VertRes
- skipw-p % PFM: HorizRes
- skipw-p % PFM: Ascent
- skipw-p % PFM: InternalLeading
- skipw-p % PFM: ExternalLeading
- skipb-p % PFM: Italic
- skipb-p % PFM: Underline
- skipb-p % PFM: Stikeout
- skipw-p % PFM: Weight
- readb-p % PFM: CharSet
- /PFMCharSet edef
- skipw-p % PFM: PixWidth
- skipw-p % PFM: PixHeight
- skipb-p % PFM: PitchAndFamily
- skipw-p % PFM: AvgWidth
- skipw-p % PFM: MaxWidth
- skipb-p % PFM: FirstChar
- skipb-p % PFM: LastChar
- skipb-p % PFM: DefaultChar
- skipb-p % PFM: BreakChar
- skipw-p % PFM: WidthBytes
- skipd-p % PFM: Device
- skipd-p % PFM: Face
- skipd-p % PFM: BitsPointer
- skipd-p % PFM: BitsOffset
- % here we assume that it is a PostScript font, i.e., it always uses
- % the extended width table, therefore the normal width table is empty
- % -------------
- % PFM EXTENSION
- % -------------
- skipw-p % PFMEX: SizeFields
- readd-p % PFMEX: ExtMetricOffset
- /PFMExtMetricOffset edef
- skipd-p % PFMEX: ExtentTable
- skipd-p % PFMEX: OriginTable
- readd-p % PFMEX: PairKernTable
- /PFMPairKernTableOffset edef
- skipd-p % PFMEX: TrackKernTable
- skipd-p % PFMEX: DriverInfo
- skipd-p % PFMEX: Reserved
-} def
-
-% requires that currPFMfile, PFMExtMetricOffset are defined
-% readPFMExtMetric -
-% defines PFMNumberofKernPairs
-
-/readPFMExtMetric {
- currPFMfile PFMExtMetricOffset setfileposition
- skips-p % EXTT: Size
- skips-p % EXTT: PointSize
- skips-p % EXTT: Orientation
- skips-p % EXTT: MasterHeight
- skips-p % EXTT: MinScale
- skips-p % EXTT: MaxScale
- skips-p % EXTT: MasterUnit
- reads-p % EXTT: CapHeight
- /PFMCapHeight edef
- reads-p % EXTT: XHeight
- /PFMXHeight edef
- reads-p % EXTT: LowerCaseAscent
- /PFMLowerCaseAscent edef
- reads-p % EXTT: LowerCaseDescent
- neg /PFMLowerCaseDescent edef
- skips-p % EXTT: Slant
- skips-p % EXTT: SuperScript
- skips-p % EXTT: SubScript
- skips-p % EXTT: SuperScriptSize
- skips-p % EXTT: SubScriptSize
- skips-p % EXTT: UnderlineOffset
- skips-p % EXTT: UnderlineWidth
- skips-p % EXTT: DoubleUpperUnderlineOffset
- skips-p % EXTT: DoubleLowerUnderlineOffset
- skips-p % EXTT: DoubleUpperUnderlineWidth
- skips-p % EXTT: DoubleLowerUnderlineWidth
- skips-p % EXTT: StrikeOutOffset
- skips-p % EXTT: StrikeOutWidth
- readw-p % EXTT: KernPairs
- /PFMNumberofKernPairs edef
- skipw-p % EXTT: KernTracks
-} def
-
-% requires that currPFMfile, PFMPairKernTableOffset, PFMNumberofKernPairs are defined
-% readPFMExtMetric -
-% prints kern pairs table in the AFM format
-
-/readPFMKernPairs {
- currPFMfile () ne {
- PFMdict begin
- PFMPairKernTableOffset 0 ne {
- currPFMfile PFMPairKernTableOffset setfileposition
- readw-p % undocumented kern count (although all remaining structures are
- % explicitly preceded by their sizes); if it were a stable
- % feature, EXTTEXTMETRICS could be skipped
- PFMNumberofKernPairs
-% 2 copy = =
- ne {
- (Inconsistent number of kern pairs\n) printquit
- } if
- (StartKernData) =to.ofi
- (StartKernPairs ) print.to.ofi
- PFMNumberofKernPairs =to.ofi
- % ---------
- % MAIN LOOP
- % ---------
- /was.notdef false def
- PFMNumberofKernPairs {
- (KPX ) print.to.ofi
- readb-p % first char
- print-charname
- readb-p % second char
- print-charname
- reads-p % kern amount
- =to.ofi
- } repeat
- was.notdef {
- (.notdef character ocurred among kern pairs) =
- (you'd better check the resulting AFM file.) =
- } if
- (EndKernPairs) =to.ofi
- (EndKernData) =to.ofi
- } if
- end
- } if
-} def
-
-% alias (for ``compatibility'' with J. Clark):
-/printkernpairs /readPFMKernPairs load def
-
-% printcharmetrics -
-
-/printcharmetrics {
- (StartCharMetrics ) print.to.ofi
- /PFBencoding currfont /Encoding get dup length array copy def
- /PFBcharstrings currfont /CharStrings get def
- PFBcharstrings length
- PFBcharstrings /.notdef known { 1 sub } if =to.ofi
- currfont 1000 scalefont setfont
- % checking Encoding array and CharStrings dictionary for
- % the consistency of names
- /was.inconsitent false def
- 0 1 255 {
- dup PFBencoding exch get
- PFBcharstrings exch known {
- pop
- }{
-% dup PFBencoding exch get =
- PFBencoding exch /.notdef put % fix Encoding array
- /was.inconsitent true def
- } ifelse
- } for
- was.inconsitent {
- (Encoding array contains name(s) absent from CharStrings dictionary) =
- } if
- % print metric data for each character in PFB encoding vector
- 0 1 255 {
- dup PFBencoding exch get
- dup /.notdef ne {
- exch dup printmetric
- }{
- pop pop
- } ifelse
- } for
- % xPFBencoding contains an entry for each name in the original
- % encoding vector
- /xPFBencoding PFBcharstrings length dict def
- PFBencoding {
- xPFBencoding exch true put
- } forall
-
- /fontiter 0 def
- /TMPFontTemplate (TMP_FONT#000) def
- {
- % NewPFBencoding is the new encoding vector
- /NewPFBencoding 256 array def
- 0 1 255 {
- NewPFBencoding exch /.notdef put
- } for
- % fill up NewPFBencoding with names from CharStrings dictionary that
- % are not encoded so far
- /i 0 def
- PFBcharstrings {
- pop
- i 255 le {
- dup xPFBencoding exch known not {
- dup xPFBencoding exch true put
- NewPFBencoding i 3 -1 roll put
- /i i 1 add def
- }{
- pop
- } ifelse
- }{
- pop exit
- } ifelse
- } forall
- i 0 eq {exit} if
- % define a new font with NewPFBencoding as its encoding vector
- currfont maxlength dict /NewTMPfont edef
- currfont {
- exch dup dup /FID ne exch /Encoding ne and {
- exch NewTMPfont 3 1 roll put
- }{
- pop pop
- } ifelse
- } forall
- % compute a unique name for a font to be registered
- /fontiter fontiter 1 add def
- TMPFontTemplate fontiter (000) cvs
- dup length TMPFontTemplate length exch sub exch putinterval
- /TMPFontName TMPFontTemplate cvn def
- NewTMPfont /FontName TMPFontName put
- NewTMPfont /Encoding NewPFBencoding put
- % make this new font the current font
- TMPFontName NewTMPfont definefont 1000 scalefont setfont
- % print metric data for each character in the newly created encoding vector
- 0 1 255 {
- dup NewPFBencoding exch get
- dup /.notdef ne {
- exch -1 printmetric
- }{
- pop pop exit
- } ifelse
- } for
- i 255 lt {exit} if
- } loop
- (EndCharMetrics) =to.ofi
-} def
-
-% name actual_code normal_code printmetric -
-
-/printmetric {
- (C ) print.to.ofi =only.to.ofi
- ( ; WX ) print.to.ofi
- onechar 0 3 -1 roll put
- onechar stringwidth pop round cvi =only.to.ofi
- ( ; N ) print.to.ofi =only.to.ofi
- ( ; B ) print.to.ofi
- newpath 0 0 moveto
- onechar false charpath flattenpath pathbbox
- newpath
- round cvi /ury edef round cvi /urx edef
- round cvi /lly edef round cvi /llx edef
- ury lly eq {/ury 0 def /lly 0 def} if % normalize degenrated BB
- urx llx eq {/urx 0 def /llx 0 def} if %
- llx =only.to.ofi ( ) print.to.ofi lly =only.to.ofi ( ) print.to.ofi
- urx =only.to.ofi ( ) print.to.ofi ury =only.to.ofi ( ) print.to.ofi
- (;) =to.ofi
-} def
-
-/printinfoitem {
- 3 1 roll 2 copy known {
- get dup type /stringtype ne { =string cvs } if exch
- print.to.ofi ( ) print.to.ofi =to.ofi
- }{
- pop pop pop
- } ifelse
-} def
-
-/printfontinfo {
- (Comment AFM Generated by Ghostscript/pf2afm) =to.ofi
- currfont /FontName (FontName) printinfoitem
- %
- currfont /FontInfo get
- dup /FullName (FullName) printinfoitem
- dup /FamilyName (FamilyName) printinfoitem
- dup /Weight (Weight) printinfoitem
- dup /Notice (Notice) printinfoitem
- dup /ItalicAngle (ItalicAngle) printinfoitem
- dup /isFixedPitch (IsFixedPitch) printinfoitem
- dup /UnderlinePosition (UnderlinePosition) printinfoitem
- dup /UnderlineThickness (UnderlineThickness) printinfoitem
- /version (Version) printinfoitem
- %
- (EncodingScheme FontSpecific) =to.ofi
- %
- (FontBBox) print.to.ofi
- currfont /FontBBox get {
- ( ) print.to.ofi round cvi =only.to.ofi
- } forall
- eolch print.to.ofi
- %
- currPFMfile () ne {
- PFMdict
- dup /PFMCapHeight (CapHeight) printinfoitem
- dup /PFMXHeight (XHeight) printinfoitem
- dup /PFMLowerCaseDescent (Descender) printinfoitem
- /PFMLowerCaseAscent (Ascender) printinfoitem
- } if
-} def
-
-/readPFBfile {
- % make a shot of the actual font directory:
- /oldFontDirectory FontDirectory dup length dict copy def
- isPFB {% defined in `makeafm'
- (r) file true /PFBDecode filter cvx % true is better (see gs_type1.ps)
- mark exch exec
- }{
- (r) file mark exch run
- } ifelse
- cleartomark
- % make a shot of the updated font directory:
- /newFontDirectory FontDirectory dup length dict copy def
- % spot the added font:
- oldFontDirectory {pop newFontDirectory exch undef} forall
- newFontDirectory length 1 ne {
- newFontDirectory length =
- (Weird PFB file?\n) printquit
- } if
- newFontDirectory {pop} forall
- findfont /currfont edef
-} def
-
-/readPFMfile {
- dup () ne {
- (r) file /currPFMfile edef
- 10 dict dup /PFMdict edef begin
- readPFMheader
- readPFMExtMetric
- end
- }{
- pop /currPFMfile () def
- } ifelse
-} def
-
-% pfmfilename pf[ba]filename filetype printafm -
-% where filetype=(a) or (b)
-
-/printafm {
- readPFBfile
- readPFMfile
- (StartFontMetrics 2.0) =to.ofi
- printfontinfo
- printcharmetrics
- printkernpairs
- (EndFontMetrics) =to.ofi
-} def
-
-/pfa_pfb_dict <<
- /.pfb /pfbn
- /.pfB /pfbn
- /.pFb /pfbn
- /.pFB /pfbn
- /.Pfb /pfbn
- /.PfB /pfbn
- /.PFb /pfbn
- /.PFB /pfbn
-
- /.pfa /pfan
- /.pfA /pfan
- /.pFa /pfan
- /.pFA /pfan
- /.Pfa /pfan
- /.PfA /pfan
- /.PFa /pfan
- /.PFA /pfan
->> readonly def
-
-% Check whether the file name has pfa or pfb extension.
-/pfa_or_pfb? { % s -> false | /name true
- dup length 4 lt {
- pop //false
- } {
- dup length 4 sub 4 getinterval //pfa_pfb_dict exch .knownget
- } ifelse
-} bind def
-
-
-% pf[ba]filename makeafm -
-/makeafm {
- count 0 eq {(Missing font file name\n) printquit} if
- /ifn edef
- ifn length 0 eq {(Empty font file name\n) printquit} if
-% the following piece of the code does, in fact, the job of a system shell,
-% i.e., it analyses the supplied names, appends extensions if needed,
-% and check files:
- /pfbn () def /pfan () def /pfmn () def % initialisation
- [ t1_glyph_equivalence { pop } forall ] { % disable glyph substitution
- t1_glyph_equivalence exch undef
- } forall
- ifn pfa_or_pfb? {
- ifn dup length string copy def
- ifn dup length 4 sub 0 exch getinterval /ifn edef
- } if
- pfbn () eq pfan () eq and dup {% no extension was supplied, try ".pfb"
- /pfbn ifn (.pfb) concatstrings def
- } if
- pfbn () ne {% check whether "filename.pfb" exists
- pfbn status {pop pop pop pop /isPFB true def}{/pfbn () def} ifelse
- } if
- pfbn () eq and {% checking "filename.pfb" unsuccessful, try ".pfa"
- /pfan ifn (.pfa) concatstrings def
- } if
- pfan () ne {% check whether "filename.pfa" exists
- pfan status {pop pop pop pop /isPFB false def}{/pfan () def} ifelse
- } if
-
- pfbn () eq pfan () eq and {
- (Neither pfa nor pfb found\n) printquit
- } if
-
- /ofn ifn (.afm) concatstrings def
- ofn status {
- pop pop pop pop (Resulting file exists\n) printquit
- } if
- /ofi ofn (w) file def
-
- /pfmn ifn (.pfm) concatstrings def
- pfmn status {
- pop pop pop pop
- }{
- () pfmn {
- (/) search dup not { pop (\\) search } if {
- 4 -1 roll exch concatstrings exch concatstrings exch
- }{
- exit
- } ifelse
- } loop
- (pfm/) exch concatstrings concatstrings
- dup status {
- pop pop pop pop /pfmn edef
- }{
- pop /pfmn () def (pfm file not found -- ignored\n) print
- } ifelse
- } ifelse
- //systemdict /.setsafe known {
- <<
- /PermitFileReading
- [ pfmn dup length 0 eq { pop } if
- isPFB {pfbn}{pfan} ifelse
- ]
- /PermitFileWriting [ ]
- /PermitFileControl [ ]
- >> setuserparams
- .locksafe
- } if
-
-
- pfmn
- isPFB {pfbn}{pfan} ifelse
- printafm
-
-} def
-
-% Check for command line arguments.
-[ shellarguments
- { ] dup length 1 eq {
- 0 get makeafm
- }{
- (This is PF2AFM -- AFM generator \(ver. 1.00\)\n) print
- (Usage: gs [-dNODISPLAY] -- pf2afm.ps disk_font_name\n) printquit
- } ifelse
- }
- {pop}
-ifelse
-
+%! +% This is a PostScript program for making an AFM file from +% PFB / PFA and (optionally) PFM files. +% +% Written in BOP s.c., Gda\'nsk, Poland +% e-mail contact: B.Jackowski@GUST.ORG.PL +% version 0.5 (18 XII 1997) +% version 0.55 (11 III 1998) -- unlimited number of chars in a font +% version 1.00 (27 III 1998) -- scanning PFM subdirectory added, +% code improved; version sent to LPD +% version 1.01 (1 II 2000) -- message changed + +% Usage: +% gs [-dNODISPLAY] -- pf2afm.ps disk_font_name +% +% The result is written to the file disk_font_name.afm, provided such +% a file does not exist; otherwise program quits. +% +% The font can be either *.pfa or *.pfb; if no extension is supplied, +% first disk_font_name.pfb is examined, then disk_font_name.pfa. +% Moreover, if there is a *.pfm file in the same directory or in the +% subdirectory PFM, i.e., disk_font_name.pfm or PFM/disk_font_name.pfm, +% kern pairs from it are extracted, as well as additional font +% parameters, usually absent from Type 1 fonts. + +% Tribute: +% $Id: pf2afm.ps 9792 2009-06-13 14:33:18Z alexcher $ +% The program is based on James Clark's <jjc@jclark.uucp> printafm.ps +% (with alterations by d.love@dl.ac.uk and L. Peter Deutsch) from +% Ghostscript 5.10 distribution. + +/onechar 1 string def +/edef {exch def} def +/WinAnsiEncoding dup /Encoding findresource def + +% charnumber print-charname - +% prints the name of the encoded character +/print-charname { + PFMCharSet 0 eq { + WinAnsiEncoding + } { + PFBencoding + } ifelse + exch get =string cvs dup + (.notdef) eq { + /was.notdef true def + } if + print.to.ofi ( ) print.to.ofi +} def + +/printquit {print flush quit} def + +% redirecting GS output to ``ofi'' file +/eolch (\r\n) def +/=only.to.ofi {ofi exch write=only} def % replaces GS's `=only' +/print.to.ofi {ofi exch writestring} def % replaces `print' +/=to.ofi { =only.to.ofi eolch print.to.ofi } def % replaces `=' + +% read and skip: byte, short, word, double and long +/readb-p {currPFMfile read not {(Unexpected EOF\n) printquit} if} def +/readw-p {readb-p readb-p 256 mul add} def +/reads-p {readw-p dup 32768 ge {65536 sub} if} def +/readd-p {readb-p readb-p readb-p readb-p 256 mul add 256 mul add 256 mul add} def +/readl-p /readd-p load def % double word is, in fact, long integer in GS +/skipb-p {readb-p pop} def +/skipw-p {skipb-p skipb-p} def +/skips-p /skipw-p load def +/skipd-p {skipb-p skipb-p skipb-p skipb-p} def +/skipl-p /skipd-p load def +/skipa-p { {skipb-p} repeat} def + +% PFMfile readPFMheader - +% defines currPFMfile, PFMExtMetricOffset, PFMPairKernTableOffset + +/readPFMheader { + currPFMfile bytesavailable + % --------------- + % PFM MAIN HEADER + % --------------- + skipw-p % PFM: version + readd-p % PFM: size (size is dword, not word as the documentation says) + ne {(Wrong file size\n) printquit} if + 60 skipa-p % PFM: copyright + skipw-p % PFM: Type + skipw-p % PFM: Points + skipw-p % PFM: VertRes + skipw-p % PFM: HorizRes + skipw-p % PFM: Ascent + skipw-p % PFM: InternalLeading + skipw-p % PFM: ExternalLeading + skipb-p % PFM: Italic + skipb-p % PFM: Underline + skipb-p % PFM: Stikeout + skipw-p % PFM: Weight + readb-p % PFM: CharSet + /PFMCharSet edef + skipw-p % PFM: PixWidth + skipw-p % PFM: PixHeight + skipb-p % PFM: PitchAndFamily + skipw-p % PFM: AvgWidth + skipw-p % PFM: MaxWidth + skipb-p % PFM: FirstChar + skipb-p % PFM: LastChar + skipb-p % PFM: DefaultChar + skipb-p % PFM: BreakChar + skipw-p % PFM: WidthBytes + skipd-p % PFM: Device + skipd-p % PFM: Face + skipd-p % PFM: BitsPointer + skipd-p % PFM: BitsOffset + % here we assume that it is a PostScript font, i.e., it always uses + % the extended width table, therefore the normal width table is empty + % ------------- + % PFM EXTENSION + % ------------- + skipw-p % PFMEX: SizeFields + readd-p % PFMEX: ExtMetricOffset + /PFMExtMetricOffset edef + skipd-p % PFMEX: ExtentTable + skipd-p % PFMEX: OriginTable + readd-p % PFMEX: PairKernTable + /PFMPairKernTableOffset edef + skipd-p % PFMEX: TrackKernTable + skipd-p % PFMEX: DriverInfo + skipd-p % PFMEX: Reserved +} def + +% requires that currPFMfile, PFMExtMetricOffset are defined +% readPFMExtMetric - +% defines PFMNumberofKernPairs + +/readPFMExtMetric { + currPFMfile PFMExtMetricOffset setfileposition + skips-p % EXTT: Size + skips-p % EXTT: PointSize + skips-p % EXTT: Orientation + skips-p % EXTT: MasterHeight + skips-p % EXTT: MinScale + skips-p % EXTT: MaxScale + skips-p % EXTT: MasterUnit + reads-p % EXTT: CapHeight + /PFMCapHeight edef + reads-p % EXTT: XHeight + /PFMXHeight edef + reads-p % EXTT: LowerCaseAscent + /PFMLowerCaseAscent edef + reads-p % EXTT: LowerCaseDescent + neg /PFMLowerCaseDescent edef + skips-p % EXTT: Slant + skips-p % EXTT: SuperScript + skips-p % EXTT: SubScript + skips-p % EXTT: SuperScriptSize + skips-p % EXTT: SubScriptSize + skips-p % EXTT: UnderlineOffset + skips-p % EXTT: UnderlineWidth + skips-p % EXTT: DoubleUpperUnderlineOffset + skips-p % EXTT: DoubleLowerUnderlineOffset + skips-p % EXTT: DoubleUpperUnderlineWidth + skips-p % EXTT: DoubleLowerUnderlineWidth + skips-p % EXTT: StrikeOutOffset + skips-p % EXTT: StrikeOutWidth + readw-p % EXTT: KernPairs + /PFMNumberofKernPairs edef + skipw-p % EXTT: KernTracks +} def + +% requires that currPFMfile, PFMPairKernTableOffset, PFMNumberofKernPairs are defined +% readPFMExtMetric - +% prints kern pairs table in the AFM format + +/readPFMKernPairs { + currPFMfile () ne { + PFMdict begin + PFMPairKernTableOffset 0 ne { + currPFMfile PFMPairKernTableOffset setfileposition + readw-p % undocumented kern count (although all remaining structures are + % explicitly preceded by their sizes); if it were a stable + % feature, EXTTEXTMETRICS could be skipped + PFMNumberofKernPairs +% 2 copy = = + ne { + (Inconsistent number of kern pairs\n) printquit + } if + (StartKernData) =to.ofi + (StartKernPairs ) print.to.ofi + PFMNumberofKernPairs =to.ofi + % --------- + % MAIN LOOP + % --------- + /was.notdef false def + PFMNumberofKernPairs { + (KPX ) print.to.ofi + readb-p % first char + print-charname + readb-p % second char + print-charname + reads-p % kern amount + =to.ofi + } repeat + was.notdef { + (.notdef character ocurred among kern pairs) = + (you'd better check the resulting AFM file.) = + } if + (EndKernPairs) =to.ofi + (EndKernData) =to.ofi + } if + end + } if +} def + +% alias (for ``compatibility'' with J. Clark): +/printkernpairs /readPFMKernPairs load def + +% printcharmetrics - + +/printcharmetrics { + (StartCharMetrics ) print.to.ofi + /PFBencoding currfont /Encoding get dup length array copy def + /PFBcharstrings currfont /CharStrings get def + PFBcharstrings length + PFBcharstrings /.notdef known { 1 sub } if =to.ofi + currfont 1000 scalefont setfont + % checking Encoding array and CharStrings dictionary for + % the consistency of names + /was.inconsitent false def + 0 1 255 { + dup PFBencoding exch get + PFBcharstrings exch known { + pop + }{ +% dup PFBencoding exch get = + PFBencoding exch /.notdef put % fix Encoding array + /was.inconsitent true def + } ifelse + } for + was.inconsitent { + (Encoding array contains name(s) absent from CharStrings dictionary) = + } if + % print metric data for each character in PFB encoding vector + 0 1 255 { + dup PFBencoding exch get + dup /.notdef ne { + exch dup printmetric + }{ + pop pop + } ifelse + } for + % xPFBencoding contains an entry for each name in the original + % encoding vector + /xPFBencoding PFBcharstrings length dict def + PFBencoding { + xPFBencoding exch true put + } forall + + /fontiter 0 def + /TMPFontTemplate (TMP_FONT#000) def + { + % NewPFBencoding is the new encoding vector + /NewPFBencoding 256 array def + 0 1 255 { + NewPFBencoding exch /.notdef put + } for + % fill up NewPFBencoding with names from CharStrings dictionary that + % are not encoded so far + /i 0 def + PFBcharstrings { + pop + i 255 le { + dup xPFBencoding exch known not { + dup xPFBencoding exch true put + NewPFBencoding i 3 -1 roll put + /i i 1 add def + }{ + pop + } ifelse + }{ + pop exit + } ifelse + } forall + i 0 eq {exit} if + % define a new font with NewPFBencoding as its encoding vector + currfont maxlength dict /NewTMPfont edef + currfont { + exch dup dup /FID ne exch /Encoding ne and { + exch NewTMPfont 3 1 roll put + }{ + pop pop + } ifelse + } forall + % compute a unique name for a font to be registered + /fontiter fontiter 1 add def + TMPFontTemplate fontiter (000) cvs + dup length TMPFontTemplate length exch sub exch putinterval + /TMPFontName TMPFontTemplate cvn def + NewTMPfont /FontName TMPFontName put + NewTMPfont /Encoding NewPFBencoding put + % make this new font the current font + TMPFontName NewTMPfont definefont 1000 scalefont setfont + % print metric data for each character in the newly created encoding vector + 0 1 255 { + dup NewPFBencoding exch get + dup /.notdef ne { + exch -1 printmetric + }{ + pop pop exit + } ifelse + } for + i 255 lt {exit} if + } loop + (EndCharMetrics) =to.ofi +} def + +% name actual_code normal_code printmetric - + +/printmetric { + (C ) print.to.ofi =only.to.ofi + ( ; WX ) print.to.ofi + onechar 0 3 -1 roll put + onechar stringwidth pop round cvi =only.to.ofi + ( ; N ) print.to.ofi =only.to.ofi + ( ; B ) print.to.ofi + newpath 0 0 moveto + onechar false charpath flattenpath pathbbox + newpath + round cvi /ury edef round cvi /urx edef + round cvi /lly edef round cvi /llx edef + ury lly eq {/ury 0 def /lly 0 def} if % normalize degenrated BB + urx llx eq {/urx 0 def /llx 0 def} if % + llx =only.to.ofi ( ) print.to.ofi lly =only.to.ofi ( ) print.to.ofi + urx =only.to.ofi ( ) print.to.ofi ury =only.to.ofi ( ) print.to.ofi + (;) =to.ofi +} def + +/printinfoitem { + 3 1 roll 2 copy known { + get dup type /stringtype ne { =string cvs } if exch + print.to.ofi ( ) print.to.ofi =to.ofi + }{ + pop pop pop + } ifelse +} def + +/printfontinfo { + (Comment AFM Generated by Ghostscript/pf2afm) =to.ofi + currfont /FontName (FontName) printinfoitem + % + currfont /FontInfo get + dup /FullName (FullName) printinfoitem + dup /FamilyName (FamilyName) printinfoitem + dup /Weight (Weight) printinfoitem + dup /Notice (Notice) printinfoitem + dup /ItalicAngle (ItalicAngle) printinfoitem + dup /isFixedPitch (IsFixedPitch) printinfoitem + dup /UnderlinePosition (UnderlinePosition) printinfoitem + dup /UnderlineThickness (UnderlineThickness) printinfoitem + /version (Version) printinfoitem + % + (EncodingScheme FontSpecific) =to.ofi + % + (FontBBox) print.to.ofi + currfont /FontBBox get { + ( ) print.to.ofi round cvi =only.to.ofi + } forall + eolch print.to.ofi + % + currPFMfile () ne { + PFMdict + dup /PFMCapHeight (CapHeight) printinfoitem + dup /PFMXHeight (XHeight) printinfoitem + dup /PFMLowerCaseDescent (Descender) printinfoitem + /PFMLowerCaseAscent (Ascender) printinfoitem + } if +} def + +/readPFBfile { + % make a shot of the actual font directory: + /oldFontDirectory FontDirectory dup length dict copy def + isPFB {% defined in `makeafm' + (r) file true /PFBDecode filter cvx % true is better (see gs_type1.ps) + mark exch exec + }{ + (r) file mark exch run + } ifelse + cleartomark + % make a shot of the updated font directory: + /newFontDirectory FontDirectory dup length dict copy def + % spot the added font: + oldFontDirectory {pop newFontDirectory exch undef} forall + newFontDirectory length 1 ne { + newFontDirectory length = + (Weird PFB file?\n) printquit + } if + newFontDirectory {pop} forall + findfont /currfont edef +} def + +/readPFMfile { + dup () ne { + (r) file /currPFMfile edef + 10 dict dup /PFMdict edef begin + readPFMheader + readPFMExtMetric + end + }{ + pop /currPFMfile () def + } ifelse +} def + +% pfmfilename pf[ba]filename filetype printafm - +% where filetype=(a) or (b) + +/printafm { + readPFBfile + readPFMfile + (StartFontMetrics 2.0) =to.ofi + printfontinfo + printcharmetrics + printkernpairs + (EndFontMetrics) =to.ofi +} def + +/pfa_pfb_dict << + /.pfb /pfbn + /.pfB /pfbn + /.pFb /pfbn + /.pFB /pfbn + /.Pfb /pfbn + /.PfB /pfbn + /.PFb /pfbn + /.PFB /pfbn + + /.pfa /pfan + /.pfA /pfan + /.pFa /pfan + /.pFA /pfan + /.Pfa /pfan + /.PfA /pfan + /.PFa /pfan + /.PFA /pfan +>> readonly def + +% Check whether the file name has pfa or pfb extension. +/pfa_or_pfb? { % s -> false | /name true + dup length 4 lt { + pop //false + } { + dup length 4 sub 4 getinterval //pfa_pfb_dict exch .knownget + } ifelse +} bind def + + +% pf[ba]filename makeafm - +/makeafm { + count 0 eq {(Missing font file name\n) printquit} if + /ifn edef + ifn length 0 eq {(Empty font file name\n) printquit} if +% the following piece of the code does, in fact, the job of a system shell, +% i.e., it analyses the supplied names, appends extensions if needed, +% and check files: + /pfbn () def /pfan () def /pfmn () def % initialisation + [ t1_glyph_equivalence { pop } forall ] { % disable glyph substitution + t1_glyph_equivalence exch undef + } forall + ifn pfa_or_pfb? { + ifn dup length string copy def + ifn dup length 4 sub 0 exch getinterval /ifn edef + } if + pfbn () eq pfan () eq and dup {% no extension was supplied, try ".pfb" + /pfbn ifn (.pfb) concatstrings def + } if + pfbn () ne {% check whether "filename.pfb" exists + pfbn status {pop pop pop pop /isPFB true def}{/pfbn () def} ifelse + } if + pfbn () eq and {% checking "filename.pfb" unsuccessful, try ".pfa" + /pfan ifn (.pfa) concatstrings def + } if + pfan () ne {% check whether "filename.pfa" exists + pfan status {pop pop pop pop /isPFB false def}{/pfan () def} ifelse + } if + + pfbn () eq pfan () eq and { + (Neither pfa nor pfb found\n) printquit + } if + + /ofn ifn (.afm) concatstrings def + ofn status { + pop pop pop pop (Resulting file exists\n) printquit + } if + /ofi ofn (w) file def + + /pfmn ifn (.pfm) concatstrings def + pfmn status { + pop pop pop pop + }{ + () pfmn { + (/) search dup not { pop (\\) search } if { + 4 -1 roll exch concatstrings exch concatstrings exch + }{ + exit + } ifelse + } loop + (pfm/) exch concatstrings concatstrings + dup status { + pop pop pop pop /pfmn edef + }{ + pop /pfmn () def (pfm file not found -- ignored\n) print + } ifelse + } ifelse + //systemdict /.setsafe known { + << + /PermitFileReading + [ pfmn dup length 0 eq { pop } if + isPFB {pfbn}{pfan} ifelse + ] + /PermitFileWriting [ ] + /PermitFileControl [ ] + >> setuserparams + .locksafe + } if + + + pfmn + isPFB {pfbn}{pfan} ifelse + printafm + +} def + +% Check for command line arguments. +[ shellarguments + { ] dup length 1 eq { + 0 get makeafm + }{ + (This is PF2AFM -- AFM generator \(ver. 1.00\)\n) print + (Usage: gs [-dNODISPLAY] -- pf2afm.ps disk_font_name\n) printquit + } ifelse + } + {pop} +ifelse + |