【问题标题】:Placing letters under underlined text in XSL-FO using Apache FOP使用 Apache FOP 在 XSL-FO 中将字母置于带下划线的文本下
【发布时间】:2014-03-14 08:19:32
【问题描述】:

我有一个项目要求我在一段文本中的一些带下划线的文本下放置一个 ID 字符串。

这是一个使用带有灰色边框的内联 SVG 对象来显示布局的示例:

我可以使用带有基线移位的内联元素来接近,然后使用 SVG 来呈现文本。然而,这有一个缺点(我认为),我必须手动输入 SVG 的宽度(以像素为单位),这对于如此简单的布局来说似乎非常复杂。

这里是 XSL-FO 标记:

<fo:block>
Normal text
<fo:inline baseline-shift="-100%">
    <fo:instream-foreign-object text-align="center" display-align="center" border="solid silver 1px">
        <svg xmlns="http://www.w3.org/2000/svg" height="25" width="120" viewport="0 0 120 25">
            <text x="60" y="10" fill="black" text-anchor="middle" text-decoration="underline" font-size="12pt">underlined text with id</text>
            <text x="60" y="25" fill="black" text-anchor="middle" font-size="12pt">123</text>
        </svg>
    </fo:instream-foreign-object>
</fo:inline>
normal text.
</fo:block>

所以我的问题是:我可以在不使用 instream-foreign-object 和 SVG 的情况下在 Apache FOP XSL-FO 中执行此布局吗?如果我不能,是否有某种方法不必将 SVG 中的宽度以像素为单位?或者有什么方法可以计算 SVG 渲染需要多少像素?

我还要注意 Apache FOP 不支持 inline-container。

https://xmlgraphics.apache.org/fop/compliance.html

提前致谢! - 丹

【问题讨论】:

  • 您的问题中没有足够的信息来提供答案。示例:如果您将其放置在其中的文本变形为多行会发生什么?以下文本行会发生什么...特别是行距以及您所绘制的内容会影响它的事实?您还没有充分考虑过这一点,或者如果您考虑过,您肯定没有提供足够的信息让某人甚至推荐解决方案。
  • 我对 Apache FOP 支持的内容没有经验,但如果我使用 RenderX,我会 (1) 将您请求的片段格式化为区域树格式(称为 XEPOUT)。由此,您可以确定片段的宽度和高度。然后 (2) 将 (a) 将该片段用作图像(在 RenderX XEP 中支持)或 (b) 您可以将该区域树转换为 SVG,并且您会知道您需要的像素宽度。我们这样做是为了将 SVG 渐变应用于文档中格式化的多行文本。
  • 嗨,Kevin,要回答您的问题,带下划线的文本应该与任何其他带下划线的文本完全一样。如果需要,它应该包装。正如我在问题中所说,我的目标是使用 Apache FOP 进行此布局,而不使用 SVG,也无需手动估计 SVG 中文本的宽度。谢谢 - 丹
  • 你能用 MathML 吗?
  • 只是为了澄清,然后使用上面的示例,假设计算的换行符出现在单词“text”处......这看起来像什么?一行是“带下划线的文本”,下一行是“with id”,底部在哪里?由于您正在绘制的对象大于单行的高度,因此在所有情况下行距是什么样的?整个段落的行距是否设置为该片段的最高高度?在了解可能发生的所有要求之前,不可能准确回答。

标签: xsl-fo apache-fop


【解决方案1】:

这是我建议的使用格式化树的 RenderX 完成的示例。

将所需的片段格式化为中间格式......对于单个片段来说是这样的:

    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
        <fo:layout-master-set>
            <fo:simple-page-master margin="0mm" master-name="MASTERsite1" page-width="214mm" page-height="29pt">
                <fo:region-body margin="0mm"/>
            </fo:simple-page-master>
        </fo:layout-master-set>    
        <fo:page-sequence master-reference="MASTERsite1">
            <fo:flow flow-name="xsl-region-body">
                <fo:table>
                    <fo:table-body>
                        <fo:table-row>
                            <fo:table-cell><fo:block text-decoration="underline" text-align="center">This is Underlined Text with ID</fo:block></fo:table-cell>
                        </fo:table-row>
                        <fo:table-row>
                            <fo:table-cell><fo:block text-align="center">1234567</fo:block></fo:table-cell>
                        </fo:table-row>
                    </fo:table-body>  
                </fo:table>
            </fo:flow>
        </fo:page-sequence> 
    </fo:root>

输出将是这样的:

    <xep:document xmlns:xep="http://www.renderx.com/XEP/xep" producer="XEP 4.19 build 20110414" creator="Unknown" author="Unknown" title="Untitled">
        <xep:page width="162708" height="29000" page-number="1" page-id="1">
    <xep:word-spacing value="0"/>
    <xep:letter-spacing value="0"/>
    <xep:font-stretch value="1.0"/>
    <xep:font family="Helvetica" weight="400" style="normal" variant="normal" size="12000"/>
    <xep:gray-color gray="0.0"/>
    <xep:text value="This is Underlined Text with ID" x="0" y="18734" width="162708"/>
    <xep:line x-from="0" x-till="162708" y-from="17534" y-till="17534" thickness="600" style="solid"/>
    <xep:text value="1234567" x="58002" y="4334" width="46704"/>
    </xep:page>
    </xep:document>

你会在哪里修改结果来改变页面宽度,但它在文本中作为关注的文本元素的宽度,即改变:

 <xep:page width="606614" height="29000" page-number="1" page-id="1">

所以宽度来自关注的文本行,以编程方式从 xep:line 或 xep:text 行获取 x-till(如上更改)。请注意,这与您的 SVG 示例完全相同,只是您可以通过编程方式访问此文件中的数字。

最后,使用这个“文件”作为图像,然后使用:

 <fo:external-graphic src="test19.xep" content-type="application/xepout" alignment-baseline="central"/>

现在,虽然您说查看所有这些步骤,但这是一个解决方案,并且上述所有步骤都可以自动化到单个流程链中。首先循环并格式化所有关注的对象并从中制作小文件,然后第二遍将代替格式化这些片段,将它们用作图像。

注意:结果的附件图像中显示的行距不能用 FOP 完成(我相信),我认为这是 FOP 的限制。

注意 #2:我不是 FOP 专家,我对它的实现一无所知,特别是使用区域树作为文档中的图像。如果 FOP 是必须的,我建议调查一下。您可以轻松地将区域树转换为 SVG 并使用它们,就像您可以使用它们的所有尺寸一样,或者更好的是,只需将区域树读入第二个转换并从中直接内联生成 instream-foreign-object SVG。

【讨论】:

  • 我用 FOP 进行了测试,您也可以这样做。
  • 哇,你们太棒了!非常令人印象深刻。我将研究 RenderX,看看是否可以下载试用版。再次感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 2023-02-22
  • 2020-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-07
相关资源
最近更新 更多