From fa6c167230a4b812fc43a572f187d8efe7d82055 Mon Sep 17 00:00:00 2001 From: yan Date: Thu, 5 Dec 2019 09:39:14 +0300 Subject: [PATCH] 8215210: [macos] Hangul text does not shape to the precomposed form on JDK8u Reviewed-by: phh --HG-- extra : amend_source : 9b9eef33b7cccf88179e821e824963d55c502812 --- .../classes/sun/net/www/MessageHeader.java | 38 +++++++++- .../native/sun/font/layout/MorphTables2.cpp | 2 +- .../font/TextLayout/HangulShapingTest.java | 72 ++++++++++++++++++ .../awt/font/TextLayout/HebrewIsRTLTest.java | 75 +++++++++++++++++++ 4 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 test/java/awt/font/TextLayout/HangulShapingTest.java create mode 100644 test/java/awt/font/TextLayout/HebrewIsRTLTest.java diff --git a/src/share/classes/sun/net/www/MessageHeader.java b/src/share/classes/sun/net/www/MessageHeader.java index 34b630782..6ab2008dd 100644 --- a/src/share/classes/sun/net/www/MessageHeader.java +++ b/src/share/classes/sun/net/www/MessageHeader.java @@ -288,14 +288,44 @@ class MessageHeader { return Collections.unmodifiableMap(m); } + /** Check if a line of message header looks like a request line. + * This method does not perform a full validation but simply + * returns false if the line does not end with 'HTTP/[1-9].[0-9]' + * @param line the line to check. + * @return true if the line might be a request line. + */ + private boolean isRequestline(String line) { + String k = line.trim(); + int i = k.lastIndexOf(' '); + if (i <= 0) return false; + int len = k.length(); + if (len - i < 9) return false; + + char c1 = k.charAt(len-3); + char c2 = k.charAt(len-2); + char c3 = k.charAt(len-1); + if (c1 < '1' || c1 > '9') return false; + if (c2 != '.') return false; + if (c3 < '0' || c3 > '9') return false; + + return (k.substring(i+1, len-3).equalsIgnoreCase("HTTP/")); + } + + /** Prints the key-value pairs represented by this - header. Also prints the RFC required blank line - at the end. Omits pairs with a null key. */ + header. Also prints the RFC required blank line + at the end. Omits pairs with a null key. Omits + colon if key-value pair is the requestline. */ public synchronized void print(PrintStream p) { for (int i = 0; i < nkeys; i++) if (keys[i] != null) { - p.print(keys[i] + - (values[i] != null ? ": "+values[i]: "") + "\r\n"); + StringBuilder sb = new StringBuilder(keys[i]); + if (values[i] != null) { + sb.append(": " + values[i]); + } else if (i != 0 || !isRequestline(keys[i])) { + sb.append(":"); + } + p.print(sb.append("\r\n")); } p.print("\r\n"); p.flush(); diff --git a/src/share/native/sun/font/layout/MorphTables2.cpp b/src/share/native/sun/font/layout/MorphTables2.cpp index ff69cb9a4..eb628a1a3 100644 --- a/src/share/native/sun/font/layout/MorphTables2.cpp +++ b/src/share/native/sun/font/layout/MorphTables2.cpp @@ -192,7 +192,7 @@ void MorphTableHeader2::process(const LEReferenceTo &base, LE for (subtable = 0; LE_SUCCESS(success) && subtable < nSubtables; subtable++) { if(subtable>0) { le_uint32 length = SWAPL(subtableHeader->length); - if (length & 0x03) { // incorrect alignment for 32 bit tables + if (length & 0x01) { // incorrect alignment for 32 bit tables success = LE_MEMORY_ALLOCATION_ERROR; // as good a choice as any return; } diff --git a/test/java/awt/font/TextLayout/HangulShapingTest.java b/test/java/awt/font/TextLayout/HangulShapingTest.java new file mode 100644 index 000000000..2febfad3d --- /dev/null +++ b/test/java/awt/font/TextLayout/HangulShapingTest.java @@ -0,0 +1,72 @@ +// Copyright 2019 Azul Systems, Inc. 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 Azul Systems, 385 Moffett Park Drive, Suite 115, Sunnyvale, +// CA 94089 USA or visit www.azul.com if you need additional information or +// have any questions. + +import java.awt.Font; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +/* + * @test + * @bug 8215210 + * @summary Downport of prr's fix to a certain ICU wrong condition breaking some Hangul shaping + * @run main/othervm -Dsun.font.layoutengine=icu HangulShapingTest + */ +public class HangulShapingTest { + public static void main(String args[]) { + if (!System.getProperty("os.name").startsWith("Mac")) { + return; + } + + // images of the strings as drawn should be identical + String beforeString = "\u1100\u1161 \u1102\u1161"; + String afterString = "\uAC00 \uB098"; + int w = 100, h = 100; + + BufferedImage bi1 = drawit(w, h, beforeString); + BufferedImage bi2 = drawit(w, h, afterString); + + boolean same = true; + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int c1 = bi1.getRGB(x, y); + int c2 = bi2.getRGB(x, y); + same &= (c1 == c2); + } + if (!same) { + break; + } + } + if (!same) { + throw new RuntimeException("Images differ"); + } + } + private static BufferedImage drawit(int w, int h, String toDraw) { + BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Graphics2D biGraphics = bi.createGraphics(); + biGraphics.setColor(Color.white); + biGraphics.fillRect(0, 0, w, h); + biGraphics.setColor(Color.black); + Font font = new Font("Dialog", Font.PLAIN, 20); + biGraphics.setFont(font); + biGraphics.drawString(toDraw, 10, 40); + return bi; + } +} diff --git a/test/java/awt/font/TextLayout/HebrewIsRTLTest.java b/test/java/awt/font/TextLayout/HebrewIsRTLTest.java new file mode 100644 index 000000000..1ced41de1 --- /dev/null +++ b/test/java/awt/font/TextLayout/HebrewIsRTLTest.java @@ -0,0 +1,75 @@ +// Copyright 2019 Azul Systems, Inc. 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 Azul Systems, 385 Moffett Park Drive, Suite 115, Sunnyvale, +// CA 94089 USA or visit www.azul.com if you need additional information or +// have any questions. + +import java.awt.Font; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +/* + * @test + * @summary Fix to 8215210 should not break RTL with AAT fonts. + * @run main/othervm -Dsun.font.layoutengine=icu HebrewIsRTLTest + */ +public class HebrewIsRTLTest { + static final String hebrewString = "\u05E9\u059E\u05E9\u0595\u05E9\u05A9\u05E9\u0592\u05E9\u0599\u05E9\u059E\u05E9\u0595\u05E9\u05A9\u05E9\u0592\u05E9\u0599 . \u05E9\u0599\u05E9\u05A1\u05E9\u0595\u05E9\u0593"; + public static void main(String args[]) { + if (!System.getProperty("os.name").startsWith("Mac")) { + return; + } + + // calculate text size + BufferedImage biMetrics = new BufferedImage(1000, 1000, BufferedImage.TYPE_INT_RGB); + Graphics2D biMetricsGraphics = biMetrics.createGraphics(); + Font font = new Font("TimesRoman", Font.PLAIN, 40); + biMetricsGraphics.setFont(font); + int width = biMetricsGraphics.getFontMetrics().stringWidth(hebrewString); + int height = biMetricsGraphics.getFontMetrics().getHeight(); + + // create minimal image + BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics2D biGraphics = bi.createGraphics(); + biGraphics.setColor(Color.white); + biGraphics.fillRect(0, 0, width, height); + biGraphics.setColor(Color.black); + biGraphics.setFont(font); + biGraphics.drawString(hebrewString, 0, height); + + int y = bi.getHeight() / 2; + int x; + int rgb, rgbLeftCount = 0, rgbRightCount = 0; + + for (x = 0; x < bi.getWidth()/2; x++) { + rgb = bi.getRGB(x, y); + if (rgb == Color.BLACK.getRGB()) { + rgbLeftCount++; + } + } + for (x = bi.getWidth()/2 + 1; x < bi.getWidth(); x++) { + rgb = bi.getRGB(x, y); + if (rgb == Color.BLACK.getRGB()) { + rgbRightCount++; + } + } + if (rgbLeftCount > rgbRightCount) { + throw new RuntimeException("Hebrew text seems drawn LTR"); + } + } +} -- GitLab