[OpenJDK 2D-Dev] fixing OpenJDK font rendering

Aekold Helbrass helbrass at gmail.com
Tue Oct 11 14:28:25 UTC 2011

Ok, maybe it is possible to request not PT but exact pixel size from
freetype? It will be able to apply proper hinting and render subpixels
properly then, but we need to get real DPI and apply that pt-to-px
transformation on java side.

On Tue, Oct 11, 2011 at 10:01 AM, Zhongcheng Lao <johnsonlaucn at gmail.com> wrote:
> Hi, Jim
> I totally agree that there is a better way to deal with DPI than what
> I did in my patches.
> A context-dependent equivelance (DPI or scaling factor in
> FTScalerContext not Scaler) or even Graphics is more acceptable for
> me.
> What OpenJDK does now is not a grace way to handle variant DPI vaules
> among systems.
> It's never a good idea to scale fonts in L&F to conform system DPI setting.
> - Johnson
> 2011/10/11 Jim Graham <james.graham at oracle.com>:
>> In addition to the issue of whether this fits with our current API contracts
>> as defined by the Graphics2D spec, this could never be a global setting.
>>  Printing, multiple screens, talking to remote displays, producing images
>> for docs and publications - all of those are examples of when a given
>> application may be dealing with many different DPI targets within a single
>> run...
>> If there was going to be a DPI adjustment (and I fully agree with everything
>> Phil said on that matter, but for sake of argument - if), then it would have
>> to be context-dependent - possibly as a new attribute on Graphics.  But, a
>> global setting on the scaler?  No...
>>                        ...jim
>> On 10/10/2011 10:18 AM, Phil Race wrote:
>>> 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
>>> remote
>>> 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.
>>> -phil.
>>>> -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