我在apache batik + apache fop svg pdf transcoder中配置字体时遇到了问题。
配置文件似乎没有正确加载,只能在Ubuntu上加载。 我尝试在MacOSX上运行完全相同的代码并且它可以正常工作 细...
尝试在两个系统上加载相同的svg会产生不同的结果。
java的相关部分是:
try {
DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
Configuration effCfg = cfgBuilder.buildFromFile(new File(this.fontCfgFilePath));
if (effCfg != null) {
PDFDocumentGraphics2DConfigurator configurator = new PDFDocumentGraphics2DConfigurator();
configurator.configure(graphics, effCfg, false);
} else {
graphics.setupDefaultFontInfo();
}
} catch (Exception e) {
throw new TranscoderException("Error while setting up PDFDocumentGraphics2D", e);
}
但完整版只是
的略微修改版本唯一的区别是配置文件的传递方式。在原来配置文件硬编码在我的版本中通过构造函数传递。
this.fontCfgFilePath在构造函数中设置,其值为" resources / fonts.cfg.xml"
文件夹结构是
project/
resources/
font.cfg.xml
fonts/
0b0b385a-f6e8-4a33-887f-2f178a576139.ttf
... a bunch of other fonts ....
pdf-generator.jar
... other files that are not relevant to the problem...
font.cfg.xml设置如下
<configuration>
<fonts>
... other fonts ....
<font kerning="no" embed-url="file:resources/fonts/0b0b385a-f6e8-4a33-887f-2f178a576139.ttf">
<font-triplet name="Papyrus" style="normal" weight="normal"></font-triplet>
</font>
<font kerning="no" embed-url="file:resources/fonts/0b0b385a-f6e8-4a33-887f-2f178a576139.ttf">
<font-triplet name="Papyrus" style="normal" weight="bold"></font-triplet>
</font>
<font kerning="no" embed-url="file:resources/fonts/0b0b385a-f6e8-4a33-887f-2f178a576139.ttf">
<font-triplet name="Papyrus" style="italic" weight="normal"></font-triplet>
</font>
<font kerning="no" embed-url="file:resources/fonts/0b0b385a-f6e8-4a33-887f-2f178a576139.ttf">
<font-triplet name="Papyrus" style="italic" weight="bold"></font-triplet>
</font>
... other fonts
</fonts>
</configuration>
如果在Ubuntu和MacOSX上同时运行完全相同的配置项目。
MacOSX使用正确的字体生成正确的PDF
Ubuntu没有......
有趣的是,Ubuntu甚至没有尝试使用字体...
如果我从mac上的配置文件中删除字体,它将不会呈现字体(如预期的那样)
如果我将字体文件更改为无效的东西,再次在mac上,它会抛出FileNotFoundException。
但是在Ubuntu上这一切都不重要......基本上看起来字体文件永远不会被读取。
我已尝试直接在系统中添加字体(在/ usr / share / fonts中)并强制使用&#34; fc-cache -fv&#34;更新ubuntu上的字体缓存。但这没有帮助。
我也尝试了各种embed-url链接(在配置中),但它没有任何效果(即更改embed-url =&#34; file://resources ...。&#34; to embed-url =&#34; file:///resources..."以及其他变体。)
两个系统都运行java1.8(Oracle JDK 1.8.151上为ubuntu,mac为Oracle JDK 1.8.131)
答案 0 :(得分:2)
经过多次在线搜索并在batik / fop和java中阅读源代码,我自己发现Batik和FOP需要在java.awt.GraphicsEnvironment
java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment()
将获取可以调用
的GraphicsEnvironment实例ge.getAvailableFontFamilyNames()
获取当前加载的字体系列数组。
请注意.ttf字体不需要定义字体系列以便正确加载。
但是Batik和FOP DO 需要指定正确的字体系列...
发生这种情况时,MacOSX会以某种方式(在安装系统级字体时)知道设置正确的字体系列。但GNU / Linux接缝不能做同样的事情。
如果某个字体在系统范围内不可用(我在linux上就是这种情况),则必须在java中注册。
这可以通过GraphicsEnvironment完成,如下所示:
boolean loaded = ge.registerFont(java.awt.Font.createFont(java.awt.Font/TRUETYPE_FONT, new File("<path to font>"));
如果加载为true,则表示字体已正确加载,它将使用batik / fop注册并正确呈现。 请注意,font.cfg.xml(来自我的问题)仍然需要存在,并且字体的路径需要与regitered字体匹配。
如果加载为false,则表示未加载字体。
这主要原因似乎是已经注册了具有相同字体名称 OR 相同字体名称的字体。 (见http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/font/FontManager.java#2921)
在任何渲染发生之前注册字体也很重要,因为batik / fop会在某处缓存字体并且不会刷新它们。
我的解决方案是删除系统字体并保留本地字体。
所以我的问题是
我的.ttf字体都没有定义正确的字体系列
字体未在java中正确注册。
我的解决方案是