tinkelman@ccavax.camb.com (Bob Tinkelman) (07/19/89)
I have written a procedure to build a Small-Caps versions (a la LaTeX) of fonts. My code is attached. I've also forwarded a copy to Mario Wolczko <mario@ux.cs.man.ac.uk>, the author of the PS-LaTeX package that we have been using here at Cambridge Computer Associates. My reason for posting it here is to get some feedback from others with more experience dealing with PostScript fonts. Other than the usual types of comments on programming style, efficiency, etc., I'd welcome feedback on a couple of specific questions: 1. I decided not to cache the font. My reasoning was that as the underlying fonts *would* be cached, the major work of rendering-the-dots wouldn't need to be redone each character. I assumed that the additional savings of avoiding my BuildChar routine would be minor in comparison. (Is that true?) In addition, I thought that I'd be wasting font cache memory which could be better used for "other characters". That obviously depends on what else is going on in the document and the size of the font cache. (What are your thoughts on the tradeoffs?) 2. I implemented a linear scaling of 0.8, uniformly in both X and Y. I didn't give this a lot of thought. I did it because Mario Wolczko had provided, as part of PS-LaTeX, TFM (TeX Font Metric) files for various SmallCaps fonts constructed this way. The Blue Book gives an example of constructing Small Caps using a more adaptive scheme: 0.8 x-scaling and y-scaling computed to give letters with tops one third of the way between x-height and cap-height. Which is better? 3. If I had decided to go with the Blue Book scaling method, I would have had to construct new TFM files. I've seen programs for creating AFM files from "what's in the printer" which, although designed for the "built-in" fonts, I believe I could adapt to work for me. I've also seen methods for building TFMs from AFMs, though I'd have to get one that worked under VMS. The part that seemed to me to require manual work was kerning. Is there any clean way to generate kerning info for pairs like "Th" where the "h" is now a short "H" which might reasonably be kerned a little under the "T"? .-----------------------------------------------------------------------------. | Bob Tinkelman | Internet: bob@ccavax.camb.com | | Cambridge Computer Associates, Inc. | UUCP: ...!{uunet,adelie}!ccavax!bob | | 56 Beaver Street, 3rd floor | BITnet: bob%ccavax@uunet.uu.net | | New York, NY 10004 | AT&T: 212-425-5830 | `-----------------------------------------------------------------------------' --.--.--.--.--.--.--.--.--.--.--.--CUT HERE--.--.--.--.--.--.--.--.--.--.--.--. % SmallCapsFont - construct a "Small Caps" font for use by PS-Latex %Creator: Bob Tinkelman <bob@ccavax.camb.com> % Cambridge Computer Associates, Inc. % 56 Beaver Street, 3rd floor % New York, NY 10004 - USA % This procedure is invoked with stack containing: % /New-Font /Base-Font % It clears the stack and defines the new font /New-Font in terms % of the base font, /Base-Font % Example of use: % /Times-SmallCaps /Times-Roman SmallCapsFont % The new font produces the same results as the base font except for "lower % case" letters (a-to-z). For these, it outputs upper case (from the base % font) scaled by .8 in each dimension. [This method of scaling was chosen, % in preference to the method recommended in the Blue Book (p157) only due % to the availability of corresponding TFM files in the PS-Latex distribution.] /SmallCapsFont % Stack: /New-Font,/Base-Font { 11 dict dup % Stack: /New-Font,/Base-Font,dict,dict 3 1 roll % Stack: /New-Font,dict,/Base-Font,dict begin % Make the new font be the current dictionary % Stack: /New-Font,dict,/Base-Font findfont dup % Find base font (leave /New-Font,dict on stack) 1000 scalefont % Scale it by 1000 /BaseFont-L exch def % and save as /BaseFont-L 800 scalefont % Also scale it by 800 and /BaseFont-S exch def % and save as /BaseFont-S /FontType 3 def % 3 means "User defined" /FontMatrix [.001 0 0 .001 0 0] def % Scale by 1000 (see above) /FontBBox BaseFont-L /FontBBox get def % Copy bounding box /Encoding BaseFont-L /Encoding get def % Copy encoding /TmpString 1 string def % Storage for 1-char string /IsLowerCase % See if char is a-z {dup (a) 0 get ge exch (z) 0 get le and } def /ToUpperCase % Convert lower to upper case {dup IsLowerCase {(a) 0 get sub (A) 0 get add} if } def /BuildChar % Stack: font, char {exch begin % font begin BaseFont-L setfont % Set to large basefont dup IsLowerCase % If char is a-z, then {BaseFont-S setfont ToUpperCase} % reset font & convert to A-Z if % TmpString 0 3 -1 roll put % put char into a temp string TmpString stringwidth % get width of current char setcharwidth % pass it to the font machinery 0 0 moveto % BuildChar builds chars at 0,0 TmpString show % output the temp string end %font% % font end } def end %font dictionary definefont pop % Define the font } def % SmallCapsFont