[OpenJDK 2D-Dev] fixing OpenJDK font rendering

Phil Race philip.race at oracle.com
Mon Oct 10 17:18:52 UTC 2011

On 10/09/11 12:26 AM, Zhongcheng Lao wrote:
> Hi, Phil
> Thanks for the reply.
> I do understand Java specification always assumes 72dpi.
> The work to match with desktop setting is left to L&F to scale the pt
> size to a proper value
> when a system L&F like GTK+ is used.

The L&F is the place this needs to be done.
> As we all know, to rasterize a glyph,
> a font rendering library always needs to know both the point size and
> the DPI setting for the calculating the actual pixel boundary.
> It is always a good behavior to do this maths in the rendering level
> without any presumption on DPI,

In Java its 72 dpi - at least in the absence of any transform.
> even when it's a fixed value in the specification.
> That's exactly why I would like to introduce a DPI setting or getting
> method in FontScaler.

That isn't a good idea, nor is it necessary.
> Doing this in FontScaler also makes it possible for a FontScaler to
> know the original information about the glyph -
> the glyph looks much bigger because the DPI has a larger value,
> not because we're asked a larger pt size.
> The FontScaler can apply a different hinting on a particular DPI or pt
> size if it is willing to do that.

That's not correct. The DPI on its own is irrelevant to hinting.
Its only the combination of DPI and point size into pixels that matters 
to hinting.

And here below is the only usage anywhere in freetype of the supplied 
dpi .. its
simply used as a multiplier to get the pixel size. So there's not even a 
possibility that the DPI is used in hinting.

#define FT_REQUEST_HEIGHT( req 
)                                            \
(req)->vertResolution                                           \
               ? (FT_Pos)( (req)->height * (req)->vertResolution + 36 ) 
/ 72 \
               : (req)->height )

> This is very important for FontConfig to select a best-matched
> configuration for the font
> which is common on *nix desktop.
> Without knowing this, only L&F knows about why the glyph is transformed,
> and the font size passing to FontScaler may be the scaled one when the
> L&F applies its own DPI value as GTK+ L&F.
> I did some tests on my Ubuntu 11.04,
> which is using the default 96dpi for Gnome, with Ubuntu 11 as the
> default application font.
> The FontScaler received a scaled 14.66 (or 15) pt (yes, 11/72*96)
> which would definitely cause the wrong font setting be selected out,
> as the FontConfig may depend on the pt size not pixel size.

I don't know what you mean by "the FontConfig", but I don't see a 
problem here
as the font system in Java does, and should continue to, expect that you
are communicating with it a font size expressed at 72dpi.

> I also found that font created by "new Font("Consolas", Font.PLAIN,
> 11)" didn't apply system DPI setting for both OpenJDK and Oracle JDK (1.6.0_26),

It doesn't because its not supposed to.
> whch really confuses users and apps since no one knows
> whether a font might be scaled or how it get scaled except the L&F.
> We may need to scale the fonts that are not scaled by the L&F by ourselves
> to make them display in the same size.
> I don't think it is natural design -
> we must be very careful all over the places as we should consider
> whether the DPI would apply.
> And it really differs to the concepts on the same native platform.

You mustn't think of the Java platform as a GTK app .. instead its a 
platform which
has a Swing L&F which can emulate GTK.

> I know nothing detali about the proprietary T2KFontScaler and T2K library.
> I may be wrong,
> but I guess simply introducing a DPI value to FontScaler would not
> affect anything
> since it is the same as moving the scaling codes from L&F down to FontScaler.
> There may be some minor compability issues come out if the application
> scaled fonts by its own
> since now they all get scaled in a certain L&F.
> I will improve the codes in SunToolkit later.
> I really hope this RFE could get approved.

Sorry, but I could not approve such an unnecessary and incompatible change.

> -Johnson
> 2011/10/7 Phil Race<philip.race at oracle.com>:
>> The unavoidable issue is that in Java when you request size "12", the
>> default
>> transform for that is 72dpi and that is actually specified here:-
>> http://download.oracle.com/javase/6/docs/api/java/awt/Graphics2D.html
>> Adjusting how this maps to pixels requires applying a transform, which
>> would apply to all rendering .. and I'm not sure that is what you want and
>> certainly can't be handled in the selective way you are trying.
>> Put another way, in the absence of any transform visible on the Graphics,
>> if "new Font("Serif", Font.PLAIN, 12)" doesn't result in a 12 pixel font,
>> and
>> instead results in a (96/72*12) pixel font you are contravening the spec.
>> So what the GTK L&F currently does is explicitly request a size of
>> (96/72*12) = 16.
>> Assuming rounding is handled properly through the chain, then the *pixel*
>> size that comes out ought to be correct and what matters, and as hinting
>> should be done
>> in pixel space. that ought to hint equivalently to telling freetype 12 px @
>> 96 DPI.
>> I can't say offhand if that is in fact all correct in implementation but
>> that is the intent.
>> And FWIW Windows default DPI isn't 72 DPI either .. but we manage to hint
>> 100%
>> (or at least 99.99%) compatibly with GDI at the same pixel sizes, although
>> those
>> results are for the proprietary JDK rasteriser not freetype. So again maybe
>> there's
>> a freetype thing we aren't doing right if you see differences *at the same
>> pixel size*
>> that are rectified purely by adjusting the DPI and pt size.
>> Apps that want to use the same size as the GTK L&F probably should query
>> the font size on a GTK L&F Label and that should tell you the standard size.
>> BTW I notice that one of your patches has SunToolkit dragging in and
>> querying
>> the Swing L&F. That's not desirable.
>> -phil.
>> On 10/3/2011 7:15 AM, Johnson Lau wrote:
>>> Hi all,
>>> I was working on the same issue as Aekold Helbrass,
>>> to improve Java2D's font rendering.
>>> I agree that instead of handling the size in L&F,
>>> it would be better when the DPI setting is passed to the scaler.
>>> I implemented this by introducing a new method in SunToolkit.
>>> The font scaler will ask SunToolkit for the DPI setting,
>>> which is either retrieved from the system by the platform-specific
>>> SunToolkit implementations, or an overrided value set by the L&F.
>>> For those who're interested in this,
>>> please refer to my patches on Java2D.
>>> https://bitbucket.org/johnsonlau/openjdk-java2d-enhanced-mq
>>> It contains several bug fixes and RFEs to Java2D
>>> which I haven't been ready to publish yet
>>> since some of them are not available on Windows currently,
>>> and focus on the reflect-fc-config.patch and
>>> font-scaler-dpi-handling.patch for the moment please.
>>> The attachment is a screenshot to my work.
>>> Johnson
>>> 11-9-30 3:33, Aekold Helbrass:

More information about the 2d-dev mailing list