I have SVG animation, and its works fine in browser, but it doesn't work, when I'm using it in my program.
<svg version="1.1" id="preloader" data-name="preloader" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 150">
<rect width="800" height="150" fill="#ffffff"/>
<rect x="0.5" y="0.5" width="799" height="149" fill="#ffffff"/>
<circle cx="0" cy="75" r="4" fill="white">
<animate id="color1_1" attributeName="fill" from="#ffffff" to="#44A0E2" dur="1s" begin="0.7s;move3_2.end+1.1s" />
<animate id="move1_1" attributeName="cx" from="153" to="337" dur="1s" begin="0.7s;move3_2.end+1.1s" calcMode="spline" keySplines="0 0.1 0.15 1"/>
<animate id="color2_1" attributeName="fill" from="#44A0E2" to="#44A0E2" dur="0.6s" begin="color1_1.end" />
<animate id="move2_1" attributeName="cx" from="337" to="337" dur="0.6s" begin="move1_1.end"/>
<animate id="color3_1" attributeName="fill" from="#44A0E2" to="#ffffff" dur="1s" begin="move2_2.end+0.1s" />
<animate id="move3_1" attributeName="cx" begin="move2_2.end+0.1s" from="337" to="521" dur="1s" calcMode="spline" keySplines="0.6 0.1 0.6 1"/>
</circle>
<circle cx="15" cy="75" r="4" fill="white">
<animate id="color1_2" attributeName="fill" from="#ffffff" to="#44A0E2" dur="1s" begin="0.6s;move3_3.end+1.1s" />
<animate id="move1_2" attributeName="cx" from="171" to="355" dur="1s" begin="0.6s;move3_3.end+1.1s" calcMode="spline" keySplines="0 0.1 0.15 1"/>
<animate id="color2_2" attributeName="fill" from="#44A0E2" to="#44A0E2" dur="0.6s" begin="color1_2.end" />
<animate id="move2_2" attributeName="cx" from="355" to="355" dur="0.6s" begin="move1_2.end"/>
<animate id="color3_2" attributeName="fill" from="#44A0E2" to="#ffffff" dur="1s" begin="move2_3.end+0.1s" />
<animate id="move3_2" attributeName="cx" begin="move2_3.end+0.1s" from="355" to="539" dur="1s" calcMode="spline" keySplines="0.6 0.1 0.6 1"/>
</circle>
<circle cx="30" cy="75" r="4" fill="white">
<animate id="color1_3" attributeName="fill" from="#ffffff" to="#44A0E2" dur="1s" begin="0.5s;move3_4.end+1.1s" />
<animate id="move1_3" attributeName="cx" from="189" to="373" dur="1s" begin="0.5s;move3_4.end+1.1s" calcMode="spline" keySplines="0 0.1 0.15 1"/>
<animate id="color2_3" attributeName="fill" from="#44A0E2" to="#44A0E2" dur="0.6s" begin="color1_3.end" />
<animate id="move2_3" attributeName="cx" from="373" to="373" dur="0.6s" begin="move1_3.end"/>
<animate id="color3_3" attributeName="fill" from="#44A0E2" to="#ffffff" dur="1s" begin="move2_4.end+0.1s" />
<animate id="move3_3" attributeName="cx" begin="move2_4.end+0.1s" from="373" to="557" dur="1s" calcMode="spline" keySplines="0.6 0.1 0.6 1"/>
</circle>
<circle cx="45" cy="75" r="4" fill="white">
<animate id="color1_4" attributeName="fill" from="#ffffff" to="#44A0E2" dur="1s" begin="0.4s;move3_5.end+1.1s" />
<animate id="move1_4" attributeName="cx" from="207" to="391" dur="1s" begin="0.4s;move3_5.end+1.1s" calcMode="spline" keySplines="0 0.1 0.15 1"/>
<animate id="color2_4" attributeName="fill" from="#44A0E2" to="#44A0E2" dur="0.6s" begin="color1_4.end" />
<animate id="move2_4" attributeName="cx" from="391" to="391" dur="0.6s" begin="move1_4.end"/>
<animate id="color3_4" attributeName="fill" from="#44A0E2" to="#ffffff" dur="1s" begin="move2_5.end+0.1s" />
<animate id="move3_4" attributeName="cx" begin="move2_5.end+0.1s" from="391" to="575" dur="1s" calcMode="spline" keySplines="0.6 0.1 0.6 1"/>
</circle>
<circle cx="60" cy="75" r="4" fill="white">
<animate id="color1_5" attributeName="fill" from="#ffffff" to="#44A0E2" dur="1s" begin="0.3s;move3_6.end+1.1s" />
<animate id="move1_5" attributeName="cx" from="225" to="409" dur="1s" begin="0.3s;move3_6.end+1.1s" calcMode="spline" keySplines="0 0.1 0.15 1"/>
<animate id="color2_5" attributeName="fill" from="#44A0E2" to="#44A0E2" dur="0.6s" begin="color1_5.end" />
<animate id="move2_5" attributeName="cx" from="409" to="409" dur="0.6s" begin="move1_5.end"/>
<animate id="color3_5" attributeName="fill" from="#44A0E2" to="#ffffff" dur="1s" begin="move2_6.end+0.1s" />
<animate id="move3_5" attributeName="cx" begin="move2_6.end+0.1s" from="409" to="593" dur="1s" calcMode="spline" keySplines="0.6 0.1 0.6 1"/>
</circle>
<circle cx="75" cy="75" r="4" fill="white">
<animate id="color1_6" attributeName="fill" from="#ffffff" to="#44A0E2" dur="1s" begin="0.2s;move3_7.end+1.1s" />
<animate id="move1_6" attributeName="cx" from="243" to="427" dur="1s" begin="0.2s;move3_7.end+1.1s" calcMode="spline" keySplines="0 0.1 0.15 1"/>
<animate id="color2_6" attributeName="fill" from="#44A0E2" to="#44A0E2" dur="0.6s" begin="color1_6.end" />
<animate id="move2_6" attributeName="cx" from="427" to="427" dur="0.6s" begin="move1_6.end"/>
<animate id="color3_6" attributeName="fill" from="#44A0E2" to="#ffffff" dur="1s" begin="move2_7.end+0.1s" />
<animate id="move3_6" attributeName="cx" begin="move2_7.end+0.1s" from="427" to="611" dur="1s" calcMode="spline" keySplines="0.6 0.1 0.6 1"/>
</circle>
<circle cx="90" cy="75" r="4" fill="white">
<animate id="color1_7" attributeName="fill" from="#ffffff" to="#44A0E2" dur="1s" begin="0.1s;move3_8.end+1.1s" />
<animate id="move1_7" attributeName="cx" from="261" to="445" dur="1s" begin="0.1s;move3_8.end+1.1s" calcMode="spline" keySplines="0 0.1 0.15 1"/>
<animate id="color2_7" attributeName="fill" from="#44A0E2" to="#44A0E2" dur="0.6s" begin="color1_7.end" />
<animate id="move2_7" attributeName="cx" from="445" to="445" dur="0.6s" begin="move1_7.end"/>
<animate id="color3_7" attributeName="fill" from="#44A0E2" to="#ffffff" dur="1s" begin="move2_8.end+0.1s"/>
<animate id="move3_7" attributeName="cx" begin="move2_8.end+0.1s" from="445" to="629" dur="1s" calcMode="spline" keySplines="0.6 0.1 0.6 1"/>
</circle>
<circle cx="105" cy="75" r="4" fill="white">
<animate id="color1_8" attributeName="fill" from="#ffffff" to="#44A0E2" dur="1s" begin="0s;move3_8.end+1s" />
<animate id="move1_8" attributeName="cx" from="279" to="463" dur="1s" begin="0s;move3_8.end+1s" calcMode="spline" keySplines="0 0.1 0.15 1"/>
<animate id="color2_8" attributeName="fill" from="#44A0E2" to="#44A0E2" dur="0.6s" begin="color1_8.end" />
<animate id="move2_8" attributeName="cx" from="463" to="463" dur="0.6s" begin="move1_8.end"/>
<animate id="color3_8" attributeName="fill" from="#44A0E2" to="#ffffff" dur="1s" begin="move2_8.end" />
<animate id="move3_8" attributeName="cx" begin="move2_8.end" from="463" to="647" dur="1s" calcMode="spline" keySplines="0.6 0.1 0.6 1"/>
</circle>
</svg>
Link to svg - https://codepen.io/ahremkov/pen/eYKdaRZ
I have another SVG animations, and everything seems fine, so it's not c++ code, something with this SVG file and it's Qt compatibility.
Maybe something with animate tag, other SVG animations doesn't use it (its 'animateColor' or 'animateTransform' there).
Related
I have the following source document;
<instance class-name="Deelnemer">
<attr attr-name="achternaam">
<value>McFly</value>
</attr>
<attr attr-name="geslacht">
<value>MAN</value>
</attr>
<attr attr-name="geboortedatum">
<value>1968-03-14</value>
</attr>
<attr attr-name="verzorgers">
<value>{"uuid":"f5a8fecd-7ea6-499e-a8a6-c6eb20e582b8","volgnummer":1}</value>
</attr>
<attr attr-name="verzorgers">
<value>{"uuid":"54748d2b-b2bf-4362-8520-4c4827a6660c","volgnummer":2}</value>
</attr>
</instance>
I transform it using this xslt (1.0);
<xsl:for-each select="./attr[#attr-name]">
<xsl:if test="string-length(.)"/>
<xsl:variable name="name" select="./#attr-name"/>
<xsl:variable name="value" select="normalize-space(./value)"/>
<modify-attr>
<xsl:attribute name="attr-name">
<xsl:value-of select="$name"/>
</xsl:attribute>
<remove-all-values/>
<add-value>
<value>
<xsl:value-of select="$value"/>
</value>
</add-value>
</modify-attr>
</xsl:for-each>
Which currently results in;
<modify-attr attr-name="geboortedatum">
<remove-all-values/>
<add-value>
<value>1968-03-14</value>
</add-value>
</modify-attr>
<modify-attr attr-name="verzorgers">
<remove-all-values/>
<add-value>
<value>{"uuid":"f5a8fecd-7ea6-499e-a8a6-c6eb20e582b8","volgnummer":1}</value>
</add-value>
</modify-attr>
<modify-attr attr-name="verzorgers">
<remove-all-values/>
<add-value>
<value>{"uuid":"54748d2b-b2bf-4362-8520-4c4827a6660c","volgnummer":2}</value>
</add-value>
</modify-attr>
But i want it to transform conditional if the previous tag (attribute) is the same as the current one.
<modify-attr attr-name="geboortedatum">
<remove-all-values/>
<add-value>
<value>1968-03-14</value>
</add-value>
</modify-attr>
<modify-attr attr-name="verzorgers">
<remove-all-values/>
<add-value>
<value>{"uuid":"f5a8fecd-7ea6-499e-a8a6-c6eb20e582b8","volgnummer":1}</value>
</add-value>
</modify-attr>
<modify-attr attr-name="verzorgers">
<add-value>
<value>{"uuid":"54748d2b-b2bf-4362-8520-4c4827a6660c","volgnummer":2}</value>
</add-value>
</modify-attr>
As seen by the "verzorgers" attr-name it appears twice but i only want a <remove-all-values> with the first occurrence of this tag/attr-name.
Tried several with currently the use of "preceding-siblings" to know the previous value of "attr-name" within the loop but the syntax keeps nagging me to result in usable code.
So helpful suggestions are more then welcome...
You could do:
<xsl:if test="not(#attr-name = preceding-sibling::attr[1]/#attr-name)">
<remove-all-values/>
</xsl:if>
Alternatively, you could define a key as:
<xsl:key name="attr-by-name" match="attr" use="#attr-name" />
and then do something along the lines of Muenchian grouping:
<xsl:if test="count(. | key('attr-by-name', #attr-name)[1]) = 1">
<remove-all-values/>
</xsl:if>
Note that the two are not the same: you will see a difference if the groups are not contiguous.
I'm getting this error in Chrome console:
Seems to be a problem with XSLT or SEF as other SEF works.
I complie SEF with the xslt3 tool on Node.js version v14.17.3.
I can run the XSLT with Saxon 9.8.12-EE in oXygen with no problem.
Maybe the problem with maps, xsl:include or xsl:import?
Here is the XSLT code:
<stylesheet exclude-result-prefixes="xs xd dme functx dita mei map array" extension-element-prefixes="ixsl" version="3.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:array="http://www.w3.org/2005/xpath-functions/array" xmlns:dita="http://dita-ot.sourceforge.net" xmlns:dme="http://www.mozarteum.at/ns/dme" xmlns:functx="http://www.functx.com" xmlns:ixsl="http://saxonica.com/ns/interactiveXSLT" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:mei="http://www.music-encoding.org/ns/mei" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.music-encoding.org/ns/mei">
<xi:include href="docs.xsl" xpointer="element(/1/1)"/>
<import href="changeLog.xsl"/>
<!--This parameter is a needed for XSpec. Cf. https://github.com/xspec/xspec/wiki/Global-Context-Item-->
<param name="global-context-item" select="."/>
<param name="source"/>
<include href="../modules/identity-transform.xsl"/>
<xd:doc>
<xd:desc>
<xd:p>Replace current scoreDef with the alternative. Note that this should be defined in the following-sibling <choice>.</xd:p>
</xd:desc>
</xd:doc>
<template match="scoreDef[not(#corresp = concat('#', $source))]">
<copy-of select="following-sibling::choice[#type = 'scoring']/*[#corresp = concat('#', $source)]/scoreDef"/>
</template>
<xd:doc>
<xd:desc/>
</xd:doc>
<template match="choice[#type = 'scoring']"/>
<xd:doc>
<xd:desc>
<xd:p>Map staffDef#n of the new scoreDef and #dme.parts.</xd:p>
</xd:desc>
</xd:doc>
<variable as="map(xs:string, item())*" name="map_staves_order">
<for-each select="$global-context-item//choice[#type = 'scoring']/*[#corresp = concat('#', $source)]/scoreDef">
<map>
<for-each select="descendant::staffDef">
<map-entry key="string(#n)" select="#dme.parts"/>
</for-each>
</map>
</for-each>
</variable>
<xd:doc>
<xd:desc>
<xd:p>Get the maximum number of staves.</xd:p>
</xd:desc>
</xd:doc>
<variable as="xs:integer" name="count_staves" select="
max(for $a in map:keys($map_staves_order)
return
if (matches($a, '\d')) then
xs:integer($a)
else
())"/>
<xd:doc>
<xd:desc>
<xd:p>Key: old #n.</xd:p>
<xd:p>Value: new #n</xd:p>
</xd:desc>
</xd:doc>
<variable as="map(xs:string, xs:string)*" name="map_new_old_staves">
<map>
<for-each select="map:keys($map_staves_order)">
<variable name="current_key" select="."/>
<map-entry key="$global-context-item//measure[#n = 1]/staff[#dme.parts = map:get($map_staves_order, $current_key)]/#n/string()" select="."/>
</for-each>
</map>
</variable>
<xd:doc>
<xd:desc>
<xd:p>Copies elements before first staff without changes, e.g. <tempo></xd:p>
<xd:p>Copies staves accordingly to the new score order. Changes the #n-attribute accordingly</xd:p>
<xd:p>Copies ControlEvents and updates the #staff attribute if neccessary.</xd:p>
</xd:desc>
</xd:doc>
<template match="measure">
<copy>
<apply-templates select="#*"/>
<apply-templates select="child::staff[1]/preceding-sibling::*"/>
<variable as="element()" name="currentMeasure" select="."/>
<for-each select="1 to $count_staves">
<variable as="xs:string" name="currentItem" select="string()"/>
<for-each select="$currentMeasure/child::staff[map:get($map_staves_order, $currentItem) = #dme.parts]">
<copy>
<attribute name="n" select="$currentItem"/>
<apply-templates select="(#* except #n) | node()"/>
</copy>
</for-each>
</for-each>
<call-template name="update_staff_controlEvents">
<with-param name="elements" select="child::staff[last()]/following-sibling::*"/>
</call-template>
</copy>
</template>
<xd:doc>
<xd:desc>
<xd:p>Receives one or more elements (controlEvents) and updates their #staff according to the $map_new_old_staves variable.</xd:p>
<xd:p>Recursive template</xd:p>
</xd:desc>
<xd:param name="elements"/>
</xd:doc>
<template name="update_staff_controlEvents">
<param name="elements"/>
<for-each select="$elements">
<choose>
<when test="#staff">
<copy>
<attribute name="staff" select="map:get($map_new_old_staves, #staff)"/>
<apply-templates select="#* except #staff"/>
<if test="node()">
<call-template name="update_staff_controlEvents">
<with-param name="elements" select="node()"/>
</call-template>
</if>
</copy>
</when>
<otherwise>
<copy>
<apply-templates select="#*"/>
<if test="node()">
<call-template name="update_staff_controlEvents">
<with-param name="elements" select="node()"/>
</call-template>
</if>
</copy>
</otherwise>
</choose>
</for-each>
</template>
</stylesheet>
JS which I run on Console:
var options = {
stylesheetLocation: "./assets/xsl/origScoring.sef.json",
sourceText: xmlString,
stylesheetParams: {"source": "source_A"},
destination: "document"
}
var result = SaxonJS.transform(options);
result.principalResult
Owing to the Saxon developers I could easily solve my issue by adding namespace prefixes in the XPath expressions when creating maps. Originally, I used xpath-default-namespace. Fo instance, here on the elements measure and staff should be:
<map-entry key="$global-context-item//mei:measure[#n = 1]/mei:staff[#dme.parts = map:get($map_staves_order, $current_key)]/#n/string()" select="."/>
instead of
<map-entry key="$global-context-item//measure[#n = 1]/staff[#dme.parts = map:get($map_staves_order, $current_key)]/#n/string()" select="."/>
i am trying to hide fo:table row or column lines based on the requirement from web application, so i used to set border-style="none" to fo:table-column or fo:table-row based on the need, but when i tried it,
either it creates dark lines in row's (if i hide column lines)
or creates dark lines in column's (if i hide row lines).
If column lines get hidden:
If row lines get hidden:
MY 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:template match="pages">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="simple"
page-height="8.5in" page-width="11in" margin-top=".5in"
margin-bottom=".5in" margin-left=".5in" margin-right=".5in">
<fo:region-body margin-top="2cm" margin-bottom="2cm" />
<fo:region-before extent="2cm" overflow="hidden" />
<fo:region-after extent="1cm" overflow="hidden" />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simple"
initial-page-number="1">
<fo:static-content flow-name="xsl-region-before">
<fo:block font-size="13.0pt" font-family="serif"
padding-after="2.0pt" space-before="4.0pt" text-align="center"
border-bottom-style="solid" border-bottom-width="1.0pt">
<fo:block>IF COLUMN LINES HIDED</fo:block>
</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after">
<fo:block font-size="12.0pt" font-family="sans-serif"
padding-after="2.0pt" space-before="2.0pt" text-align="center"
border-top-style="solid" border-bottom-width="1.0pt">
<xsl:text>Page</xsl:text>
<fo:page-number />
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates select="page-body" />
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="page-body">
<fo:block text-align="center" break-before="page">
<fo:table table-layout="fixed" width="100%"
border-style="solid">
<fo:table-column border-style="solid"/>
<fo:table-column border-style="solid"/>
<fo:table-column border-style="solid"/>
<!-- For hiding column lines -->
<!-- <fo:table-column border-style="none"/> -->
<!-- <fo:table-column border-style="none"/> -->
<!-- <fo:table-column border-style="none"/> -->
<fo:table-header>
<xsl:apply-templates select="table-header" />
</fo:table-header>
<fo:table-body>
<xsl:apply-templates select="table-data" />
</fo:table-body>
</fo:table>
</fo:block>
</xsl:template>
<xsl:template match="table-header">
<fo:table-row keep-together.within-page="always"
border-style="solid">
<fo:table-cell>
<fo:block font-size="10pt" font-family="sans-serif"
padding-top="3pt">
<xsl:value-of select="column-one"></xsl:value-of>
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block font-size="10pt" font-family="sans-serif"
padding-top="3pt">
<xsl:value-of select="column-two"></xsl:value-of>
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block font-size="10pt" font-family="sans-serif"
padding-top="3pt">
<xsl:value-of select="column-three"></xsl:value-of>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>
<xsl:template match="table-data">
<fo:table-row keep-together.within-page="always"
border-style="none">
<!-- For showing row lines -->
<!-- <fo:table-row keep-together.within-page="always" -->
<!-- border-style="solid"> -->
<fo:table-cell>
<fo:block font-size="10pt" font-family="sans-serif"
padding-top="3pt">
<xsl:value-of select="column-one"></xsl:value-of>
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block font-size="10pt" font-family="sans-serif"
padding-top="3pt">
<xsl:if test="number(column-two) = number(column-two)">
<xsl:value-of select="format-number(translate(column-two, ',','.'), '#,###.##')"></xsl:value-of>
</xsl:if>
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block font-size="10pt" font-family="sans-serif"
padding-top="3pt">
<xsl:value-of select="column-three"></xsl:value-of>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>
</xsl:stylesheet>
MY XML:
<?xml version="1.0" encoding="UTF-8"?>
<pages>
<page-body>
<table-header>
<column-one>Column One</column-one>
<column-two>Column Two</column-two>
<column-three>Column Three</column-three>
</table-header>
<table-data>
<column-one>One</column-one>
<column-two>5000</column-two>
<column-three>Three</column-three>
</table-data>
<table-data>
<column-one>One</column-one>
<column-two>5000</column-two>
<column-three>Three</column-three>
</table-data>
<table-data>
<column-one>One</column-one>
<column-two>0</column-two>
<column-three>Three</column-three>
</table-data>
<table-data>
<column-one>One</column-one>
<column-two>0</column-two>
<column-three>Four</column-three>
</table-data>
<table-data>
<column-one>One</column-one>
<column-two>2000</column-two>
<column-three>Four</column-three>
</table-data>
<table-data>
<column-one>One</column-one>
<column-two>1234</column-two>
<column-three>Five</column-three>
</table-data>
<table-data>
<column-one>One</column-one>
<column-two>5666</column-two>
<column-three>Five</column-three>
</table-data>
<table-data>
<column-one>One</column-one>
<column-two>5666</column-two>
<column-three>Five</column-three>
</table-data>
</page-body>
</pages>
I am using these xml and xsl files to generate PDF using apache fop, Is there any problem in my code?
Unfortunately, this sort of thing crops up from time to time in FO development involving FOP rendering.
For your answer, please see Section 6.9 of xmlgraphics.apache.org's FAQ re anti-aliasing and Acrobat.
Notice that if you play with the zoom factor in Acrobat, the problem will disappear/reappear depending on the setting.
Also note that if you try your example with RenderX (a.k.a XEP), this won't happen. They've apparently figured out (or never had) the problem.
One of the perils of trying to get away with a non-commercial FO product. (Not that something has to be commercial to be good, of course, but it's just fact that commercial FO processors are better and more powerful than FOP, though FOP is improving, albeit slowly.)
If you have to continue using FOP, make sure you're on the latest version (see this pin). Some important benefit to be had with 2.4.
ADDENDUM (Usage of SVG):
You can avoid this FOP bugginess by dynamically-built-out SVG markup.
Here's an example of the kind of markup you'd have to generate to get a PDF table by this method:
<fo:instream-foreign-object>
<svg:svg width="1000%" height="1000%">
<svg:g id='rowGroup' transform='translate(0, 0)' role="table">
<svg:text x='30' y='30' font-size='18px' font-weight='bold' fill='crimson' text-anchor='middle' role="row">
<svg:tspan role="columnheader" x='100'>Sales</svg:tspan>
<svg:tspan role="columnheader" x='200'>Expenses</svg:tspan>
<svg:tspan role="columnheader" x='300'>Net</svg:tspan>
</svg:text>
<svg:rect x='30' y='40' width='310' height='1' fill='black'/>
<svg:text x='30' y='30' font-size='18px' text-anchor='middle' role="row">
<svg:tspan id="q1" role="rowheader" x='30' dy='1.5em' font-weight='bold' fill='crimson' text-anchor='start'>Q1</svg:tspan>
<svg:tspan role="cell" x='100'>$223</svg:tspan>
<svg:tspan role="cell" x='200'>$195</svg:tspan>
<svg:tspan role="cell" x='300'>$28</svg:tspan>
</svg:text>
<svg:rect x='30' y='60' width='310' height='1' fill='black'/>
<svg:text x='30' y='50' font-size='18px' text-anchor='middle' role="row">
<svg:tspan id="q2" role="rowheader" x='30' dy='1.5em' font-weight='bold' fill='crimson' text-anchor='start'>Q2</svg:tspan>
<svg:tspan role="cell" x='100'>$295</svg:tspan>
<svg:tspan role="cell" x='200'>$263</svg:tspan>
<svg:tspan role="cell" x='300'>$32</svg:tspan>
</svg:text>
<svg:rect x='30' y='80' width='310' height='1' fill='black'/>
<svg:text x='30' y='70' font-size='18px' text-anchor='middle' role="row">
<svg:tspan id="q3" role="rowheader" x='30' dy='1.5em' font-weight='bold' fill='crimson' text-anchor='start'>Q3</svg:tspan>
<svg:tspan role="cell" x='100'>$951</svg:tspan>
<svg:tspan role="cell" x='200'>$232</svg:tspan>
<svg:tspan role="cell" x='300'>$719</svg:tspan>
</svg:text>
<svg:rect x='30' y='100' width='310' height='1' fill='black'/>
<svg:text x='30' y='90' font-size='18px' text-anchor='middle' role="row">
<svg:tspan id="q4" role="rowheader" x='30' dy='1.5em' font-weight='bold' fill='crimson' text-anchor='start'>Q4</svg:tspan>
<svg:tspan role="cell" x='100'>$823</svg:tspan>
<svg:tspan role="cell" x='200'>$175</svg:tspan>
<svg:tspan role="cell" x='300'>$648</svg:tspan>
</svg:text>
<svg:rect x='30' y='120' width='310' height='1' fill='black'/>
</svg:g>
</svg:svg>
</fo:instream-foreign-object>
I leave it to you to dynamicize the FO creation for your particular case, but this ought to teach you how to build tables this way.
You can easily achieve the effects you desire by drawing the borders as SVG polygons, which is where Kevin was going with this (although I believe he was speaking of the code inside the RenderX engine. My solution externalizes that via embedded SVG creation.) Of course, the <svg:rect> tag is a form of polygon, and that's what you'd use to render borders.
Remember to specify the SVG namespace on your <xsl:stylesheet> tag if you're going to attempt this.
xmlns:svg="http://www.w3.org/2000/svg"
Check out this recently merged patch (merged 2020-12-29), which seems to fix this problem for me:
https://issues.apache.org/jira/browse/FOP-2536 (Varying table border thickness in PDF output)
Revision 1884907: FOP-2536: Allow overpaint of PDF border
From the Apache FOP 2.6 you can to set the following parameter into the configuration file (by default fop.xconf):
<table-border-overpaint>true</table-border-overpaint>
This option may to make your borders thicker, but fix an issue:
https://xmlgraphics.apache.org/fop/faq.html#acrobat-anti-aliasing
Also this issue is registered as Chromium Pdf rendering bug:
https://bugs.chromium.org/p/chromium/issues/detail?id=500023
I am using Apache FOP to generate PDF's. My data is in a XML file and I use a XSL stylesheet to render it. I am having trouble using SVG in my stylesheet. I have create an SVG which is
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.0" width="400" height="400" id="svg2">
<path d="M200,200 L390,200 A190,190 0 0,1 200,390 z" fill="red" stroke="black" stroke-width="2" fill-opacity="0.5" stroke-linejoin="round" />
<path d="M200,200 L200,390 A190,190 0 0,1 10,200 z" fill="orange" stroke="black" stroke-width="2" fill-opacity="0.5" stroke-linejoin="round" />
<path d="M200,200 L10,200 A190,190 0 0,1 200,10 z" fill="yellow" stroke="black" stroke-width="2" fill-opacity="0.5" stroke-linejoin="round" />
<path d="M200,200 L200,10 A190,190 0 0,1 390,200 z" fill="green" stroke="black" stroke-width="2" fill-opacity="0.5" stroke-linejoin="round" />
</svg>
But how do I put it in the stylesheet. I have tried putting it in an <fo:instream-foreign-object> like
<fo:instream-foreign-object xmlns:svg="http://www.w3.org/2000/svg">
<svg:svg width="400" height="400">
<svg:path d="M200,200 L390,200 A190,190 0 0,1 200,390 z" fill="red" stroke="black" stroke-width="2" fill-opacity="0.5" stroke-linejoin="round" />
...
</svg:svg>
</fo:instream-foreign-object>
But this doesn't work. Does anyone know what I'm doing wrong?
He's my example of SVG inside FOP as a letter size background (with text 'background region'):
<fo:block-container absolute-position="absolute"
top="0in" left="0in" width="8.5in" height="11in"
content-height="scale-to-fit" content-width="scale-to-fit"
scaling="non-uniform"
background-position="center" background-repeat="no-repeat"
background-image="url(your_xml_file.svg)">
<fo:block>background region
</fo:block>
</fo:block-container>
its turns out I was doing it all wrong. The correct way to do it is rather than doing
<svg:path stroke="black" stroke-width="2" fill-opacity="0.5" stroke-linejoin="round" />
You need to draw the path like this
<svg:path stroke="black" stroke-width="2" fill-opacity="0.5" stroke-linejoin="round">
<xsl:attribute name="fill">red</xsl:attribute>
<xsl:attribute name="d">M200,200 L390,200 A190,190 0 0,1 200,390 z</xsl:attribute>
</svg:path>
I am using below XSLT to generate report with running footer, but the first page of ther report doesn't have the running footer, please advice what needs to be changed
<?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:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:my-scripts">
<xsl:template match="/" >
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<!-- defines the layout master -->
<fo:layout-master-set >
<fo:simple-page-master master-name="first"
page-height="290mm" page-width="210mm" margin-top="0mm" margin-bottom="10mm" margin-left="20mm" margin-right="0mm">
<fo:region-body margin-top="15mm" margin-bottom="15mm"/>
<fo:region-after extent="10mm" region-name="footer-normal"></fo:region-after>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="first">
<fo:static-content flow-name="footer-normal">
<fo:block text-align="center" font-size="7pt" font-style="italic" font-family="sans-serif">
<fo:retrieve-marker retrieve-class-name="chapter"/>
PAGE <fo:page-number/> of
<fo:page-number-citation ref-id="last-page"/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xsl:for-each select="ArrayOfRoomReportBE/RoomReportBE" >
<xsl:variable name="RoomNo_node" select=".//RoomNumber"/>
<fo:marker marker-class-name="chapter" font-size="7pt" font-style="italic"
font-family="sans-serif">
<xsl:value-of select="$RoomNo_node"/>
</fo:marker>
<!-- Dispaly datat -->
</xsl:for-each>
<fo:block id="last-page"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
Input document used is as follows
<ArrayOfRoomReportBE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<RoomReportBE>
<Id>0</Id>
<RoomNumber>TestCap1</RoomNumber>
<RoomName>TestCap1</RoomName>
<Comment>Testing a bit</Comment>
<GeneralAspect>
<GeneralAttributeTitle>
<ReferenceLink>Reference Link</ReferenceLink>
<Notes>General Notes</Notes>
<GeneralHeader>General</GeneralHeader>
<MaxCO2>Max CO2</MaxCO2>
<DimensionHeader>Dimension</DimensionHeader>
<NetAreaTitle>Net area</NetAreaTitle>
<ClimateHeader>Climate</ClimateHeader>
<MinTempTitle>Min Temperature</MinTempTitle>
<MaxTempTitle>Max Temperature </MaxTempTitle>
<OpenHoursTitle>Open hours</OpenHoursTitle>
<NonOpenHoursTitle>Non open hours</NonOpenHoursTitle>
<AcousticsHeader>Acoustics</AcousticsHeader>
<MaxInstallationNoiseTitle>Max installation noise</MaxInstallationNoiseTitle>
<SoundInsulationTitle>Sound insulation</SoundInsulationTitle>
<WorkplacesOccupancyHeader>Occupancy/Workplaces</WorkplacesOccupancyHeader>
<OccupancyTitle>Occupancy</OccupancyTitle>
<NoOfWorkspaceTitle>Number of workplaces</NoOfWorkspaceTitle>
<TypeOfWorkspaceTitle>Type of workplaces</TypeOfWorkspaceTitle>
</GeneralAttributeTitle>
<AspectAttributeItems>
<GeneralAttributeItemBE>
<GeneralNoOfWorkplaces />
<GeneralDimensionNetArea>12</GeneralDimensionNetArea>
<GeneralClimateMinTempOpen>-19°C</GeneralClimateMinTempOpen>
<GeneralClimateMinTempNonOpen>-15°C</GeneralClimateMinTempNonOpen>
<GeneralClimateMaxTempOpen>-6°C</GeneralClimateMaxTempOpen>
<GeneralClimateMaxTempNonOpen>-11°C</GeneralClimateMaxTempNonOpen>
<Notes />
<ReferenceLink />
</GeneralAttributeItemBE>
</AspectAttributeItems>
</GeneralAspect>
<FloorAspect>
<FloorAttributeTitle>
<Description>Description</Description>
<ReferenceLink>Reference Link</ReferenceLink>
<Notes>General Notes</Notes>
<FloorFinishTitle>Floor Finish</FloorFinishTitle>
<FloorHeader>Floor</FloorHeader>
<FloorSubstractTitle>Floor Substrate</FloorSubstractTitle>
<FloorColorTitle>Floor Colour</FloorColorTitle>
<FloorSkirtingTitle>Skirting</FloorSkirtingTitle>
</FloorAttributeTitle>
<AspectAttributeItems>
<FloorAttributeItemBE>
<Description />
<Notes />
<ReferenceLink />
</FloorAttributeItemBE>
<FloorAttributeItemBE>
<FloorSubstract>Block pavement</FloorSubstract>
<FloorColor>Medium grey</FloorColor>
<FloorSkirting>N/A</FloorSkirting>
<FloorFinish>Ceramic tiles textured</FloorFinish>
<Description>test</Description>
<Notes />
<ReferenceLink />
</FloorAttributeItemBE>
</AspectAttributeItems>
</FloorAspect>
<WallAspect>
<WallAttributeTitle>
<Description>Description</Description>
<ReferenceLink>Reference Link</ReferenceLink>
<Notes>General Notes</Notes>
<WallHeader>Wall</WallHeader>
<WallNameTitle>Wall</WallNameTitle>
<WallFinishTitle>Wall finish</WallFinishTitle>
<WallColorTitle>Wall Colour</WallColorTitle>
</WallAttributeTitle>
<AspectAttributeItems>
<WallAttributeItemBE>
<WallName>Facade</WallName>
<WallFinish>Special</WallFinish>
<WallColor>TestValue</WallColor>
<Description>test</Description>
<Notes />
<ReferenceLink>test</ReferenceLink>
</WallAttributeItemBE>
</AspectAttributeItems>
</WallAspect>
<CeilingAspect>
<CeilingAttributeTitle>
<ReferenceLink>Reference Link</ReferenceLink>
<Notes>General Notes</Notes>
<AcousticsTitle>Acoustics</AcousticsTitle>
<CeilingInsertsTitle>Inserts</CeilingInsertsTitle>
<CeilingHeightTitle>Ceiling height</CeilingHeightTitle>
<CeilingHeader>Ceiling</CeilingHeader>
<CeilingSuspendedTitle>Suspended Ceiling</CeilingSuspendedTitle>
<CeilingRoomAcousticsTitle>Room acoustics</CeilingRoomAcousticsTitle>
<CeilingCoverageTitle>Coverage</CeilingCoverageTitle>
<CeilingTypeTitle>Type</CeilingTypeTitle>
<CeilingOthersTitle>Other</CeilingOthersTitle>
</CeilingAttributeTitle>
<AspectAttributeItems>
<CeilingAttributeItemBE>
<Notes />
<ReferenceLink />
</CeilingAttributeItemBE>
</AspectAttributeItems>
</CeilingAspect>
<EquipmentAspect>
<EquipmentAttributeTitle>
<ReferenceLink>Reference Link</ReferenceLink>
<Notes>General Notes</Notes>
<EquipmentHeader>Equipment</EquipmentHeader>
<EquipmentNameTitle>Equipment</EquipmentNameTitle>
<EquipmentQuantityTitle>Quantity</EquipmentQuantityTitle>
<EquipmentConnectionsTitle>Connections</EquipmentConnectionsTitle>
<Description>Description</Description>
</EquipmentAttributeTitle>
<AspectAttributeItems>
<EquipmentAttributeItemBE>
<EquipmentName>-</EquipmentName>
<EquipmentQuantity>100</EquipmentQuantity>
<EquipmentConnections>220V</EquipmentConnections>
<Description>test2</Description>
<Notes />
<ReferenceLink />
</EquipmentAttributeItemBE>
</AspectAttributeItems>
</EquipmentAspect>
</RoomReportBE>
<RoomReportBE>
</RoomReportBE>
</ArrayOfRoomReportBE>
Please change two things: first, <fo:region-after extent="10mm" region-name="footer-normal"> to <fo:region-after extent="10mm">. And second, change <fo:static-content flow-name="footer-normal"> to <fo:static-content flow-name="xsl-region-after">.