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;
}