Feedback request: Add new RenderingHints.KEY_FONT_HINTING

Daniel Gredler djgredler at gmail.com
Mon Jul 22 19:08:08 UTC 2024


Hi Phil,

The FM ON + AA GASP bug has been assigned bug ID JDK-8336865.

I also had a look at a few other graphics stacks to see how they handle AA
and font hints, for comparison:
 - It looks like Cairo also has two independent configuration items for AA
and font hints: `cairo_font_options_set_antialias` and
`cairo_font_options_set_hint_style` [1, 2, 3]
 - It looks like .NET does have a nice unified text rendering hint which
surfaces only the AA and font hint combinations which make sense (AA only,
AA+hint, hint only, neither, etc), but I don't think there's a nice way to
fit something like that into the existing RenderingHints API... [4, 5]
- HTML Canvas only provides higher-level configuration options, in keeping
with existing web standards like CSS and SVG [6]

Take care,

Daniel

[1] https://www.cairographics.org/manual/cairo-text.html
[2]
https://www.cairographics.org/manual/cairo-cairo-font-options-t.html#cairo-font-options-set-antialias
[3]
https://www.cairographics.org/manual/cairo-cairo-font-options-t.html#cairo-font-options-set-hint-style
[4]
https://learn.microsoft.com/en-us/dotnet/api/system.drawing.graphics.textrenderinghint?view=net-8.0
[5]
https://learn.microsoft.com/en-us/dotnet/api/system.drawing.text.textrenderinghint?view=net-8.0
[6]
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textRendering


On Wed, Jul 17, 2024 at 8:05 PM Daniel Gredler <djgredler at gmail.com> wrote:

