changeset 2620:ec4f9f18e7b6

S6623219: Font.canDisplayUpTo does not work with supplementary characters
author ptisnovs
date Tue, 28 Jun 2011 09:51:50 +0200
parents 562d984677e8
children 2a3b854d6940 7183dbf25d56
files ChangeLog Makefile.am NEWS patches/openjdk/6623219-Font_canDisplayUpTo_does_not_work.patch
diffstat 4 files changed, 214 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Jun 27 17:46:58 2011 +0200
+++ b/ChangeLog	Tue Jun 28 09:51:50 2011 +0200
@@ -1,3 +1,10 @@
+2011-06-27  Pavel Tisnovsky  <ptisnovs@redhat.com>
+
+	* Makefile.am: added new patch
+	* NEWS: updated with backport
+	* patches/openjdk/6623219-Font_canDisplayUpTo_does_not_work.patch
+	Backport of 6623219 fix.
+
 2011-06-27  Pavel Tisnovsky  <ptisnovs@redhat.com>
 
 	* Makefile.am: added new patch
--- a/Makefile.am	Mon Jun 27 17:46:58 2011 +0200
+++ b/Makefile.am	Tue Jun 28 09:51:50 2011 +0200
@@ -366,7 +366,8 @@
 	patches/openjdk/7008106-WindowOpacity.patch \
 	patches/openjdk/6956668-misbehavior_of_XOR_operator_with_int.patch \
 	patches/openjdk/6699843-IllegalArgumentException_drawString.patch \
-	patches/openjdk/6918065-Crash_in_Java2D_blit_loop.patch
+	patches/openjdk/6918065-Crash_in_Java2D_blit_loop.patch \
+	patches/openjdk/6623219-Font_canDisplayUpTo_does_not_work.patch
 
 if WITH_ALT_HSBUILD
 ICEDTEA_PATCHES += \
--- a/NEWS	Mon Jun 27 17:46:58 2011 +0200
+++ b/NEWS	Tue Jun 28 09:51:50 2011 +0200
@@ -38,6 +38,7 @@
   - S6956668: misbehavior of XOR operator (^) with int
   - S6699843: IllegalArgumentException when using Graphics.drawString( "", 0, 0 )
   - S6918065: Crash in Java2D blit loop (IntArgbToIntArgbPreSrcOverMaskBlit) in 64bit mode
+  - S6623219: Font.canDisplayUpTo does not work with supplementary characters
 * Bug fixes
   - PR637: make check should exit with an error code if any regression test failed.
   - G356743: Support libpng 1.5.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/6623219-Font_canDisplayUpTo_does_not_work.patch	Tue Jun 28 09:51:50 2011 +0200
