UPDATE:
Oracle accepted my bug report:
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8223834
You will find a possible workaround below:
This seems to be a bug in Mac OS implementation of Font2D class.
I was able to workaround the problem using reflection. Here is a code that produces correct results on Mac. It's in Kotlin, but it should be straightforward to translate it to Java if necessary.
// Mac OS workaround for incorrectly implemented canDisplayUpTo method
fun Font.macCanDisplayUpTo(str: String): Int {
val getFontMethod = Font::class.java.getDeclaredMethod("getFont2D")
getFontMethod.isAccessible = true
val font2d = getFontMethod.invoke(this)
val getMapperMethod = font2d.javaClass.getDeclaredMethod("getMapper")
getMapperMethod.isAccessible = true
val mapper = getMapperMethod.invoke(font2d)
val charToGlyphMethod = mapper.javaClass.getDeclaredMethod("charToGlyph", Char::class.java)
val len = str.length
var i = 0
while (i < len) {
val c = str[i]
val glyph = charToGlyphMethod.invoke(mapper, c) as Int
if (glyph >= 0) {
i++
continue
}
if (!Character.isHighSurrogate(c)
|| (charToGlyphMethod.invoke(mapper, str.codePointAt(i)) as Int) < 0) {
return i
}
i += 2
}
return -1
}
If you're using Java 9 or newer, you will need to pass these command args to VM to make the code work:
--add-opens java.desktop/java.awt=your.module.name
--add-opens java.desktop/sun.font=your.module.name
This code won't work on Windows (will produce incorrect results). It's for MacOS only.