How can I keep my content from being cutoff with apache fop? - xslt

I am going through the Apache FOP quickstart. From the command line I am converting a simple xml file that contains an svg element and converting it to a pdf file. I am able to do this, but the image generated by the svg is being cut off. I am new to XSL-FO & Apache FOP, but I did check out the w3c documentation of properties. Now I'm even more confused, unfortunately. I have tried the following with no luck: altering the width & height properties in the svg itself; setting page-height & page-width to "auto" in the simple page master element; eliminating the margin property. I didn't see anything indicating the region-body starts with some default size.
Here is the xml:
<chart>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
<circle cx="100" cy="100" r="40" stroke="black" stroke-width="2" fill="green" />
</svg>
And here's the xsl:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="A4-portrait"
margin="10">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4-portrait">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<fo:instream-foreign-object xmlns:svg="http://www.w3.org/2000/svg" content-width="600" content-height="300">
<svg:svg>
<xsl:copy-of select="/chart/svg:svg"/>
</svg:svg>
</fo:instream-foreign-object>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
The image is supposed to show a red & green circle overlapping, but it's only showing the upper left corner of the green one. I expect there's a property in the block element I am missing, but I don't know which. I looks like the block is limited to a 100px x 100px size.
What am I missing of the properties and how can I get the whole svg image to show properly (two full circles overlapping)?
Thanks,
Brandt
PS: I would have sent an image showing the problem, but I don't have a high enough reputation.

Errors are the specification of size with no units in FO in three places (margin, content-width and content-height). Also the SVG as stated in the comment above has a height of 100 which exceeds half of the green circle.
Correcting these and showing just the FO:
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4-portrait">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4-portrait">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<fo:instream-foreign-object xmlns:svg="http://www.w3.org/2000/svg">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="200">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
<circle cx="100" cy="100" r="40" stroke="black" stroke-width="2" fill="green" />
</svg>
</fo:instream-foreign-object>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
This shows the complete SVG image in your output.

Related

Apache FOP XSLT with svg-text render quality chaged after batik library upgrade

We recently migrated from FOP 2.1 to FOP 2.6 and witnessed a change in PNG output quality.
In our application fop is used with antialiasing OFF and in fop2.1 ( +batik 1.8) the text output is rendered nicely with no antialiasing .
But after we upgraded to FOP 2.6, PNG output is generated with antialiasing, without considering the fop.xconf setting or the text-rendering settings.
FOP 2.1 - Batik 1.8 output
FOP 2.6 - Batik 1.14 output
I tried various options by setting different text-rendering values but not able to get the same quality any more. I tried different versions of Batik lib and it seems that this change is seen from v1.9 onwards.
Seems like batik is ignoring anti-aliasing OFF configuration from the fop.xconf .
fop.xconf
<?xml version="1.0"?>
<fop version="1.0">
<complex-scripts disabled="false"/>
<renderers>
<renderer mime="image/png">
<color-mode>rgb</color-mode>
<transparent-page-background>false</transparent-page-background>
<background-color>white</background-color>
<anti-aliasing>false</anti-aliasing>
<rendering>false</rendering>
<fonts>
</fonts>
</renderer>
</renderers>
</fop>
Sample XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo">
<xsl:output method="xml" version="1.0" omit-xml-declaration="no" indent="yes"/>
<xsl:param name="versionParam" select="'1.0'"/>
<xsl:template match="articles[#page=1]">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="simpleA4" page-height="168px" page-width="384px">
<fo:region-body /> <!-- background-color="#FFFF00" -->
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simpleA4">
<fo:flow flow-name="xsl-region-body">
<!-- Temporarily Unavailable -->
<fo:block-container position="absolute" overflow="visible">
<fo:block>
<fo:instream-foreign-object xmlns:svg="http://www.w3.org/2000/svg">
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="240" viewport="10 10 290 200">
<text x="150" y="20" fill="black" text-anchor="start" font-size="22pt" text-rendering="optimizeLegibility">STWOA</text>
</svg>
</fo:instream-foreign-object>
</fo:block>
</fo:block-container>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
Any help or hints would be highly appreciated !

XSL-FO Region-Body background image

