From 0dad241f8439e62de7e83bf792d2e53753a597e1 Mon Sep 17 00:00:00 2001 From: bae Date: Fri, 30 Nov 2018 23:21:05 +0300 Subject: [PATCH] 8139178: Wrong fontMetrics when printing in Landscape (OpenJDK) Reviewed-by: prr Contributed-by: alvdavi@amazon.com --- src/share/native/sun/font/freetypeScaler.c | 18 ++++- .../font/Rotate/RotatedFontMetricsTest.java | 79 +++++++++++++++++++ .../font/Rotate/RotatedFontMetricsTest.java | 0 3 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 test/java/awt/font/Rotate/RotatedFontMetricsTest.java create mode 100644 test/jdk/java/awt/font/Rotate/RotatedFontMetricsTest.java diff --git a/src/share/native/sun/font/freetypeScaler.c b/src/share/native/sun/font/freetypeScaler.c index 0723352c8..c98db1e36 100644 --- a/src/share/native/sun/font/freetypeScaler.c +++ b/src/share/native/sun/font/freetypeScaler.c @@ -562,6 +562,14 @@ Java_sun_font_FreetypeFontScaler_getFontMetricsNative( /* See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=657854 */ #define FT_MulFixFloatShift6(a, b) (((float) (a)) * ((float) (b)) / 65536.0 / 64.0) +#define contextAwareMetricsX(x, y) \ + (FTFixedToFloat(context->transform.xx) * (x) - \ + FTFixedToFloat(context->transform.xy) * (y)) + +#define contextAwareMetricsY(x, y) \ + (-FTFixedToFloat(context->transform.yx) * (x) + \ + FTFixedToFloat(context->transform.yy) * (y)) + /* * See FreeType source code: src/base/ftobjs.c ft_recompute_scaled_metrics() * http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1659 @@ -594,9 +602,13 @@ Java_sun_font_FreetypeFontScaler_getFontMetricsNative( my = 0; metrics = (*env)->NewObject(env, - sunFontIDs.strikeMetricsClass, - sunFontIDs.strikeMetricsCtr, - ax, ay, dx, dy, bx, by, lx, ly, mx, my); + sunFontIDs.strikeMetricsClass, + sunFontIDs.strikeMetricsCtr, + contextAwareMetricsX(ax, ay), contextAwareMetricsY(ax, ay), + contextAwareMetricsX(dx, dy), contextAwareMetricsY(dx, dy), + bx, by, + contextAwareMetricsX(lx, ly), contextAwareMetricsY(lx, ly), + contextAwareMetricsX(mx, my), contextAwareMetricsY(mx, my)); return metrics; } diff --git a/test/java/awt/font/Rotate/RotatedFontMetricsTest.java b/test/java/awt/font/Rotate/RotatedFontMetricsTest.java new file mode 100644 index 000000000..b4d9d2c9d --- /dev/null +++ b/test/java/awt/font/Rotate/RotatedFontMetricsTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test RotatedFontMetricsTest + * @bug 8139178 + * @summary This test verifies that rotation does not affect font metrics. + * @run main RotatedFontMetricsTest + */ + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +public class RotatedFontMetricsTest { + static final int FONT_SIZE = Integer.getInteger("font.size", 20); + + public static void main(String ... args) { + Font font = new Font(Font.DIALOG, Font.PLAIN, FONT_SIZE); + Graphics2D g2d = createGraphics(); + + FontMetrics ref = null; + RuntimeException failure = null; + for (int a = 0; a < 360; a += 15) { + Graphics2D g = (Graphics2D)g2d.create(); + g.rotate(Math.toRadians(a)); + FontMetrics m = g.getFontMetrics(font); + g.dispose(); + + boolean status = true; + if (ref == null) { + ref = m; + } else { + status = ref.getAscent() == m.getAscent() && + ref.getDescent() == m.getDescent() && + ref.getLeading() == m.getLeading() && + ref.getMaxAdvance() == m.getMaxAdvance(); + } + + System.out.printf("Metrics a%d, d%d, l%d, m%d (%d) %s\n", + m.getAscent(), m.getDescent(), m.getLeading(), m.getMaxAdvance(), + (int)a, status ? "OK" : "FAIL"); + + if (!status && failure == null) { + failure = new RuntimeException("Font metrics differ for angle " + a); + } + } + if (failure != null) { + throw failure; + } + System.out.println("done"); + } + + private static Graphics2D createGraphics() { + BufferedImage dst = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); + return dst.createGraphics(); + } +} diff --git a/test/jdk/java/awt/font/Rotate/RotatedFontMetricsTest.java b/test/jdk/java/awt/font/Rotate/RotatedFontMetricsTest.java new file mode 100644 index 000000000..e69de29bb -- GitLab