[OpenJDK 2D-Dev] fixing OpenJDK font rendering
Jim Graham
james.graham at oracle.com
Tue Oct 11 01:05:10 UTC 2011
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