我正在尝试从我的系统上的TTF文件创建一个java.awt.Font实例,但只有一些字体可以加载而不会出错。下面的代码是我在网上找到的一些测试代码。在我的系统上运行时,它能够成功加载285种字体(例如Arial.ttf),但是在83种字体上失败(例如AmericanTypewriter.ttf)。
所有错误都是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)
非常感谢任何帮助。
答案 0 :(得分:4)
好的,经过一番挖掘后发现,这个问题是由于java.awt实现中的一个错误(功能!)造成的。也就是说,如果字体文件的名称表不包含姓氏和全名记录,则加载物理TrueType字体会失败。
为了识别问题,我使用GrepCode从OpenJDK的AWT实现中的相关异常向后追溯。一旦我发现了名称表问题,我使用ttx,一个简洁的TrueType元数据编辑器来添加Java寻找的名称条目。例如:
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
American Typewriter
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
American Typewriter
</namerecord>
现在可以通过Java打开由ttx生成的新TTF文件。耶!
答案 1 :(得分:3)
这是Oracle JDK / OpenJDK功能(bug)。
问题是由sun.font.TrueTypeFont
导致的,并且缺少对Mac TrueType字体名称的支持。
TrueTypeFont.java
包含用于读取TrueType字体的名称表的检查,仅用于读取Microsoft平台ID名称(platformID == 3)
,而不是Mac平台ID (platformID == 1)
。在许多情况下,OSX上包含的truetype字体只有platformID
为1的名称。因此,initNames()
方法不会为familyName
或{{1}设置值并且fullName
之后的代码运行检查以查看它们是否为空(它们当然是空的)并抛出initNames()
异常。
在Apple JDK(1.6甚至1.5?)上,Apple并没有使用TrueTypeFont作为FontHandler。他们有自己的实现,称为Font name not found
。您甚至无法在Apple JDK上使用sun.font.AppleNativeFont
,因为它始终使用sun.font.TrueTypeFont
处理程序,该处理程序支持Mac和Microsoft平台ID。
似乎sun.font.AppleNativeFont
在OpenJDK或Oracle JDK中不存在,即使Apple&#34;捐赠&#34; Oracle的代码。
从连续性的角度来看,在OpenJDK / Oracle JDK中包含sun.font.AppleNativeFont
会很方便。如果sun.font.AppleNativeFont
得到改进以包含对Mac TrueType字体的支持,那就更好了。
更新:解决方法。
以下评论中的一个补丁已提交给OpenJDK存储库。如果使用正确的修订版克隆存储库,则可以获取已修补的文件。
TrueTypeFont.java
从hg clone -r 8b05f9b91765 http://hg.openjdk.java.net/jdk7/jdk7/jdk
复制以下这些文件:
jdk/src/shared/classes/sun/font
到当前JDK(我使用jdk8-b132)的trunk中的同一目录下,编译它,你将获得Mac字体支持。您可能还想应用在Mac字体修补程序之后创建的此修补程序:
http://hg.openjdk.java.net/jdk7/jdk7/jdk/rev/3dabb2f78e73
瞧!