5.7 Font Matching
As
we've seen, CSS allows for the matching of font
families, weights, and variants. This is all done through font
matching, which is a vaguely complicated procedure. Understanding it
is important for authors who want to help user agents make good font
selections when displaying their documents. I left it for the end of
the chapter because it's not really necessary to
understand how the font properties work, and some people will
probably want to skip this part and go on to the next chapter. If
you're still interested, here's how
font matching works.
The user agent creates, or otherwise
accesses, a database of font properties. This database lists the
various CSS properties of all the fonts to which the user agent has
access. Typically, this will be all fonts installed on the machine,
although there could be others (for example, the user agent could
have its own built-in fonts). If the user agent encounters two
identical fonts, it will simply ignore one of them. The user agent takes apart an element to which font properties have
been applied and constructs a list of font properties necessary for
the display of that element. Based on that list, the user agent makes
an initial choice of a font family to use in displaying the element.
If there is a complete match, then the user agent can use that font.
Otherwise, it needs to do a little more work. A font is first matched against the font-style.
The keyword italic is matched by any font that is
labeled as either "italic" or
"oblique." If neither is available,
then the match fails. The
next match attempt is on font-variant. Any font
that is not labeled "small-caps" is
assumed to be normal. A font can be matched to
small-caps by any font that is labeled as
"small-caps," by any font that
allows the synthesis of a small-caps style, or by any font where
lowercase letters are replaced by uppercase letters. The next match is to
font-weight, which can never fail thanks to the
way font-weight is handled in CSS (explained
earlier in the chapter). Then, font-size is
tackled. This must be matched within a certain tolerance, but the
tolerance is left to the user agent to define. Thus, one user agent
might allow matching within a 20% margin of error, whereas another
might allow only 10% differences between the size specified and the
size that is actually used.
If there was no font match in Step 2, the user agent looks for
alternate fonts within the same font family. If it finds any, then it
repeats Step 2 for that font. Assuming a generic match has been found, but it
doesn't contain everything needed to display a given
element—the font is missing the copyright symbol, for
instance—then the user agent goes back to Step 3, which entails
a search for another alternate font and another trip through Step 2. Finally, if no match has been made and all alternate fonts have been
tried, then the user agent selects the default font for the given
generic font family and does the best it can to display the element
correctly.
The
whole process is long and tedious, but it helps to understand how
user agents pick the fonts they do. For example, you might specify
the use of Times or any other serif font in a document:
body {font-family: Times, serif;}
For each element, the user agent should examine the characters in
that element and determine whether Times can provide characters to
match. In most cases, it can do so with no problem. Assume, however,
that a Chinese character has been placed in the middle of a
paragraph. Times has nothing that can match this character, so the
user agent has to work around the character or look for another font
that can fulfill the needs of displaying that element. Of course, any
Western font is highly unlikely to contain Chinese characters, but
should one exist (let's call it AsiaTimes), the user
agent could use it in the display of that one element—or simply
for the single character. Thus, the whole paragraph might be
displayed using AsiaTimes, or everything in the paragraph might be in
Times except for the single Chinese character, which is displayed in
AsiaTimes.
5.7.1 Font Face Rules
CSS2 introduced a way to exert much
greater control over font matching through an
@font-face rule. Since no
web browsers had fully
implemented this as of spring 2003, @font-face was
removed from CSS2.1. I will not spend much time on it, as the aspects
of this rule are very complicated and could probably fill a chapter
(or a book!) of their own.
There are four ways to arrive at a font to be used in the document.
We'll look briefly at each, since future versions of
CSS may use this mechanism, and most SVG renderers at least partially
support the font face matching described in CSS2. If you are in a
situation where you need to implement @font-face,
please refer to the CSS2 specification, or whatever the latest
version of CSS might be (such as the CSS3 Web Fonts module); the
following descriptions are incomplete at best.
5.7.1.1 Font name matching
To match the font name, the user agent uses
an available font that has the same family name as the requested
font. The font's appearance and metrics might not be
the same. This is the method described earlier in this section.
5.7.1.2 Intelligent font matching
In this case, the user agent uses an
available font that is the closest match in appearance to the
requested font. The two may not match exactly, but they should be as
close as possible.
The information used to match the two fonts includes the kind of font
(text or symbol), nature of serifs, weight, cap height, x-height,
ascent, descent, slant, and so on. For example, an author could
request that a certain font be as close as possible to a certain
slant by writing:
@font-face {font-style: normal; font-family: "Times"; slope: -5;}
It would then be up to the user agent to find a serif normal
(upright) font whose slope was as close to five degrees to the right
as possible, if Times does not fit the bill. There are a great many
font aspects described in CSS2, all of which can be used to drive the
matching process in a user agent that supports them.
5.7.1.3 Font synthesis
It's also possible that a
user agent would choose to actually generate, on the fly, a font
whose appearance and metrics match the description given in the
@font-face rule. CSS2 has this to say about the
process:
In this case, the user agent creates a font that is not only a close
match in appearance, but also matches the metrics of the requested
font. The synthesizing information includes the matching information
and typically requires more accurate values for the parameters than
are used for some matching schemes. In particular, synthesis requires
accurate width metrics and character to glyph substitution and
position information if all the layout characteristics of the
specified font are to be preserved.
If this makes sense to you, then you probably don't
need my help to explain it. If not, you probably need never worry
about it.
5.7.1.4 Font download
In
this approach, the user agent may download a remote font for use in
the document. To declare a font for downloading, you might write
something like this:
@font-face {font-family: "Scarborough Fair";
src: url(http://www.example.com/fonts/ps/scarborough.ps);}
You could then use that font throughout the document.
Even in a user agent that permits font downloading, it may take some
time to retrieve the font file (such files can be quite large), which
would delay the rendering of the document, or at least delay the
final rendering.
|