I'll do this for you.

-phil.

On 1/27/20, 1:10 AM, Dmitry Batrak wrote:
Thanks!
Now that that change has two +1's, would anyone be able to push it?

Best regards,
Dmitry Batrak

On Tue, Jan 21, 2020 at 8:05 AM Sergey Bylokhov <sergey.bylok...@oracle.com <mailto:sergey.bylok...@oracle.com>> wrote:

    Looks fine.
    Thank you for contribution!

    On 1/20/20 12:14 am, Dmitry Batrak wrote:
    > > Ok approved. Seems it is making a few things better if not
    ideal, but nothing worse.
    >
    > Thanks!
    > Anyone else volunteering to review?
    >
    > Best regards,
    > Dmitry Batrak
    >
    > On Tue, Jan 14, 2020 at 8:58 PM Phil Race
    <philip.r...@oracle.com <mailto:philip.r...@oracle.com>
    <mailto:philip.r...@oracle.com <mailto:philip.r...@oracle.com>>>
    wrote:
    >
    >     Ok approved. Seems it is making a few things better if not
    ideal, but nothing worse.
    >
    >     -phil.
    >
    >     On 1/14/20 8:14 AM, Dmitry Batrak wrote:
    >> > So this is a workaround for a buggy font that doesn't play
    well with GDI ?
    >>
    >>     This is a workaround for all cases (or the vast majority of
    them) of broken
    >>     rendering reported by our customers. The case with Roboto
    is just the one we
    >>     have steps to reproduce for. There can be other cases where
    GDI's logic is not
    >>     matched by JDK. Even if all of them are caused by
    'mis-constructed' fonts, I'm
    >>     afraid, this will not be considered as a good excuse by our
    customers, as only
    >>     Java applications have such problems with these fonts.
    >>
    >>     See JDK-8192972, still unsolved in OpenJDK, as an example
    of the problems which
    >>     will be, at least partially, solved with this fix (correct
    glyphs will be
    >>     rendered, albeit using FreeType).
    >>
    >>     I did test the fix with fonts preinstalled in Windows 10.
    Fallback was actually
    >>     triggered for one font (bold italic 'Segoe UI Semibold'),
    which is not a 'false'
    >>     positive, but actually a manifestation of another JDK bug
    from the same family -
    >>     I've just raised
    https://bugs.openjdk.java.net/browse/JDK-8237085 for it. That's
    >>     yet another example of an issue which will be (mostly)
    solved by the proposed
    >>     fix.
    >>
    >>     Using file length as a 'checksum' certainly doesn't
    guarantee we choose the
    >>     right font, but the probability of error is very low, and
    this value seems to be
    >>     the best candidate in our circumstances in terms of cost
    vs. benefit. Even if
    >>     the validation mistreats a different font (having the same
    length) as a correct
    >>     one, we'll not be in a worse position than before.
    >>
    >>     Of course, there's a certain risk that rendering for
    unaffected fonts might
    >>     change, but, given quite straightforward contract of
    GetFontData function, I
    >>     would consider it very low.
    >>
    >> > Since you aren't retrieving the data, just asking what the
    size is, I'd expect
    >> > it to be unmeasurable.
    >>
    >>     Well, we don't know how GetFontData works exactly, but it
    does seem to add some
    >>     overhead. On my Windows 10 machine OpenJDK with the
    proposed fix yields about 7%
    >>     larger result for the following benchmark program. The
    reported value does
    >>     fluctuate from run to run, but the impact of the fix seems
    to be larger than the
    >>     fluctuations.
    >>
    >>     --- Benchmark source code ----
    >>     import java.awt.*;
    >>     import java.awt.font.GlyphVector;
    >>     import java.awt.image.BufferedImage;
    >>
    >>     public class PerfTestOneFont {
    >>         private static final Font FONT = new Font("Segoe UI",
    Font.PLAIN, 12);
    >>
    >>         public static void main(String[] args) {
    >>             FONT.getFamily(); // preload font
    >>
    >>             BufferedImage image = new BufferedImage(1, 1,
    BufferedImage.TYPE_INT_RGB);
    >>             Graphics2D g = image.createGraphics();
    >>     g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
    >>     RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
    >>             int glyphCount = FONT.getNumGlyphs();
    >>             long startTime = System.currentTimeMillis();
    >>             for (int glyphCode = 0; glyphCode < glyphCount;
    glyphCode++) {
    >>                 GlyphVector gv =
    FONT.createGlyphVector(g.getFontRenderContext(),
    >>                                            new int[]{glyphCode});
    >>                 g.drawGlyphVector(gv, 0, 0);
    >>             }
    >>             long endTime = System.currentTimeMillis();
    >>             g.dispose();
    >>             System.out.println(endTime - startTime);
    >>         }
    >>     }
    >>     ------------------------------
    >>
    >>     Best regards,
    >>     Dmitry Batrak
    >>
    >>     On Mon, Jan 13, 2020 at 11:09 PM Phil Race
    <philip.r...@oracle.com <mailto:philip.r...@oracle.com>
    <mailto:philip.r...@oracle.com <mailto:philip.r...@oracle.com>>>
    wrote:
    >>
    >>         So this is a workaround for a buggy font that doesn't
    play well with GDI ?
    >>
    >>         It does rely on the fonts always being different sizes
    which is highly
    >>         likely if not guaranteed.
    >>         I suppose it is OK so long as we aren't getting any
    "false" positives.
    >>
    >>         What I mean is that almost no one will have these
    Roboto fonts
    >>         installed, so the fix
    >>         is solving a problem they don't have, but if it is
    wrong in some way,
    >>         then they could lose
    >>         GDI rendering of LCD glyphs and that could affect a lot
    of people.
    >>
    >>         So have you tested this with the full set of Windows 10
    fonts -
    >>         including Indic, CJK, etc  - to be sure
    >>         there are no cases where it fails for these or other
    spurious failures.
    >>
    >> > As for performance impact, during testing I didn't observe
    average
    >>         glyph generation time increase of more than 15%.
    >>
    >>         Since you aren't retrieving the data, just asking what
    the size is, I'd
    >>         expect it to be unmeasurable.
    >>
    >>         -phil.
    >>
    >>         On 1/13/20 1:25 AM, Dmitry Batrak wrote:
    >> > Hello,
    >> >
    >> > I'd like to submit a patch for JDK-8236996. I'm not a
    Committer, so
    >> > I'll need someone to sponsor this change.
    >> >
    >> > Issue: https://bugs.openjdk.java.net/browse/JDK-8236996
    >> > Webrev:
    http://cr.openjdk.java.net/~dbatrak/8236996/webrev.00/
    <http://cr.openjdk.java.net/%7Edbatrak/8236996/webrev.00/>
    >> >
    >> > The problem described in JDK-8236996 is from a group of
    issues (see
    >> > also e.g. JDK-8078382 and JDK-8192972), where JDK
    >> > uses one font to perform char-to-glyph conversion, but GDI,
    when asked
    >> > to render the glyph is picking a different font,
    >> > leading to completely random glyphs being rendered, as
    char-to-glyph
    >> > mapping obviously differs for different fonts.
    >> >
    >> > Specific version of Roboto font, mentioned in JDK-8236996, is
    most
    >> > probably causing the issue because it's not following
    >> > the naming guidelines from OpenType specification
    >> > (https://docs.microsoft.com/en-us/typography/opentype/spec/name),
    >> > having more than 4 variants (regular, bold, italic and bold
    italic)
    >> > with the same 'Font Family name' (name ID = 1). So,
    >> > GDI gets confused and picks Roboto Black for rendering, when
    asked to
    >> > choose a regular font from Roboto family (Roboto
    >> > Black having weight of 400, just like Roboto Regular,
    probably adds to
    >> > the confusion).
    >> >
    >> > But the reasoning, given above, about the issue cause is only
    a guess.
    >> > GDI is not an open-source subsystem, so we cannot
    >> > know for sure how it selects the font for rendering, and cannot
    >> > implement matching logic in JDK. Ideally, we'd want to
    >> > select the font by specifying its file path, but that's not
    possible
    >> > with GDI. Luckily, it allows us to query file data
    >> > for the selected font using GetFontData function
    >> >
    
(https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getfontdata),
    >> > which we can use to validate that the
    >> > selected font is the one we need.
    >> >
    >> > The proposed solution is to check the file size of the font,
    selected
    >> > by GDI, before using it for rendering. If a mismatch
    >> > is detected, fallback to FreeType is performed. It can produce a
    >> > somewhat different glyph representation, but, at least,
    >> > the correct glyph will be rendered. For members of font
    collections,
    >> > file size for validation is calculated in a special
    >> > way, in accordance with GetFontData logic described in the
    >> > documentation. I've verified that it works for font collections
    >> > bundled with Windows 10.
    >> >
    >> > As for performance impact, during testing I didn't observe
    average
    >> > glyph generation time increase of more than 15%.
    >> > Taking glyph caching into account, it shouldn't be that
    significant
    >> > for typical UI applications, I think. Performance
    >> > impact can be made even smaller - by performing the
    validation only
    >> > once per font, but, I believe, having a Java
    >> > application always render correct glyphs (even if fonts are
    added or
    >> > removed while application is running) is more
    >> > important.
    >> >
    >> > Proposed patch doesn't add any tests, as reproducing the issue
    >> > requires installation of fonts. Existing automated
    >> > OpenJDK tests pass after the fix. Proposed approach has been
    used in
    >> > JetBrains Runtime without known issues for about 3
    >> > months in testing and for about 1 month in production.
    >> >
    >> > Best regards,
    >> > Dmitry Batrak
    >>
    >>
    >
    >
    >


-- Best regards, Sergey.




Reply via email to