Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8218854

FontMetrics.getMaxAdvance may be less than the maximum FontMetrics.charWidth

XMLWordPrintable

    • 2d
    • b14
    • generic
    • generic

        On fonts where algorithmic bold is applied, FontMetrics.getMaxAdvance may be less than the maximum FontMetrics.charWidth.

        This bug was noticed in JDK-11 with Z003-MediumItalic.otf font (1px, italic + bold style, default rendering mode). Char point 37 width was greater than the max advance (2px vs. 1px). Libfreetype 2.6 font rendering library in Linux was used.

        A test case that reproduces the above scenario is attached to this ticket. Note: test case works before changset for JDK-8214002 was introduced into main line. This changeset prevents the test case from triggering the bug but the root cause was not fixed.

        Test case failure message is:

        Testing java.awt.Font[family=Z003,name=Z003-MediumItalic,style=bolditalic,size=1] in FT_LOAD_TARGET_MONO
        getMaxAdvance: 1
        Exception in thread "main" java.lang.Exception: FAILED: getMaxAdvance is not max for font: java.awt.Font[family=Z003,name=Z003-MediumItalic,style=bolditalic,size=1]getMaxAdvance(): 1getWidths()[37]: 2
        at MaxAdvanceIsMax.main(MaxAdvanceIsMax.java:135)

        Expected value is:

        "TEST PASS - OK"

        The root cause of this bug is well understood. FontMetrics.getMaxAdvance value is based on a font file attribute and the scale. Assuming the font file attribute is correct, the effects of applying algorithmic bold are not taken into account at all. On the other hand, FontMetrics.charWidth renders the glyph (a bitmap previous to JDK-8214002, or an outline after JDK-8214002) to obtain the char width. If algorithmic bold were required, it's applied calling FT_GlyphSlot_Embolden and its effects are considered. For a given scale and rendering modes, effects may become visible on the width value. FontMetrics.getMaxAdvance should have considered the effects of applying algorithmic bold to return a more accurate value.

        We can compare this issue with algorithmic obliqueness. The difference is that FontMetrics.getMaxAdvance takes into account the effect of applying obliqueness and adds a value based on Libfreetype internals.

        One possible way to fix this issue would be to follow the same strategy and add a value, taken from Libfreetype internals, in case of algorithmic bold. The Libfreetype function related to algorithmic bold is FT_GlyphSlot_Embolden.

        As part of this ticket, we propose to update algorithmic obliqueness value to align with the current libfreetype version (2.9.1).

          1. GetMaxAdvanceTests.java
            2 kB
            Ramesh Gangadhar

              mbalao Martin Balao Alonso
              mbalao Martin Balao Alonso
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved: