procedure BestFont: generate best X fonts procedure RankFonts: generate scores for X fonts
link xbfont
May 2, 2001; Gregg M. Townsend
Requires: Version 9 graphics under Unix
This file is in the public domain.
BestFont(W, s, ...) generates X-windows font names matching a given specification, beginning with the closest match. The ranking algorithm is similar to that used in Font() but it is not identical. ____________________________________________________________ BestFont(window, spec, ...) returns the name of whichever available X-Windows font most closely matches the given specification. Note that matching is done using a slightly different algorithm from that of the Icon runtime system; this procedure preceded Icon's font selection implementation and served as a prototype. The font specification is one or more strings containing whitespace- or comma-separated tokens. Tokens are case-insensitive. There are three kinds of tokens. A token having the form of an integer specifies the desired "pixel size" (height). If no size is included, a target size of 14 is used. An unrecognized token is taken as a substring of the desired X font name. Family names, weights, and other such factors are specified this way. Certain tokens are recognized and handled specially: m mono monospaced p prop proportional r roman i italic o oblique s sans sans-serif sansserif These are turned into search strings of a particular form. For example, "roman" and "r" specify the search string "-r-". The "best match" to a given specification is calculated by reviewing all the available fonts, assigning a score to each, then choosing the one with the highest value. There are several aspects of scoring. Size is the most important factor. A tuned font of the correct size gets the maximum score. Nearby sizes receive partial credit, with an undersized font preferred over an oversized font. Scalable fonts are also recognized, but a tuned font of the correct or nearly-correct size gets a higher score. Each successful substring match increases the score, whether the test string comes from an unrecognized token or a special keyword. Earlier tokens receive slightly more weight than later ones. All tokens need not match. The string "lucida gill sans 18" is perfectly reasonable; it specifies a preference for Lucida Sans over Gill Sans by the position of the tokens, but will match either. Ties are broken by giving slight preferences for normal weight, no slant, normal width, and ASCII ("iso8859") encoding. A slight penalty is assessed for "typewriter" fonts. Oblique fonts receive partial credit for matching "italic" requests, and vice versa. The scoring function can be altered by assigning values to certain global variables. See XBF_defaults() for a commented list of these. For a scalable font, the returned value is a string specifying an instance of the font scaled to the target size. For large sizes, the scaling time may be noticeable when the font is used. BestFont() is actually a generator that produces the entire list of available fonts in order of preference. RankFonts(w, spec, ...) is similar to BestFont but produces a sequence of two-element records, where result.str is the font name and result.val is its score. For either of these, a list of X font names can be passed instead of a window. There is some startup cost the first time BestFont is called; it opens a pipe to the "xlsfonts" program and reads the output. Results are cached, so this overhead is only incurred once. Examples: Font(w, BestFont(w, "times bold italic 20")) s := BestFont(w, size, family, "italic")