I have to add a background image to a page and add some text/content on the page. I am new to XSL-FO so I did some research. It looks like I need to use Region-Body and add the image using background-image attribute.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
<!-- Entry point -->
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
<fo:layout-master-set>
<fo:simple-page-master master-name="cover-page" page-height="21cm" page-width="29.7cm">
<fo:region-body background-image="url('Cover.jpg')" fox:background-image-width="29.7cm" fox:background-image-height="21cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<!-- Cover Page -->
<fo:page-sequence master-reference="cover-page" force-page-count="no-force" format="i">
<fo:flow flow-name="xsl-region-body">
<xsl:call-template name="tpltCoverPage"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<!-- Cover Page -->
<xsl:template name="tpltCoverPage">
<fo:block></fo:block>
</xsl:template>
</xsl:stylesheet>
The image appears as a background however it is 1700 * 1200 so the image is zoomed in and I can only see partial image in the background. Is there anyway I can zoom out the image so it fits the page height and width (without altering the actual image)?
Using only XSL 1.1 properties, you can position a background image but you can't scale it.
FOP has extension properties for setting the width and height of a background image: https://xmlgraphics.apache.org/fop/2.3/extensions.html#backgroundimages
(AH Formatter can do that and more: https://www.antennahouse.com/product/ahf66/ahf-ext.html#background)
Formatting just the XSL-FO from your sample worked for me with FOP 2.2:
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
<fo:layout-master-set>
<fo:simple-page-master master-name="cover-page"
page-height="21cm" page-width="29.7cm">
<fo:region-body background-image="url('Cover.jpg')"
fox:background-image-width="29.7cm"
fox:background-image-height="21cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<!-- Cover Page -->
<fo:page-sequence master-reference="cover-page"
force-page-count="no-force" format="i">
<fo:flow flow-name="xsl-region-body">
<fo:block></fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>

FOP XSL-FO Internal page anchor link URI problems

Morning folks!
So I am currently working on an FOP solution for a project, the end goal of which is basically to allow me to print onto a medium with the second iteration of the same information upside down, a feature which is not possible in Access 2007.
Everything is working swimmingly, and I can get the FOP to parse when I duplicate the code for the front side and use it for the back side.
However, when I try to use the parameter, I am getting an error I simply don't understand from the FOP terminal, having spent the better part of 4-5 hours trying to get my head around it. Code and error to follow.
<?xml version="1.0" encoding="utf-8"?>
<!-- WARNING - THIS TEMPLATE IS FOR Z FOLD CANON STOCK - DOUBLE SIDED -->
<!-- In order to covert CM to pixels, multiply the CM by 37.7952755905511, and round to two decimal places. It may be easier to use a spreadsheet to do this if you are editing multiple values -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<!-- EDIT THIS ROW TO CHANGE THE SIZE OF THE PAGE - AKA SET THIS TO THE SIZE OF THE MEDIUM YOU ARE PRINTING TO - CONVERTED TO PIXELS-->
<fo:simple-page-master master-name="simple" page-height="740.787px" page-width="317.480px">
<!-- IGNORE EVERYTHING BETWEEN HERE-->
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simple">
<fo:flow flow-name="xsl-region-body">
<xsl:for-each select="//Person">
<fo:block>
<fo:instream-foreign-object>
<!--<svg xmlns="http://www.w3.org/2000/svg">-->
<!-- AND HERE-->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="370.4" height="634.96">
<g class="mirrorpage">
<rect style= "fill:none; stroke: black" width="370.394" height="317.480"/>
<text x="37.8" y="122.83" style="text-anchor:start;" font-family="'ChevinLight'">
<tspan font-size="20">
Firstname
</tspan>
<tspan font-size="20">
Lastname
</tspan>
</text>
<text style="text-anchor:start;" x="37.8" y="150" font-family="'ChevinLight'">
<tspan font-size="20">
Company Name
</tspan>
</text>
<xsl:variable name="code" select="Code"/>
<image xlink:href="LINK REDACTED" x="37.8" y="190" height="50" width="50"/>
<image xlink:href="LINK REDACTED" x="250" y="200" height="100"width="100"/>
</g>
<use href= "#mirrorpage" transform="translate (370.394 634.96) scale (-1 -1)"/>
</svg>
</fo:instream-foreign-object>
</fo:block>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
The error I am then receiving when I try to parse this is as follows:
[ERROR] svg graphic could not be built: file:/C:/Users/Events/Desktop/Angledtext/BadgePrinting/PDF/:-1
The URI '' specified on the element is invalid.
From my (limited) understanding, there is an issue with the parsing of the "#" in the use line. I have tried to research URI properties but I have to be honest, I am completely lost.
Any help, or even a pointer to some relevant material I can read would be greatly appreciated.
Thanks

How to show correctly tabulation in xsl-fo?

I have an XML document and I am creating an XSL-FO file to convert it to pdf with apache-fop.
In the xml, there are sections <code> to show... code.
In the xsl-fo, I added the white-space="pre" sentence to preserve the code format, but tabulations are shown like single space:
XML section:
<code><![CDATA[
function callback( widget )
{
var ui = widget; // It should be a tab
}
]]></code>
XSL-FO section:
<xsl:template match="code">
<fo:block font-size="10pt" font-family="monospace" white-space="pre" color="#008000" background-color="#f8f8f8">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
Resulting PDF:
function callback( widget )
{
var ui = widget; // It should be a tab
}
So my question is: How to preserve or set the size of the tabulation?
Edited: I am using apache-fop 1.1
A full example:
proyecto.xml (do not forget to replace the 4 spaces by a tab before "var ui...")
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="proyecto.xsl"?>
<document>
<code><![CDATA[
function callback( widget )
{
var ui = widget; // It should be a tab
}
]]></code>
</document>
proyecto.xsl
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match ="document">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="OnePage" margin="1in"
page-height="29.7cm"
page-width="21cm"
margin-top="2.5cm"
margin-bottom="2.5cm"
margin-left="3.5cm"
margin-right="2.5cm">
<fo:region-body margin="0cm"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="Page">
<fo:single-page-master-reference master-reference="OnePage"/>
</fo:page-sequence-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="Page">
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="code">
<fo:block font-size="10pt" font-family="monospace" white-space="pre">
<xsl:apply-templates/>
<!--<xsl:value-of select="replace( . , 'a', 'b')"/>-->
</fo:block>
</xsl:template>
</xsl:stylesheet>
PDF result (screen):
Replace the tabs by four spaces, as suggested by #mzjn already in the comments.
XML Input
<code><![CDATA[
function callback( widget )
{
var ui = widget; // It should be a tab
}
]]></code>
XSLT Stylesheet
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="A4-portrait"
page-height="29.7cm" page-width="21.0cm" margin="2cm">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4-portrait">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="10pt" font-family="monospace" linefeed-treatment="preserve" white-space-collapse="false" white-space-treatment="preserve" wrap-option="no-wrap" color="#008000" background-color="#f8f8f8">
<xsl:value-of select="replace(code,' ',' ')"/>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
Now, after replacing the tab characters with whitespaces, the output is rendered correctly by FOP.
There is no obvious flaw with outputting tabs, but bear in mind that Apache FOP is only partially compliant in regard to the whitespace-treatment property: http://xmlgraphics.apache.org/fop/compliance.html , even if it says that only fo:inline elements are affected of this.

Aligning an element to the right using XSL-FO, Apache FOP

I'm using XSL-FO with Apache FOP to take a sexy looking XML file and output it as a PDF, however I'm having a really basic problem trying to get a particular bit of information (the address) to be positioned from the right of the page, I can force it over to the right by increasing the left attribute, but if I change my page size, orientation or margins this will immediately be useless.
Below is the code for the XSL, note the comment on line 23.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="all-pages"
page-height="297mm"
page-width="210mm"
margin-top="1cm"
margin-bottom="1cm"
margin-left="1cm"
margin-right="1cm" >
<fo:region-body margin-top="5cm" margin-bottom="1.1cm"/>
<fo:region-before extent="1cm"/>
<fo:region-after extent="5mm"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="default-sequence">
<fo:repeatable-page-master-reference master-reference="all-pages"/>
</fo:page-sequence-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="default-sequence">
<fo:static-content flow-name="xsl-region-before" font-size="10pt" font-family="Helvetica" >
<!-- HERE'S MY PROBLEM, THE RIGHT ATTRIBUTE ISN'T BEHAVING ITSELF -->
<fo:block-container absolute-position="absolute" right="4cm" top="1cm" width="6cm" border-style="solid" border-width="1mm" >
<fo:list-block >
<fo:list-item>
<fo:list-item-label>
<fo:block></fo:block>
</fo:list-item-label>
<fo:list-item-body>
<fo:block>ABC</fo:block>
</fo:list-item-body>
</fo:list-item>
<fo:list-item>
<fo:list-item-label>
<fo:block></fo:block>
</fo:list-item-label>
<fo:list-item-body>
<fo:block>123</fo:block>
</fo:list-item-body>
</fo:list-item>
</fo:list-block>
</fo:block-container>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after" padding-top="2pt" border-top-style="solid" border-top-width="1pt" border-top-color="rgb(192,192,192)" font-size="10pt" font-family="Helvetica">
<fo:block></fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body" font-size="10pt" font-family="Helvetica">
<fo:block></fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
And as you can see by this screenshot the element isn't positioning correctly:
Any one know know why this is happening?
Bugger, looked at the FOP changelog and the two years between versions 0.95 and 1.0 made me think whether it was a bug, downloaded the new binaries and it's now positioning my element from the right.