[OpenJDK 2D-Dev] fixing OpenJDK font rendering

Phil Race philip.race at oracle.com
Thu Oct 6 18:19:49 UTC 2011

The unavoidable issue is that in Java when you request size "12", the 
transform for that is 72dpi and that is actually specified here:-

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 
the Swing L&F. That's not desirable.


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:
>> On Thu, Sep 29, 2011 at 9:40 PM, Phil Race<philip.race at oracle.com>  
>> wrote:
>>> On 9/29/2011 11:33 AM, Aekold Helbrass wrote:
>>>> So... You really mean that swing may not respect desktop font
>>>> rendering settings and must keep rendering fonts with the same
>>>> uglyness forever, even in native look and feels? No wonder swing is so
>>>> dead...
>>> I don't think you are reading what I wrote. The native GTK  L&F 
>>> *does* do
>>> that  ..
>>> I even pointed you to the source code that handles it.
>> I am reading, also I checked PangoFonts class. It is just changing
>> size of font instead of setting up proper freetype rendering. Because
>> of this freetype first of all will not be able to apply proper
>> subpixel rendering, because it has to know real number of pixels,
>> calculated from DPI and pt size of font, not just 72 dpi and increased
>> size. Second, hinting algorythms of freetype will not work either,
>> because hinting depends on pixel grid so needs exact pixel sizes too.
>> Please see screenshot in attachment, showing that even GTK look and
>> feel rendering is different from real GTK app (gedit in the
>> background).
>>> And "size difference" != "ugliness"
>> With that I can fully agree, but I have few points here too. First of
>> all, swing fonts are still ugly as you can see on screenshots I've
>> sent. Also, swing is not respecting desktop properties, so in any
>> modern linux desktop environment all apps will look similar (they
>> respect fontconfig settings, written by user himself or distribution
>> developers) but swing will be different, and not in a good way.
>> Being fan of netbeans and swing architecture I wanted to see pretty
>> fonts and to get rid of those "wow your netbeans is ugly, why don't
>> you switch to eclipse?", and with my dirty hack I almost did, with few
>> problems when components are requesting fonts with greyscale or mono
>> rendering. So as you can see I am not very happy that swing is doomed
>> because it has to render fonts in some strange manner instead of
>> respecting system and user settings and getting 100% similar glyphs.
>> It's a pity swing is so powerful and with really great design, but
>> nothing is written in swing but few developer tools and maybe few
>> corporate apps based on netbeans platform. And as for me this visual
>> difference between swing and native apps is not the last reason for
>> this.
>>> -phil.
>>>> On Thu, Sep 29, 2011 at 8:56 PM, Phil 
>>>> Race<philip.race at oracle.com>    wrote:
>>>>> On 9/28/2011 11:10 PM, Aekold Helbrass wrote:
>>>>>> Hi! Thanx for your answer.
>>>>>> On Wed, Sep 28, 2011 at 8:50 PM, Phil Race<philip.race at oracle.com>
>>>>>>   wrote:
>>>>>>> I can't see exactly what you are proposing since you aren't 
>>>>>>> providing
>>>>>>> a diff against openjdk master.
>>>>>> Well, before providing diffs against openjdk master - I want to make
>>>>>> it as good as possible. So for now those are just experiments with
>>>>>> what I can and what I can't do.
>>>>>>> In so far as I could traverse your git repository and find anything
>>>>>>> I'm concerned by seeing references to "x11Display" in the
>>>>>>> freetypeScaler.c
>>>>>>> file which is actually used on Windows too ..
>>>>>> Exactly. That's why I called it "a dirty hack", "a proof of 
>>>>>> concept",
>>>>>> and that's the reason I am asking my questions now - to implement it
>>>>>> properly. To do that I want to see ideas behind font rendering 
>>>>>> layer.
>>>>>> OpenJDK does not belong to me, so I am the one who should be 
>>>>>> compliant
>>>>>> with original developer's ideas and styles.
>>>>>>> And I think you misunderstand how Java defines point sizes.
>>>>>>> The point size specified to the Font constructor should be scaled
>>>>>>> from pixels only according to the transform on the Java Graphics2D
>>>>>>> instance.
>>>>>>> NOT in response to any desktop DPI setting.
>>>>>> But freetype2 needs DPI setting to render font properly. That's the
>>>>>> reason why swing apps are always ugly on linux - swing does not
>>>>>> respect DPI nor fontconfig proeprties. Every other UI toolkit on 
>>>>>> linux
>>>>>> does, including Qt and GTK. And the more DPI screen has - the uglier
>>>>>> swing looks there. I want to use the same font in kwrite and in
>>>>>> netbeans, but in kwrite its size 9 and in netbeans I have to set 
>>>>>> size
>>>>>> 12-13 to make it the same, but it still looks different. Not to be
>>>>>> unfounded - please see comparison in attachment, to the left - Qt
>>>>>> rendering, the same as KDE has, Consolas, from size 16 to size 9 top
>>>>>> to bottom. To the right - the same but in swing (jdk6u24). And 
>>>>>> that's
>>>>>> on the screen with only 96 DPI, on the screens with 130 and more -
>>>>>> it's even worse. Additionaly, freetype2 has to know exact pixel 
>>>>>> size,
>>>>>> calculated from pt size and DPI or set up directly, to render 
>>>>>> subpixel
>>>>>> structure properly and make hinter do its job properly. Otherwise
>>>>>> subpixel structure will be wrong and you'll probably get rendering
>>>>>> artefacts, plus hinting will be broken.
>>>>>> Just got another thought... Do you mean that Java have to work that
>>>>>> way because of backward compatibility or compatibility with
>>>>>> T2KFontScaler or for any other reason? I mean, that java does not 
>>>>>> need
>>>>>> to respect desktop settings but has to work in predefined manner?
>>>>> I mean that this is how Java is specified. So its not something 
>>>>> you can
>>>>> change.
>>>>> The GTKLookAndFeel code accounts for the desktop DPI used by the 
>>>>> desktop
>>>>> and scales the font size appropriately.  Take a look at
>>>>> src/share/classes/com/sun/java/swing/plaf/gtk/PangoFonts.java
>>>>> In your application, not in JDK code, you could try what it does 
>>>>> there
>>>>> and getDeskProperty("gnome.Xft/DPI"); and scale your font size
>>>>> appropriately.
>>>>> -phil.
>>>>>>> -phil.
>>>>>>> On 9/28/2011 6:35 AM, Aekold Helbrass wrote:
>>>>>>>> Hi All!
>>>>>>>> I am working on fixing openjdk font rendering on linux (because
>>>>>>>> currently it's just horrible!), and I've done working
>>>>>>>> proof-of-concept: https://github.com/Helbrass/openjdk-fontfix
>>>>>>>> So now I would like to move from dirty workaround to proper 
>>>>>>>> clean and
>>>>>>>> working implementation. And I have some questions about code that
>>>>>>>> surrounds font rendering and ideas behind that code.
>>>>>>>> First question is: FreetypeFontScaler.createScalerContext() is not
>>>>>>>> doing anything, just acting as bridge, and all logic is in
>>>>>>>> FileFontStrike constructor. And I have to pass DPI to
>>>>>>>> createScalerContext(). Should I change FileFontStrike and pass 
>>>>>>>> DPI to
>>>>>>>> any scaler implementation or make
>>>>>>>> FreetypeFontScaler.createScalerContext() read DPI itself because
>>>>>>>> T2KFontScaler doesn't need DPI or can read it itself?
>>>>>>>> Thanx!

More information about the 2d-dev mailing list