I have been exploring the way fonts are handled by Java as part of setting up a Java layout engine and renderer. I have committed a new class - org.apache.fop.render.awt.fonts - as a first cut at a fonts database for this application. I will attach the class description to this email.

The focus of the Fonts class is to provide the facilities required by the Recommendation. The Rec and the CSS2 spec talk about the User Agent having a database of known fonts, and the new class is a sketch of this requirement. The work is far from complete, but out of the WIP the lines of an interface for such a fonts database start to emerge, for me at least.

The database must be able to match a font given
 family name
 style - normal, italic, oblique
 variant - normal, small-caps
 weight - normal, bold, lighter, bolder, 100 - 900
 stretch - ultra-condensed - ultra-expanded
 size

Java font handling can match on family name, style and size directly and, with the fonts commonly available, on variant, weight and stretch only by constructing virtual fonts.

The database must be able to provide a complete set of selectors for each of the system-fonts caption, icon, menu, message-box, small-caption, status-bar.

Given the scope for the User Agent here, Java font handling can manage this.

The database must support the generic font families serif, sans-serif, monospace, cursive and fantasy.

This requirement is both system and installation dependent, but serif, sans-serif and monospace are available as logical fonts in Java. Cursive and fantasy fonts support will depend on available fonts, but individual renderers can check for the availability of a number of fonts known to fall into these categories.

I have read again the Wiki page on the font subsystem in the light of my current work with Java fonts. I'm afraid that I am still convinced that font handling is properly the preserve of the renderers. The layout engine needs only the font metrics, even for Java-based layout. As far as layout is concerned, the glyphs could all be Wingdings, as long as the metrics are right. The other required information is that relating to font selection, as discussed above. The logical home for font selection information is the renderer.

This is not to say that, once a clean fonts interface has been developed and implemented in all of the renderers, a further level of abstraction cannot be applied to bring all of the information under one umbrella. However, consider the problem of creating a new renderer. Fonts are inherently renderer specific. It may be that those fonts are shared between more that one renderer, but that fact is incidental to, e.g., the common ancestry of PS and PDF. Which is more sensible - writing a renderer's font handling to a common renderer font interface as an integral part of the renderer implementation, or discovering the fonts quirks of this particular renderer and adding them separately to a central font handler/registry?

I'll try attaching the Javadoc description from org.apache.fop.render.awt.Fonts, as the included HTML may cause problems otherwise.

Peter
--
Peter B. West <http://www.powerup.com.au/~pbwest/resume.html>
Java font selection is based on family names.  It seems that Java
handles font mapping something like this:<br>
Given a set of physical fonts like, e.g., Arial, Java reports them as
<pre>
font face: Arial
    logical:Arial
    family:Arial
    PSName:ArialMT
    Style:
        PLAIN
    FAMILY
    WEIGHT
    POSTURE
    SIZE
    TRANSFORM
font face: Arial Cursiva
    logical:Arial Cursiva
    family:Arial
    PSName:Arial-ItalicMT
    Style:
        PLAIN
    FAMILY
    WEIGHT
    POSTURE
    SIZE
    TRANSFORM
font face: Arial Negreta
    logical:Arial Negreta
    family:Arial
    PSName:Arial-BoldMT
    Style:
        PLAIN
    FAMILY
    WEIGHT
    POSTURE
    SIZE
    TRANSFORM
font face: Arial Negreta cursiva
    logical:Arial Negreta cursiva
    family:Arial
    PSName:Arial-BoldItalicMT
    Style:
        PLAIN
    FAMILY
    WEIGHT
    POSTURE
    SIZE
    TRANSFORM
</pre>
There are other Arial forms, e.g. Arial Black and Arial Narrow, but
they fall into different families, as indicated by the font name.
java.awt.font.TextAttribute defines a number of TextAttribute
constants, and querying a Font object via getAvailableAttributes()
will provide an array of attributes available on the Font.
<p>It seems there is a common set available on both Type1 and TrueType
fonts in 1.4.2; viz FAMILY, WEIGHT, POSTURE, SIZE and TRANSFORM.
Note that style is reported as PLAIN on all fonts, irrespective of
the actual style according to the font name.
<p>SIZE works as one might expect.  WEIGHT is supported directly only
for the weights provided in the set of family fonts.  In the case of
Arial, only REGULAR and BOLD.  The same is true of POSTURE: REGULAR
and OBLIQUE.  There seems to be room here to experiment with
virtual fonts.  A virtual Arial font might be constructed from the
Arial, Arial Narrow, Arial Black and Arial Black MT fonts.
Another area where virtual fonts might be handy is for small caps.

