JDK-6623219 : Font.canDisplayUpTo does not work with supplementary characters
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2007-10-29
  • Updated: 2013-11-27
  • Resolved: 2011-03-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b134Fixed
Description
FULL PRODUCT VERSION :
java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Linux hostname 2.6.18 #1 Wed Sep 20 03:01:24 CDT 2006 i686 athlon-4 i386 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
The Font.canDisplayUpTo methods behave unpredictably with supplementary characters.  Given a String containing only supplementary characters, the canDisplayUpTo methods either always return -1 regardless of the font, or always return 0 regardless of the font.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Pass a String containing only supplementary characters to the Font.canDisplayUpTo method, once for a font containing the supplementary characters and once for a font which does not.  (The only font I know of which contains supplementary characters is the freeware Code2001 font.)

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
One call to canDisplayUpTo should return -1, while the other should return a nonnegative number.
ACTUAL -
Both calls to canDisplayUpTo always return the same value.  Either both calls return -1 or both return 0.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.Font;

public class SupplementaryFontTest
{
    static void test(String family)
    {
        String s = String.valueOf(Character.toChars(0x10000));

        Font font = new Font(family, Font.PLAIN, 12);
        if (font.canDisplayUpTo(s) < 0)
        {
            System.out.printf(
                "Font \"%s\" can display supplementary characters.%n",
                family);
        }
        else
        {
            System.out.printf(
                "Font \"%s\" cannot display supplementary characters.%n",
                family);
        }
    }

    public static void main(String[] args)
    {
        test("Courier");
        test("Code2001");
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Font.canDisplay(int) works correctly.  Therefore, one can check the String's contents explicitly:

public static int canDisplayUpTo(Font font,
                                 String s)
{
    int len = s.length();
    int index = 0;
    while (index < len)
    {
        int codePoint = s.codePointAt(index);
        if (!font.canDisplay(codePoint))
        {
            return index;
        }
        index += Character.charCount(codePoint);
    }
    return -1;
}

Comments
EVALUATION Probably this should have been taken care of as part of "JSR 204: Unicode Supplementary Character Support" which added the "canDisplay(int codePoint)" in 1.5 Internally canDisplay(String) uses canDisplayUpTo(CharacterIterator iter, ..) which uses char type, not int.
30-10-2007