changeset 57185:327b35573471

8210058: Algorithmic Italic font leans opposite angle in Printing Reviewed-by: prr, jdv, psadhukhan
author dbatrak
date Wed, 27 Nov 2019 16:39:52 +0530
parents b4c6bc80171d
children 7637e77c4c8a
files src/java.desktop/share/native/libfontmanager/freetypeScaler.c test/jdk/java/awt/font/Rotate/A.ttf test/jdk/java/awt/font/Rotate/RotatedItalicsTest.java
diffstat 3 files changed, 82 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.desktop/share/native/libfontmanager/freetypeScaler.c	Wed Nov 27 13:35:27 2019 +0530
+++ b/src/java.desktop/share/native/libfontmanager/freetypeScaler.c	Wed Nov 27 16:39:52 2019 +0530
@@ -472,17 +472,41 @@
     return ptr_to_jlong(context);
 }
 
+// values used by FreeType (as of version 2.10.1) for italics transformation matrix in FT_GlyphSlot_Oblique
+#define FT_MATRIX_ONE 0x10000
+#define FT_MATRIX_OBLIQUE_XY 0x0366A
+
+static void setupTransform(FT_Matrix* target, FTScalerContext *context) {
+    FT_Matrix* transform = &context->transform;
+    if (context->doItalize) {
+        // we cannot use FT_GlyphSlot_Oblique as it doesn't work well with arbitrary transforms,
+        // so we add corresponding shear transform to the requested glyph transformation
+        target->xx = FT_MATRIX_ONE;
+        target->xy = FT_MATRIX_OBLIQUE_XY;
+        target->yx = 0;
+        target->yy = FT_MATRIX_ONE;
+        FT_Matrix_Multiply(transform, target);
+    } else {
+        target->xx = transform->xx;
+        target->xy = transform->xy;
+        target->yx = transform->yx;
+        target->yy = transform->yy;
+    }
+}
+
 static int setupFTContext(JNIEnv *env,
                           jobject font2D,
                           FTScalerInfo *scalerInfo,
                           FTScalerContext *context) {
+    FT_Matrix matrix;
     int errCode = 0;
 
     scalerInfo->env = env;
     scalerInfo->font2D = font2D;
 
     if (context != NULL) {
-        FT_Set_Transform(scalerInfo->face, &context->transform, NULL);
+        setupTransform(&matrix, context);
+        FT_Set_Transform(scalerInfo->face, &matrix, NULL);
 
         errCode = FT_Set_Char_Size(scalerInfo->face, 0, context->ptsz, 72, 72);
 
@@ -496,11 +520,8 @@
     return errCode;
 }
 
-/* ftsynth.c uses (0x10000, 0x0366A, 0x0, 0x10000) matrix to get oblique
-   outline.  Therefore x coordinate will change by 0x0366A*y.
-   Note that y coordinate does not change. These values are based on
-   libfreetype version 2.9.1. */
-#define OBLIQUE_MODIFIER(y)  (context->doItalize ? ((y)*0x366A/0x10000) : 0)
+// using same values as for the transformation matrix
+#define OBLIQUE_MODIFIER(y)  (context->doItalize ? ((y)*FT_MATRIX_OBLIQUE_XY/FT_MATRIX_ONE) : 0)
 
 /* FT_GlyphSlot_Embolden (ftsynth.c) uses FT_MulFix(units_per_EM, y_scale) / 24
  * strength value when glyph format is FT_GLYPH_FORMAT_OUTLINE. This value has
@@ -871,9 +892,6 @@
     if (context->doBold) { /* if bold style */
         FT_GlyphSlot_Embolden(ftglyph);
     }
-    if (context->doItalize) { /* if oblique */
-        FT_GlyphSlot_Oblique(ftglyph);
-    }
 
     /* generate bitmap if it is not done yet
      e.g. if algorithmic styling is performed and style was added to outline */
@@ -1118,9 +1136,6 @@
     if (context->doBold) { /* if bold style */
         FT_GlyphSlot_Embolden(ftglyph);
     }
-    if (context->doItalize) { /* if oblique */
-        FT_GlyphSlot_Oblique(ftglyph);
-    }
 
     FT_Outline_Translate(&ftglyph->outline,
                          FloatToF26Dot6(xpos),
Binary file test/jdk/java/awt/font/Rotate/A.ttf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/font/Rotate/RotatedItalicsTest.java	Wed Nov 27 16:39:52 2019 +0530
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 JetBrains s.r.o.
+ * 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
+ * @bug 8210058
+ * @summary Algorithmic Italic font leans opposite angle in Printing
+ */
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+
+public class RotatedItalicsTest {
+    public static void main(String[] args) throws Exception {
+        File fontFile = new File(System.getProperty("test.src", "."), "A.ttf");
+        Font baseFont = Font.createFont(Font.TRUETYPE_FONT, fontFile);
+        Font font = baseFont.deriveFont(Font.ITALIC, 120);
+
+        BufferedImage image = new BufferedImage(100, 100,
+                                                BufferedImage.TYPE_INT_RGB);
+
+        Graphics2D g = image.createGraphics();
+        g.rotate(Math.PI / 2);
+        g.setFont(font);
+        g.drawString("A", 10, -10);
+        g.dispose();
+
+        if (image.getRGB(50, 76) != Color.white.getRGB()) {
+            throw new RuntimeException("Wrong glyph rendering");
+        }
+    }
+}