2

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

Font.canDisplay()

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

Environment:

VM Version 1.6.0_26
Mac OS X 10.7.2

字体文件(truetype):http ://www.fontsc.com/font/depth-charge (你可以在这个网站上查看字符映射,字形在 CAPs 中不可用)

4

2 回答 2

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.....    
}
于 2013-06-09T10:22:27.050 回答
0

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

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

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

我能够使用反射解决这个问题。这是在 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 或更高版本,则需要将这些命令参数传递给 VM 以使代码正常工作:

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

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

于 2019-05-09T18:15:15.163 回答