You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-dev@xmlgraphics.apache.org by "Peter B. West" <pb...@tpg.com.au> on 2004/05/23 15:03:36 UTC

Fonts

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>

Re: Fonts

Posted by "Peter B. West" <pb...@tpg.com.au>.
Glen Mazza wrote:
> Peter B. West wrote:
> 
>>>   I wrote:
>>>
>>> The latter is outside my scope of knowledge (but sounds messy ;)--as 
>>> for the former, what font-specific methods (and their signatures) do 
>>> you see us needing to add to our render.Render interface (which 
>>> declares the minimal methods needed by layout to interact with a 
>>> renderer)?  getFontMetrics()?  isFontSupported()? (Currently, there 
>>> is just a setupFontInfo() in this interface, which, as you say, seems 
>>> nonideal--layout feeding the renderers the FontInfo.)
>>
>>
>>
>> At the moment, I don't see any font-specific methods required.
>>
> (Still learning...)
> 
> But wouldn't we need to add some form of isFontSupported(fontName, ...) 
> to the Renderer interface?  AFAICT, the XSL font-family property allows 
> me to specify any font I want, so long as it is supported by the 
> RenderType I chose.   So if I invent a new RenderType, say Glen Document 
> Format (GDF), and invent a new font for it, "Glen Font", 
> isFontSupported("Glen Font") would return "true" for the -gdf output 
> type and "false" for the -pdf output type.  Then, layout would use that 
> boolean value to determine whether it needs to fall back to a 
> backup/default font.

That would be covered in the combination of getFont(...) and 
selectionStrategy.  If the selection strategy excludes intelligent font 
substitution, and the given font family is not available, return null. 
If intelligent substitution is allowed, then let the renderer select 
another font family.  It's worth reading the relevant parts of the Fonts 
section in the CSS2 spec for some insight into the recommended font 
selection strategy.  XSL-FO adds another twist through 
font-selection-strategy.

The font-family property returns a list, the idea being that a series of 
family-names or generic-names can be tried in sequence to resolve a 
font.  I'll have to read the CSS2 description again to determine exactly 
how .