<p>In the case of the set of <i>logical</i> fonts defined for all Java
implementations, the characteristics are reported like this:
<pre>
font face: serif.plain
    logical:serif
    family:serif
    PSName:serif
    PLAIN              
    FAMILY
    WEIGHT
    POSTURE
    SIZE
    TRANSFORM
font face: serif.bold
    logical:serif.bold
    family:serif
    PSName:serif.bold
    PLAIN              
    FAMILY
    WEIGHT
    POSTURE
    SIZE
    TRANSFORM
font face: serif.bolditalic
    logical:serif.bolditalic
    family:serif
    PSName:serif.bolditalic
    PLAIN              
    FAMILY
    WEIGHT
    POSTURE
    SIZE
    TRANSFORM
font face: serif.italic
    logical:serif.italic
    family:serif
    PSName:serif.italic
    PLAIN              
    FAMILY
    WEIGHT
    POSTURE
    SIZE
    TRANSFORM
</pre>
Note that in this case, the logical name of the serif.plain font is
<i>serif</i>.  This correspondence only seems to occur with the logical
fonts.

<p>Three names are available for each <code>Font</code> object:
<dl>
<dt>Font Face Name</dt>
  <dd>Aka Font Name. Corresponds to a phsical font in the underlying
      system.</dd>
<dt>Family Name</dt>
  <dd>the name of the font family that determines the typographic design
      across several faces.</dd>
<dt>Logical Name</dt>
  <dd>The name that was used to construct the font.  Each font has
      such a name, irrespective of whether it is a <i>logical</i> or
      <i>physical</i> font.  The logical name only differs from the
      font face name in the case of <i>logical</i> fonts.  <i>E.g.</i>
      the logical name of <code>serif.plain</code> is
      <code>serif</code>, which is also the name of the pre-defined
      logical font <i>serif</i>.</dd>
<dt>Postscript Name</dt>
  <dd>The Postscript name of the font.  Derivation and significance
      unknown.<dd>
</dl>

Initial font mapping is based on the names available to the font.

<h4>XSL-FO/CSS2 system fonts</h4>
The CSS2 system fonts are:
<ul>
<li>caption</li>
<li>icon</li>
<li>menu</li>
<li>message-box</li>
<li>small-caption</li>
<li>status-bar</li>
</ul>
The situation on linux systems is that there are no system fonts as
such.  Individual GUI environments like Gnome, KDE, CDE and the like
may define such fonts, but determining them will depend on the
individual system's GUI environment.  The closest parallel in Java is
the set of <i>logical</i> fonts defined in every Java implementation,
<i>viz.</i>
<ul>
<li>Serif</li>
<li>SansSerif</li>
<li>Monospaced</li>
<li>Dialog</li>
<li>DialogInput</li>.
</ul>
The most obvious mapping from Java logical fonts to XSL-FO/CSS2
system fonts is
<dl>
<dt>caption</dt><dd>SansSerif at size A</dd>
<dt>icon</dt><dd>SansSerif at size B</dd>
<dt>menu</dt><dd>SansSerif at size C</dd>
<dt>message-box</dt><dd>Dialog</dd>
<dt>small-caption</dt><dd>caption at size A/1.2</dd>
<dt>status-bar</dt><dd>SansSerif at size D</dd>
</dl>
where sizes A, B, C and D are UserAgent prerogatives determined in
consultation with the underlying JVM font system.  I.e., the fonts
must support fractional metrics and dynamic sizing, which, in default
Java implementations, they do, as far as I know.

<h4>XSL-FO/CSS2 Generic Font Families</h4>
The generic families in the Recommendation are:
<ul>
<li>serif</li>
<li>sans-serif</li>
<li>cursive</li>
<li>fantasy</li>
<li>monospace</li>.
</ul> 
The mapping of the CSS2 generics <code>serif</code>,
<code>sans-serif</code> and <code>monospace</code> is a straightforward
name translation.  There is no such convenient correspondence between
the Java font system and <code>cursive</code> and <code>fantasy</code>
fonts.  This mapping must be determined by the UserAgent by
interrogating the JVM.

Reply via email to