6943963: NumericShaper with ARABIC doesn't shape digits correctly after calling another instance
authorpeytoia
Wed, 21 Apr 2010 10:34:56 +0900
changeset 5447 30d843beb284
parent 5286 960c1ce0f14d
child 5448 96e9d2b5c719
6943963: NumericShaper with ARABIC doesn't shape digits correctly after calling another instance Reviewed-by: okutsu
jdk/src/share/classes/java/awt/font/NumericShaper.java
jdk/test/java/awt/font/NumericShaper/MTTest.java
jdk/test/java/awt/font/NumericShaper/ShapingTest.java
--- a/jdk/src/share/classes/java/awt/font/NumericShaper.java	Tue Apr 20 15:01:31 2010 +0900
+++ b/jdk/src/share/classes/java/awt/font/NumericShaper.java	Wed Apr 21 10:34:56 2010 +0900
@@ -1163,8 +1163,14 @@
                         lastkey = newkey;
 
                         ctxKey = newkey;
-                        if (((mask & EASTERN_ARABIC) != 0) && (ctxKey == ARABIC_KEY || ctxKey == EASTERN_ARABIC_KEY)) {
+                        if (((mask & EASTERN_ARABIC) != 0) &&
+                             (ctxKey == ARABIC_KEY ||
+                              ctxKey == EASTERN_ARABIC_KEY)) {
                             ctxKey = EASTERN_ARABIC_KEY;
+                        } else if (((mask & ARABIC) != 0) &&
+                             (ctxKey == ARABIC_KEY ||
+                              ctxKey == EASTERN_ARABIC_KEY)) {
+                            ctxKey = ARABIC_KEY;
                         } else if ((mask & (1<<ctxKey)) == 0) {
                             ctxKey = EUROPEAN_KEY;
                         }
--- a/jdk/test/java/awt/font/NumericShaper/MTTest.java	Tue Apr 20 15:01:31 2010 +0900
+++ b/jdk/test/java/awt/font/NumericShaper/MTTest.java	Wed Apr 21 10:34:56 2010 +0900
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright (c) 2010 Sun Microsystems, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6843181
+ * @bug 6843181 6943963
  * @summary Confirm that NumericShaper is thread-safe.
  * @run main/timeout=300/othervm MTTest
  */
@@ -37,33 +37,34 @@
     static volatile boolean runrun = true;
     static volatile boolean err = false;
 
-    final static String text = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -789 (Thai) \u0e01\u0e33 01.23";
-    static char[] t1, t2;
+    final static String text = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -456 (Thai) \u0e01\u0e33 01.23";
+    final static char[] expected1 = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -\u06f4\u06f5\u06f6 (Thai) \u0e01\u0e33 \u0e50\u0e51.\u0e52\u0e53".toCharArray(); // for EASTERN_ARABIC
+    final static char[] expected2 = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -\u0664\u0665\u0666 (Thai) \u0e01\u0e33 \u0e50\u0e51.\u0e52\u0e53".toCharArray(); // for ARABIC
+
     static NumericShaper ns1, ns2, ns3, ns4;
 
     public static void main(String[] args) {
-        System.out.println("   original: " + text);
-        ns1 = getContextualShaper(EnumSet.of(Range.ARABIC), Range.ARABIC);
-        t1 = text.toCharArray();
-        ns1.shape(t1, 0, t1.length);
-        System.out.println("expected t1: " + String.valueOf(t1));
-
-        ns2 = getContextualShaper(EnumSet.of(Range.THAI), Range.THAI);
-        t2 = text.toCharArray();
-        ns2.shape(t2, 0, t2.length);
-        System.out.println("expected t2: " + String.valueOf(t2));
+        System.out.println("original: " + text);
+        ns1 = getContextualShaper(EnumSet.of(Range.EASTERN_ARABIC, Range.THAI),
+                                  Range.EUROPEAN);
+        ns2 = getContextualShaper(EnumSet.of(Range.ARABIC, Range.THAI),
+                                  Range.EUROPEAN);
+        System.out.println("expected for Eastern-Arabic & Thai: " +
+                           String.valueOf(expected1));
+        System.out.println("expected for Arabic & Thai: " +
+                           String.valueOf(expected2));
 
-        ns3 = getContextualShaper(ARABIC, ARABIC);
-        ns4 = getContextualShaper(THAI, THAI);
+        ns3 = getContextualShaper(EASTERN_ARABIC|THAI, EUROPEAN);
+        ns4 = getContextualShaper(ARABIC|THAI, EUROPEAN);
 
-        Thread th1 = new Thread(new Work(ns1, t1));
-        Thread th2 = new Thread(new Work(ns2, t2));
-        Thread th3 = new Thread(new Work(ns1, t1));
-        Thread th4 = new Thread(new Work(ns2, t2));
-        Thread th5 = new Thread(new Work(ns3, t1));
-        Thread th6 = new Thread(new Work(ns4, t2));
-        Thread th7 = new Thread(new Work(ns3, t1));
-        Thread th8 = new Thread(new Work(ns4, t2));
+        Thread th1 = new Thread(new Work(ns1, expected1));
+        Thread th2 = new Thread(new Work(ns2, expected2));
+        Thread th3 = new Thread(new Work(ns1, expected1));
+        Thread th4 = new Thread(new Work(ns2, expected2));
+        Thread th5 = new Thread(new Work(ns3, expected1));
+        Thread th6 = new Thread(new Work(ns4, expected2));
+        Thread th7 = new Thread(new Work(ns3, expected1));
+        Thread th8 = new Thread(new Work(ns4, expected2));
 
         th1.start();
         th2.start();
@@ -110,8 +111,8 @@
             int count = 0;
             while (runrun) {
                 char[] t = text.toCharArray();
+                count++;
                 try {
-                    count++;
                     ns.shape(t, 0, t.length);
                 } catch (Exception e) {
                     System.err.println("Error: Unexpected exception: " + e);
--- a/jdk/test/java/awt/font/NumericShaper/ShapingTest.java	Tue Apr 20 15:01:31 2010 +0900
+++ b/jdk/test/java/awt/font/NumericShaper/ShapingTest.java	Wed Apr 21 10:34:56 2010 +0900
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright (c) 2010 Sun Microsystems, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6842557
+ * @bug 6842557 6943963
  * @summary confirm that shaping works as expected. (Mainly for new characters which were added in Unicode 5)
  * used where appropriate.
  */
@@ -33,15 +33,25 @@
 import static java.awt.font.NumericShaper.*;
 
 public class ShapingTest {
+
+    private static boolean err = false;
+
     public static void main(String[] args) {
+        test6842557();
+        test6943963();
+
+        if (err) {
+            throw new RuntimeException("shape() returned unexpected value.");
+        }
+    }
+
+    private static void test6842557() {
         NumericShaper ns_old = getContextualShaper(ARABIC | TAMIL | ETHIOPIC,
                                    EUROPEAN);
         NumericShaper ns_new = getContextualShaper(EnumSet.of(
                                    Range.ARABIC, Range.TAMIL, Range.ETHIOPIC),
                                    Range.EUROPEAN);
 
-        boolean err = false;
-
         String[][] data = {
            // Arabic "October 10"
           {"\u0623\u0643\u062a\u0648\u0628\u0631 10",
@@ -60,45 +70,62 @@
         };
 
         for (int i = 0; i < data.length; i++) {
-            String expected = data[i][1];
+            checkResult("ARABIC | TAMIL | ETHIOPIC",
+                        ns_old, data[i][0], data[i][1]);
 
-            char[] text = data[i][0].toCharArray();
-            ns_old.shape(text, 0, text.length);
-            String got = new String(text);
+            checkResult("Range.ARABIC, Range.TAMIL, Range.ETHIOPIC",
+                        ns_new, data[i][0], data[i][1]);
+        }
+    }
 
-            if (!expected.equals(got)) {
-                err = true;
-                System.err.println("Error with traditional range.");
-                System.err.println("  text = " + data[i][0]);
-                System.err.println("  got = " + got);
-                System.err.println("  expected = " + expected);
-            } else {
-                System.err.println("OK with traditional range.");
-                System.err.println("  text = " + data[i][0]);
-                System.err.println("  got = " + got);
-                System.err.println("  expected = " + expected);
-            }
+    private static void test6943963() {
+        // Needed to reproduce this bug.
+        NumericShaper ns_dummy = getContextualShaper(ARABIC | TAMIL | ETHIOPIC,
+                                   EUROPEAN);
+        char[] c = "\u1200 1".toCharArray();
+        ns_dummy.shape(c, 0, c.length);
+
+
+        String given = "\u0627\u0628 456";
+        String expected_ARABIC = "\u0627\u0628 \u0664\u0665\u0666";
+        String expected_EASTERN_ARABIC = "\u0627\u0628 \u06f4\u06f5\u06f6";
+
+        NumericShaper ns = getContextualShaper(ARABIC);
+        checkResult("ARABIC", ns, given, expected_ARABIC);
+
+        ns = getContextualShaper(EnumSet.of(Range.ARABIC));
+        checkResult("Range.ARABIC", ns, given, expected_ARABIC);
 
-            text = data[i][0].toCharArray();
-            ns_new.shape(text, 0, text.length);
-            got = new String(text);
+        ns = getContextualShaper(EASTERN_ARABIC);
+        checkResult("EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+
+        ns = getContextualShaper(EnumSet.of(Range.EASTERN_ARABIC));
+        checkResult("Range.EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+
+        ns = getContextualShaper(ARABIC | EASTERN_ARABIC);
+        checkResult("ARABIC | EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+
+        ns = getContextualShaper(EnumSet.of(Range.ARABIC, Range.EASTERN_ARABIC));
+        checkResult("Range.ARABIC, Range.EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+    }
 
-            if (!expected.equals(got)) {
-                err = true;
-                System.err.println("Error with new Enum range.");
-                System.err.println("  text = " + data[i][0]);
-                System.err.println("  got = " + got);
-                System.err.println("  expected = " + expected);
-            } else {
-                System.err.println("OK with new Enum range.");
-                System.err.println("  text = " + data[i][0]);
-                System.err.println("  got = " + got);
-                System.err.println("  expected = " + expected);
-            }
-        }
+    private static void checkResult(String ranges, NumericShaper ns,
+                                    String given, String expected) {
+        char[] text = given.toCharArray();
+        ns.shape(text, 0, text.length);
+        String got = new String(text);
 
-        if (err) {
-            throw new RuntimeException("shape() returned unexpected value.");
+        if (!expected.equals(got)) {
+            err = true;
+            System.err.println("Error with range(s) <" + ranges + ">.");
+            System.err.println("  text     = " + given);
+            System.err.println("  got      = " + got);
+            System.err.println("  expected = " + expected);
+        } else {
+            System.out.println("OK with range(s) <" + ranges + ">.");
+            System.out.println("  text     = " + given);
+            System.out.println("  got      = " + got);
+            System.out.println("  expected = " + expected);
         }
     }