> Also, (this point I'm less certain on) a getFontMetrics(fontName) of 
> some sort would be needed so layout can determine how much space "Mary 
> had a Little Lamb" would consume using my new font on the defined output 
> type, correct?  getFontMetrics() could be centralized in one place 
> instead of being renderer-specific, but if so we may need to handle the 
> issue of multiple renderers possibly having the same name for a font 
> type but different metrics/meanings for them.  (E.g., "courier new" 
> having different sizes in awt than it would in pdf, or a render type 
> short-circuiting a popular font that it doesn't support to a similar 
> supported one with slightly different metrics.)

The font metrics would be implicit in the Font (or FopFont) object 
returned from the renderer.  Having the renderers (explicitly or 
implicitly) returning the Font object ensures that the layout's notion 
of metrics is the same as that of the renderer.

Peter
-- 
Peter B. West <http://www.powerup.com.au/~pbwest/resume.html>

Re: Fonts

Posted by Glen Mazza <gr...@yahoo.com>.
Peter B. West wrote:

>>> 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 wrote:
>>
>> The latter is outside my scope of knowledge (but sounds messy ;)--as 
>> for the former, what font-specific methods (and their signatures) do 
>> you see us needing to add to our render.Render interface (which 
>> declares the minimal methods needed by layout to interact with a 
>> renderer)?  getFontMetrics()?  isFontSupported()? (Currently, there 
>> is just a setupFontInfo() in this interface, which, as you say, seems 
>> nonideal--layout feeding the renderers the FontInfo.)
>
>
> At the moment, I don't see any font-specific methods required.
>
(Still learning...)

But wouldn't we need to add some form of isFontSupported(fontName, ...) 
to the Renderer interface?  AFAICT, the XSL font-family property allows 
me to specify any font I want, so long as it is supported by the 
RenderType I chose.   So if I invent a new RenderType, say Glen Document 
Format (GDF), and invent a new font for it, "Glen Font", 
isFontSupported("Glen Font") would return "true" for the -gdf output 
type and "false" for the -pdf output type.  Then, layout would use that 
boolean value to determine whether it needs to fall back to a 
backup/default font.

Also, (this point I'm less certain on) a getFontMetrics(fontName) of 
some sort would be needed so layout can determine how much space "Mary 
had a Little Lamb" would consume using my new font on the defined output 
type, correct?  getFontMetrics() could be centralized in one place 
instead of being renderer-specific, but if so we may need to handle the 
issue of multiple renderers possibly having the same name for a font 
type but different metrics/meanings for them.  (E.g., "courier new" 
having different sizes in awt than it would in pdf, or a render type 
short-circuiting a popular font that it doesn't support to a similar 
supported one with slightly different metrics.)

Thanks,
Glen


Re: Fonts

Posted by "Peter B. West" <pb...@tpg.com.au>.
Glen Mazza wrote:
> (Far from being an expert on fonts, but commenting anyway...  ;)
> 
> Peter B. West wrote:
> 
>> 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.
> 
> 
> 
> I see no problem with this.  Ideally, anything renderer-specific, 
> including fonts, should be in the appropriate fop.render.{rendertype} 
> package.
> 
>>
>> 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.  
> 
> 
> 
> If any render type relies on the fonts of another render type (e.g. PS 
> using PDF), we can have it import or subclass the font libraries of that 
> render type.   (E.g. render.ps.xxxx code would import, say,  
> render.pdf.font.xxx classes.)  The dependencies are better 
> self-documenting that way, IMO.
> 

This seems to be the pivot around which both approaches can coalesce. 
As I look at this for longer, I see that my initial notions about the 
requirement for fonts are compatible with the generics that Jeremias and 
Victor are working towards.  Those are, it seems to me, a set of 
handlers for different types of Fonts - Type 1, TrueType, OpenType, 
Metafont, Framemaker fonts, whatever.

>> 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?
> 
> 
> 
> The latter is outside my scope of knowledge (but sounds messy ;)--as for 
> the former, what font-specific methods (and their signatures) do you see 
> us needing to add to our render.Render interface (which declares the 
> minimal methods needed by layout to interact with a renderer)?  
> getFontMetrics()?  isFontSupported()? (Currently, there is just a 
> setupFontInfo() in this interface, which, as you say, seems 
> nonideal--layout feeding the renderers the FontInfo.)

At the moment, I don't see any font-specific methods required.  The 
basic methods are
  FopFont getFont(String family, <enum> style, <enum> variant, <enum> 
weight, <enum> stretch, float size, <enum> selectionStrategy);
  FopFont getGenericFont(<enum> type. <enum> style, <enum> variant, 
<enum> weight, <enum> stretch, float size);
  FopFont getSystemFont(<enum> type);
where <enum> is probably an int in all cases.  selectionStrategy 
determines whether, e.g., intelligent font substitution occurs if the 
family doesn't have an exact match.

Individual renderers would access their own databases of available 
fonts, and make their own decisions about what comprises a generic font, 
what comprises a system font, and how to build virtual fonts if 
necessary.  This functionality within the renderers could be built on 
top of the Type1, TrueType, etc. versions of FopFont.  However, 
individual renderers may need to vary the outcomes.  For example, PDF, 
although it uses Type1 and TrueType fonts, needs to express them 
somewhat differently.  Consider that a throw-away comment; I don't know 
how PDF uses these font types.

Take the Java renderer.  By including "appendedfontpath" in a new or 
modified font.properties file, I can add new Type 1 or TrueType fonts to 
the JVM.  Let's say I find a Garamond font when I start up.  Does it 
qualify as a serif font?  As a fantasy font?  That sort of information 
can be built into the relevant underlying font handler, but I can see 
that individual renderers might want to override some methods in order 
to make their own Quality Of Service decisions.  See the Note under 
"auto" in 7.8.3 "font-selection-strategy" in the 1.1 Draft.

What I have said qualifies as a "central font registry" in a loose 
sense, which may be refined later.  E.g., QoS information may 
progressively be moved into the underlying font type handlers.  However, 
it seems to me that the final decision is with the renderer, and it is 
the renderer that should be queried when the FO tree is being built and 
fonts resolved.

Peter
-- 
Peter B. West <http://www.powerup.com.au/~pbwest/resume.html>

Re: Fonts

Posted by Glen Mazza <gr...@yahoo.com>.
(Far from being an expert on fonts, but commenting anyway...  ;)

Peter B. West wrote:

> 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.


I see no problem with this.  Ideally, anything renderer-specific, 
including fonts, should be in the appropriate fop.render.{rendertype} 
package. 

>
> 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.  


If any render type relies on the fonts of another render type (e.g. PS 
using PDF), we can have it import or subclass the font libraries of that 
render type.   (E.g. render.ps.xxxx code would import, say,  
render.pdf.font.xxx classes.)  The dependencies are better 
self-documenting that way, IMO.

> 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?


The latter is outside my scope of knowledge (but sounds messy ;)--as for 
the former, what font-specific methods (and their signatures) do you see 
us needing to add to our render.Render interface (which declares the 
minimal methods needed by layout to interact with a renderer)?  
getFontMetrics()?  isFontSupported()? (Currently, there is just a 
setupFontInfo() in this interface, which, as you say, seems 
nonideal--layout feeding the renderers the FontInfo.)

Thanks,
Glen


RE: Fonts

Posted by Victor Mote <vi...@outfitr.com>.
Peter B. West wrote:

> 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 last time I checked, there was no way to get to the physical font file
through the awt interface. It is possible that java.awt.font.OpenType can
provide some or all of what is needed for TTF and OT fonts, but I don't know
of a way to handle Type1 embedding at all. This means that you cannot ever
embed the said font, unless you set up a parallel system (similar to the way
FOP handles things now) to find the physical file. Another issue is headless
environments. I once went down the path of trying to figure out how to
register fonts in a headless environment, and frankly don't remember what I
learned. It is probably possible.

There may come a time when the awt system is the way to go, but AFAICT, it
isn't here yet, but I'll be glad to be proven wrong. I don't say this to
discourage you -- if you know how to make it work, that will be a very good
thing. BTW, Hansuli Anderegg has been a frequent advocate of the awt system
for this work.

One important point here is that, even if awt font handling were the correct
*implementation* of font handling to use, there would still be, IMO anyway,
utility in hiding even that fact from the rest of FOP, certainly no harm.

I am taking the next comment out of sequence from Peter's original post,
because it is fundamental to comments earlier in his post, which I will
address below:

> Fonts are inherently renderer specific.  It may be that those 

No. Font *embedding* is renderer specific. AFAICT, everything else about the
font is the same.

> 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.

It is a non sequiter to say that layout needs only font metrics (which is
true), and therefore the logical home for font selection information is the
renderer.

One thing that may be confusing you is the distinction that awt makes
between java.awt.Font and java.awt.FontMetrics. There is only one
constructor for FontMetrics:

    protected FontMetrics(Font font)

Therefore, at a *logical* level, there is a one-to-one relationship between
the two. At the physical file level there is also a strict one-to-one
relationship between the two, when the metrics are separated at all. There
is no need that I can see for FOP to treat the concepts of Font and
FontMetric as two different things. Once a font object is stored in the
FOTree that object should be able to return any metrics information about
that font.

> 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. 

I have always found that cleaning up the abstraction levels and interfaces
(i.e. getting the big-picture stuff straight first) makes getting the
details right easier as well, by isolating them. However, I won't quibble
with you.

> 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 

Again, the underlying font is the same whether you are rendering to PDF,
Postscript, or anything else. Only the embedding would change. Please let me
know if I have missed something.

> 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?

This is a very good question, one that I have already pondered at some
length. Again, I am thinking only of the process of embedding here. The
first principle that I look to is that in either case, font embedding should
be factored out of FOP. There is nothing about either font-handling or the
creation of PDF files (or PostScript, or PCL, or whatever) that is
FOP-specific. Assuming this, I would lean heavily toward placing the
font-embedding logic in the output-specific library (i.e., put the PDF
embedding logic into the pdf output library, instead of fonts), because not
everything wanting Font support needs the ability to embed a font in PDF,
while almost certainly anything creating PDF will want to embed fonts.

Victor Mote