使用 Apache FOP 在 XSL-FO 中的带下划线的文本下放置字母 [英] Placing letters under underlined text in XSL-FO using Apache FOP

查看:28
本文介绍了使用 Apache FOP 在 XSL-FO 中的带下划线的文本下放置字母的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

这是用于此的 XSL-FO 标记:

普通文本<fo:inline baseline-shift=-100%"><fo:instream-foreign-object text-align="center";显示对齐=中心"边框=纯银 1px"><svg xmlns="http://www.w3.org/2000/svg";高度=25"宽度=120"视口=0 0 120 25"><text x=60"y=10"填充=黑色"文本锚=中间"文本装饰=下划线"font-size=12pt">带下划线的带有id的文本</text><text x=60"y=25"填充=黑色"文本锚=中间"font-size=12pt">123</svg></fo:instream-foreign-object></fo:inline>普通文本.</fo:block>

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

我还应该注意到 Apache FOP 不支持内联容器.

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

提前致谢!- 丹

解决方案

以下是我建议的使用格式化树的 RenderX 示例.

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

 <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">这是带下划线的带有 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=无题"><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="这是带下划线的 ID 文本" x="0" y="18734" width="162708"/><xep:line x-from="0" x-till="162708" y-from="17534" y-till="17534" depth="600" style="solid"/><xep:text value="1234567" x="58002" y="4334" width="46704"/></xep:page></xep:document>

您将在哪里修改结果以更改页面宽度,但它在文本中作为关注的文本元素的宽度,即更改:

 

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

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

 

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

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

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

I have a project that requires me to place a ID string under some underlined text in a passage of text.

Here is an example using an inline SVG object with a gray border to show the layout:

I can get close using an inline element with a baseline-shift and then use SVG to render the text. However this has the disadvantage (I think) that I have to manually put in the width of the SVG in pixels, which seems very complicated for such a simple layout.

Here is the XSL-FO markup for this:

<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>

So my question is: Can I perform this layout in Apache FOP XSL-FO without using instream-foreign-object and SVG? If I can not, is there some way to not have to put the width in the SVG in pixels? Or is there some way to calculate how many pixels the SVG will take to render?

I should also note inline-container is not supported in Apache FOP.

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

Thanks in advance! - Dan

解决方案

Here is a sample done as I suggested with RenderX using the formatting tree.

Format the desired fragments to the intermediate format ... something like this for a single one:

    <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>

The output of that would be this:

    <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>

Where you would modify the result to change the page width, but it's right in the text as the width of the text element of concern, that is change:

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

so the width is from the text line of concern, programmatically pick up the x-till from xep:line or the xep:text line (changing as above). Note, this is exactly equivalent to your SVG example except you have the number programmatically to access right inside this file.

last, using this "file" as an image, one would then use:

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

Now, while you say look at all those steps, this is a solution and all of the above could be automated into a single process chain. First loop through and format all of the objects of concern and make little files from them, then a second pass would instead of formatting those fragments, would use them as images.

Note: The line spacing shown in the attached image of the result cannot be done with FOP (I believe), I think that is a limitation of FOP.

Note #2: I am not a FOP expert and I know nothing of it's implementation, specifically using the area tree as an image in a document. If FOP is a must, I would suggest looking into it. You could just as easily convert the area tree to SVGs and use them as you would be able to use all their dimensions or better just read the area tree into the second transform and generate instream-foreign-object SVGs from it right inline.

这篇关于使用 Apache FOP 在 XSL-FO 中的带下划线的文本下放置字母的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