使用Apache FOP在XSL-FO中将带下划线的文本下的字母放置

时间:2014-03-07 14:48:43

标签: xsl-fo apache-fop

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

以下是使用带灰色边框的内联SVG对象显示布局的示例:

sample use of SVG inline to simulate inline

我可以使用带有基线移位的内联元素来关闭,然后使用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

提前致谢! - 丹

1 个答案:

答案 0 :(得分:2)

以下是我使用格式树向RenderX建议的示例。 Sample Output

将所需的片段格式化为中间格式......对于单个格式:

    <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-until(如上所述更改)。请注意,这与您的SVG示例完全相同,只是您可以通过编程方式在该文件中访问该数字。

最后,使用这个&#34;文件&#34;作为图像,然后使用:

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

现在,当你说看看所有这些步骤时,这是一个解决方案,所有上述内容都可以自动化到一个流程链中。首先循环并格式化所有关注的对象并从中生成小文件,然后第二遍不是格式化这些片段,而是将它们用作图像。

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

注意#2:我不是FOP专家,我对它的实现一无所知,特别是使用区域树作为文档中的图像。如果FOP是必须的,我建议调查一下。您可以轻松地将区域树转换为SVG并使用它们,因为您可以使用它们的所有维度或更好地将区域树读入第二个转换并从内联生成异步外部对象SVG。