[OpenJDK 2D-Dev] Font rendering issue
Roman Kennke
Roman.Kennke at Sun.COM
Tue May 18 19:07:41 UTC 2010
Hi Mario,
> > > ly = (jfloat) ROUND(FT26Dot6ToFloat(
> > > scalerInfo->face->size->metrics.height +
> > > bmodifier) + ay - dy);
> > >
> >
> > And here is the proposed webrev:
> >
> > http://cr.openjdk.java.net/~neugens/100134/webrev.02/
> >
> > As noted, this doesn't really fix all the bugs, it just fixes the
> > rounding for leading, which, by chance, workarounds the other issues and
> > appear to fix the rendering as well.
> >
> > Cheers,
> > Mario
>
> Any comment on that?
To be honest, I don't like that. It's (yet another) workaround for
problems in other areas of JDK. We already have plenty of workarounds
and adjustments on the metrics, and adding more of it doesn't seem
right.
I already started a 'discussion' (well, so far it's been a
monologue ;-) ) on the topic here:
http://mail.openjdk.java.net/pipermail/swing-dev/2010-May/001034.html
I believe that the metrics returned by the freetype scaler are (mostly)
correct. Mostly, because the leading is most likely broken, it should
not be -1. But the leading is rarely used and doesn't really have a
direct impact. What *does* matter is the line height. And this comes out
correctly, albeit only per accident. Why accident? Well, height is not
fetched directly from the font scaler (as it should IMO), but instead
calculated from ascent, descent and leading. And since we calculate
leading from height, ascent and descent as reported by the scaler, it
comes out right in the end. (Funny, eh?)
So what is the actual problem that leads to 'g' and '_' beeing cut off?
In my opinion, it is a problem in how Swing renders and lays out text.
In many places (for example, in PlainView) it assumes that font height
is the space that a single line of text needs to fully contain all its
glyphs. But if you take a look at the specification, that's not the
case: height is the distance from one baseline to the next. Why is that
different? Because two lines of text may have a slight overlap. For
example, the undershoot of 'g' (in certain fonts at certain sizes)
overlaps by one pixel into the next row of text. The only metrics that
guarantee to fully contain a line are maxAscent and maxDescent. So, for
a multiline textfield (just to pick an example) the total height would
be maxAscent + (n-1) * height + maxDescent. The total height for a
single line would be maxAscent + maxDescent (which is actually a
degenerated case of the other formula).
To really fix this problem (which I'd support, as opposed to add more
workarounds), we'd need to fix Swing's text rendering. Problem here is
that this would break 3rd party code, as can be witnessed already. For
example, Netbeans' text rendering is also broken, and it's not using
Swing for its text editors, which leads to '_' beeing invisible in many
cases, when running in OpenJDK. On the other hand, introducing more
workarounds would make OpenJDK remain 'compatible' in the sense that
existing apps would run as fine as with closed JDK, but by sacrificing
correct text rendering (as specified in the by the font designer).
I also blogged about it:
http://rkennke.wordpress.com/2010/05/09/subtleties-in-java-text-rendering/
So to summarize, I think fixing this involves the following:
- Fix Swing text rendering
- File bugs in important projects like Netbeans
- Fix metrics so that height is not calculated from ascent, descent and
leading, but instead fetched from the scaler directly.
- Review and get rid of workarounds that wrongly adjust the metrics
Not sure if it's likely to ever happen for compatibility reasons, I
think it would be nice, and would improve Java's font rendering subtly
but significantly.
Would like to hear other's (Phil, Igor,..) opinions on that, I might be
missing important points.
Cheers, Roman
More information about the 2d-dev
mailing list