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

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

问题描述

我有一个项目,要求我在文本段落中的某些带下划线的文本下放置一个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>

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

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

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

提前谢谢! -丹

解决方案

这是我建议使用格式树的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并使用它们,就像可以使用它们的所有维度一样,或者更好的方法是将区域树读入第二个转换并直接内联从中生成流中外来对象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天全站免登陆