从Java中的TTF文件加载一些TrueType字体会导致FontFormatException:找不到字体名称

我试图从我的系统上的TTF文件创建一个java.awt.Font实例,但只有一些字体能够加载而不会出错。 下面的代码是我在网上找到的一些测试代码。 在我的系统上运行时,它能够成功加载285种字体(例如Arial.ttf),但是在83种字体上失败(例如AmericanTypewriter.ttf)。

所有错误都是FontFormatException: Font name not foundformsFontFormatException: Font name not found没有嵌入原因的FontFormatException: Font name not found

java.awt.Font和格式兼容性是否存在已知问题? 经过谷歌搜索后我找不到任何东西。

 public static void main(String[] args) { String rootPath = "/Library/Fonts"; File root = new File(rootPath); if (root.canRead()) { String[] fontFiles = root.list(); Font font = null; for (String fontFile : fontFiles) { try { System.out.println(fontFile); font = Font.createFont(Font.TRUETYPE_FONT, new File(root + "/" + fontFile)); System.out.println(font); } catch (Exception e) { e.printStackTrace(); } } } } 

我的环境是Java 7,OS X Mavericks(10.9.1)。

 java version "1.7.0_40" Java(TM) SE Runtime Environment (build 1.7.0_40-b43) Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode) 

这里的任何帮助将不胜感激。

好的,经过一番挖掘后发现,这个问题是由于java.awt实现中的一个bug(feature!)引起的。 即,如果字体文件的名称表不包含姓氏和全名记录,则加载物理TrueType字体会失败。

为了识别问题,我使用GrepCode从OpenJDK的AWT实现中的相关exception向后追溯。 一旦我发现了名称表问题,我使用了ttx ,一个简单的TrueType元数据编辑器来添加Java寻找的名称条目。 例如:

  American Typewriter   American Typewriter  

现在可以通过Java打开由ttx生成的新TTF文件。 好极了!

这是Oracle JDK / OpenJDKfunction( bug )。

问题是由sun.font.TrueTypeFont引起的,它缺乏对Mac TrueType字体名称的支持。

TrueTypeFont.java包含用于读取TrueType字体的名称表的检查,以仅读取Microsoft平台ID名称(platformID == 3)而不读取Mac平台ID (platformID == 1) 。 在许多情况下,OSX上包含的truetype字体只有platformID为1的名称。因此, initNames()方法不会为familyNamefullName设置值,并且initNames()运行检查以查看它们是否为是null(它们当然是)并抛出Font name not found例外。

在Apple JDK(1.6甚至1.5?)上,Apple没有使用TrueTypeFont作为FontHandler。 他们有自己的实现,称为sun.font.AppleNativeFont 。 你甚至sun.font.TrueTypeFont在Apple JDK上使用sun.font.TrueTypeFont ,因为它总是使用sun.font.AppleNativeFont处理程序,它支持Mac和Microsoft平台ID。

似乎sun.font.AppleNativeFont在OpenJDK或Oracle JDK中不存在,即使Apple“将”代码“捐赠”给Oracle。

从连续性的角度来看,在OpenJDK / Oracle JDK中包含sun.font.AppleNativeFont会很方便。 如果对TrueTypeFont.java进行改进以包含对Mac TrueType字体的支持,那就更好了。

更新:解决方案。

以下评论中的一个补丁已提交给OpenJDK存储库。 如果使用正确的修订版克隆存储库,则可以获取已修补的文件。

hg clone -r 8b05f9b91765 http://hg.openjdk.java.net/jdk7/jdk7/jdk

jdk/src/shared/classes/sun/font复制以下文件:

 TrueTypeFont.java LCIDMap.java AppleLangID.java 

对于当前JDK(我使用jdk8-b132)的trunk中的同一目录,编译它,你将获得Mac字体支持。 您可能还想应用此补丁,该补丁是在Mac字体补丁之后制作的:

http://hg.openjdk.java.net/jdk7/jdk7/jdk/rev/3dabb2f78e73

瞧!