> Hi Phil,
>
> Thanks again for the quick response, there's a lot to chew on.
>
> > It crossed my mind that I wasn't sure if we do the right thing
> > in this case - the decision to use AA may be seen by the impl
> > in a way that it can't tell the origin. This would not be a
> > reason to add a new font hinting RenderingHint, it would just
> > be a bug. The hinting should only be off if FM=ON and AA=ON
> > (not GASP).
>
> Understood, I will set aside some time to put together a minimal test
> case, file a bug, and provide the bug ID.
>
> > If you are creating documents to be printed (which is really just
> > another hidpi destination like a retina screen) hinting is OFF
> > whether you ask for it to be ON or not, because there simply
> > won't be hints in the font for that scale. The GASP table for
> > example will typically indicate hinting off above something
> > like 24 pixel size.
>
> I'm not sure that this is true.
>
> The ttfautohint tool, which is widely adopted and used by many popular
> open source fonts, creates a single AA+H (antialiasing + hinting enabled)
> entry in the "gasp" table for all sizes. By default it also generates hints
> for all sizes between 8 PPEM and 50 PPEM, and only turns off hinting
> completely above 200 PPEM. See --hinting-range-min, --hinting-range-max,
> --hinting-limit, and "Hint Sets" at [1]. This means using hints for all
> sizes under 200 PPEM (by default).
>
> Based on a "gasp" table check in my Windows and Linux system font
> directories [2], another popular approach is to suggest AA without hinting
> below 8 PPEM or so, and then either (a) enable both AA and hinting for all
> sizes above ~8 PPEM, or (b) enable only hinting for sizes between ~8 PPEM
> and ~15 PPEM and then enable both AA and hinting above ~15 PPEM. Overall,
> most fonts seem to want to enable hinting above 8 or 10 PPEM.
>
> So I do think hints are often available at the sizes that we are
> discussing.
>
> > the more ways you have to ask for the same thing, then the more
> > you have to figure out a sensible answer if two are specified ..
> > I am not sure it would ever make sense to specify GASP with ANY
> > value of the proposed new hint but you wouldn't be able to stop
> > people doing it.
> >
> > [...]
> >
> > So my view is this new hint is not needed and potentially
> > introduces difficult to answer questions.
>
> Completely agree that a new font hinting "knob" would introduce
> combinations of configuration that probably never make sense. And of course
> if it doesn't provide value for users, then it's a net negative (just extra
> complexity). But I do think this "knob" would be valuable to users, based
> on the observation that font hints are common and are sometimes useful,
> depending on the application. Indeed, they are separate flags in the "gasp"
> table itself (you can enable one, or the other, or neither, or both), so it
> seems pretty standard to have two separate "knobs" for these two separate
> settings.
>
> As a thought exercise, I went through and thought about which combinations
> of AA and hinting might not make sense, and I think the only hard ones
> really are just the combinations involving AA GASP. Do you agree? If this
> is the case, the options would be to let it happen, or to forbid these two
> or three combinations completely. I would be inclined to allow people to
> try any of the three AA GASP combinations that they want, with perhaps a
> warning in the JavaDoc :-)
>
> AA      HINT        VALID?
> --      ----        ------
> ON      ON          Y
> ON      OFF         Y
> ON      DEFAULT     Y
> OFF     ON          Y
> OFF     OFF         Y
> OFF     DEFAULT     Y
> DEFAULT ON          Y
> DEFAULT OFF         Y
> DEFAULT DEFAULT     Y
> GASP    ON          ?
> GASP    OFF         ?
> GASP    DEFAULT     Y
>
> Thanks again for engaging on this topic. I'm off to see about filing that
> "FM + AA ON vs FM + AA GASP" bug!
>
> Take care,
>
> Daniel
>
> [1] http://freetype.org/ttfautohint/doc/ttfautohint.html
> [2] https://gist.github.com/gredler/a890145b50d4bfc0de1c1e482a52cd5d
>
>
>
> On Tue, Jul 16, 2024 at 7:07 PM Philip Race <philip.race at oracle.com>
> wrote:
>
>>
>>
>> On 7/15/24 5:11 PM, Daniel Gredler wrote:
>>
>> Hi Phil,
>>
>> Thank you for the response and the insights!
>>
>> I have to admit I don't know much about the situation in macOS, but I
>> assume they're moving things in a direction that works best for their
>> particular situation (complete control over both the software and hardware
>> stacks, and best-in-class displays).
>>
>> I have indeed experimented with VALUE_TEXT_ANTIALIAS_GASP, and I have two
>> problems with this "font knows best" approach:
>>
>> 1. You're not actually trusting the font to know best. For example, the
>> Google Noto Sans Condensed Bold "gasp" table contains a single entry
>> indicating that grid-fitting (i.e. hinting) and grayscale rendering (i.e.
>> anti-aliasing) should both always be used, at all sizes. However, when I
>> use this font in Java with VALUE_TEXT_ANTIALIAS_GASP and
>> VALUE_FRACTIONALMETRICS_ON, Java correctly trusts the font regarding AA and
>> enables it, but then ignores the font regarding hinting (because currently
>> AA + FM = no hinting, and everything else is hinted, regardless of what
>> "gasp" says).
>>
>>
>> It crossed my mind that I wasn't sure if we do the right thing in this
>> case - the decision to use AA may be seen by the impl in a way
>> that it can't tell the origin. This would not be a reason to add a new
>> font hinting RenderingHint, it would just be a bug.
>> The hinting should only be off if FM=ON and AA=ON (not GASP).
>> And it also shows that the more ways you have to ask for the same thing,
>> then the more you have to figure out a sensible answer if two
>> are specified .. I am not sure it would ever make sense to specify GASP
>> with ANY value of the proposed new hint but you wouldn't be
>> able to stop people doing it.
>>
>>
>> 2. The font doesn't actually always know best. The application developer
>> knows whether they are creating documents to be printed (and if so, whether
>> they are intended to be printed on low-DPI or high-DPI devices), whether
>> they are creating a desktop application with text animation and scaling
>> (like a dynamic reporting dashboard or a videogame), whether they are
>> creating a desktop application with static text (like a PDF viewer), etc.
>> The developer may want to use one font for all of these use cases, but with
>> different rendering hints.
>>
>>
>> if you are creating documents to be printed (which is really just another
>> hidpi destination like a retina screen)
>> hinting is OFF whether you ask for it to be ON or not, because there
>> simply won't be hints in the font for that scale.
>> The GASP table for example will typically indicate hinting off above
>> something like 24 pixel size.
>> But if you are drawing them to the screen to proof for the printer you
>> still don't want the rendering to be awful, and that's what you will
>> get. Really you just want it laid out properly.
>> This is the use case for FM because otherwise text is laid out snapped to
>> screen pixels which means it won't scale on a printer.
>>
>> So my view is this new hint is not needed and potentially introduces
>> difficult to answer questions.
>>
>> -phil.
>>
>>
>> Interestingly, in addition to the three key values that I had proposed
>> (VALUE_FONT_HINTING_DEFAULT, VALUE_FONT_HINTING_ON,
>> VALUE_FONT_HINTING_OFF), I had actually considered a fourth:
>> VALUE_FONT_HINTING_GASP. I didn't include it originally because I think the
>> direct control over font hinting is most valuable, but it does make for a
>> nice parallel with VALUE_TEXT_ANTIALIAS_GASP, and the combination would
>> enable a real "font knows best" mode.
>>
>> Let me know what you think about these two points and the idea of a
>> fourth hinting option.
>>
>> Take care,
>>
>> Daniel
>>
>>
>>
>> On Mon, Jul 15, 2024 at 9:22 PM Philip Race <philip.race at oracle.com>
>> wrote:
>>
>>>
>>>
>>> Platforms are tending towards AA+unhinted - this is all we can get from
>>> macOS today so I'm not sure how well we could support this hint.
>>>
>>> And being able to turn off hinting when doing modes such as B&W is
>>> unlikely to produce good results on any font you'd want to use.
>>>
>>> Have you looked at the existing VALUE_TEXT_ANTIALIAS_GASP hint ?
>>>
>>>
>>> https://docs.oracle.com/en/java/javase/21/docs/api/java.desktop/java/awt/RenderingHints.html#VALUE_TEXT_ANTIALIAS_GASP
>>>
>>> it uses the OpenType table
>>> https://learn.microsoft.com/en-us/typography/opentype/spec/gasp
>>> which basically tells the rasteriser at a specific size which
>>> combination of hinting and anti-aliasing to use.
>>>
>>> If apps use together with the FM hint they should get most of what they
>>> want.
>>> Where JDK can (this means when we use freetype) you'd get FM PLUS the
>>> appropriate AA PLUS the appropriate hinting choice
>>>
>>> I think this is better than a hint where an app will have to guess,
>>> probably wrongly.
>>>
>>> -phil.
>>>
>>>
>>> On 7/14/24 7:15 AM, Daniel Gredler wrote:
>>> > Hi all,
>>> >
>>> > We've had a bit of back-and-forth regarding whether font hinting is
>>> > enabled or disabled when drawing grayscale text with anti-aliasing and
>>> > fractional metrics enabled [1, 2]. Setting AA + FM disabled font
>>> > hinting in JDK 8 - 10, then JDK 11 changed this so that AA + FM would
>>> > *not* disable hinting, and finally the behavior was reverted in JDK 14
>>> > (and backported to JDK 11).
>>> >
>>> > Generalizing a bit, the current behavior (AA + FM disables hinting) is
>>> > optimal for "the desktop use case" (JavaFX, animations, smooth
>>> > scaling, etc). The JDK 11/12/13 behavior was optimal for "the backend
>>> > use case" (individual image creation, no animations).
>>> >
>>> > I think it would be useful to have a new java.awt.RenderingHints key
>>> > named RenderingHints.KEY_FONT_HINTING, with the following possible
>>> values:
>>> > - RenderingHints.VALUE_FONT_HINTING_DEFAULT: current behavior,
>>> > dictated by AA + FM
>>> > - RenderingHints.VALUE_FONT_HINTING_ON: enable font hinting,
>>> > regardless of AA + FM
>>> > - RenderingHints.VALUE_FONT_HINTING_OFF: disable font hinting,
>>> > regardless of AA + FM
>>> >
>>> > This new rendering hint would allow direct control over whether font
>>> > hinting is enabled or not, and would specifically enable the use of AA
>>> > + FM + font hints in Java.
>>> >
>>> > I'm happy to create a patch with this feature (I have a signed OCA on
>>> > file), but wanted to get feedback on the idea first. Let me know what
>>> > you think!
>>> >
>>> > Take care,
>>> >
>>> > Daniel
>>> >
>>> > [1] https://bugs.openjdk.org/browse/JDK-8214481
>>> > [2] https://bugs.openjdk.org/browse/JDK-8242285
>>> >
>>>
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/client-libs-dev/attachments/20240722/d43aeaca/attachment-0001.htm>


More information about the client-libs-dev mailing list