@@ -0,0 +1,204 @@
+# HG changeset patch
+# User okutsu
+# Date 1298437763 -32400
+# Node ID 5957bd3cfdc3fa2014ff1d9abbb51fbb2f8a5779
+# Parent  f8fdf9bca1592dd55ff0fad08114cbd00e08c77d
+6623219: Font.canDisplayUpTo does not work with supplementary characters
+Reviewed-by: prr, peytoia
+
+diff -r f8fdf9bca159 -r 5957bd3cfdc3 src/share/classes/java/awt/Font.java
+--- openjdk.orig/jdk/src/share/classes/java/awt/Font.java	Tue Feb 22 14:51:43 2011 +0900
++++ openjdk/jdk/src/share/classes/java/awt/Font.java	Wed Feb 23 14:09:23 2011 +0900
+@@ -1985,8 +1985,22 @@
+      * @since 1.2
+      */
+     public int canDisplayUpTo(String str) {
+-        return canDisplayUpTo(new StringCharacterIterator(str), 0,
+-            str.length());
++        Font2D font2d = getFont2D();
++        int len = str.length();
++        for (int i = 0; i < len; i++) {
++            char c = str.charAt(i);
++            if (font2d.canDisplay(c)) {
++                continue;
++            }
++            if (!Character.isHighSurrogate(c)) {
++                return i;
++            }
++            if (!font2d.canDisplay(str.codePointAt(i))) {
++                return i;
++            }
++            i++;
++        }
++        return -1;
+     }
+ 
+     /**
+@@ -2009,11 +2023,21 @@
+      * @since 1.2
+      */
+     public int canDisplayUpTo(char[] text, int start, int limit) {
+-        while (start < limit && canDisplay(text[start])) {
+-            ++start;
++        Font2D font2d = getFont2D();
++        for (int i = start; i < limit; i++) {
++            char c = text[i];
++            if (font2d.canDisplay(c)) {
++                continue;
++            }
++            if (!Character.isHighSurrogate(c)) {
++                return i;
++            }
++            if (!font2d.canDisplay(Character.codePointAt(text, i, limit))) {
++                return i;
++            }
++            i++;
+         }
+-
+-        return start == limit ? -1 : start;
++        return -1;
+     }
+ 
+     /**
+@@ -2034,13 +2058,26 @@
+      * @since 1.2
+      */
+     public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
+-        for (char c = iter.setIndex(start);
+-             iter.getIndex() < limit && canDisplay(c);
+-             c = iter.next()) {
++        Font2D font2d = getFont2D();
++        char c = iter.setIndex(start);
++        for (int i = start; i < limit; i++, c = iter.next()) {
++            if (font2d.canDisplay(c)) {
++                continue;
++            }
++            if (!Character.isHighSurrogate(c)) {
++                return i;
++            }
++            char c2 = iter.next();
++            // c2 could be CharacterIterator.DONE which is not a low surrogate.
++            if (!Character.isLowSurrogate(c2)) {
++                return i;
++            }
++            if (!font2d.canDisplay(Character.toCodePoint(c, c2))) {
++                return i;
++            }
++            i++;
+         }
+-
+-        int result = iter.getIndex();
+-        return result == limit ? -1 : result;
++        return -1;
+     }
+ 
+     /**
+diff -r f8fdf9bca159 -r 5957bd3cfdc3 test/java/awt/FontClass/SurrogateTest/SupplementaryCanDisplayUpToTest.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/test/java/awt/FontClass/SurrogateTest/SupplementaryCanDisplayUpToTest.java	Wed Feb 23 14:09:23 2011 +0900
+@@ -0,0 +1,105 @@
++/*
++ * Copyright (c) 2011, 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
++ * @bug 6623219
++ * @summary Test canDisplayUpTo with supplementary characters.
++ */
++
++import java.awt.*;
++import java.text.*;
++
++public class SupplementaryCanDisplayUpToTest {
++    // Lists consisting of a font name, test text, and its expected
++    // return value. Test text uses private area code point U+F0000
++    // (\udb80\udc00).
++    private static String[][] DATA = {
++        // Windows
++        { "Meiryo", "\ud87e\udd45\ud87e\udd47\udb80\udc00", "4" },
++        { "Meiryo", "\ud87e\udd45\ud87e\udd47\udb80Z", "4" },
++        { "Meiryo", "\ud87e\udd45\ud87e\udd47\udb80", "4" },
++        { "Meiryo", "\ud87e\udd45\ud87e\udd47\udc00", "4" },
++        { "Meiryo", "\ud87e\udd45\ud87e\udd47", "-1" },
++
++        // Linux
++        { "AR PL UMing TW", "\ud87e\udc25\ud87e\udc3b\udb80\udc00", "4" },
++        { "AR PL UMing TW", "\ud87e\udc25\ud87e\udc3b\udb80Z", "4" },
++        { "AR PL UMing TW", "\ud87e\udc25\ud87e\udc3b\udb80", "4" },
++        { "AR PL UMing TW", "\ud87e\udc25\ud87e\udc3b\udc00", "4" },
++        { "AR PL UMing TW", "\ud87e\udc25\ud87e\udc3b", "-1" },
++
++        // Solaris
++        { "FZMingTi", "\ud87e\udc25\ud87e\udc3b\udb80\udc00", "4" },
++        { "FZMingTi", "\ud87e\udc25\ud87e\udc3b\udb80Z", "4" },
++        { "FZMingTi", "\ud87e\udc25\ud87e\udc3b\udb80", "4" },
++        { "FZMingTi", "\ud87e\udc25\ud87e\udc3b\udc00", "4" },
++        { "FZMingTi", "\ud87e\udc25\ud87e\udc3b", "-1" },
++    };
++    private static int errorcount = 0;
++
++    public static void main(String[] args) {
++        for (String[] data : DATA) {
++            String fontname = data[0];
++            Font font = new Font(fontname, Font.PLAIN, 16);
++            if (font.getFamily().equals(Font.DIALOG)) {
++                // Skip any unavailable fonts.
++                continue;
++            }
++
++            System.out.printf("Testing with font '%s'... ", fontname);
++            int errors = 0;
++            String text = data[1];
++            int expected = Integer.parseInt(data[2]);
++
++            int result = font.canDisplayUpTo(text);
++            if (result != expected) {
++                System.err.println("canDisplayUpTo(String) returns " + result);
++                errors++;
++            }
++
++            result = font.canDisplayUpTo(text.toCharArray(), 0, text.length());
++            if (result != expected) {
++                System.err.println("canDisplayUpTo(char[], int, int) returns " + result);
++                errors++;
++            }
++
++            CharacterIterator iter = new StringCharacterIterator(text);
++            result = font.canDisplayUpTo(iter, iter.getBeginIndex(), iter.getEndIndex());
++            if (result != expected) {
++                System.err.println("canDisplayUpTo(CharacterIterator, int, int) returns " + result);
++                errors++;
++            }
++
++            if (errors == 0) {
++                System.out.println("passed");
++            } else {
++                System.out.println("failed");
++                errorcount += errors;
++            }
++        }
++        if (errorcount > 0) {
++            throw new RuntimeException("SupplementaryCanDisplayUpToTest: failed");
++        }
++    }
++}