Font.canDisplay始终在mac上返回true

时间:2013-06-09 09:01:44

标签: java fonts awt glyph true-type-fonts

我编写了一个简单的代码来检查给定的自定义字体文件(.ttf或.otf)中是否有可用的字形,为此我正在使用:

Font.canDisplay()

当我在Windows上测试我的代码时工作正常,但是在mac上它总是返回true,即使该字形不可用,我猜在mac中默认为字体替换选项,任何建议如何关闭它?

Environment:

VM Version 1.6.0_26
Mac OS X 10.7.2

字体文件(truetype):http://www.fontsc.com/font/depth-charge(您可以在此网站上查看字符映射字符在CAP中不可用)

2 个答案:

答案 0 :(得分:1)

Font font = Font.createFont(int fontFormat, File fontFile)
/(int fontFormat, InputStream fontStream)

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(font);

if (font.canDisplay()/canDisplayUpTo()){
    //your code with font.....    
}

答案 1 :(得分:0)

更新: Oracle接受了我的错误报告: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8223834

您将在下面找到可能的解决方法:

这似乎是Mac OS的Font2D类实现中的错误。

我能够使用反射解决该问题。这是在Mac上产生正确结果的代码。它在Kotlin中,但是在必要时将其直接翻译为Java应该很简单。

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

如果您使用的是Java 9或更高版本,则需要将以下命令args传递给VM,以使代码正常工作:

--add-opens java.desktop/java.awt=your.module.name
--add-opens java.desktop/sun.font=your.module.name

此代码在Windows上不起作用(将产生不正确的结果)。仅适用于MacOS。