当前位置: 首页 > 知识库问答 >
问题:

Apache Batik 1.7 Apache FOP 1.1未在Ubuntu上呈现字体

仲孙鸣
2023-03-14

我有麻烦在apache batik apache fop svg pdf代码转换配置字体。

配置文件似乎没有正确加载,只是在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);
}

但完整版只是稍作修改

https://github.com/naofum/thinreports-java/blob/master/src/com/github/naofum/thinreports/MultiPagePDFTranscoder.java

唯一的区别是配置文件的传递方式。在原始版本中,配置文件在我的版本中是硬编码的,并通过构造函数传递。

这FontCfFilePath在构造函数中设置为值“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),并强制用“fc-acache-fv”更新ubuntu上的字体缓存,但这并没有帮助。

我也尝试了各种嵌入网址链接(在配置中),但它没有任何效果(即更改嵌入网址="文件://资源..."到嵌入网址="文件:///资源..."和其他变体)。

两个系统都运行java1。8(ubuntu在Oracle JDK 1.8.151上运行,mac在Oracle JDK 1.8.131上运行)

共有1个答案

姬熙云
2023-03-14

在网上进行了大量搜索并阅读了batik/fop和java的源代码之后,我发现batik和fop需要在java中提供字体。awt。图形环境

java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment() 

将获取可以调用的GraphicsEnvironment实例

ge.getAvailableFontFamilyNames()

获取当前加载的字体系列的数组。

请注意,. ttf字体不需要定义字体系列才能正确加载。

但是蜡染和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>"));

如果loaded为true,则字体已正确加载,它将注册到batik/fop并正确渲染。注意字体。cfg。xml(来自我的问题)仍然需要存在,字体的路径需要与注册字体匹配。

如果loaded为false,则未加载字体。

出现这种情况的主要原因似乎是已经注册了具有相同字体系列或相同字体名称的字体。(见此处)http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/font/FontManager.java#2921)

同样重要的是,在进行任何渲染之前注册字体,因为batik/fop会将字体缓存在某个位置,而不会刷新它们。

我的解决方案是删除系统字体,保留本地字体。

所以我的问题是

>

  • 不关我的事。ttf字体定义了适当的字体系列

    字体未在java中正确注册。

    我的解决方案是

    1. 1。使用fontforge将正确的字体系列添加到我的所有字体中

  •  类似资料:
    • 问题内容: 我正在建立一个新的WordPress主题(不知道是否相关),并且这个问题一直困扰着我。 我已经从Google Webfonts(包括CSS 部分)中加载了Roboto Slab 。在其他所有浏览器上,除了Google Chrome之外,字体都可以正常显示。当我第一次在Google Chrome浏览器中加载网站时,使用该自定义字体的文本根本不会显示(即使字体库将佐治亚州作为后备- )。当

    • 问题内容: 我的Firebase数据库中有一些条目,这些条目正试图显示在html页面上。console.log显示数据库中的子级,但未显示在页面上。这是我的代码: D B: 控制器: HTML: console.log显示 正确渲染,但不渲染任何东西。那么如何让每个人都显示在页面上? 问题答案: Firebase异步加载和监视数据。只要有(新的或更新的)数据,就会触发您的回调函数。不幸的是,那时A

    • 在我的React17.0.1 SPA翻译应用程序中,我有一个包含两个部分的页面。顶部用于输入,底部用于该输入的翻译。我在为该页面使用单个上下文/状态时遇到过问题,因为翻译是由远程API执行的,当它返回时,如果不更新输入部分并将其重置为调用翻译API时所保持的值,我就无法更新UI。 因此,我将页面分成两个上下文,一个用于输入,一个用于翻译。到目前为止还好。翻译的渲染是我第一次做的。但是,尽管翻译上下

    • 我在另一个帖子上问了一个类似的问题,我得到的答案适用于firefox,但不适用于chrome,因为chrome会阻止弹出窗口。 我试着用一个按钮打开文件,但文件没有重新编辑。

    • 问题内容: 我正在开始一个JSF项目(这是我第一次使用JSF),并且在呈现标签方面遇到问题。我正在Eclipse中进行开发,并将TomCat用作服务器。 我的login.jsp文件:https : //gist.github.com/code-curve/e7e557262d407dddd1f3 我的web.xml文件:https : //gist.github.com/code-curve/52