JDK-8214481 : freetype path does not disable TrueType hinting with AA+FM hints
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 11,12
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux_ubuntu
  • CPU: x86_64
  • Submitted: 2018-11-27
  • Updated: 2020-06-16
  • Resolved: 2019-12-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 13 JDK 14
11.0.8-oracleFixed 13.0.4Fixed 14 b27Fixed
Related Reports
Relates :  
Description
A DESCRIPTION OF THE PROBLEM :
Output is different on Java 11.0.1 vs 10.0.1

import java.awt.Color;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.GlyphVector;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;

public class DrawText {
    public static void main(String arg[]) throws IOException, FontFormatException {
        BufferedImage bufferedImage = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = (Graphics2D) bufferedImage.getGraphics();
        graphics2D.setBackground(Color.white);
        graphics2D.setPaint(Color.white);
        graphics2D.fillRect(0, 0, 800, 600);
        graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
                RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                    RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);
        graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
                RenderingHints.VALUE_STROKE_PURE);
        graphics2D.scale(1 / 1000f, 1 / 1000f);
        graphics2D.setColor(Color.BLACK);
        Font f = Font.createFont(Font.TRUETYPE_FONT,
                new FileInputStream("cambria.ttc"));
        f = f.deriveFont(12000f);
        graphics2D.setFont(f);
        GlyphVector gv = graphics2D.getFont().createGlyphVector(graphics2D.getFontRenderContext(), "test");
        graphics2D.drawGlyphVector(gv, 0, 10530);
        ImageIO.write(bufferedImage, "tif", new File("image.tif"));
    }
}

REGRESSION : Last worked in version 10.0.1


FREQUENCY : always



Comments
Fix request (13u): Requesting backport to 13u for parity with 11u. The original change applies cleanly.
11-06-2020

Fix Request jdk11u release is affected by this bug. Patch applies cleanly.
03-04-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/002b849de829 User: psadhukhan Date: 2019-12-11 06:34:35 +0000
11-12-2019

URL: https://hg.openjdk.java.net/jdk/client/rev/002b849de829 User: prr Date: 2019-12-05 01:42:23 +0000
05-12-2019

It is actually older than 8. It was first shipped in JDk 6u14 in Summer 2009 so it is now over 10 years old, and was also in JDK 7 GA. https://bugs.openjdk.java.net/browse/JDK-6797728 So I am thinking it might be best just to restore the behaviour in 11+
12-11-2019

The string "test" wasn't really a sufficient one to see much. It needs more glyph samples. The test uses lots of rendering hints and scales down the graphics by 1000 and scales up the font by 1000. This muddies the picture quite a lot, but I think we should end up with 12 pt Cambria, and the graphics AA hint when using text should defer to the text AA hint and stroke control is not relevant. And it uses createGlyphVector for some reason .. And why tif ? More things read png. But what remains and is important is drawing 12 pt Cambria, anti-aliased ... with fractional metrics ! That last part is the key. The old (JDK 8 - JDK 10) closed rasteriser code path did something special with this combination which was to disable hinting. The Freetype code path does no such thing. So what you see is that if you run on JDK 10 toggling fractional metrics then as well as the advances being fractional, the glyph shapes change. If you do the same on 11, only the advances change. Since this test has FM on, it sees a difference due to that. The JDK 8 - 10 behaviour is not necessarily "right" and isn't how it always was. It was a change we chose to make in JDK a number of years ago to support the JavaFX rendering pipeline when it ran on top of Java2D It was better for animation, scaling etc and also let the glyphs better it the fractional metrics advances in some cases. So the question now is can we, and if so should we, introduce that behaviour to the freetype rendering path.
29-11-2018

"Looks different" is not automatically "a regression". We changed rasterisers in 11 so differences can be normal.
29-11-2018

As per description cambria Font looks different in JDK 11 when compared to JDK 10.0.2. Checked this in Windows 10 as well as Ubuntu 17.10.1 and could confirm the results. This seems a regression in JDK 11. See attached screenshot as reference. Results: ======== 10.0.2: Ok 11: Fail 11.0.1: Fail 12 ea b21: Fail To verify, run the attached test case with respective JDK versions.
29-11-2018