git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@699801 13f79535-47bb-0310-9956-ffa450edef68pull/17/head
@@ -21,6 +21,8 @@ pub 1024D/4358C584 2006-12-08 Vincent Hennebert <vhennebert@apache.org> | |||
sub 2048g/0BD6AC9B 2006-12-08 | |||
pub 1024D/CC31AE97 2008-03-27 [expires: 2011-01-01] | |||
uid Maximilian Berger <maxberger@apache.org> | |||
pub 1024R/C93C5700 2008-07-12 | |||
uid Maximilian Berger <maxberger@apache.org> | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
Version: GnuPG v1.0.6 (GNU/Linux) | |||
@@ -189,3 +191,58 @@ eW/0pQUpJcvolxbT9xvF | |||
=bbQO | |||
-----END PGP PUBLIC KEY BLOCK----- | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
Version: GnuPG v1.2.6 (GNU/Linux) | |||
mI4ESHiTQAEEANXyMbT/YZLUQoG2e5bVl1OcZ4Ttpt+Uk7KfZd1vehgwkr7VOUT5 | |||
Y5JZ74mS/XxdG3JoSI5AF96pAxEl/xplqnTXtR/ZG6IcK7BZPblpYf4l8zB+M9g0 | |||
QbTphAAiYeWBLoDWNZW6jiicsQ27EZmGgotcJ855t1x3CbEey0KpmEeHACCrR/j3 | |||
tChNYXhpbWlsaWFuIEJlcmdlciA8bWF4YmVyZ2VyQGFwYWNoZS5vcmc+iEYEEBEC | |||
AAYFAkh5tUsACgkQ4+RAT8wxrpeT/gCgvLNl0Ygmq8vBSdu6QXRzrWzQqGoAmQEq | |||
gEXNzkIENamBEmderAxauC8HiLYEEwECACAFAkh4lMECGwMGCwkIBwMCBBUCCAME | |||
FgIDAQIeAQIXgAAKCRD5iaLlyTxXAJlABACYHTf8nSIv0wR57ApHmF2AKub6OKPs | |||
KBzHP0/xQKpJ+75suk/0CNL7ve5RknHZ9f202DBQ1UOE2ibW6CbXokuhLPQHiWcD | |||
h/LNjn/gIB8y8yIr64SNX2u6563ZKhs2p72BTAJRquWdIwjcg6sXeWbvY/B7AFeJ | |||
14v8GKWL3YWxQbiOBEh4k0gBBADGhb6pch9zGC9pGDPEyOujwXK1Iq9V7k6ECBSs | |||
uzANb8GCAA+xj+jna20Nphnckd7ZMkiNyd+GD2fyFGL6BvIMGQZrLcuOK0yCkZqN | |||
SVZ/Tk98u0PaaFMBMh1XwdCgn5NKtzxBOZ2b2klBJlI3Rr4vBUqwe6/mytH96DfM | |||
cP5KWwAg9S7R24ifBBgBAgAJBQJIeJNIAhsgAAoJEPmJouXJPFcAFl8D/i5vkJOc | |||
O/x3ANfQE/tod4DVo1f5+oEULBZOrq03M3bBAQOqe41hvlmrLjr0gTcKAwBp70w4 | |||
iu/YXdirZTx9eTRMhnMS7HRJE2Aeui2eE3adDQV0hl7MouOgdWidIAQC3H+sNwT2 | |||
rvqbxAg5UkH8u6UUGuMmtbOteaHArPDrujg5uI4ESHiTVgEEANRz9ivIoA1WSH+4 | |||
Sr8QhhFMn/SUit/o403tAhCkIRJszvzIfelTLQzv17jBgNiVsnxtOtY+dIJLFfWS | |||
cJohYlTEnLjeZeeA8abQUMjXpuKc0jUxspaHes3ywB/dcTAUZcsKxLboVT/X9S6j | |||
99ErdM4Map9KOVgAzPGZLNgxLcq9ACCUGpzdiJ8EGAECAAkFAkh4k1YCGwwACgkQ | |||
+Ymi5ck8VwBjxAQAhdcrZG0Q4LIk0d1RewO5dGua4XjqwyyhYuzHjs2X3Bel62bW | |||
oK46DpretsNxnP80m79leHQOJalTAW2jMU6KGdLvlGaaaaZ0aAcxzeRltBsBWwe8 | |||
9TdzBiO/eMiU4XB3PW+cjsc/gN/T4+hcbculNFB9skt7ODV4JHu6EZdSLmO5AaIE | |||
SHm3yBEEALKRSNJ7OcgSRHAEDGLj0KZuy2PxMoCtUl4dPkdnWlcGe57j6l6PE5aW | |||
jK6lxKQ10i7J4KM5kOt4nudWCmxD4SzSiZx7O7md4PgLypzDG3nDvPImS0Yu3G+S | |||
g1oZ5bksqjd77X6f/OuGUl3/gOpo6IejlaMy21ixeRPR/8ZMl/OjAKDLontnXlp0 | |||
y39oOJx+tQ8iWIzzuQP+NOqKnaO3aHnRE+Balyw/TpBpX5NnufgCFr0Psejf2fQz | |||
xTbPpny7CsmMbMJlPHXE+OZ8mSy8mdryUIFy8C9bwPe/6iSsv5rnZ6JWJ2oRc8qC | |||
fI38oSepEHTtHz9PhgaN8RNCqVyomuzXZmfkrcIVitsq3KVFTw8HhBA1Y/mHFjME | |||
AIW1VSa0Pxm2eHCCcuieqa8zVtg/dt3qO5bgyyR2qCvA5xuYLrnTRYiOkddw9MQx | |||
Zz5ZB2IGlF2jAyja+zHZqZAO3NiepvZwjo9zhQKzacKP/w94C1R/gL1V54/7p80H | |||
ySRD1JolwBjoYxdKFtDj5HoJ5rC3jTbWY3l1AQQMShJxiO0EGAECAA8FAkh5t8gC | |||
GwIFCQHhM4AAUgkQ+Ymi5ck8VwBHIAQZEQIABgUCSHm3yAAKCRCmAuWryUxvA7AE | |||
AJ9jajPUCTGt3apXlLI18VFpxB8yCACdHKZcZ1JoDN94BVI2Qyt5SJ7RKknmMQQA | |||
k6cWvEftN5Q94VOMjPuFOcrOvnjDGJkh4GgpbfSCLBTkX/nqus9iOMNYjHLL5pUi | |||
jWEfdXJUenPfo58avgTzvDtF1EGoTw8ykzbPUZ1+CmekCt1/NaVSSY8+8HxS2FiE | |||
kZoXlf56ekQOjeoa01Uo+MLc3aLBnFjW1fWAQmocRfC5AaIESHm4zBEEANrn/MA4 | |||
BglSMlASTsCEnVJZ7vQwZYuQfxxCiGsjFckBWY/D4Xm+RB0L4y5bOuqNeAc01sb0 | |||
+2MHpBqE1Zeq0nLFfTBACKH5GUnWB6f4T5P613Yjo3kR17/WSb28FnSQww2sP9gW | |||
oSDoTn1x6iNeXh2waXW9WJQoCZHUDfkT68OrAKC9nE6MeuSPd+PNhAfBcR3S6SOd | |||
hQQAuTmpLKGqx2auUnwDAajM/RuDCS1lNCAku2tHpvqSdDb0xfyLnTNwbjHG/cDX | |||
oZLx9CYEoNkxQmlyUfg91/64xXjskbs7aTRV4tERV24duQnNXrWvQ2bfJeYxWNrV | |||
VqlSeGokL5EYe7AViMwi+uLmDVlHjtxASiWaqqxIVC3dLXEEAK0F7bdFvw3RnPGT | |||
x+JJV/5+L8mbTFdfwvWVXuN8oDkgAu9PkCLcAuPD/ZYsaZDic8MkcMbo5dmbH9+j | |||
Qr8pft0pWJjueAj77zmETGKohqsf6LGRc10FAFF1E9zPFS8hvqdI9TfVBlxdPjwi | |||
pNisGmlYsIUBqnHvrQva5L0sEofziO0EGAECAA8FAkh5uMwCGwIFCQHhM4AAUgkQ | |||
+Ymi5ck8VwBHIAQZEQIABgUCSHm4zAAKCRCOHjXGZ1Q1G9DZAKC9K0qtWQE6CVic | |||
IV659tdM0rZzqgCfaOC25bYAp4ISZBo+HUH6zJy51BDMzAP/TyqD7Fme1lwF2dWT | |||
tWcUInqOwhLX896WaH9Y5NJYe98MNpQxr3wizYOwdJa3t9+MVvH0+s6ih4aaJ49n | |||
71yaef7YVkZ+0gbdKrOOrILwPg4hHizMKKDGbMaJ1OTJbE3PjFhEsdZRy1M1wjzX | |||
Jysr6rop4tOTfXLTX7m5hXkfJ/k= | |||
=soRW | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -17,6 +17,13 @@ | |||
## checkstyle binary distribution. | |||
# checkstyle.home.dir = /home/bart/stuff/checkstyle-4.0-beta6 | |||
## Path to the java 1.4 runtime libary (rt.jar on most systems) | |||
## On OS X this is /System/Library/Frameworks/JavaVM.framework/Versions/1.4/Classes/classes.jar | |||
#java14.rt.lib=/opt/j2re1.4.2_07/lib/rt.jar | |||
## Path to the java 1.4 jce libary (jce.jar on most systems) | |||
## On OS X this is /System/Library/Frameworks/JavaVM.framework/Versions/1.4/Classes/jce.jar | |||
#java14.jce.lib=/opt/j2re1.4.2_07/lib/jce.jar | |||
## =================================================================== | |||
## 2. Switches for common tasks | |||
@@ -44,4 +51,4 @@ | |||
## Specify an alternate directory to scan for user supplied | |||
## hyphenation pattern files. | |||
# user.hyph.dir = /home/bart/offo | |||
# user.hyph.dir = /home/bart/offo |
@@ -459,15 +459,31 @@ list of possible build targets. | |||
</manifest> | |||
</jar> | |||
</target> | |||
<target name="retro" depends="compile"> | |||
<!-- | |||
<target name="retro-unavail" unless="java14.rt.lib"> | |||
<echo message="Please set the path to a JDK 1.4 installation in your build-local.properties" /> | |||
<echo message="to allow for verification!" /> | |||
</target> | |||
<target name="retro-avail" depends="compile" if="java14.rt.lib"> | |||
<taskdef name="retroweaver" classname="net.sourceforge.retroweaver.ant.RetroWeaverTask"> | |||
<classpath> | |||
<path refid="libs-build-classpath"/> | |||
<path refid="libs-build-tools-classpath"/> | |||
</classpath> | |||
</taskdef> | |||
RetroWeaver will be added here --> | |||
<path id="verify-classpath"> | |||
<pathelement location="${java14.rt.lib}"/> | |||
<pathelement location="${java14.jce.lib}"/> | |||
<pathelement location="${ant.home}/lib/ant.jar"/> | |||
<path refid="libs-build-classpath"/> | |||
</path> | |||
<!-- If we decide to use retroweaver for the actual weaving, the mkdir and | |||
destdir= will have to be removed. Also, the weaving task would additionally | |||
need to be defined even if no jdk 14 is available. --> | |||
<mkdir dir="${build.dir}/temp"/> | |||
<retroweaver srcdir="${build.classes.dir}" destdir="${build.dir}/temp" | |||
classpathref="verify-classpath" lazy="false" | |||
verify="true" target="1.4" /> | |||
</target> | |||
<target name="retro" depends="retro-avail,retro-unavail,compile"> | |||
</target> | |||
<!-- =================================================================== --> | |||
<!-- main FOP JARs --> | |||
@@ -538,9 +554,6 @@ RetroWeaver will be added here --> | |||
<fileset dir="${src.java.dir}"> | |||
<patternset refid="java-only"/> | |||
</fileset> | |||
<fileset dir="${src.java.version.dir}"> | |||
<patternset refid="java-only"/> | |||
</fileset> | |||
<fileset dir="${basedir}"> | |||
<include name="LICENSE"/> | |||
<include name="NOTICE"/> | |||
@@ -589,6 +602,7 @@ RetroWeaver will be added here --> | |||
<include name="org/apache/fop/util/SubInputStream.class"/> | |||
<include name="org/apache/fop/util/Finalizable.class"/> | |||
<include name="org/apache/fop/util/CharUtilities.class"/> | |||
<include name="org/apache/fop/util/DecimalFormatCache*.class"/> | |||
</patternset> | |||
<!-- PDF transcoder --> | |||
<patternset> |
@@ -1,20 +1,4 @@ | |||
<?xml version="1.0"?> | |||
<!-- | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
--> | |||
<!-- $Id$ --> | |||
<!-- |
@@ -81,4 +81,4 @@ if "%JAVACMD%" == "" set JAVACMD=java | |||
:runFop | |||
rem ECHO "%JAVACMD%" | |||
"%JAVACMD%" %JAVAOPTS% %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS% | |||
"%JAVACMD%" %JAVAOPTS% %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" %FOP_OPTS% org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS% |
@@ -70,6 +70,6 @@ if "%JAVACMD%" == "" set JAVACMD=java | |||
:runFop | |||
rem echo "%JAVACMD%" %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS% | |||
"%JAVACMD%" %JAVAOPTS% %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS% | |||
"%JAVACMD%" %JAVAOPTS% %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" %FOP_OPTS% org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS% | |||
ENDLOCAL |
@@ -1,28 +1,38 @@ | |||
# redirect moved files | |||
RedirectMatch Permanent ^/fop/anttask(.*) http://xmlgraphics.apache.org/fop/0.94/anttask$1 | |||
RedirectMatch Permanent ^/fop/compiling(.*) http://xmlgraphics.apache.org/fop/0.94/compiling$1 | |||
RedirectMatch Permanent ^/fop/configuration(.*) http://xmlgraphics.apache.org/fop/0.94/configuration$1 | |||
RedirectMatch Permanent ^/fop/embedding(.*) http://xmlgraphics.apache.org/fop/0.94/embedding$1 | |||
RedirectMatch Permanent ^/fop/extensions(.*) http://xmlgraphics.apache.org/fop/0.94/extensions$1 | |||
RedirectMatch Permanent ^/fop/fonts(.*) http://xmlgraphics.apache.org/fop/0.94/fonts$1 | |||
RedirectMatch Permanent ^/fop/graphics(.*) http://xmlgraphics.apache.org/fop/0.94/graphics$1 | |||
RedirectMatch Permanent ^/fop/hyphenation(.*) http://xmlgraphics.apache.org/fop/0.94/hyphenation$1 | |||
RedirectMatch Permanent ^/fop/intermediate(.*) http://xmlgraphics.apache.org/fop/0.94/intermediate$1 | |||
RedirectMatch Permanent ^/fop/output(.*) http://xmlgraphics.apache.org/fop/0.94/output$1 | |||
RedirectMatch Permanent ^/fop/pdfa(.*) http://xmlgraphics.apache.org/fop/0.94/pdfa$1 | |||
RedirectMatch Permanent ^/fop/pdfencryption(.*) http://xmlgraphics.apache.org/fop/0.94/pdfencryption$1 | |||
RedirectMatch Permanent ^/fop/pdfx(.*) http://xmlgraphics.apache.org/fop/0.94/pdfx$1 | |||
RedirectMatch Permanent ^/fop/running(.*) http://xmlgraphics.apache.org/fop/0.94/running$1 | |||
RedirectMatch Permanent ^/fop/servlets(.*) http://xmlgraphics.apache.org/fop/0.94/servlets$1 | |||
RedirectMatch Permanent ^/fop/upgrading(.*) http://xmlgraphics.apache.org/fop/0.94/upgrading$1 | |||
RedirectMatch Permanent ^/fop/anttask(.*) http://xmlgraphics.apache.org/fop/0.95/anttask$1 | |||
RedirectMatch Permanent ^/fop/compiling(.*) http://xmlgraphics.apache.org/fop/0.95/compiling$1 | |||
RedirectMatch Permanent ^/fop/configuration(.*) http://xmlgraphics.apache.org/fop/0.95/configuration$1 | |||
RedirectMatch Permanent ^/fop/embedding(.*) http://xmlgraphics.apache.org/fop/0.95/embedding$1 | |||
RedirectMatch Permanent ^/fop/extensions(.*) http://xmlgraphics.apache.org/fop/0.95/extensions$1 | |||
RedirectMatch Permanent ^/fop/fonts(.*) http://xmlgraphics.apache.org/fop/0.95/fonts$1 | |||
RedirectMatch Permanent ^/fop/graphics(.*) http://xmlgraphics.apache.org/fop/0.95/graphics$1 | |||
RedirectMatch Permanent ^/fop/hyphenation(.*) http://xmlgraphics.apache.org/fop/0.95/hyphenation$1 | |||
RedirectMatch Permanent ^/fop/intermediate(.*) http://xmlgraphics.apache.org/fop/0.95/intermediate$1 | |||
RedirectMatch Permanent ^/fop/output(.*) http://xmlgraphics.apache.org/fop/0.95/output$1 | |||
RedirectMatch Permanent ^/fop/pdfa(.*) http://xmlgraphics.apache.org/fop/0.95/pdfa$1 | |||
RedirectMatch Permanent ^/fop/pdfencryption(.*) http://xmlgraphics.apache.org/fop/0.95/pdfencryption$1 | |||
RedirectMatch Permanent ^/fop/pdfx(.*) http://xmlgraphics.apache.org/fop/0.95/pdfx$1 | |||
RedirectMatch Permanent ^/fop/running(.*) http://xmlgraphics.apache.org/fop/0.95/running$1 | |||
RedirectMatch Permanent ^/fop/servlets(.*) http://xmlgraphics.apache.org/fop/0.95/servlets$1 | |||
RedirectMatch Permanent ^/fop/upgrading(.*) http://xmlgraphics.apache.org/fop/0.95/upgrading$1 | |||
# redirect to versioned documentation | |||
Redirect Temp /fop/stable http://xmlgraphics.apache.org/fop/0.94 | |||
# Current stable release | |||
Redirect Temp /fop/stable http://xmlgraphics.apache.org/fop/0.95 | |||
# Current unstable release (or trunk if no beta is the latest release) | |||
Redirect Temp /fop/unstable http://xmlgraphics.apache.org/fop/trunk | |||
# Latest release | |||
Redirect Temp /fop/current http://xmlgraphics.apache.org/fop/0.95 | |||
Redirect Temp /fop/unstable http://xmlgraphics.apache.org/fop/0.95 | |||
Redirect Temp /fop/latest http://xmlgraphics.apache.org/fop/trunk | |||
Redirect Temp /fop/maintenance http://xmlgraphics.apache.org/fop/0.93 | |||
Redirect Temp /fop/previous http://xmlgraphics.apache.org/fop/0.93 | |||
Redirect Temp /fop/0.90alpha1 http://xmlgraphics.apache.org/fop/0.93 | |||
Redirect Temp /fop/0.91beta http://xmlgraphics.apache.org/fop/0.93 | |||
Redirect Temp /fop/0.92beta http://xmlgraphics.apache.org/fop/0.93 | |||
Redirect Temp /fop/latest http://xmlgraphics.apache.org/fop/0.95 | |||
# Previous stable release | |||
Redirect Temp /fop/previous http://xmlgraphics.apache.org/fop/0.94 | |||
# Old releases | |||
Redirect Temp /fop/maintenance http://xmlgraphics.apache.org/fop/0.94 | |||
Redirect Temp /fop/0.90alpha1 http://xmlgraphics.apache.org/fop/0.94 | |||
Redirect Temp /fop/0.91beta http://xmlgraphics.apache.org/fop/0.94 | |||
Redirect Temp /fop/0.92beta http://xmlgraphics.apache.org/fop/0.94 | |||
Redirect Temp /fop/0.93 http://xmlgraphics.apache.org/fop/0.94 |
@@ -48,7 +48,7 @@ | |||
<p> | |||
By convention, FO extensions in FOP use the "fox" namespace prefix. | |||
To use any of the FO extensions, add a namespace entry for | |||
<code>http://xml.apache.org/fop/extensions</code> to the root element: | |||
<code>http://xmlgraphics.apache.org/fop/extensions</code> to the root element: | |||
</p> | |||
<source><![CDATA[<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" | |||
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">]]></source> |
@@ -48,7 +48,7 @@ | |||
<p> | |||
By convention, FO extensions in FOP use the "fox" namespace prefix. | |||
To use any of the FO extensions, add a namespace entry for | |||
<code>http://xml.apache.org/fop/extensions</code> to the root element: | |||
<code>http://xmlgraphics.apache.org/fop/extensions</code> to the root element: | |||
</p> | |||
<source><![CDATA[<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" | |||
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">]]></source> |
@@ -0,0 +1,243 @@ | |||
<?xml version="1.0" standalone="no"?> | |||
<!-- | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
--> | |||
<!-- $Id$ --> | |||
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "document-v20.dtd"> | |||
<document> | |||
<header> | |||
<title>Metadata</title> | |||
</header> | |||
<body> | |||
<section id="overview"> | |||
<title>Overview</title> | |||
<p> | |||
Document metadata is an important tool for categorizing and finding documents. | |||
Various formats support different kinds of metadata representation and to | |||
different levels. One of the more popular and flexible means of representing | |||
document or object metadata is | |||
<a href="http://www.adobe.com/products/xmp/">XMP (eXtensible Metadata Platform, specified by Adobe)</a>. | |||
PDF 1.4 introduced the use of XMP. The XMP specification lists recommendation for | |||
embedding XMP metdata in other document and image formats. Given its flexibility it makes | |||
sense to make use this approach in the XSL-FO context. Unfortunately, unlike SVG which | |||
also refers to XMP, XSL-FO doesn't recommend a preferred way of specifying document and | |||
object metadata. Therefore, there's no portable way to represent metadata in XSL-FO | |||
documents. Each implementation does it differently. | |||
</p> | |||
</section> | |||
<section id="xmp-in-fo"> | |||
<title>Embedding XMP in an XSL-FO document</title> | |||
<p> | |||
As noted above, there's no officially recommended way to embed metadata in XSL-FO. | |||
Apache FOP supports embedding XMP in XSL-FO. Currently, only support for document-level | |||
metadata is implemented. Object-level metadata will be implemented when there's | |||
interest. | |||
</p> | |||
<p> | |||
Document-level metadata can be specified in the <code>fo:declarations</code> element. | |||
XMP specification recommends to use <code>x:xmpmeta</code>, <code>rdf:RDF</code>, and | |||
<code>rdf:Description</code> elements as shown in example below. Both | |||
<code>x:xmpmeta</code> and <code>rdf:RDF</code> elements are recognized as the top-level | |||
element introducing an XMP fragment (as per the XMP specification). | |||
</p> | |||
<section id="xmp-example"> | |||
<title>Example</title> | |||
<source><![CDATA[[..] | |||
</fo:layout-master-set> | |||
<fo:declarations> | |||
<x:xmpmeta xmlns:x="adobe:ns:meta/"> | |||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> | |||
<rdf:Description rdf:about="" | |||
xmlns:dc="http://purl.org/dc/elements/1.1/"> | |||
<!-- Dublin Core properties go here --> | |||
<dc:title>Document title</dc:title> | |||
<dc:creator>Document author</dc:creator> | |||
<dc:description>Document subject</dc:description> | |||
</rdf:Description> | |||
<rdf:Description rdf:about="" | |||
xmlns:xmp="http://ns.adobe.com/xap/1.0/"> | |||
<!-- XMP properties go here --> | |||
<xmp:CreatorTool>Tool used to make the PDF</xmp:CreatorTool> | |||
</rdf:Description> | |||
</rdf:RDF> | |||
</x:xmpmeta> | |||
</fo:declarations> | |||
<fo:page-sequence ... | |||
[..]]]></source> | |||
<note> | |||
<code>fo:declarations</code> <strong>must</strong> be declared after | |||
<code>fo:layout-master-set</code> and before the first <code>page-sequence</code>. | |||
</note> | |||
</section> | |||
</section> | |||
<section id="xmp-impl-in-fop"> | |||
<title>Implementation in Apache FOP</title> | |||
<p> | |||
Currently, XMP support is only available for PDF output. | |||
</p> | |||
<p> | |||
Originally, you could set some metadata information through FOP's FOUserAgent by | |||
using its set*() methods (like setTitle(String) or setAuthor(String). These values are | |||
directly used to set value in the PDF Info object. Since PDF 1.4, adding metadata as an | |||
XMP document to a PDF is possible. That means that there are now two mechanisms in PDF | |||
that hold metadata. | |||
</p> | |||
<p> | |||
Apache FOP now synchronizes the Info and the Metadata object in PDF, i.e. when you | |||
set the title and the author through the FOUserAgent, the two values will end up in | |||
the (old) Info object and in the new Metadata object as XMP content. If instead of | |||
FOUserAgent, you embed XMP metadata in the XSL-FO document (as shown above), the | |||
XMP metadata will be used as-is in the PDF Metadata object and some values from the | |||
XMP metadata will be copied to the Info object to maintain backwards-compatibility | |||
for PDF readers that don't support XMP metadata. | |||
</p> | |||
<p> | |||
The mapping between the Info and the Metadata object used by Apache FOP comes from | |||
the <a href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=38920">PDF/A-1 specification</a>. | |||
For convenience, here's the mapping table: | |||
</p> | |||
<table> | |||
<tr> | |||
<th colspan="2">Document information dictionary</th> | |||
<th colspan="3">XMP</th> | |||
</tr> | |||
<tr> | |||
<th>Entry</th> | |||
<th>PDF type</th> | |||
<th>Property</th> | |||
<th>XMP type</th> | |||
<th>Category</th> | |||
</tr> | |||
<tr> | |||
<td>Title</td> | |||
<td>text string</td> | |||
<td>dc:title</td> | |||
<td>Text</td> | |||
<td>External</td> | |||
</tr> | |||
<tr> | |||
<td>Author</td> | |||
<td>text string</td> | |||
<td>dc:creator</td> | |||
<td>seq Text</td> | |||
<td>External</td> | |||
</tr> | |||
<tr> | |||
<td>Subject</td> | |||
<td>text string</td> | |||
<td>dc:description["x-default"]</td> | |||
<td>Text</td> | |||
<td>External</td> | |||
</tr> | |||
<tr> | |||
<td>Keywords</td> | |||
<td>text string</td> | |||
<td>pdf:Keywords</td> | |||
<td>Text</td> | |||
<td>External</td> | |||
</tr> | |||
<tr> | |||
<td>Creator</td> | |||
<td>text string</td> | |||
<td>xmp:CreatorTool</td> | |||
<td>Text</td> | |||
<td>External</td> | |||
</tr> | |||
<tr> | |||
<td>Producer</td> | |||
<td>text string</td> | |||
<td>pdf:Producer</td> | |||
<td>Text</td> | |||
<td>Internal</td> | |||
</tr> | |||
<tr> | |||
<td>CreationDate</td> | |||
<td>date</td> | |||
<td>xmp:CreationDate</td> | |||
<td>Date</td> | |||
<td>Internal</td> | |||
</tr> | |||
<tr> | |||
<td>ModDate</td> | |||
<td>date</td> | |||
<td>xmp:ModifyDate</td> | |||
<td>Date</td> | |||
<td>Internal</td> | |||
</tr> | |||
</table> | |||
<note> | |||
"Internal" in the Category column means that the user should not set this value. | |||
It is set by the application. | |||
</note> | |||
<note> | |||
The "Subject" used to be mapped to <code>dc:subject</code> in the initial publication of | |||
PDF/A-1 (ISO 19005-1). In the | |||
<a href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=45613">Technical Corrigendum 1</a> | |||
this was changed to map to <code>dc:description["x-default"]</code>. | |||
</note> | |||
<section id="namespaces"> | |||
<title>Namespaces</title> | |||
<p> | |||
Metadata is made of property sets where each property set uses a different namespace URI. | |||
</p> | |||
<p> | |||
The following is a listing of namespaces that Apache FOP recognizes and acts upon, | |||
mostly to synchronize the XMP metadata with the PDF Info dictionary: | |||
</p> | |||
<table> | |||
<tr> | |||
<th>Set/Schema</th> | |||
<th>Namespace Prefix</th> | |||
<th>Namespace URI</th> | |||
</tr> | |||
<tr> | |||
<td>Dublin Core</td> | |||
<td>dc</td> | |||
<td>http://purl.org/dc/elements/1.1/</td> | |||
</tr> | |||
<tr> | |||
<td>XMP Basic</td> | |||
<td>xmp</td> | |||
<td>http://ns.adobe.com/xap/1.0/</td> | |||
</tr> | |||
<tr> | |||
<td>Adobe PDF Schema</td> | |||
<td>pdf</td> | |||
<td>http://ns.adobe.com/pdf/1.3/</td> | |||
</tr> | |||
</table> | |||
<p> | |||
Please refer to the <a href="http://partners.adobe.com/public/developer/en/xmp/sdk/XMPspecification.pdf">XMP Specification</a> | |||
for information on other metadata namespaces. | |||
</p> | |||
<p> | |||
Property sets (Namespaces) not listed here are simply passed through to the final | |||
document (if supported). That is useful if you want to specify a custom metadata | |||
schema. | |||
</p> | |||
</section> | |||
</section> | |||
<section id="links"> | |||
<title>Links</title> | |||
<ul> | |||
<li><a href="http://www.adobe.com/products/xmp/">Adobe's Extensible Metadata Platform (XMP) website</a></li> | |||
<li><a href="http://partners.adobe.com/public/developer/en/xmp/sdk/XMPspecification.pdf">Adobe XMP Specification</a></li> | |||
<li><a href="http://partners.adobe.com/public/developer/en/xmp/sdk/XMPspecification.pdf">Adobe XMP Specification</a></li> | |||
<li><a href="http://dublincore.org/">http://dublincore.org/</a></li> | |||
</ul> | |||
</section> | |||
</body> | |||
</document> |
@@ -28,9 +28,6 @@ | |||
<body> | |||
<section id="overview"> | |||
<title>Overview</title> | |||
<warning> | |||
Support for PDF/A is available beginning with version 0.92. | |||
</warning> | |||
<p> | |||
PDF/A is a standard which turns PDF into an "electronic document file | |||
format for long-term preservation". PDF/A-1 is the first part of the |
@@ -385,6 +385,47 @@ | |||
</p> | |||
</answer> | |||
</faq> | |||
<faq id="saxexception-mismatch"> | |||
<question>I get a SAXException: Mismatch: page-sequence vs. root | |||
(or similar).</question> | |||
<answer> | |||
<p> | |||
The full exception usually looks similar to this: | |||
</p> | |||
<source>Mismatch: page-sequence (http://www.w3.org/1999/XSL/Format) vs. root | |||
(http://www.w3.org/1999/XSL/Format)</source> | |||
<p> | |||
This exception is usually a follow-up error after another exception. Sometimes | |||
the original exception gets swallowed by Xalan's default <code>ErrorListener</code> | |||
(should be fixed in the latest Xalan release). | |||
</p> | |||
<p> | |||
The work-around is to set an explicit <code>ErrorListener</code> on the | |||
<code>Transformer</code>. The <code>ErrorListener</code> can be as simple as this: | |||
</p> | |||
<source><![CDATA[ | |||
import javax.xml.transform.ErrorListener; | |||
import javax.xml.transform.TransformerException; | |||
public class DefaultErrorListener implements ErrorListener { | |||
public void warning(TransformerException exc) { | |||
System.err.println(exc.toString()); | |||
} | |||
public void error(TransformerException exc) | |||
throws TransformerException { | |||
throw exc; | |||
} | |||
public void fatalError(TransformerException exc) | |||
throws TransformerException { | |||
throw exc; | |||
} | |||
}]]></source> | |||
</answer> | |||
</faq> | |||
</part> | |||
<part id="part-output"> | |||
<title>Problems with FOP output</title> | |||
@@ -551,8 +592,10 @@ Check the following:</p> | |||
text flows into adjacent cells/block, obscuring stuff there.</question> | |||
<answer> | |||
<p> | |||
Clipping as specified by the <code>overflow="hidden"</code> is not yet | |||
implemented. If you have long words overflowing table cells, try to | |||
Since the <code>overflow</code> property doesn't apply to table-cell, you | |||
can wrap the cell content in a block-container and specify | |||
<code>overflow="hidden"</code> there. Alternatively, | |||
if you have long words overflowing table cells, try to | |||
get them hyphenated. Artificial names like product identifications or | |||
long numbers usually aren't hyphenated. You can try special processing | |||
at XSLT level, like | |||
@@ -574,6 +617,15 @@ Check the following:</p> | |||
<link href="http://www.mulberrytech.com/xsl/xsl-list/">XSL list | |||
archive</link> for how to perform these tasks. | |||
</p> | |||
<p> | |||
If your text is not hyphenated at all and overflows the cell, please check | |||
if you've specified <code>keep-together="always"</code> on the table-cell | |||
or one of its parent elements. <code>keep-together="always"</code> implicitely | |||
also sets <code>keep-together.within-line="always"</code> which forbids FOP | |||
to break the text into multiple lines. This is important as FOP supports inline-level | |||
keeps since version 0.94. It's a good idea not to use the shorthand | |||
<code>keep-together="always"</code> at all! | |||
</p> | |||
</answer> | |||
</faq> | |||
<faq id="row-height-constraint"> |
@@ -123,6 +123,7 @@ | |||
<fonts label="Fonts" href="fonts.html"/> | |||
<hyphenation label="Hyphenation" href="hyphenation.html"/> | |||
<extensions label="Extensions" href="extensions.html"/> | |||
<metadata label="Metadata" href="metadata.html"/> | |||
</features> | |||
</trunk> | |||
@@ -157,6 +158,7 @@ | |||
<hyphenation label="Hyphenation" href="hyphenation.html"/> | |||
<extensions label="Extensions" href="extensions.html"/> | |||
<events label="Events" href="events.html"/> | |||
<metadata label="Metadata" href="metadata.html"/> | |||
</features> | |||
</trunk> |
@@ -48,7 +48,7 @@ | |||
<p> | |||
By convention, FO extensions in FOP use the "fox" namespace prefix. | |||
To use any of the FO extensions, add a namespace entry for | |||
<code>http://xml.apache.org/fop/extensions</code> to the root element: | |||
<code>http://xmlgraphics.apache.org/fop/extensions</code> to the root element: | |||
</p> | |||
<source><![CDATA[<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" | |||
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">]]></source> |
@@ -0,0 +1,243 @@ | |||
<?xml version="1.0" standalone="no"?> | |||
<!-- | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
--> | |||
<!-- $Id$ --> | |||
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "document-v20.dtd"> | |||
<document> | |||
<header> | |||
<title>Metadata</title> | |||
</header> | |||
<body> | |||
<section id="overview"> | |||
<title>Overview</title> | |||
<p> | |||
Document metadata is an important tool for categorizing and finding documents. | |||
Various formats support different kinds of metadata representation and to | |||
different levels. One of the more popular and flexible means of representing | |||
document or object metadata is | |||
<a href="http://www.adobe.com/products/xmp/">XMP (eXtensible Metadata Platform, specified by Adobe)</a>. | |||
PDF 1.4 introduced the use of XMP. The XMP specification lists recommendation for | |||
embedding XMP metdata in other document and image formats. Given its flexibility it makes | |||
sense to make use this approach in the XSL-FO context. Unfortunately, unlike SVG which | |||
also refers to XMP, XSL-FO doesn't recommend a preferred way of specifying document and | |||
object metadata. Therefore, there's no portable way to represent metadata in XSL-FO | |||
documents. Each implementation does it differently. | |||
</p> | |||
</section> | |||
<section id="xmp-in-fo"> | |||
<title>Embedding XMP in an XSL-FO document</title> | |||
<p> | |||
As noted above, there's no officially recommended way to embed metadata in XSL-FO. | |||
Apache FOP supports embedding XMP in XSL-FO. Currently, only support for document-level | |||
metadata is implemented. Object-level metadata will be implemented when there's | |||
interest. | |||
</p> | |||
<p> | |||
Document-level metadata can be specified in the <code>fo:declarations</code> element. | |||
XMP specification recommends to use <code>x:xmpmeta</code>, <code>rdf:RDF</code>, and | |||
<code>rdf:Description</code> elements as shown in example below. Both | |||
<code>x:xmpmeta</code> and <code>rdf:RDF</code> elements are recognized as the top-level | |||
element introducing an XMP fragment (as per the XMP specification). | |||
</p> | |||
<section id="xmp-example"> | |||
<title>Example</title> | |||
<source><![CDATA[[..] | |||
</fo:layout-master-set> | |||
<fo:declarations> | |||
<x:xmpmeta xmlns:x="adobe:ns:meta/"> | |||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> | |||
<rdf:Description rdf:about="" | |||
xmlns:dc="http://purl.org/dc/elements/1.1/"> | |||
<!-- Dublin Core properties go here --> | |||
<dc:title>Document title</dc:title> | |||
<dc:creator>Document author</dc:creator> | |||
<dc:description>Document subject</dc:description> | |||
</rdf:Description> | |||
<rdf:Description rdf:about="" | |||
xmlns:xmp="http://ns.adobe.com/xap/1.0/"> | |||
<!-- XMP properties go here --> | |||
<xmp:CreatorTool>Tool used to make the PDF</xmp:CreatorTool> | |||
</rdf:Description> | |||
</rdf:RDF> | |||
</x:xmpmeta> | |||
</fo:declarations> | |||
<fo:page-sequence ... | |||
[..]]]></source> | |||
<note> | |||
<code>fo:declarations</code> <strong>must</strong> be declared after | |||
<code>fo:layout-master-set</code> and before the first <code>page-sequence</code>. | |||
</note> | |||
</section> | |||
</section> | |||
<section id="xmp-impl-in-fop"> | |||
<title>Implementation in Apache FOP</title> | |||
<p> | |||
Currently, XMP support is only available for PDF output. | |||
</p> | |||
<p> | |||
Originally, you could set some metadata information through FOP's FOUserAgent by | |||
using its set*() methods (like setTitle(String) or setAuthor(String). These values are | |||
directly used to set value in the PDF Info object. Since PDF 1.4, adding metadata as an | |||
XMP document to a PDF is possible. That means that there are now two mechanisms in PDF | |||
that hold metadata. | |||
</p> | |||
<p> | |||
Apache FOP now synchronizes the Info and the Metadata object in PDF, i.e. when you | |||
set the title and the author through the FOUserAgent, the two values will end up in | |||
the (old) Info object and in the new Metadata object as XMP content. If instead of | |||
FOUserAgent, you embed XMP metadata in the XSL-FO document (as shown above), the | |||
XMP metadata will be used as-is in the PDF Metadata object and some values from the | |||
XMP metadata will be copied to the Info object to maintain backwards-compatibility | |||
for PDF readers that don't support XMP metadata. | |||
</p> | |||
<p> | |||
The mapping between the Info and the Metadata object used by Apache FOP comes from | |||
the <a href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=38920">PDF/A-1 specification</a>. | |||
For convenience, here's the mapping table: | |||
</p> | |||
<table> | |||
<tr> | |||
<th colspan="2">Document information dictionary</th> | |||
<th colspan="3">XMP</th> | |||
</tr> | |||
<tr> | |||
<th>Entry</th> | |||
<th>PDF type</th> | |||
<th>Property</th> | |||
<th>XMP type</th> | |||
<th>Category</th> | |||
</tr> | |||
<tr> | |||
<td>Title</td> | |||
<td>text string</td> | |||
<td>dc:title</td> | |||
<td>Text</td> | |||
<td>External</td> | |||
</tr> | |||
<tr> | |||
<td>Author</td> | |||
<td>text string</td> | |||
<td>dc:creator</td> | |||
<td>seq Text</td> | |||
<td>External</td> | |||
</tr> | |||
<tr> | |||
<td>Subject</td> | |||
<td>text string</td> | |||
<td>dc:description["x-default"]</td> | |||
<td>Text</td> | |||
<td>External</td> | |||
</tr> | |||
<tr> | |||
<td>Keywords</td> | |||
<td>text string</td> | |||
<td>pdf:Keywords</td> | |||
<td>Text</td> | |||
<td>External</td> | |||
</tr> | |||
<tr> | |||
<td>Creator</td> | |||
<td>text string</td> | |||
<td>xmp:CreatorTool</td> | |||
<td>Text</td> | |||
<td>External</td> | |||
</tr> | |||
<tr> | |||
<td>Producer</td> | |||
<td>text string</td> | |||
<td>pdf:Producer</td> | |||
<td>Text</td> | |||
<td>Internal</td> | |||
</tr> | |||
<tr> | |||
<td>CreationDate</td> | |||
<td>date</td> | |||
<td>xmp:CreationDate</td> | |||
<td>Date</td> | |||
<td>Internal</td> | |||
</tr> | |||
<tr> | |||
<td>ModDate</td> | |||
<td>date</td> | |||
<td>xmp:ModifyDate</td> | |||
<td>Date</td> | |||
<td>Internal</td> | |||
</tr> | |||
</table> | |||
<note> | |||
"Internal" in the Category column means that the user should not set this value. | |||
It is set by the application. | |||
</note> | |||
<note> | |||
The "Subject" used to be mapped to <code>dc:subject</code> in the initial publication of | |||
PDF/A-1 (ISO 19005-1). In the | |||
<a href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=45613">Technical Corrigendum 1</a> | |||
this was changed to map to <code>dc:description["x-default"]</code>. | |||
</note> | |||
<section id="namespaces"> | |||
<title>Namespaces</title> | |||
<p> | |||
Metadata is made of property sets where each property set uses a different namespace URI. | |||
</p> | |||
<p> | |||
The following is a listing of namespaces that Apache FOP recognizes and acts upon, | |||
mostly to synchronize the XMP metadata with the PDF Info dictionary: | |||
</p> | |||
<table> | |||
<tr> | |||
<th>Set/Schema</th> | |||
<th>Namespace Prefix</th> | |||
<th>Namespace URI</th> | |||
</tr> | |||
<tr> | |||
<td>Dublin Core</td> | |||
<td>dc</td> | |||
<td>http://purl.org/dc/elements/1.1/</td> | |||
</tr> | |||
<tr> | |||
<td>XMP Basic</td> | |||
<td>xmp</td> | |||
<td>http://ns.adobe.com/xap/1.0/</td> | |||
</tr> | |||
<tr> | |||
<td>Adobe PDF Schema</td> | |||
<td>pdf</td> | |||
<td>http://ns.adobe.com/pdf/1.3/</td> | |||
</tr> | |||
</table> | |||
<p> | |||
Please refer to the <a href="http://partners.adobe.com/public/developer/en/xmp/sdk/XMPspecification.pdf">XMP Specification</a> | |||
for information on other metadata namespaces. | |||
</p> | |||
<p> | |||
Property sets (Namespaces) not listed here are simply passed through to the final | |||
document (if supported). That is useful if you want to specify a custom metadata | |||
schema. | |||
</p> | |||
</section> | |||
</section> | |||
<section id="links"> | |||
<title>Links</title> | |||
<ul> | |||
<li><a href="http://www.adobe.com/products/xmp/">Adobe's Extensible Metadata Platform (XMP) website</a></li> | |||
<li><a href="http://partners.adobe.com/public/developer/en/xmp/sdk/XMPspecification.pdf">Adobe XMP Specification</a></li> | |||
<li><a href="http://partners.adobe.com/public/developer/en/xmp/sdk/XMPspecification.pdf">Adobe XMP Specification</a></li> | |||
<li><a href="http://dublincore.org/">http://dublincore.org/</a></li> | |||
</ul> | |||
</section> | |||
</body> | |||
</document> |
@@ -28,9 +28,6 @@ | |||
<body> | |||
<section id="overview"> | |||
<title>Overview</title> | |||
<warning> | |||
Support for PDF/A is available beginning with version 0.92. | |||
</warning> | |||
<p> | |||
PDF/A is a standard which turns PDF into an "electronic document file | |||
format for long-term preservation". PDF/A-1 is the first part of the |
@@ -34,14 +34,12 @@ import javax.xml.transform.stream.StreamSource; | |||
import org.apache.commons.logging.Log; | |||
import org.apache.commons.logging.LogFactory; | |||
import org.apache.xmlgraphics.util.io.Base64EncodeStream; | |||
import org.apache.fop.util.DataURIResolver; | |||
import org.apache.xmlgraphics.util.uri.CommonURIResolver; | |||
/** | |||
* Provides FOP specific URI resolution. This is the default URIResolver | |||
* {@link FOUserAgent} will use unless overidden. | |||
* {@link FOUserAgent} will use unless overridden. | |||
* | |||
* @see javax.xml.transform.URIResolver | |||
*/ | |||
@@ -50,8 +48,8 @@ public class FOURIResolver implements javax.xml.transform.URIResolver { | |||
// log | |||
private Log log = LogFactory.getLog("FOP"); | |||
/** URIResolver for RFC 2397 data URLs */ | |||
private URIResolver dataURIResolver = new DataURIResolver(); | |||
/** Common URIResolver */ | |||
private CommonURIResolver commonURIResolver = new CommonURIResolver(); | |||
/** A user settable URI Resolver */ | |||
private URIResolver uriResolver = null; | |||
@@ -152,7 +150,7 @@ public class FOURIResolver implements javax.xml.transform.URIResolver { | |||
// data URLs can be quite long so evaluate early and don't try to build a File | |||
// (can lead to problems) | |||
source = dataURIResolver.resolve(href, base); | |||
source = commonURIResolver.resolve(href, base); | |||
// Custom uri resolution | |||
if (source == null && uriResolver != null) { |
@@ -47,7 +47,7 @@ Any reference to it will be considered a reference to the first occurrence in th | |||
<message key="org.apache.fop.fo.FOValidationEventProducer.flowNameNotMapped">The flow-name "{flowName}" on {elementName} could not be mapped to a region-name in the layout-master-set.{{locator}}</message> | |||
<message key="org.apache.fop.fo.FOValidationEventProducer.masterNotFound">The master-reference "{masterReference}" on {elementName} matches no simple-page-master or page-sequence-master.{{locator}}</message> | |||
<message key="org.apache.fop.fo.FOValidationEventProducer.illegalRegionName">The region-name "{regionName}" for {elementName} is not permitted.{{locator}}</message> | |||
<message key="org.apache.fop.fo.FOValidationEventProducer.nonZeroBorderPaddingOnRegion">Border and padding for {elementName} "{regionName}" must be '0' (See 6.4.13 in XSL 1.0).{{locator}}</message> | |||
<message key="org.apache.fop.fo.FOValidationEventProducer.nonZeroBorderPaddingOnRegion">Border and padding for {elementName} "{regionName}" should be '0' (See 6.4.14 in XSL 1.1); non-standard values are allowed if relaxed validation is enabled. {{locator}}</message> | |||
<message key="org.apache.fop.fo.FOValidationEventProducer.columnCountErrorOnRegionBodyOverflowScroll">If overflow property is set to "scroll" on {elementName}, a column-count other than "1" may not be specified.{{locator}}</message> | |||
<message key="org.apache.fop.fo.FOValidationEventProducer.invalidFORoot">First element must be the fo:root formatting object. Found {elementName} instead. Please make sure you're producing a valid XSL-FO document.</message> | |||
<message key="org.apache.fop.fo.FOValidationEventProducer.emptyDocument">Document is empty (something might be wrong with your XSLT stylesheet).</message> |
@@ -370,8 +370,10 @@ public abstract class PropertyList { | |||
if (attributeValue != null) { | |||
if (attributeName.startsWith("xmlns:")) { | |||
//Ignore namespace declarations | |||
if (attributeName.startsWith("xmlns:") | |||
|| "xmlns".equals(attributeName)) { | |||
//Ignore namespace declarations if the XML parser/XSLT processor | |||
//reports them as 'regular' attributes | |||
return; | |||
} | |||
@@ -519,7 +521,7 @@ public abstract class PropertyList { | |||
} | |||
/** | |||
* @param propID ID of property | |||
* @param propId ID of property | |||
* @return new Property object | |||
* @throws PropertyException if there's a problem while processing the property | |||
*/ | |||
@@ -638,7 +640,6 @@ public abstract class PropertyList { | |||
return new CommonAbsolutePosition(this); | |||
} | |||
/** | |||
* Constructs a CommonFont object. | |||
* |
@@ -228,6 +228,7 @@ public class XMLWhiteSpaceHandler { | |||
nestedBlockStack.pop(); | |||
} | |||
charIter = null; | |||
firstWhiteSpaceInSeq = null; | |||
} | |||
} | |||
} |
@@ -94,61 +94,33 @@ public class ConditionalPageMasterReference extends FObj { | |||
* @param isFirstPage True if page is first page | |||
* @param isLastPage True if page is last page | |||
* @param isBlankPage True if page is blank | |||
* @param isOnlyPage True if page is the only page | |||
* @return True if the conditions for this reference are met | |||
*/ | |||
protected boolean isValid(boolean isOddPage, | |||
boolean isFirstPage, | |||
boolean isLastPage, | |||
boolean isOnlyPage, | |||
boolean isBlankPage) { | |||
// page-position | |||
if (isOnlyPage) { | |||
if (pagePosition != EN_ONLY) { | |||
return false; | |||
} | |||
} else if (isFirstPage) { | |||
if (pagePosition == EN_REST) { | |||
return false; | |||
} else if (pagePosition == EN_LAST) { | |||
return false; | |||
} | |||
} else if (isLastPage) { | |||
if (pagePosition == EN_REST) { | |||
return false; | |||
} else if (pagePosition == EN_FIRST) { | |||
return false; | |||
} | |||
} else { | |||
if (pagePosition == EN_FIRST) { | |||
return false; | |||
} else if (pagePosition == EN_LAST) { | |||
return false; | |||
} | |||
} | |||
// odd-or-even | |||
if (isOddPage) { | |||
if (oddOrEven == EN_EVEN) { | |||
return false; | |||
} | |||
} else { | |||
if (oddOrEven == EN_ODD) { | |||
return false; | |||
} | |||
} | |||
return ( | |||
// page-position | |||
(pagePosition == EN_ANY | |||
|| (pagePosition == EN_FIRST && isFirstPage) | |||
|| (pagePosition == EN_LAST && isLastPage) | |||
|| (pagePosition == EN_ONLY && (isFirstPage && isLastPage)) | |||
|| (pagePosition == EN_REST && !(isFirstPage || isLastPage)) | |||
) | |||
// odd-or-even | |||
&& (oddOrEven == EN_ANY | |||
|| (oddOrEven == EN_ODD && isOddPage) | |||
|| (oddOrEven == EN_EVEN && !isOddPage) | |||
) | |||
// blank-or-not-blank | |||
&& (blankOrNotBlank == EN_ANY | |||
|| (blankOrNotBlank == EN_BLANK && isBlankPage) | |||
|| (blankOrNotBlank == EN_NOT_BLANK && !isBlankPage) | |||
)); | |||
// blank-or-not-blank | |||
if (isBlankPage) { | |||
if (blankOrNotBlank == EN_NOT_BLANK) { | |||
return false; | |||
} | |||
} else { | |||
if (blankOrNotBlank == EN_BLANK) { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
/** |
@@ -127,19 +127,19 @@ public class PageSequence extends AbstractPageSequence { | |||
protected void validateChildNode(Locator loc, String nsURI, String localName) | |||
throws ValidationException { | |||
if (FO_URI.equals(nsURI)) { | |||
if (localName.equals("title")) { | |||
if ("title".equals(localName)) { | |||
if (titleFO != null) { | |||
tooManyNodesError(loc, "fo:title"); | |||
} else if (flowMap.size() > 0) { | |||
} else if (!flowMap.isEmpty()) { | |||
nodesOutOfOrderError(loc, "fo:title", "fo:static-content"); | |||
} else if (mainFlow != null) { | |||
nodesOutOfOrderError(loc, "fo:title", "fo:flow"); | |||
} | |||
} else if (localName.equals("static-content")) { | |||
} else if ("static-content".equals(localName)) { | |||
if (mainFlow != null) { | |||
nodesOutOfOrderError(loc, "fo:static-content", "fo:flow"); | |||
} | |||
} else if (localName.equals("flow")) { | |||
} else if ("flow".equals(localName)) { | |||
if (mainFlow != null) { | |||
tooManyNodesError(loc, "fo:flow"); | |||
} | |||
@@ -157,15 +157,20 @@ public class PageSequence extends AbstractPageSequence { | |||
public void addChildNode(FONode child) throws FOPException { | |||
int childId = child.getNameId(); | |||
if (childId == FO_TITLE) { | |||
this.titleFO = (Title) child; | |||
} else if (childId == FO_FLOW) { | |||
this.mainFlow = (Flow) child; | |||
switch (childId) { | |||
case FO_TITLE: | |||
this.titleFO = (Title)child; | |||
break; | |||
case FO_FLOW: | |||
this.mainFlow = (Flow)child; | |||
addFlow(mainFlow); | |||
} else if (childId == FO_STATIC_CONTENT) { | |||
addFlow((StaticContent) child); | |||
String flowName = ((StaticContent) child).getFlowName(); | |||
flowMap.put(flowName, child); | |||
break; | |||
case FO_STATIC_CONTENT: | |||
addFlow((StaticContent)child); | |||
flowMap.put(((StaticContent)child).getFlowName(), child); | |||
break; | |||
default: | |||
assert false; | |||
} | |||
} | |||
@@ -245,17 +250,14 @@ public class PageSequence extends AbstractPageSequence { | |||
* page sequence | |||
* @param isLastPage indicator whether this page is the last page of the | |||
* page sequence | |||
* @param isOnlyPage indicator whether this page is the only page of the | |||
* page sequence | |||
* @param isBlank indicator whether the page will be blank | |||
* @return the SimplePageMaster to use for this page | |||
* @throws PageProductionException if there's a problem determining the page master | |||
*/ | |||
public SimplePageMaster getNextSimplePageMaster(int page, | |||
boolean isFirstPage, | |||
boolean isLastPage, | |||
boolean isOnlyPage, | |||
boolean isBlank) throws PageProductionException { | |||
boolean isFirstPage, | |||
boolean isLastPage, | |||
boolean isBlank) throws PageProductionException { | |||
if (pageSequenceMaster == null) { | |||
return simplePageMaster; | |||
@@ -266,11 +268,10 @@ public class PageSequence extends AbstractPageSequence { | |||
+ " isOdd=" + isOddPage | |||
+ " isFirst=" + isFirstPage | |||
+ " isLast=" + isLastPage | |||
+ " isOnly=" + isOnlyPage | |||
+ " isBlank=" + isBlank + ")"); | |||
} | |||
return pageSequenceMaster.getNextSimplePageMaster(isOddPage, | |||
isFirstPage, isLastPage, isOnlyPage, isBlank); | |||
isFirstPage, isLastPage, isBlank); | |||
} | |||
/** | |||
@@ -278,29 +279,17 @@ public class PageSequence extends AbstractPageSequence { | |||
* @return true if there is a previous item, false if the current one was the first one. | |||
*/ | |||
public boolean goToPreviousSimplePageMaster() { | |||
if (pageSequenceMaster == null) { | |||
return true; | |||
} else { | |||
return pageSequenceMaster.goToPreviousSimplePageMaster(); | |||
} | |||
return pageSequenceMaster == null || pageSequenceMaster.goToPreviousSimplePageMaster(); | |||
} | |||
/** @return true if the page-sequence has a page-master with page-position="last" */ | |||
public boolean hasPagePositionLast() { | |||
if (pageSequenceMaster == null) { | |||
return false; | |||
} else { | |||
return pageSequenceMaster.hasPagePositionLast(); | |||
} | |||
return pageSequenceMaster != null && pageSequenceMaster.hasPagePositionLast(); | |||
} | |||
/** @return true if the page-sequence has a page-master with page-position="only" */ | |||
public boolean hasPagePositionOnly() { | |||
if (pageSequenceMaster == null) { | |||
return false; | |||
} else { | |||
return pageSequenceMaster.hasPagePositionOnly(); | |||
} | |||
return pageSequenceMaster != null && pageSequenceMaster.hasPagePositionOnly(); | |||
} | |||
/** |
@@ -177,7 +177,6 @@ public class PageSequenceMaster extends FObj { | |||
* @param isOddPage True if the next page number is odd | |||
* @param isFirstPage True if the next page is the first | |||
* @param isLastPage True if the next page is the last | |||
* @param isOnlyPage True if the next page is the only page | |||
* @param isBlankPage True if the next page is blank | |||
* @return the requested page master | |||
* @throws PageProductionException if there's a problem determining the next page master | |||
@@ -185,7 +184,6 @@ public class PageSequenceMaster extends FObj { | |||
public SimplePageMaster getNextSimplePageMaster(boolean isOddPage, | |||
boolean isFirstPage, | |||
boolean isLastPage, | |||
boolean isOnlyPage, | |||
boolean isBlankPage) | |||
throws PageProductionException { | |||
if (currentSubSequence == null) { | |||
@@ -198,7 +196,7 @@ public class PageSequenceMaster extends FObj { | |||
} | |||
} | |||
String pageMasterName = currentSubSequence | |||
.getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isOnlyPage, isBlankPage); | |||
.getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isBlankPage); | |||
boolean canRecover = true; | |||
while (pageMasterName == null) { | |||
SubSequenceSpecifier nextSubSequence = getNextSubSequence(); | |||
@@ -213,7 +211,7 @@ public class PageSequenceMaster extends FObj { | |||
currentSubSequence = nextSubSequence; | |||
} | |||
pageMasterName = currentSubSequence | |||
.getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isOnlyPage, isBlankPage); | |||
.getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isBlankPage); | |||
} | |||
SimplePageMaster pageMaster = this.layoutMasterSet | |||
.getSimplePageMaster(pageMasterName); |
@@ -117,7 +117,6 @@ public class RepeatablePageMasterAlternatives extends FObj | |||
public String getNextPageMasterName(boolean isOddPage, | |||
boolean isFirstPage, | |||
boolean isLastPage, | |||
boolean isOnlyPage, | |||
boolean isBlankPage) { | |||
if (getMaximumRepeats() != INFINITE) { | |||
if (numberConsumed < getMaximumRepeats()) { | |||
@@ -132,7 +131,7 @@ public class RepeatablePageMasterAlternatives extends FObj | |||
for (int i = 0; i < conditionalPageMasterRefs.size(); i++) { | |||
ConditionalPageMasterReference cpmr | |||
= (ConditionalPageMasterReference)conditionalPageMasterRefs.get(i); | |||
if (cpmr.isValid(isOddPage, isFirstPage, isLastPage, isOnlyPage, isBlankPage)) { | |||
if (cpmr.isValid(isOddPage, isFirstPage, isLastPage, isBlankPage)) { | |||
return cpmr.getMasterReference(); | |||
} | |||
} |
@@ -90,7 +90,6 @@ public class RepeatablePageMasterReference extends FObj | |||
public String getNextPageMasterName(boolean isOddPage, | |||
boolean isFirstPage, | |||
boolean isLastPage, | |||
boolean isOnlyPage, | |||
boolean isEmptyPage) { | |||
if (getMaximumRepeats() != INFINITE) { | |||
if (numberConsumed < getMaximumRepeats()) { |
@@ -86,8 +86,7 @@ public class SinglePageMasterReference extends FObj | |||
public String getNextPageMasterName(boolean isOddPage, | |||
boolean isFirstPage, | |||
boolean isLastPage, | |||
boolean isOnlyPage, | |||
boolean isEmptyPage) { | |||
boolean isBlankPage) { | |||
if (this.state == FIRST) { | |||
this.state = DONE; | |||
return masterReference; | |||
@@ -101,8 +100,6 @@ public class SinglePageMasterReference extends FObj | |||
this.state = FIRST; | |||
} | |||
/** {@inheritDoc} */ | |||
public boolean goToPrevious() { | |||
if (state == FIRST) { |
@@ -31,7 +31,6 @@ public interface SubSequenceSpecifier { | |||
* @param isOddPage True if the next page number is odd | |||
* @param isFirstPage True if the next page is the first | |||
* @param isLastPage True if the next page is the last | |||
* @param isOnlyPage True if the next page is the only page | |||
* @param isBlankPage True if the next page is blank | |||
* @return the page master name | |||
* @throws PageProductionException if there's a problem determining the next page master | |||
@@ -39,7 +38,6 @@ public interface SubSequenceSpecifier { | |||
String getNextPageMasterName(boolean isOddPage, | |||
boolean isFirstPage, | |||
boolean isLastPage, | |||
boolean isOnlyPage, | |||
boolean isBlankPage) | |||
throws PageProductionException; | |||
@@ -33,9 +33,12 @@ import java.lang.ref.WeakReference; | |||
*/ | |||
public final class PropertyCache { | |||
private static final int SEGMENT_COUNT = 32; //0x20 | |||
private static final int INITIAL_BUCKET_COUNT = SEGMENT_COUNT; | |||
/** bitmask to apply to the hash to get to the | |||
* corresponding cache segment */ | |||
private static final int SEGMENT_MASK = 0x1F; | |||
private static final int SEGMENT_MASK = SEGMENT_COUNT - 1; //0x1F | |||
/** | |||
* Indicates whether the cache should be used at all | |||
* Can be controlled by the system property: | |||
@@ -44,13 +47,13 @@ public final class PropertyCache { | |||
private final boolean useCache; | |||
/** the segments array (length = 32) */ | |||
private CacheSegment[] segments = new CacheSegment[SEGMENT_MASK + 1]; | |||
private CacheSegment[] segments = new CacheSegment[SEGMENT_COUNT]; | |||
/** the table of hash-buckets */ | |||
private CacheEntry[] table = new CacheEntry[8]; | |||
private CacheEntry[] table = new CacheEntry[INITIAL_BUCKET_COUNT]; | |||
private Class runtimeType; | |||
final boolean[] votesForRehash = new boolean[SEGMENT_MASK + 1]; | |||
private boolean[] votesForRehash = new boolean[SEGMENT_COUNT]; | |||
/* same hash function as used by java.util.HashMap */ | |||
private static int hash(Object x) { | |||
@@ -72,53 +75,61 @@ public final class PropertyCache { | |||
} | |||
/* Class modeling a cached entry */ | |||
private final class CacheEntry extends WeakReference { | |||
volatile CacheEntry nextEntry; | |||
final int hash; | |||
private static class CacheEntry extends WeakReference { | |||
private volatile CacheEntry nextEntry; | |||
private final int hash; | |||
/* main constructor */ | |||
public CacheEntry(Object p, CacheEntry nextEntry, ReferenceQueue refQueue) { | |||
super(p, refQueue); | |||
this.nextEntry = nextEntry; | |||
this.hash = p.hashCode(); | |||
this.hash = hash(p); | |||
} | |||
/* main constructor */ | |||
public CacheEntry(Object p, CacheEntry nextEntry) { | |||
super(p); | |||
this.nextEntry = nextEntry; | |||
this.hash = hash(p); | |||
} | |||
} | |||
/* Wrapper objects to synchronize on */ | |||
private final class CacheSegment { | |||
private static class CacheSegment { | |||
private int count = 0; | |||
private volatile ReferenceQueue staleEntries = new ReferenceQueue(); | |||
} | |||
private void cleanSegment(int segmentIndex) { | |||
CacheEntry entry; | |||
CacheSegment segment = segments[segmentIndex]; | |||
int bucketIndex; | |||
int oldCount = segment.count; | |||
while ((entry = (CacheEntry) segment.staleEntries.poll()) != null) { | |||
bucketIndex = hash(entry.hash) & (table.length - 1); | |||
/* remove obsolete entry */ | |||
/* 1. move to the corresponding entry */ | |||
/* clean all buckets in this segment */ | |||
for (int bucketIndex = segmentIndex; | |||
bucketIndex < table.length; | |||
bucketIndex += SEGMENT_COUNT) { | |||
CacheEntry prev = null; | |||
CacheEntry e = table[bucketIndex]; | |||
while (e != null | |||
&& e.nextEntry != null | |||
&& e.hash != entry.hash) { | |||
prev = e; | |||
e = e.nextEntry; | |||
CacheEntry entry = table[bucketIndex]; | |||
if (entry == null) { | |||
continue; | |||
} | |||
if (e != null) { | |||
/* 2. remove reference from the chain */ | |||
if (prev == null) { | |||
table[bucketIndex] = e.nextEntry; | |||
do { | |||
if (entry.get() == null) { | |||
if (prev == null) { | |||
table[bucketIndex] = entry.nextEntry; | |||
} else { | |||
prev.nextEntry = entry.nextEntry; | |||
} | |||
segment.count--; | |||
assert segment.count >= 0; | |||
} else { | |||
prev.nextEntry = e.nextEntry; | |||
prev = entry; | |||
} | |||
segment.count--; | |||
} | |||
entry = entry.nextEntry; | |||
} while (entry != null); | |||
} | |||
synchronized (votesForRehash) { | |||
if (oldCount > segment.count) { | |||
votesForRehash[segmentIndex] = false; | |||
@@ -129,7 +140,7 @@ public final class PropertyCache { | |||
/* first time for this segment */ | |||
votesForRehash[segmentIndex] = true; | |||
int voteCount = 0; | |||
for (int i = SEGMENT_MASK + 1; --i >= 0; ) { | |||
for (int i = SEGMENT_MASK + 1; --i >= 0;) { | |||
if (votesForRehash[i]) { | |||
voteCount++; | |||
} | |||
@@ -156,14 +167,15 @@ public final class PropertyCache { | |||
private void put(Object o) { | |||
int hash = hash(o); | |||
CacheSegment segment = segments[hash & SEGMENT_MASK]; | |||
int segmentIndex = hash & SEGMENT_MASK; | |||
CacheSegment segment = segments[segmentIndex]; | |||
synchronized (segment) { | |||
int index = hash & (table.length - 1); | |||
CacheEntry entry = table[index]; | |||
if (entry == null) { | |||
entry = new CacheEntry(o, null, segment.staleEntries); | |||
entry = new CacheEntry(o, null); | |||
table[index] = entry; | |||
segment.count++; | |||
} else { | |||
@@ -171,14 +183,14 @@ public final class PropertyCache { | |||
if (eq(p, o)) { | |||
return; | |||
} else { | |||
CacheEntry newEntry = new CacheEntry(o, entry, segment.staleEntries); | |||
CacheEntry newEntry = new CacheEntry(o, entry); | |||
table[index] = newEntry; | |||
segment.count++; | |||
} | |||
} | |||
if (segment.count > (2 * table.length)) { | |||
cleanSegment(hash & SEGMENT_MASK); | |||
cleanSegment(segmentIndex); | |||
} | |||
} | |||
} | |||
@@ -195,7 +207,7 @@ public final class PropertyCache { | |||
/* try non-synched first */ | |||
for (CacheEntry e = entry; e != null; e = e.nextEntry) { | |||
if (e.hash == o.hashCode() | |||
if (e.hash == hash | |||
&& (q = e.get()) != null | |||
&& eq(q, o)) { | |||
return q; | |||
@@ -209,7 +221,7 @@ public final class PropertyCache { | |||
synchronized (segment) { | |||
entry = table[index]; | |||
for (CacheEntry e = entry; e != null; e = e.nextEntry) { | |||
if (e.hash == o.hashCode() | |||
if (e.hash == hash | |||
&& (q = e.get()) != null | |||
&& eq(q, o)) { | |||
return q; | |||
@@ -235,7 +247,7 @@ public final class PropertyCache { | |||
/* double the amount of buckets */ | |||
int newLength = table.length << 1; | |||
if (newLength > 0) { //no overflow? | |||
/* reset segmentcounts */ | |||
/* reset segment counts */ | |||
for (int i = segments.length; --i >= 0;) { | |||
segments[i].count = 0; | |||
} | |||
@@ -250,8 +262,7 @@ public final class PropertyCache { | |||
if ((o = c.get()) != null) { | |||
hash = c.hash; | |||
idx = hash & newLength; | |||
newTable[idx] = new CacheEntry(o, newTable[idx], | |||
segments[hash & SEGMENT_MASK].staleEntries); | |||
newTable[idx] = new CacheEntry(o, newTable[idx]); | |||
segments[hash & SEGMENT_MASK].count++; | |||
} | |||
} | |||
@@ -313,7 +324,7 @@ public final class PropertyCache { | |||
* @param prop the Property instance to check for | |||
* @return the cached instance | |||
*/ | |||
public final Property fetch(Property prop) { | |||
public Property fetch(Property prop) { | |||
return (Property) fetch((Object) prop); | |||
} | |||
@@ -326,7 +337,7 @@ public final class PropertyCache { | |||
* @param chy the CommonHyphenation instance to check for | |||
* @return the cached instance | |||
*/ | |||
public final CommonHyphenation fetch(CommonHyphenation chy) { | |||
public CommonHyphenation fetch(CommonHyphenation chy) { | |||
return (CommonHyphenation) fetch((Object) chy); | |||
} | |||
@@ -339,7 +350,7 @@ public final class PropertyCache { | |||
* @param cf the CommonFont instance to check for | |||
* @return the cached instance | |||
*/ | |||
public final CommonFont fetch(CommonFont cf) { | |||
public CommonFont fetch(CommonFont cf) { | |||
return (CommonFont) fetch((Object) cf); | |||
} | |||
@@ -352,21 +363,21 @@ public final class PropertyCache { | |||
* @param cbpb the CommonBorderPaddingBackground instance to check for | |||
* @return the cached instance | |||
*/ | |||
public final CommonBorderPaddingBackground fetch(CommonBorderPaddingBackground cbpb) { | |||
public CommonBorderPaddingBackground fetch(CommonBorderPaddingBackground cbpb) { | |||
return (CommonBorderPaddingBackground) fetch((Object) cbpb); | |||
} | |||
/** | |||
* Checks if the given {@link CommonBorderPaddingBackground.BorderInfo} is present in the cache - | |||
* if so, returns a reference to the cached instance. | |||
* Checks if the given {@link CommonBorderPaddingBackground.BorderInfo} is present | |||
* in the cache - if so, returns a reference to the cached instance. | |||
* Otherwise the given object is added to the cache and returned. | |||
* | |||
* @param bi the BorderInfo instance to check for | |||
* @return the cached instance | |||
*/ | |||
public final CommonBorderPaddingBackground.BorderInfo fetch(CommonBorderPaddingBackground.BorderInfo bi) { | |||
public CommonBorderPaddingBackground.BorderInfo fetch( | |||
CommonBorderPaddingBackground.BorderInfo bi) { | |||
return (CommonBorderPaddingBackground.BorderInfo) fetch((Object) bi); | |||
} | |||
@@ -26,12 +26,14 @@ import java.util.Map; | |||
import javax.xml.parsers.DocumentBuilderFactory; | |||
import org.w3c.dom.Document; | |||
import org.w3c.dom.Element; | |||
import org.apache.commons.logging.LogFactory; | |||
import org.apache.fop.Version; | |||
import org.apache.fop.fonts.type1.PFMFile; | |||
import org.apache.fop.util.CommandLineLogger; | |||
import org.w3c.dom.Document; | |||
import org.w3c.dom.Element; | |||
/** | |||
* A tool which reads PFM files from Adobe Type 1 fonts and creates | |||
@@ -256,7 +258,7 @@ public class PFMReader extends AbstractFontReader { | |||
el = doc.createElement("descender"); | |||
root.appendChild(el); | |||
value = new Integer(-pfm.getLowerCaseDescent()); | |||
value = new Integer(pfm.getLowerCaseDescent()); | |||
el.appendChild(doc.createTextNode(value.toString())); | |||
Element bbox = doc.createElement("bbox"); |
@@ -983,10 +983,17 @@ public class TTFFile { | |||
/** | |||
* Read the "OS/2" table | |||
*/ | |||
private final void readOS2(FontFileReader in) throws IOException { | |||
private void readOS2(FontFileReader in) throws IOException { | |||
// Check if font is embeddable | |||
if (dirTabs.get("OS/2") != null) { | |||
seekTab(in, "OS/2", 2 * 2); | |||
TTFDirTabEntry os2Entry = (TTFDirTabEntry)dirTabs.get("OS/2"); | |||
if (os2Entry != null) { | |||
seekTab(in, "OS/2", 0); | |||
int version = in.readTTFUShort(); | |||
if (log.isDebugEnabled()) { | |||
log.debug("OS/2 table: version=" + version | |||
+ ", offset=" + os2Entry.getOffset() + ", len=" + os2Entry.getLength()); | |||
} | |||
in.skip(2); //xAvgCharWidth | |||
this.usWeightClass = in.readTTFUShort(); | |||
// usWidthClass | |||
@@ -1005,22 +1012,30 @@ public class TTFFile { | |||
in.skip(3 * 2); | |||
int v; | |||
os2Ascender = in.readTTFShort(); //sTypoAscender | |||
log.debug("sTypoAscender: " + os2Ascender | |||
+ " " + convertTTFUnit2PDFUnit(os2Ascender)); | |||
os2Descender = in.readTTFShort(); //sTypoDescender | |||
log.debug("sTypoDescender: " + os2Descender | |||
+ " " + convertTTFUnit2PDFUnit(os2Descender)); | |||
v = in.readTTFShort(); //sTypoLineGap | |||
log.debug("sTypoLineGap: " + v); | |||
v = in.readTTFUShort(); //usWinAscent | |||
log.debug("usWinAscent: " + v + " " + convertTTFUnit2PDFUnit(v)); | |||
v = in.readTTFUShort(); //usWinDescent | |||
log.debug("usWinDescent: " + v + " " + convertTTFUnit2PDFUnit(v)); | |||
in.skip(2 * 4); | |||
this.os2xHeight = in.readTTFShort(); //sxHeight | |||
log.debug("sxHeight: " + this.os2xHeight); | |||
this.os2CapHeight = in.readTTFShort(); //sCapHeight | |||
log.debug("sCapHeight: " + this.os2CapHeight); | |||
if (log.isDebugEnabled()) { | |||
log.debug("sTypoAscender: " + os2Ascender | |||
+ " " + convertTTFUnit2PDFUnit(os2Ascender)); | |||
log.debug("sTypoDescender: " + os2Descender | |||
+ " " + convertTTFUnit2PDFUnit(os2Descender)); | |||
log.debug("sTypoLineGap: " + v); | |||
log.debug("usWinAscent: " + v + " " + convertTTFUnit2PDFUnit(v)); | |||
log.debug("usWinDescent: " + v + " " + convertTTFUnit2PDFUnit(v)); | |||
} | |||
//version 1 OS/2 table might end here | |||
if (os2Entry.getLength() >= 78 + (2 * 4) + (2 * 2)) { | |||
in.skip(2 * 4); | |||
this.os2xHeight = in.readTTFShort(); //sxHeight | |||
this.os2CapHeight = in.readTTFShort(); //sCapHeight | |||
if (log.isDebugEnabled()) { | |||
log.debug("sxHeight: " + this.os2xHeight); | |||
log.debug("sCapHeight: " + this.os2CapHeight); | |||
} | |||
} | |||
} else { | |||
isEmbeddable = true; |
@@ -19,6 +19,7 @@ | |||
package org.apache.fop.fonts.type1; | |||
import java.io.EOFException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.DataInputStream; | |||
@@ -30,7 +31,7 @@ import java.io.InputStreamReader; | |||
*/ | |||
public class PFMInputStream extends java.io.FilterInputStream { | |||
private DataInputStream datain; | |||
private final DataInputStream datain; | |||
/** | |||
* Constructs a PFMInputStream based on an InputStream representing the | |||
@@ -97,11 +98,15 @@ public class PFMInputStream extends java.io.FilterInputStream { | |||
public String readString() throws IOException { | |||
InputStreamReader reader = new InputStreamReader(in, "ISO-8859-1"); | |||
StringBuffer buf = new StringBuffer(); | |||
int ch = reader.read(); | |||
while (ch != 0) { | |||
while (ch > 0) { | |||
buf.append((char)ch); | |||
ch = reader.read(); | |||
} | |||
if (ch == -1) { | |||
throw new EOFException("Unexpected end of stream reached"); | |||
} | |||
return buf.toString(); | |||
} | |||
@@ -32,19 +32,18 @@ import org.apache.batik.dom.svg.SVGDOMImplementation; | |||
import org.apache.batik.gvt.GraphicsNode; | |||
import org.apache.commons.logging.Log; | |||
import org.apache.commons.logging.LogFactory; | |||
import org.apache.fop.svg.SimpleSVGUserAgent; | |||
import org.apache.xmlgraphics.image.loader.Image; | |||
import org.apache.xmlgraphics.image.loader.ImageException; | |||
import org.apache.xmlgraphics.image.loader.ImageFlavor; | |||
import org.apache.xmlgraphics.image.loader.ImageProcessingHints; | |||
import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor; | |||
import org.apache.xmlgraphics.image.loader.impl.AbstractImageConverter; | |||
import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D; | |||
import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; | |||
import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; | |||
import org.apache.xmlgraphics.util.UnitConv; | |||
import org.apache.fop.svg.SimpleSVGUserAgent; | |||
/** | |||
* This ImageConverter converts SVG images to Java2D. | |||
* <p> | |||
@@ -132,7 +131,7 @@ public class ImageConverterSVG2G2D extends AbstractImageConverter { | |||
/** {@inheritDoc} */ | |||
public ImageFlavor getSourceFlavor() { | |||
return BatikImageFlavors.SVG_DOM; | |||
return XMLNamespaceEnabledImageFlavor.SVG_DOM; | |||
} | |||
/** {@inheritDoc} */ |
@@ -20,6 +20,7 @@ | |||
package org.apache.fop.image.loader.batik; | |||
import org.apache.xmlgraphics.image.loader.ImageFlavor; | |||
import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor; | |||
import org.apache.xmlgraphics.image.loader.impl.AbstractImageLoaderFactory; | |||
import org.apache.xmlgraphics.image.loader.spi.ImageLoader; | |||
import org.apache.xmlgraphics.util.MimeConstants; | |||
@@ -30,7 +31,7 @@ import org.apache.xmlgraphics.util.MimeConstants; | |||
public class ImageLoaderFactorySVG extends AbstractImageLoaderFactory { | |||
private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { | |||
BatikImageFlavors.SVG_DOM}; | |||
XMLNamespaceEnabledImageFlavor.SVG_DOM}; | |||
private static final String[] MIMES = new String[] { | |||
MimeConstants.MIME_SVG}; |
@@ -23,12 +23,12 @@ import java.io.IOException; | |||
import java.util.Map; | |||
import org.apache.batik.dom.svg.SVGDOMImplementation; | |||
import org.apache.xmlgraphics.image.loader.Image; | |||
import org.apache.xmlgraphics.image.loader.ImageException; | |||
import org.apache.xmlgraphics.image.loader.ImageFlavor; | |||
import org.apache.xmlgraphics.image.loader.ImageInfo; | |||
import org.apache.xmlgraphics.image.loader.ImageSessionContext; | |||
import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor; | |||
import org.apache.xmlgraphics.image.loader.impl.AbstractImageLoader; | |||
import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; | |||
import org.apache.xmlgraphics.util.MimeConstants; | |||
@@ -45,7 +45,7 @@ public class ImageLoaderSVG extends AbstractImageLoader { | |||
* @param targetFlavor the target flavor | |||
*/ | |||
public ImageLoaderSVG(ImageFlavor targetFlavor) { | |||
if (!(targetFlavor.isCompatible(ImageFlavor.XML_DOM))) { | |||
if (!(XMLNamespaceEnabledImageFlavor.SVG_DOM.equals(targetFlavor))) { | |||
throw new IllegalArgumentException("Unsupported target ImageFlavor: " + targetFlavor); | |||
} | |||
this.targetFlavor = targetFlavor; |
@@ -406,7 +406,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager | |||
if (forcedBreakAfterLast != null) { | |||
forcedBreakAfterLast.clearPendingMarks(); | |||
wrapPositionElement(forcedBreakAfterLast, returnList, false); | |||
returnList.add(forcedBreakAfterLast); | |||
} | |||
context.updateKeepWithNextPending(getKeepWithNextStrength()); | |||
@@ -1043,7 +1043,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager | |||
} | |||
return breakBefore; | |||
} | |||
/** | |||
* Creates Knuth elements for break-after and adds them to the return list. | |||
* @param returnList return list to add the additional elements to |
@@ -234,13 +234,13 @@ public class PageProvider implements Constants { | |||
indexOfCachedLastPage = (isLastPage ? intIndex : -1); | |||
} | |||
if (replace) { | |||
disardCacheStartingWith(intIndex); | |||
discardCacheStartingWith(intIndex); | |||
page = cacheNextPage(index, isBlank, isLastPage); | |||
} | |||
return page; | |||
} | |||
private void disardCacheStartingWith(int index) { | |||
private void discardCacheStartingWith(int index) { | |||
while (index < cachedPages.size()) { | |||
this.cachedPages.remove(cachedPages.size() - 1); | |||
if (!pageSeq.goToPreviousSimplePageMaster()) { | |||
@@ -251,8 +251,9 @@ public class PageProvider implements Constants { | |||
private Page cacheNextPage(int index, boolean isBlank, boolean isLastPage) { | |||
String pageNumberString = pageSeq.makeFormattedPageNumber(index); | |||
boolean isFirstPage = (startPageOfPageSequence == index); | |||
SimplePageMaster spm = pageSeq.getNextSimplePageMaster( | |||
index, (startPageOfPageSequence == index), isLastPage, false, isBlank); | |||
index, isFirstPage, isLastPage, isBlank); | |||
Region body = spm.getRegion(FO_REGION_BODY); | |||
if (!pageSeq.getMainFlow().getFlowName().equals(body.getRegionName())) { |
@@ -334,7 +334,8 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager | |||
fromIndex = oldListIterator.previousIndex(); | |||
} else if (currLM == prevLM) { | |||
bSomethingChanged | |||
= prevLM.applyChanges(oldList.subList(fromIndex, oldList.size())) | |||
= (prevLM != null) | |||
&& prevLM.applyChanges(oldList.subList(fromIndex, oldList.size())) | |||
|| bSomethingChanged; | |||
} else { | |||
bSomethingChanged |
@@ -183,17 +183,23 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { | |||
childContext.setAlignmentContext(context.getAlignmentContext()); | |||
contentList = clm.getNextKnuthElements(childContext, 0); | |||
int width = clm.getStackingSize(); | |||
Space spacer = null; | |||
if (fobj.getLeaderPatternWidth().getValue(this) > width) { | |||
spacer = new Space(); | |||
spacer.setIPD(fobj.getLeaderPatternWidth().getValue(this) - width); | |||
width = fobj.getLeaderPatternWidth().getValue(this); | |||
} | |||
fa.setUnitWidth(width); | |||
if (spacer != null) { | |||
fa.addChildArea(spacer); | |||
if (width != 0) { | |||
Space spacer = null; | |||
if (fobj.getLeaderPatternWidth().getValue(this) > width) { | |||
spacer = new Space(); | |||
spacer.setIPD(fobj.getLeaderPatternWidth().getValue(this) - width); | |||
width = fobj.getLeaderPatternWidth().getValue(this); | |||
} | |||
fa.setUnitWidth(width); | |||
if (spacer != null) { | |||
fa.addChildArea(spacer); | |||
} | |||
leaderArea = fa; | |||
} else { | |||
//Content collapsed to nothing, so use a space | |||
leaderArea = new Space(); | |||
leaderArea.setBPD(1); | |||
} | |||
leaderArea = fa; | |||
} | |||
TraitSetter.setProducerID(leaderArea, fobj.getId()); | |||
return leaderArea; |
@@ -27,13 +27,19 @@ import java.util.ListIterator; | |||
import org.apache.commons.logging.Log; | |||
import org.apache.commons.logging.LogFactory; | |||
import org.apache.fop.area.Block; | |||
import org.apache.fop.area.Trait; | |||
import org.apache.fop.fo.flow.table.ConditionalBorder; | |||
import org.apache.fop.fo.flow.table.EffRow; | |||
import org.apache.fop.fo.flow.table.EmptyGridUnit; | |||
import org.apache.fop.fo.flow.table.GridUnit; | |||
import org.apache.fop.fo.flow.table.PrimaryGridUnit; | |||
import org.apache.fop.fo.flow.table.Table; | |||
import org.apache.fop.fo.flow.table.TableColumn; | |||
import org.apache.fop.fo.flow.table.TablePart; | |||
import org.apache.fop.fo.properties.CommonBorderPaddingBackground; | |||
import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo; | |||
import org.apache.fop.layoutmgr.ElementListUtils; | |||
import org.apache.fop.layoutmgr.KnuthElement; | |||
import org.apache.fop.layoutmgr.KnuthPossPosIter; | |||
@@ -202,10 +208,16 @@ class RowPainter { | |||
recordRowOffset(currentRow.getIndex(), currentRowOffset); | |||
// Need to compute the actual row height first | |||
// and determine border behaviour for empty cells | |||
boolean firstCellPart = true; | |||
boolean lastCellPart = true; | |||
int actualRowHeight = 0; | |||
for (int i = 0; i < colCount; i++) { | |||
GridUnit currentGU = currentRow.getGridUnit(i); | |||
if (!currentGU.isEmpty() && currentGU.getColSpanIndex() == 0 | |||
if (currentGU.isEmpty()) { | |||
continue; | |||
} | |||
if (currentGU.getColSpanIndex() == 0 | |||
&& (lastInPart || currentGU.isLastGridUnitRowSpan()) | |||
&& firstCellParts[i] != null) { | |||
// TODO | |||
@@ -225,21 +237,53 @@ class RowPainter { | |||
actualRowHeight = Math.max(actualRowHeight, cellOffset + cellHeight | |||
- currentRowOffset); | |||
} | |||
if (firstCellParts[i] != null && !firstCellParts[i].isFirstPart()) { | |||
firstCellPart = false; | |||
} | |||
if (lastCellParts[i] != null && !lastCellParts[i].isLastPart()) { | |||
lastCellPart = false; | |||
} | |||
} | |||
// Then add areas for cells finishing on the current row | |||
for (int i = 0; i < colCount; i++) { | |||
GridUnit currentGU = currentRow.getGridUnit(i); | |||
if (currentGU.isEmpty()) { | |||
// TODO remove once missing cells are properly implemented (i.e., replaced | |||
// by an fo:table-cell element containing an empty fo:block) | |||
if (currentGU.isEmpty() && !tclm.isSeparateBorderModel()) { | |||
int borderBeforeWhich; | |||
if (firstCellPart) { | |||
if (firstCellOnPage[i]) { | |||
borderBeforeWhich = ConditionalBorder.LEADING_TRAILING; | |||
} else { | |||
borderBeforeWhich = ConditionalBorder.NORMAL; | |||
} | |||
} else { | |||
borderBeforeWhich = ConditionalBorder.REST; | |||
} | |||
int borderAfterWhich; | |||
if (lastCellPart) { | |||
if (lastInPart) { | |||
borderAfterWhich = ConditionalBorder.LEADING_TRAILING; | |||
} else { | |||
borderAfterWhich = ConditionalBorder.NORMAL; | |||
} | |||
} else { | |||
borderAfterWhich = ConditionalBorder.REST; | |||
} | |||
addAreaForEmptyGridUnit((EmptyGridUnit)currentGU, | |||
currentRow.getIndex(), i, | |||
actualRowHeight, | |||
borderBeforeWhich, borderAfterWhich, | |||
lastOnPage); | |||
firstCellOnPage[i] = false; | |||
} else if (currentGU.getColSpanIndex() == 0 | |||
&& (lastInPart || currentGU.isLastGridUnitRowSpan()) | |||
&& firstCellParts[i] != null) { | |||
assert firstCellParts[i].pgu == currentGU.getPrimary(); | |||
int borderBeforeWhich; | |||
if (firstCellParts[i].start == 0) { | |||
if (firstCellParts[i].isFirstPart()) { | |||
if (firstCellOnPage[i]) { | |||
borderBeforeWhich = ConditionalBorder.LEADING_TRAILING; | |||
} else { | |||
@@ -259,6 +303,7 @@ class RowPainter { | |||
} else { | |||
borderAfterWhich = ConditionalBorder.REST; | |||
} | |||
addAreasForCell(firstCellParts[i].pgu, | |||
firstCellParts[i].start, lastCellParts[i].end, | |||
actualRowHeight, borderBeforeWhich, borderAfterWhich, | |||
@@ -387,6 +432,56 @@ class RowPainter { | |||
startRowIndex == firstRowOnPageIndex, lastOnPage, this, firstRowHeight); | |||
} | |||
private void addAreaForEmptyGridUnit(EmptyGridUnit gu, int rowIndex, int colIndex, | |||
int actualRowHeight, | |||
int borderBeforeWhich, int borderAfterWhich, boolean lastOnPage) { | |||
//get effective borders | |||
BorderInfo borderBefore = gu.getBorderBefore(borderBeforeWhich); | |||
BorderInfo borderAfter = gu.getBorderAfter(borderAfterWhich); | |||
BorderInfo borderStart = gu.getBorderStart(); | |||
BorderInfo borderEnd = gu.getBorderEnd(); | |||
if (borderBefore.getRetainedWidth() == 0 | |||
&& borderAfter.getRetainedWidth() == 0 | |||
&& borderStart.getRetainedWidth() == 0 | |||
&& borderEnd.getRetainedWidth() == 0) { | |||
return; //no borders, no area necessary | |||
} | |||
TableLayoutManager tableLM = tclm.getTableLM(); | |||
Table table = tableLM.getTable(); | |||
TableColumn col = tclm.getColumns().getColumn(colIndex + 1); | |||
//position information | |||
boolean firstOnPage = (rowIndex == firstRowOnPageIndex); | |||
boolean inFirstColumn = (colIndex == 0); | |||
boolean inLastColumn = (colIndex == table.getNumberOfColumns() - 1); | |||
//determine the block area's size | |||
int ipd = col.getColumnWidth().getValue(tableLM); | |||
ipd -= (borderStart.getRetainedWidth() + borderEnd.getRetainedWidth()) / 2; | |||
int bpd = actualRowHeight; | |||
bpd -= (borderBefore.getRetainedWidth() + borderAfter.getRetainedWidth()) / 2; | |||
//generate the block area | |||
Block block = new Block(); | |||
block.setPositioning(Block.ABSOLUTE); | |||
block.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE); | |||
block.setIPD(ipd); | |||
block.setBPD(bpd); | |||
block.setXOffset(tclm.getXOffsetOfGridUnit(colIndex) | |||
+ (borderStart.getRetainedWidth() / 2)); | |||
block.setYOffset(getRowOffset(rowIndex) | |||
- (borderBefore.getRetainedWidth() / 2)); | |||
boolean[] outer = new boolean[] {firstOnPage, lastOnPage, inFirstColumn, | |||
inLastColumn}; | |||
TraitSetter.addCollapsingBorders(block, | |||
borderBefore, | |||
borderAfter, | |||
borderStart, | |||
borderEnd, outer); | |||
tableLM.addChildArea(block); | |||
} | |||
/** | |||
* Registers the given area, that will be used to render the part of |
@@ -305,13 +305,21 @@ public class TableContentLayoutManager implements PercentBaseContext { | |||
} | |||
/** | |||
* Retuns the X offset of the given grid unit. | |||
* Returns the X offset of the given grid unit. | |||
* @param gu the grid unit | |||
* @return the requested X offset | |||
*/ | |||
protected int getXOffsetOfGridUnit(PrimaryGridUnit gu) { | |||
int col = gu.getColIndex(); | |||
return startXOffset + getTableLM().getColumns().getXOffset(col + 1, getTableLM()); | |||
return getXOffsetOfGridUnit(gu.getColIndex()); | |||
} | |||
/** | |||
* Returns the X offset of the grid unit in the given column. | |||
* @param colIndex the column index (zero-based) | |||
* @return the requested X offset | |||
*/ | |||
protected int getXOffsetOfGridUnit(int colIndex) { | |||
return startXOffset + getTableLM().getColumns().getXOffset(colIndex + 1, getTableLM()); | |||
} | |||
/** |
@@ -48,6 +48,9 @@ public class AlphaRasterImage implements PDFImage { | |||
*/ | |||
public AlphaRasterImage(String k, Raster alpha) { | |||
this.key = k; | |||
//Enable the commented line below if 16-bit alpha channels are desired. | |||
//Otherwise, we compress the alpha channel to 8 bit which should be sufficient. | |||
//this.bitsPerComponent = alpha.getSampleModel().getSampleSize(0); | |||
this.bitsPerComponent = 8; | |||
this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_GRAY); | |||
if (alpha == null) { | |||
@@ -148,6 +151,18 @@ public class AlphaRasterImage implements PDFImage { | |||
alpha.getDataElements(0, y, w, 1, line); | |||
out.write(line); | |||
} | |||
} else if (dataType == DataBuffer.TYPE_USHORT) { | |||
short[] sline = new short[nbands * w]; | |||
byte[] line = new byte[nbands * w]; | |||
for (int y = 0; y < h; y++) { | |||
alpha.getDataElements(0, y, w, 1, sline); | |||
for (int i = 0; i < w; i++) { | |||
//this compresses a 16-bit alpha channel to 8 bits! | |||
//we probably don't ever need a 16-bit channel | |||
line[i] = (byte)(sline[i] >> 8); | |||
} | |||
out.write(line); | |||
} | |||
} else if (dataType == DataBuffer.TYPE_INT) { | |||
//Is there an better way to get a 8bit raster from a TYPE_INT raster? | |||
int shift = 24; |
@@ -163,6 +163,11 @@ public class PDFFilterList { | |||
* @param type which filter list to modify | |||
*/ | |||
public void addDefaultFilters(Map filters, String type) { | |||
if (METADATA_FILTER.equals(type)) { | |||
//XMP metadata should not be embedded in clear-text | |||
addFilter(new NullFilter()); | |||
return; | |||
} | |||
List filterset = null; | |||
if (filters != null) { | |||
filterset = (List)filters.get(type); | |||
@@ -171,10 +176,7 @@ public class PDFFilterList { | |||
} | |||
} | |||
if (filterset == null || filterset.size() == 0) { | |||
if (METADATA_FILTER.equals(type)) { | |||
//XMP metadata should not be embedded in clear-text | |||
addFilter(new NullFilter()); | |||
} else if (JPEG_FILTER.equals(type)) { | |||
if (JPEG_FILTER.equals(type)) { | |||
//JPEG is already well compressed | |||
addFilter(new NullFilter()); | |||
} else if (TIFF_FILTER.equals(type)) { |
@@ -35,7 +35,7 @@ import java.awt.image.WritableRaster; | |||
import java.io.IOException; | |||
import org.apache.fop.render.RendererContext.RendererContextWrapper; | |||
import org.apache.fop.util.UnitConv; | |||
import org.apache.xmlgraphics.util.UnitConv; | |||
/** | |||
* Abstract base class for Graphics2DAdapter implementations. |
@@ -48,6 +48,7 @@ import org.apache.fop.fo.Constants; | |||
import org.apache.fop.fo.extensions.ExtensionElementMapping; | |||
import org.apache.fop.fonts.FontMetrics; | |||
import org.apache.fop.traits.BorderProps; | |||
import org.apache.xmlgraphics.util.UnitConv; | |||
/** | |||
* Abstract base class for renderers like PDF and PostScript where many painting operations | |||
@@ -485,8 +486,8 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
int borderPaddingStart = bv.getBorderAndPaddingWidthStart(); | |||
int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore(); | |||
//This is the content-rect | |||
float width = (float)bv.getIPD() / 1000f; | |||
float height = (float)bv.getBPD() / 1000f; | |||
float width = bv.getIPD() / 1000f; | |||
float height = bv.getBPD() / 1000f; | |||
if (bv.getPositioning() == Block.ABSOLUTE | |||
|| bv.getPositioning() == Block.FIXED) { | |||
@@ -515,7 +516,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
saveGraphicsState(); | |||
//Viewport position | |||
concatenateTransformationMatrix(mptToPt(positionTransform)); | |||
concatenateTransformationMatrix(UnitConv.mptToPt(positionTransform)); | |||
//Background and borders | |||
float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f; | |||
@@ -525,7 +526,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
//Shift to content rectangle after border painting | |||
AffineTransform contentRectTransform = new AffineTransform(); | |||
contentRectTransform.translate(borderPaddingStart, borderPaddingBefore); | |||
concatenateTransformationMatrix(mptToPt(contentRectTransform)); | |||
concatenateTransformationMatrix(UnitConv.mptToPt(contentRectTransform)); | |||
//Clipping | |||
if (bv.getClip()) { | |||
@@ -535,7 +536,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
saveGraphicsState(); | |||
//Set up coordinate system for content rectangle | |||
AffineTransform contentTransform = ctm.toAffineTransform(); | |||
concatenateTransformationMatrix(mptToPt(contentTransform)); | |||
concatenateTransformationMatrix(UnitConv.mptToPt(contentTransform)); | |||
currentIPPosition = 0; | |||
currentBPPosition = 0; | |||
@@ -581,7 +582,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
currentIPPosition = saveIP; | |||
currentBPPosition = saveBP; | |||
currentBPPosition += (int)(bv.getAllocBPD()); | |||
currentBPPosition += (bv.getAllocBPD()); | |||
} | |||
} | |||
@@ -599,7 +600,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
if (!at.isIdentity()) { | |||
saveGraphicsState(); | |||
concatenateTransformationMatrix(mptToPt(at)); | |||
concatenateTransformationMatrix(UnitConv.mptToPt(at)); | |||
} | |||
currentIPPosition = 0; | |||
@@ -632,7 +633,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
if (!at.isIdentity()) { | |||
saveGraphicsState(); | |||
concatenateTransformationMatrix(mptToPt(at)); | |||
concatenateTransformationMatrix(UnitConv.mptToPt(at)); | |||
} | |||
currentIPPosition = 0; |
@@ -20,7 +20,6 @@ | |||
package org.apache.fop.render; | |||
// FOP | |||
import java.awt.Color; | |||
import java.awt.geom.Rectangle2D; | |||
import java.util.List; | |||
import java.util.Map; | |||
@@ -112,29 +111,6 @@ public abstract class PrintRenderer extends AbstractRenderer { | |||
return fontInfo.getFontInstance(triplet, size); | |||
} | |||
/** | |||
* Lightens up a color for groove, ridge, inset and outset border effects. | |||
* @param col the color to lighten up | |||
* @param factor factor by which to lighten up (negative values darken the color) | |||
* @return the modified color | |||
*/ | |||
public static Color lightenColor(Color col, float factor) { | |||
// TODO: This function converts the color into the sRGB namespace. | |||
// This should be avoided if possible. | |||
float[] cols = new float[4]; | |||
cols = col.getRGBComponents(cols); | |||
if (factor > 0) { | |||
cols[0] += (1.0 - cols[0]) * factor; | |||
cols[1] += (1.0 - cols[1]) * factor; | |||
cols[2] += (1.0 - cols[2]) * factor; | |||
} else { | |||
cols[0] -= cols[0] * -factor; | |||
cols[1] -= cols[1] * -factor; | |||
cols[2] -= cols[2] * -factor; | |||
} | |||
return new Color(cols[0], cols[1], cols[2], cols[3]); | |||
} | |||
/** | |||
* Creates a RendererContext for an image. | |||
* @param x the x coordinate (in millipoints) |
@@ -88,6 +88,7 @@ import org.apache.fop.render.afp.modca.AFPConstants; | |||
import org.apache.fop.render.afp.modca.AFPDataStream; | |||
import org.apache.fop.render.afp.modca.ImageObject; | |||
import org.apache.fop.render.afp.modca.PageObject; | |||
import org.apache.fop.util.ColorUtil; | |||
/** | |||
* This is an implementation of a FOP Renderer that renders areas to AFP. | |||
@@ -850,8 +851,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { | |||
{ | |||
float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f); | |||
if (horz) { | |||
Color uppercol = lightenColor(col, -colFactor); | |||
Color lowercol = lightenColor(col, colFactor); | |||
Color uppercol = ColorUtil.lightenColor(col, -colFactor); | |||
Color lowercol = ColorUtil.lightenColor(col, colFactor); | |||
float h3 = h / 3; | |||
float ym1 = y1; | |||
afpDataStream.createLine( | |||
@@ -879,8 +880,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { | |||
lowercol | |||
); | |||
} else { | |||
Color leftcol = lightenColor(col, -colFactor); | |||
Color rightcol = lightenColor(col, colFactor); | |||
Color leftcol = ColorUtil.lightenColor(col, -colFactor); | |||
Color rightcol = ColorUtil.lightenColor(col, colFactor); | |||
float w3 = w / 3; | |||
float xm1 = x1 + (w3 / 2); | |||
afpDataStream.createLine( |
@@ -77,6 +77,7 @@ import org.apache.fop.render.Graphics2DAdapter; | |||
import org.apache.fop.render.RendererContext; | |||
import org.apache.fop.render.pdf.CTMHelper; | |||
import org.apache.fop.util.CharUtilities; | |||
import org.apache.fop.util.ColorUtil; | |||
/** | |||
* The <code>Java2DRenderer</code> class provides the abstract technical | |||
@@ -652,8 +653,8 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem | |||
case Constants.EN_RIDGE: | |||
float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f); | |||
if (horz) { | |||
Color uppercol = lightenColor(col, -colFactor); | |||
Color lowercol = lightenColor(col, colFactor); | |||
Color uppercol = ColorUtil.lightenColor(col, -colFactor); | |||
Color lowercol = ColorUtil.lightenColor(col, colFactor); | |||
float h3 = h / 3; | |||
float ym1 = y1 + (h3 / 2); | |||
g2d.setStroke(new BasicStroke(h3)); | |||
@@ -664,8 +665,8 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem | |||
g2d.setColor(lowercol); | |||
g2d.draw(new Line2D.Float(x1, ym1 + h3 + h3, x2, ym1 + h3 + h3)); | |||
} else { | |||
Color leftcol = lightenColor(col, -colFactor); | |||
Color rightcol = lightenColor(col, colFactor); | |||
Color leftcol = ColorUtil.lightenColor(col, -colFactor); | |||
Color rightcol = ColorUtil.lightenColor(col, colFactor); | |||
float w3 = w / 3; | |||
float xm1 = x1 + (w3 / 2); | |||
g2d.setStroke(new BasicStroke(w3)); | |||
@@ -681,13 +682,13 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem | |||
case Constants.EN_OUTSET: | |||
colFactor = (style == EN_OUTSET ? 0.4f : -0.4f); | |||
if (horz) { | |||
col = lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); | |||
col = ColorUtil.lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); | |||
g2d.setStroke(new BasicStroke(h)); | |||
float ym1 = y1 + (h / 2); | |||
g2d.setColor(col); | |||
g2d.draw(new Line2D.Float(x1, ym1, x2, ym1)); | |||
} else { | |||
col = lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); | |||
col = ColorUtil.lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); | |||
float xm1 = x1 + (w / 2); | |||
g2d.setStroke(new BasicStroke(w)); | |||
g2d.setColor(col); | |||
@@ -859,7 +860,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem | |||
case EN_RIDGE: | |||
float half = area.getRuleThickness() / 2000f; | |||
state.updateColor(lightenColor(col, 0.6f)); | |||
state.updateColor(ColorUtil.lightenColor(col, 0.6f)); | |||
moveTo(startx, starty); | |||
lineTo(endx, starty); | |||
lineTo(endx, starty + 2 * half); |
@@ -45,8 +45,7 @@ import java.util.Locale; | |||
import org.apache.commons.io.output.ByteArrayOutputStream; | |||
import org.apache.xmlgraphics.image.GraphicsUtil; | |||
import org.apache.fop.util.UnitConv; | |||
import org.apache.xmlgraphics.util.UnitConv; | |||
/** | |||
* This class provides methods for generating PCL print files. | |||
@@ -72,7 +71,7 @@ public class PCLGenerator { | |||
private final DecimalFormat df2 = new DecimalFormat("0.##", symbols); | |||
private final DecimalFormat df4 = new DecimalFormat("0.####", symbols); | |||
private OutputStream out; | |||
private final OutputStream out; | |||
private boolean currentSourceTransparency = true; | |||
private boolean currentPatternTransparency = true; | |||
@@ -83,7 +82,7 @@ public class PCLGenerator { | |||
* true: Standard PCL shades are used (poor quality). false: user-defined pattern are used | |||
* to create custom dither patterns for better grayscale quality. | |||
*/ | |||
private boolean usePCLShades = false; | |||
private final boolean usePCLShades = false; | |||
/** | |||
* Main constructor. | |||
@@ -412,7 +411,7 @@ public class PCLGenerator { | |||
private static void setValueInMatrix(int[] dn, int half, int part, int idx, int value) { | |||
int xoff = (part & 1) * half; | |||
int yoff = (part & 2) * half * half; | |||
int matrixIndex = yoff + ((int)(idx / half) * half * 2) + (idx % half) + xoff; | |||
int matrixIndex = yoff + ((idx / half) * half * 2) + (idx % half) + xoff; | |||
dn[matrixIndex] = value; | |||
} | |||
@@ -42,9 +42,9 @@ import java.awt.image.renderable.RenderableImage; | |||
import java.io.IOException; | |||
import java.text.AttributedCharacterIterator; | |||
import org.apache.fop.util.UnitConv; | |||
import org.apache.xmlgraphics.java2d.AbstractGraphics2D; | |||
import org.apache.xmlgraphics.java2d.GraphicContext; | |||
import org.apache.xmlgraphics.util.UnitConv; | |||
/** | |||
* Graphics2D implementation implementing PCL and HP GL/2. | |||
@@ -55,7 +55,7 @@ public class PCLGraphics2D extends AbstractGraphics2D { | |||
/** The PCL generator */ | |||
protected PCLGenerator gen; | |||
private boolean failOnUnsupportedFeature = true; | |||
private final boolean failOnUnsupportedFeature = true; | |||
private boolean clippingDisabled = false; | |||
/** |
@@ -34,7 +34,7 @@ import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; | |||
import org.apache.fop.render.AbstractGraphics2DAdapter; | |||
import org.apache.fop.render.RendererContext; | |||
import org.apache.fop.util.UnitConv; | |||
import org.apache.xmlgraphics.util.UnitConv; | |||
/** | |||
* Graphics2DAdapter implementation for PCL and HP GL/2. | |||
@@ -111,7 +111,7 @@ public class PCLGraphics2DAdapter extends AbstractGraphics2DAdapter { | |||
if (!painted) { | |||
//Fallback solution: Paint to a BufferedImage | |||
int resolution = (int)Math.round(context.getUserAgent().getTargetResolution()); | |||
int resolution = Math.round(context.getUserAgent().getTargetResolution()); | |||
BufferedImage bi = paintToBufferedImage(painter, pclContext, | |||
resolution, !pclContext.isColorCanvas(), false); | |||
@@ -24,7 +24,7 @@ import java.awt.Rectangle; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import org.apache.fop.util.UnitConv; | |||
import org.apache.xmlgraphics.util.UnitConv; | |||
/** | |||
* This class represents a page format with PCL-specific properties. | |||
@@ -34,11 +34,11 @@ public class PCLPageDefinition { | |||
private static List pageDefinitions; | |||
private static PCLPageDefinition defaultPageDefinition; | |||
private String name; | |||
private int selector; | |||
private Dimension physicalPageSize; | |||
private Rectangle logicalPageRect; | |||
private boolean landscape; | |||
private final String name; | |||
private final int selector; | |||
private final Dimension physicalPageSize; | |||
private final Rectangle logicalPageRect; | |||
private final boolean landscape; | |||
static { | |||
createPageDefinitions(); |
@@ -96,7 +96,7 @@ import org.apache.fop.render.java2d.InstalledFontCollection; | |||
import org.apache.fop.render.java2d.Java2DRenderer; | |||
import org.apache.fop.render.pcl.extensions.PCLElementMapping; | |||
import org.apache.fop.traits.BorderProps; | |||
import org.apache.fop.util.UnitConv; | |||
import org.apache.xmlgraphics.util.UnitConv; | |||
/* Note: | |||
* There are some commonalities with AbstractPathOrientedRenderer but it's not possible | |||
@@ -122,7 +122,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
protected PCLGenerator gen; | |||
private boolean ioTrouble = false; | |||
private Stack graphicContextStack = new Stack(); | |||
private final Stack graphicContextStack = new Stack(); | |||
private GraphicContext graphicContext = new GraphicContext(); | |||
private PCLPageDefinition currentPageDefinition; | |||
@@ -147,7 +147,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
* This can be used to work around problems with Apache Batik, for example, but setting | |||
* this to true will increase memory consumption. | |||
*/ | |||
private boolean useColorCanvas = false; | |||
private final boolean useColorCanvas = false; | |||
/** | |||
* Controls whether the generation of PJL commands gets disabled. | |||
@@ -239,7 +239,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
/** @return the target resolution */ | |||
protected int getResolution() { | |||
int resolution = (int)Math.round(userAgent.getTargetResolution()); | |||
int resolution = Math.round(userAgent.getTargetResolution()); | |||
if (resolution <= 300) { | |||
return 300; | |||
} else { | |||
@@ -928,8 +928,8 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
int borderPaddingStart = bv.getBorderAndPaddingWidthStart(); | |||
int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore(); | |||
//This is the content-rect | |||
float width = (float)bv.getIPD() / 1000f; | |||
float height = (float)bv.getBPD() / 1000f; | |||
float width = bv.getIPD() / 1000f; | |||
float height = bv.getBPD() / 1000f; | |||
if (bv.getPositioning() == Block.ABSOLUTE | |||
@@ -951,7 +951,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
saveGraphicsState(); | |||
//Viewport position | |||
concatenateTransformationMatrix(mptToPt(positionTransform)); | |||
concatenateTransformationMatrix(UnitConv.mptToPt(positionTransform)); | |||
//Background and borders | |||
float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f; | |||
@@ -961,7 +961,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
//Shift to content rectangle after border painting | |||
AffineTransform contentRectTransform = new AffineTransform(); | |||
contentRectTransform.translate(borderPaddingStart, borderPaddingBefore); | |||
concatenateTransformationMatrix(mptToPt(contentRectTransform)); | |||
concatenateTransformationMatrix(UnitConv.mptToPt(contentRectTransform)); | |||
//Clipping | |||
if (bv.getClip()) { | |||
@@ -971,7 +971,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
saveGraphicsState(); | |||
//Set up coordinate system for content rectangle | |||
AffineTransform contentTransform = ctm.toAffineTransform(); | |||
concatenateTransformationMatrix(mptToPt(contentTransform)); | |||
concatenateTransformationMatrix(UnitConv.mptToPt(contentTransform)); | |||
currentIPPosition = 0; | |||
currentBPPosition = 0; | |||
@@ -1017,7 +1017,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
currentIPPosition = saveIP; | |||
currentBPPosition = saveBP; | |||
currentBPPosition += (int)(bv.getAllocBPD()); | |||
currentBPPosition += (bv.getAllocBPD()); | |||
} | |||
//currentFontName = saveFontName; | |||
} | |||
@@ -1041,7 +1041,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
if (!at.isIdentity()) { | |||
saveGraphicsState(); | |||
concatenateTransformationMatrix(mptToPt(at)); | |||
concatenateTransformationMatrix(UnitConv.mptToPt(at)); | |||
} | |||
currentIPPosition = 0; | |||
@@ -1079,7 +1079,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
if (!at.isIdentity()) { | |||
saveGraphicsState(); | |||
concatenateTransformationMatrix(mptToPt(at)); | |||
concatenateTransformationMatrix(UnitConv.mptToPt(at)); | |||
} | |||
currentIPPosition = 0; | |||
@@ -1102,7 +1102,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
*/ | |||
protected void concatenateTransformationMatrix(AffineTransform at) { | |||
if (!at.isIdentity()) { | |||
graphicContext.transform(ptToMpt(at)); | |||
graphicContext.transform(UnitConv.ptToMpt(at)); | |||
changePrintDirection(); | |||
} | |||
} | |||
@@ -1416,13 +1416,13 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { | |||
borderRect.width, | |||
borderRect.height); | |||
final Rectangle paintRect = new Rectangle( | |||
(int)Math.round(borderRect.x * 1000f), | |||
(int)Math.round(borderRect.y * 1000f), | |||
Math.round(borderRect.x * 1000f), | |||
Math.round(borderRect.y * 1000f), | |||
(int)Math.floor(borderRect.width * 1000f) + 1, | |||
(int)Math.floor(borderRect.height * 1000f) + 1); | |||
//Add one pixel wide safety margin around the paint area | |||
int pixelWidth = (int)Math.round(UnitConv.in2mpt(1) / userAgent.getTargetResolution()); | |||
final int xoffset = (int)Math.round(-effBorderRect.x * 1000f) + pixelWidth; | |||
final int xoffset = Math.round(-effBorderRect.x * 1000f) + pixelWidth; | |||
final int yoffset = pixelWidth; | |||
paintRect.x += xoffset; | |||
paintRect.y += yoffset; |
@@ -27,9 +27,9 @@ import org.apache.commons.logging.Log; | |||
import org.apache.commons.logging.LogFactory; | |||
import org.apache.fop.fo.Constants; | |||
import org.apache.fop.render.PrintRenderer; | |||
import org.apache.fop.render.intermediate.BorderPainter; | |||
import org.apache.fop.traits.RuleStyle; | |||
import org.apache.fop.util.ColorUtil; | |||
/** | |||
* PDF-specific implementation of the {@code BorderPainter}. | |||
@@ -150,8 +150,8 @@ public class PDFBorderPainter extends BorderPainter { | |||
float colFactor = (style == Constants.EN_GROOVE ? 0.4f : -0.4f); | |||
generator.add("[] 0 d "); | |||
if (horz) { | |||
Color uppercol = PrintRenderer.lightenColor(col, -colFactor); | |||
Color lowercol = PrintRenderer.lightenColor(col, colFactor); | |||
Color uppercol = ColorUtil.lightenColor(col, -colFactor); | |||
Color lowercol = ColorUtil.lightenColor(col, colFactor); | |||
float h3 = h / 3; | |||
generator.add(format(h3) + " w\n"); | |||
float ym1 = y1 + (h3 / 2); | |||
@@ -165,8 +165,8 @@ public class PDFBorderPainter extends BorderPainter { | |||
generator.add(format(x1) + " " + format(ym1 + h3 + h3) + " m " | |||
+ format(x2) + " " + format(ym1 + h3 + h3) + " l S\n"); | |||
} else { | |||
Color leftcol = PrintRenderer.lightenColor(col, -colFactor); | |||
Color rightcol = PrintRenderer.lightenColor(col, colFactor); | |||
Color leftcol = ColorUtil.lightenColor(col, -colFactor); | |||
Color rightcol = ColorUtil.lightenColor(col, colFactor); | |||
float w3 = w / 3; | |||
generator.add(format(w3) + " w\n"); | |||
float xm1 = x1 + (w3 / 2); | |||
@@ -189,14 +189,14 @@ public class PDFBorderPainter extends BorderPainter { | |||
generator.add("[] 0 d "); | |||
Color c = col; | |||
if (horz) { | |||
c = PrintRenderer.lightenColor(c, (startOrBefore ? 1 : -1) * colFactor); | |||
c = ColorUtil.lightenColor(c, (startOrBefore ? 1 : -1) * colFactor); | |||
generator.add(format(h) + " w\n"); | |||
float ym1 = y1 + (h / 2); | |||
generator.setColor(c, false); | |||
generator.add(format(x1) + " " + format(ym1) + " m " | |||
+ format(x2) + " " + format(ym1) + " l S\n"); | |||
} else { | |||
c = PrintRenderer.lightenColor(c, (startOrBefore ? 1 : -1) * colFactor); | |||
c = ColorUtil.lightenColor(c, (startOrBefore ? 1 : -1) * colFactor); | |||
generator.add(format(w) + " w\n"); | |||
float xm1 = x1 + (w / 2); | |||
generator.setColor(c, false); | |||
@@ -254,7 +254,7 @@ public class PDFBorderPainter extends BorderPainter { | |||
break; | |||
case Constants.EN_GROOVE: | |||
case Constants.EN_RIDGE: | |||
generator.setColor(PrintRenderer.lightenColor(color, 0.6f), true); | |||
generator.setColor(ColorUtil.lightenColor(color, 0.6f), true); | |||
generator.add(format(start.x) + " " + format(starty) + " m\n"); | |||
generator.add(format(end.x) + " " + format(starty) + " l\n"); | |||
generator.add(format(end.x) + " " + format(starty + 2 * half) + " l\n"); |
@@ -93,6 +93,7 @@ import org.apache.fop.render.Graphics2DAdapter; | |||
import org.apache.fop.render.RendererContext; | |||
import org.apache.fop.traits.RuleStyle; | |||
import org.apache.fop.util.CharUtilities; | |||
import org.apache.fop.util.ColorUtil; | |||
/** | |||
* Renderer that renders areas to PDF. |
@@ -106,6 +106,7 @@ import org.apache.fop.render.ps.extensions.PSExtensionAttachment; | |||
import org.apache.fop.render.ps.extensions.PSSetPageDevice; | |||
import org.apache.fop.render.ps.extensions.PSSetupCode; | |||
import org.apache.fop.util.CharUtilities; | |||
import org.apache.fop.util.ColorUtil; | |||
/** | |||
* Renderer that renders to PostScript. | |||
@@ -839,8 +840,8 @@ public class PSRenderer extends AbstractPathOrientedRenderer | |||
float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f); | |||
gen.useDash(null); | |||
if (horz) { | |||
Color uppercol = lightenColor(col, -colFactor); | |||
Color lowercol = lightenColor(col, colFactor); | |||
Color uppercol = ColorUtil.lightenColor(col, -colFactor); | |||
Color lowercol = ColorUtil.lightenColor(col, colFactor); | |||
float h3 = h / 3; | |||
gen.useLineWidth(h3); | |||
float ym1 = y1 + (h3 / 2); | |||
@@ -851,8 +852,8 @@ public class PSRenderer extends AbstractPathOrientedRenderer | |||
gen.useColor(lowercol); | |||
drawLine(x1, ym1 + h3 + h3, x2, ym1 + h3 + h3); | |||
} else { | |||
Color leftcol = lightenColor(col, -colFactor); | |||
Color rightcol = lightenColor(col, colFactor); | |||
Color leftcol = ColorUtil.lightenColor(col, -colFactor); | |||
Color rightcol = ColorUtil.lightenColor(col, colFactor); | |||
float w3 = w / 3; | |||
gen.useLineWidth(w3); | |||
float xm1 = x1 + (w3 / 2); | |||
@@ -869,13 +870,13 @@ public class PSRenderer extends AbstractPathOrientedRenderer | |||
colFactor = (style == EN_OUTSET ? 0.4f : -0.4f); | |||
gen.useDash(null); | |||
if (horz) { | |||
Color c = lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); | |||
Color c = ColorUtil.lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); | |||
gen.useLineWidth(h); | |||
float ym1 = y1 + (h / 2); | |||
gen.useColor(c); | |||
drawLine(x1, ym1, x2, ym1); | |||
} else { | |||
Color c = lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); | |||
Color c = ColorUtil.lightenColor(col, (startOrBefore ? 1 : -1) * colFactor); | |||
gen.useLineWidth(w); | |||
float xm1 = x1 + (w / 2); | |||
gen.useColor(c); | |||
@@ -1570,7 +1571,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer | |||
case EN_RIDGE: | |||
float half = area.getRuleThickness() / 2000f; | |||
gen.useColor(lightenColor(col, 0.6f)); | |||
gen.useColor(ColorUtil.lightenColor(col, 0.6f)); | |||
moveTo(startx, starty); | |||
lineTo(endx, starty); | |||
lineTo(endx, starty + 2 * half); |
@@ -222,7 +222,7 @@ public class RTFHandler extends FOEventHandler { | |||
PageSequenceMaster master | |||
= pageSeq.getRoot().getLayoutMasterSet().getPageSequenceMaster(reference); | |||
this.pagemaster = master.getNextSimplePageMaster( | |||
false, false, false, false, false); | |||
false, false, false, false); | |||
} | |||
} | |||
@@ -26,8 +26,8 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc; | |||
* the FOP project. | |||
*/ | |||
import java.io.Writer; | |||
import java.io.IOException; | |||
import java.io.Writer; | |||
import java.util.Iterator; | |||
/** A cell in an RTF table, container for paragraphs, lists, etc. | |||
@@ -237,12 +237,12 @@ public class RtfTableCell | |||
// Reach the column index in table context corresponding to the current column cell | |||
// id is the index of the current cell (it begins at 1) | |||
// getColumnIndex() is the index of the current column in table context (it begins at 0) | |||
// => so we must widthdraw 1 when comparing these two variables. | |||
// => so we must withdraw 1 when comparing these two variables. | |||
while ((this.id - 1) != tableColumnsInfo.getColumnIndex()) { | |||
tableColumnsInfo.selectNextColumn(); | |||
} | |||
// We widthdraw one cell because the first cell is already created | |||
// We withdraw one cell because the first cell is already created | |||
// (it's the current cell) ! | |||
int i = nbMergedCells - 1; | |||
while (i > 0) { | |||
@@ -255,21 +255,18 @@ public class RtfTableCell | |||
final int xPos = offset + iCurrentWidth; | |||
//these lines added by Chris Scott, Westinghouse | |||
//some attributes need to be writting before opening block | |||
//some attributes need to be written before opening block | |||
if (setCenter) { | |||
writeControlWord("qc"); | |||
writeControlWord("trqc"); | |||
} else if (setRight) { | |||
writeControlWord("qr"); | |||
writeControlWord("trqr"); | |||
} else { | |||
writeControlWord("ql"); | |||
writeControlWord("trql"); | |||
} | |||
writeAttributes (attrib, ITableAttributes.CELL_VERT_ALIGN); | |||
writeControlWord("cellx" + xPos); | |||
//TODO Why is this here, right after an alignment command is written (see above)? | |||
writeControlWord("ql"); | |||
return xPos; | |||
} |
@@ -37,6 +37,7 @@ import org.apache.fop.area.inline.TextArea; | |||
import org.apache.fop.render.AbstractPathOrientedRenderer; | |||
import org.apache.fop.render.txt.border.AbstractBorderElement; | |||
import org.apache.fop.render.txt.border.BorderManager; | |||
import org.apache.xmlgraphics.util.UnitConv; | |||
/** | |||
* Renderer that renders areas to plain text. | |||
@@ -85,10 +86,10 @@ public class TXTRenderer extends AbstractPathOrientedRenderer { | |||
* Every line except the last line on a page (which will end with | |||
* pageEnding) will be terminated with this string. | |||
*/ | |||
private String lineEnding = "\r\n"; | |||
private final String lineEnding = "\r\n"; | |||
/** Every page except the last one will end with this string. */ | |||
private String pageEnding = "\f"; | |||
private final String pageEnding = "\f"; | |||
/** Equals true, if current page is first. */ | |||
private boolean firstPage = false; | |||
@@ -100,7 +101,7 @@ public class TXTRenderer extends AbstractPathOrientedRenderer { | |||
private char fillChar; | |||
/** Saves current coordinate transformation. */ | |||
private TXTState currentState = new TXTState(); | |||
private final TXTState currentState = new TXTState(); | |||
private String encoding; | |||
@@ -570,7 +571,7 @@ public class TXTRenderer extends AbstractPathOrientedRenderer { | |||
/** {@inheritDoc} */ | |||
protected void concatenateTransformationMatrix(AffineTransform at) { | |||
currentState.push(new CTM(ptToMpt(at))); | |||
currentState.push(new CTM(UnitConv.ptToMpt(at))); | |||
} | |||
} |
@@ -285,7 +285,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { | |||
/** | |||
* Get the string containing all the commands written into this | |||
* Grpahics. | |||
* Graphics. | |||
* @return the string containing the PDF markup | |||
*/ | |||
public String getString() { | |||
@@ -294,7 +294,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { | |||
/** | |||
* Get the string buffer from the currentStream, containing all | |||
* the commands written into this Grpahics so far. | |||
* the commands written into this Graphics so far. | |||
* @return the StringBuffer containing the PDF markup | |||
*/ | |||
public StringBuffer getBuffer() { | |||
@@ -876,7 +876,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { | |||
if (paint instanceof RadialGradientPaint) { | |||
RadialGradientPaint rgp = (RadialGradientPaint)paint; | |||
// There is essentially no way to support repeate | |||
// There is essentially no way to support repeats | |||
// in PDF for radial gradients (the one option would | |||
// be to 'grow' the outer circle until it fully covered | |||
// the bounds and then grow the stops accordingly, the |
@@ -147,7 +147,9 @@ public class PDFTextPainter extends StrokingTextPainter { | |||
textUtil.beginTextObject(); | |||
textUtil.setFonts(fonts); | |||
textUtil.setTextRenderingMode(tpi.fillPaint != null, tpi.strokePaint != null, false); | |||
boolean stroke = (tpi.strokePaint != null) | |||
&& (tpi.strokeStroke != null); | |||
textUtil.setTextRenderingMode(tpi.fillPaint != null, stroke, false); | |||
AffineTransform localTransform = new AffineTransform(); | |||
Point2D prevPos = null; |
@@ -1,36 +0,0 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.traits; | |||
import org.apache.fop.datatypes.Length; | |||
/** | |||
* Store all block-level layout properties on an FO. | |||
* Public "structure" allows direct member access. | |||
*/ | |||
public class BlockProps { | |||
public Length firstIndent; // text-indent | |||
public int lastIndent; // last-line-indent | |||
public int textAlign; | |||
public int textAlignLast; | |||
public int lineStackType; // line-stacking-strategy (enum) | |||
} |
@@ -1,35 +0,0 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.traits; | |||
/** | |||
* Store all inline "margin" related properties | |||
* Public "structure" allows direct member access. | |||
*/ | |||
public class InlineProps { | |||
public int marginTop; | |||
public int marginBottom; | |||
public int marginLeft; | |||
public int marginRight; | |||
public SpaceVal spaceStart; | |||
public SpaceVal spaceEnd; | |||
} |
@@ -1,88 +0,0 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.traits; | |||
import org.apache.fop.datatypes.KeepValue; | |||
import org.apache.fop.fo.Constants; | |||
/** | |||
* Store properties affecting layout: break-before, break-after, keeps, span. | |||
* for a block level FO. | |||
* Public "structure" allows direct member access. | |||
*/ | |||
public class LayoutProps { | |||
public int breakBefore; // enum constant BreakBefore.xxx | |||
public int breakAfter; // enum constant BreakAfter.xxx | |||
public KeepValue keepWithPrevious; /*LF*/ | |||
public KeepValue keepWithNext; /*LF*/ | |||
public KeepValue keepTogether; /*LF*/ | |||
public int orphans; /*LF*/ | |||
public int widows; /*LF*/ | |||
public int blockProgressionUnit; /*LF*/ | |||
public int lineStackingStrategy; /*LF*/ | |||
public boolean bIsSpan; | |||
public SpaceVal spaceBefore; | |||
public SpaceVal spaceAfter; | |||
private static final int[] BREAK_PRIORITIES = | |||
new int[]{ Constants.EN_AUTO, Constants.EN_COLUMN, Constants.EN_PAGE }; | |||
public LayoutProps() { | |||
breakBefore = breakAfter = Constants.EN_AUTO; | |||
bIsSpan = false; | |||
} | |||
// public static int higherBreak(int brkParent, int brkChild) { | |||
// if (brkParent == brkChild) return brkChild; | |||
// for (int i=0; i < s_breakPriorities.length; i++) { | |||
// int bp = s_breakPriorities[i]; | |||
// if (bp == brkParent) return brkChild; | |||
// else if (bp == brkChild) return brkParent; | |||
// } | |||
// return brkChild; | |||
// } | |||
public void combineWithParent(LayoutProps parentLP) { | |||
if (parentLP.breakBefore != breakBefore) { | |||
for (int i = 0; i < BREAK_PRIORITIES.length; i++) { | |||
int bp = BREAK_PRIORITIES[i]; | |||
if (bp == breakBefore) { | |||
breakBefore = parentLP.breakBefore; | |||
break; | |||
} else if (bp == parentLP.breakBefore) { | |||
break; | |||
} | |||
} | |||
} | |||
// Parent span always overrides child span | |||
bIsSpan = parentLP.bIsSpan; | |||
} | |||
public String toString() { | |||
return "LayoutProps:\n" + | |||
"breakBefore = " + breakBefore + "; breakAfter = " + breakAfter + "\n" + | |||
"spaceBefore = " + ((spaceBefore != null) ? spaceBefore.toString() : "null") + "\n" + | |||
"spaceAfter = " + ((spaceAfter != null) ? spaceAfter.toString() : "null") + "\n" + | |||
"bIsSpan = " + bIsSpan + "\n"; | |||
} | |||
} | |||
@@ -658,4 +658,27 @@ public final class ColorUtil { | |||
colorMap.put("transparent", new Color(0, 0, 0, 0)); | |||
} | |||
/** | |||
* Lightens up a color for groove, ridge, inset and outset border effects. | |||
* @param col the color to lighten up | |||
* @param factor factor by which to lighten up (negative values darken the color) | |||
* @return the modified color | |||
*/ | |||
public static Color lightenColor(Color col, float factor) { | |||
// TODO: This function converts the color into the sRGB namespace. | |||
// This should be avoided if possible. | |||
float[] cols = new float[4]; | |||
cols = col.getRGBComponents(cols); | |||
if (factor > 0) { | |||
cols[0] += (1.0 - cols[0]) * factor; | |||
cols[1] += (1.0 - cols[1]) * factor; | |||
cols[2] += (1.0 - cols[2]) * factor; | |||
} else { | |||
cols[0] -= cols[0] * -factor; | |||
cols[1] -= cols[1] * -factor; | |||
cols[2] -= cols[2] * -factor; | |||
} | |||
return new Color(cols[0], cols[1], cols[2], cols[3]); | |||
} | |||
} |
@@ -19,60 +19,25 @@ | |||
package org.apache.fop.util; | |||
import java.io.ByteArrayInputStream; | |||
import javax.xml.transform.Source; | |||
import javax.xml.transform.TransformerException; | |||
import javax.xml.transform.URIResolver; | |||
import javax.xml.transform.stream.StreamSource; | |||
// base64 support for "data" urls | |||
import org.apache.xmlgraphics.util.io.Base64DecodeStream; | |||
/** | |||
* Resolves data URLs (described in RFC 2397) returning its data as a StreamSource. | |||
* | |||
* @see javax.xml.transform.URIResolver | |||
* @see <a href="http://www.ietf.org/rfc/rfc2397">RFC 2397</a> | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.uri.DataURIResolver | |||
*/ | |||
public class DataURIResolver implements URIResolver { | |||
/** | |||
* {@inheritDoc} | |||
*/ | |||
public Source resolve(String href, String base) throws TransformerException { | |||
if (href.startsWith("data:")) { | |||
return parseDataURI(href); | |||
} else { | |||
return null; | |||
} | |||
} | |||
private final URIResolver newResolver = new org.apache.xmlgraphics.util.uri.DataURIResolver(); | |||
/** | |||
* Parses inline data URIs as generated by MS Word's XML export and FO | |||
* stylesheet. | |||
* | |||
* @see <a href="http://www.ietf.org/rfc/rfc2397">RFC 2397</a> | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.uri.DataURIResolver#resolve(String, | |||
* String) | |||
*/ | |||
private Source parseDataURI(String href) { | |||
int commaPos = href.indexOf(','); | |||
// header is of the form data:[<mediatype>][;base64] | |||
String header = href.substring(0, commaPos); | |||
String data = href.substring(commaPos + 1); | |||
if (header.endsWith(";base64")) { | |||
byte[] bytes = data.getBytes(); | |||
ByteArrayInputStream encodedStream = new ByteArrayInputStream(bytes); | |||
Base64DecodeStream decodedStream = new Base64DecodeStream( | |||
encodedStream); | |||
return new StreamSource(decodedStream); | |||
} else { | |||
// Note that this is not quite the full story here. But since we are | |||
// only interested | |||
// in base64-encoded binary data, the next line will probably never | |||
// be called. | |||
//TODO Handle un-escaping of special URL chars like %20 | |||
return new StreamSource(new java.io.StringReader(data)); | |||
} | |||
public Source resolve(String href, String base) throws TransformerException { | |||
return newResolver.resolve(href, base); | |||
} | |||
} |
@@ -21,47 +21,33 @@ package org.apache.fop.util; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.StringWriter; | |||
import java.io.Writer; | |||
import org.apache.commons.io.IOUtils; | |||
import org.apache.xmlgraphics.util.io.Base64EncodeStream; | |||
/** | |||
* Utility classes for generating RFC 2397 data URLs. | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.uri.DataURLUtil | |||
*/ | |||
public class DataURLUtil { | |||
/** | |||
* Creates a new data URL and returns it as a String. | |||
* @param in the InputStream to read the data from | |||
* @param mediatype the MIME type of the content, or null | |||
* @return the newly created data URL | |||
* @throws IOException if an I/O error occurs | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.uri.DataURLUtil#createDataURL(InputStream, | |||
* String) | |||
*/ | |||
public static String createDataURL(InputStream in, String mediatype) throws IOException { | |||
StringWriter writer = new StringWriter(); | |||
writeDataURL(in, mediatype, writer); | |||
return writer.toString(); | |||
public static String createDataURL(InputStream in, String mediatype) | |||
throws IOException { | |||
return org.apache.xmlgraphics.util.uri.DataURLUtil.createDataURL(in, | |||
mediatype); | |||
} | |||
/** | |||
* Generates a data URL and writes it to a Writer. | |||
* @param in the InputStream to read the data from | |||
* @param mediatype the MIME type of the content, or null | |||
* @param writer the Writer to write to | |||
* @throws IOException if an I/O error occurs | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.uri.DataURLUtil#writeDataURL(InputStream, | |||
* String, Writer) | |||
*/ | |||
public static void writeDataURL(InputStream in, String mediatype, Writer writer) | |||
throws IOException { | |||
writer.write("data:"); | |||
if (mediatype != null) { | |||
writer.write(mediatype); | |||
} | |||
writer.write(";base64,"); | |||
Base64EncodeStream out = new Base64EncodeStream( | |||
new WriterOutputStream(writer, "US-ASCII")); | |||
IOUtils.copy(in, out); | |||
out.flush(); | |||
public static void writeDataURL(InputStream in, String mediatype, | |||
Writer writer) throws IOException { | |||
org.apache.xmlgraphics.util.uri.DataURLUtil.writeDataURL(in, mediatype, | |||
writer); | |||
} | |||
} |
@@ -15,94 +15,114 @@ | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
/* $Id: $ */ | |||
package org.apache.fop.util; | |||
import java.awt.geom.AffineTransform; | |||
/** | |||
* Utility class for unit conversions. | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv instead. | |||
*/ | |||
public final class UnitConv { | |||
/** conversion factory from millimeters to inches. */ | |||
public static final float IN2MM = 25.4f; | |||
/** | |||
* conversion factory from millimeters to inches. | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.IN2MM instead. | |||
*/ | |||
public static final float IN2MM = org.apache.xmlgraphics.util.UnitConv.IN2MM; | |||
/** conversion factory from centimeters to inches. */ | |||
public static final float IN2CM = 2.54f; | |||
/** | |||
* conversion factory from centimeters to inches. | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.IN2CM instead. | |||
*/ | |||
public static final float IN2CM = org.apache.xmlgraphics.util.UnitConv.IN2CM; | |||
/** conversion factory from inches to points. */ | |||
public static final int IN2PT = 72; | |||
/** | |||
* conversion factory from inches to points. | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.IN2PT instead. | |||
*/ | |||
public static final int IN2PT = org.apache.xmlgraphics.util.UnitConv.IN2PT; | |||
/** | |||
* Converts millimeters (mm) to points (pt) | |||
* @param mm the value in mm | |||
* @return the value in pt | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.mm2pt(mm) instead. | |||
*/ | |||
public static double mm2pt(double mm) { | |||
return mm * IN2PT / IN2MM; | |||
return org.apache.xmlgraphics.util.UnitConv.mm2pt(mm); | |||
} | |||
/** | |||
* Converts millimeters (mm) to millipoints (mpt) | |||
* @param mm the value in mm | |||
* @return the value in mpt | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.mm2mpt(mm) instead. | |||
*/ | |||
public static double mm2mpt(double mm) { | |||
return mm * 1000 * IN2PT / IN2MM; | |||
return org.apache.xmlgraphics.util.UnitConv.mm2mpt(mm); | |||
} | |||
/** | |||
* Converts points (pt) to millimeters (mm) | |||
* @param pt the value in pt | |||
* @return the value in mm | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.pt2mm(pt) instead. | |||
*/ | |||
public static double pt2mm(double pt) { | |||
return pt * IN2MM / IN2PT; | |||
return org.apache.xmlgraphics.util.UnitConv.pt2mm(pt); | |||
} | |||
/** | |||
* Converts millimeters (mm) to inches (in) | |||
* @param mm the value in mm | |||
* @return the value in inches | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.pt2mm(pt) instead. | |||
*/ | |||
public static double mm2in(double mm) { | |||
return mm / IN2MM; | |||
return org.apache.xmlgraphics.util.UnitConv.mm2in(mm); | |||
} | |||
/** | |||
* Converts inches (in) to millimeters (mm) | |||
* @param in the value in inches | |||
* @return the value in mm | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.in2mm(in) instead. | |||
*/ | |||
public static double in2mm(double in) { | |||
return in * IN2MM; | |||
return org.apache.xmlgraphics.util.UnitConv.in2mm(in); | |||
} | |||
/** | |||
* Converts inches (in) to millipoints (mpt) | |||
* @param in the value in inches | |||
* @return the value in mpt | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.in2mpt(in) instead. | |||
*/ | |||
public static double in2mpt(double in) { | |||
return in * IN2PT * 1000; | |||
return org.apache.xmlgraphics.util.UnitConv.in2mpt(in); | |||
} | |||
/** | |||
* Converts inches (in) to points (pt) | |||
* @param in the value in inches | |||
* @return the value in pt | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.in2pt(in) instead. | |||
*/ | |||
public static double in2pt(double in) { | |||
return in * IN2PT; | |||
return org.apache.xmlgraphics.util.UnitConv.in2pt(in); | |||
} | |||
/** | |||
* Converts millipoints (mpt) to inches (in) | |||
* @param mpt the value in mpt | |||
* @return the value in inches | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.mpt2in(mpt) instead. | |||
*/ | |||
public static double mpt2in(double mpt) { | |||
return mpt / IN2PT / 1000; | |||
return org.apache.xmlgraphics.util.UnitConv.mpt2in(mpt); | |||
} | |||
/** | |||
@@ -110,9 +130,10 @@ public final class UnitConv { | |||
* @param mm the value in mm | |||
* @param resolution the resolution in dpi (dots per inch) | |||
* @return the value in pixels | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.mm2px(mm, resolution) instead. | |||
*/ | |||
public static double mm2px(double mm, int resolution) { | |||
return mm2in(mm) * resolution; | |||
return org.apache.xmlgraphics.util.UnitConv.mm2px(mm, resolution); | |||
} | |||
/** | |||
@@ -120,9 +141,30 @@ public final class UnitConv { | |||
* @param mpt the value in mpt | |||
* @param resolution the resolution in dpi (dots per inch) | |||
* @return the value in pixels | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.mpt2px(mpt, resolution) instead. | |||
*/ | |||
public static double mpt2px(double mpt, int resolution) { | |||
return mpt2in(mpt) * resolution; | |||
return org.apache.xmlgraphics.util.UnitConv.mpt2px(mpt, resolution); | |||
} | |||
/** | |||
* Converts a millipoint-based transformation matrix to points. | |||
* @param at a millipoint-based transformation matrix | |||
* @return a point-based transformation matrix | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.mptToPt(at) instead. | |||
*/ | |||
public static AffineTransform mptToPt(AffineTransform at) { | |||
return org.apache.xmlgraphics.util.UnitConv.mptToPt(at); | |||
} | |||
/** | |||
* Converts a point-based transformation matrix to millipoints. | |||
* @param at a point-based transformation matrix | |||
* @return a millipoint-based transformation matrix | |||
* @deprecated use org.apache.xmlgraphics.util.UnitConv.ptToMpt(at) instead. | |||
*/ | |||
public static AffineTransform ptToMpt(AffineTransform at) { | |||
return org.apache.xmlgraphics.util.UnitConv.ptToMpt(at); | |||
} | |||
} |
@@ -24,68 +24,72 @@ import java.io.OutputStream; | |||
import java.io.Writer; | |||
/** | |||
* An OutputStream wrapper for a Writer. | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.WriterOutputStream | |||
*/ | |||
public class WriterOutputStream extends OutputStream { | |||
private Writer writer; | |||
private String encoding; | |||
private final org.apache.xmlgraphics.util.WriterOutputStream writerOutputStream; | |||
/** | |||
* Creates a new WriterOutputStream. | |||
* @param writer the Writer to write to | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.WriterOutputStream#WriterOutputStream(Writer) | |||
* String) | |||
*/ | |||
public WriterOutputStream(Writer writer) { | |||
this(writer, null); | |||
writerOutputStream = new org.apache.xmlgraphics.util.WriterOutputStream( | |||
writer); | |||
} | |||
/** | |||
* Creates a new WriterOutputStream. | |||
* @param writer the Writer to write to | |||
* @param encoding the encoding to use, or null if the default encoding should be used | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.WriterOutputStream#WriterOutputStream(Writer, | |||
* String) String) | |||
*/ | |||
public WriterOutputStream(Writer writer, String encoding) { | |||
this.writer = writer; | |||
this.encoding = encoding; | |||
writerOutputStream = new org.apache.xmlgraphics.util.WriterOutputStream( | |||
writer, encoding); | |||
} | |||
/** | |||
* {@inheritDoc} | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.WriterOutputStream#close() | |||
*/ | |||
public void close() throws IOException { | |||
writer.close(); | |||
writerOutputStream.close(); | |||
} | |||
/** | |||
* {@inheritDoc} | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.WriterOutputStream#flush() | |||
*/ | |||
public void flush() throws IOException { | |||
writer.flush(); | |||
writerOutputStream.flush(); | |||
} | |||
/** | |||
* {@inheritDoc} | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.WriterOutputStream#write(byte[], int, | |||
* int) | |||
*/ | |||
public void write(byte[] buf, int offset, int length) throws IOException { | |||
if (encoding != null) { | |||
writer.write(new String(buf, offset, length, encoding)); | |||
} else { | |||
writer.write(new String(buf, offset, length)); | |||
} | |||
writerOutputStream.write(buf, offset, length); | |||
} | |||
/** | |||
* {@inheritDoc} | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.WriterOutputStream#write(byte[]) | |||
*/ | |||
public void write(byte[] buf) throws IOException { | |||
write(buf, 0, buf.length); | |||
writerOutputStream.write(buf); | |||
} | |||
/** | |||
* {@inheritDoc} | |||
* @deprecated | |||
* @see org.apache.xmlgraphics.util.WriterOutputStream#write(int) | |||
*/ | |||
public void write(int b) throws IOException { | |||
write(new byte[] {(byte)b}); | |||
writerOutputStream.write(b); | |||
} | |||
} |
@@ -53,6 +53,46 @@ | |||
<changes> | |||
<release version="FOP Trunk" date="TBD"> | |||
<action context="Layout" dev="AD" type="fix" fixes-bug="40798"> | |||
Bugzilla 40798: A conditional-page-master-reference with page-position="last" qualifies | |||
for a first page, if it is also the last. Additionally: also added support for | |||
page-position="only". | |||
</action> | |||
<action context="Code" dev="AD" type="fix" fixes-bug="45842" due-to="Carsten Siedentop"> | |||
Make fop.bat and fop.cmd use the %FOP_OPTS% environment variable. | |||
</action> | |||
<action context="Renderers" dev="JM" type="add" fixes-bug="45795"> | |||
PDF Output: Added support for handling 16-bit alpha channel. They are currently | |||
converted to 8 bits. | |||
</action> | |||
<action context="Renderers" dev="JM" type="fix"> | |||
PDF Output: Made sure the XMP Metadata stream is never compressed. | |||
</action> | |||
<action context="Fonts" dev="JM" type="fix" fixes-bug="45734" due-to="J. Frantzius"> | |||
Fix for PFMReader after bug #43089 changed the behavior of PFMFile. Fixes baseline | |||
problems when Type 1 fonts are used in conjunction with XML font metric files. | |||
</action> | |||
<action context="Renderers" dev="JM" type="fix" fixes-bug="45616" due-to="Pavel Kysilka"> | |||
Fix for table handling in RTF output, so the output works with OpenOffice and AbiWord, too. | |||
</action> | |||
<action context="Code" dev="AD" type="fix" fixes-bug="45667"> | |||
Quick-fix to avoid a possible NullPointerException when using | |||
empty inlines and hyphenation. | |||
</action> | |||
<action context="Layout" dev="JM" type="add"> | |||
Added missing generation of areas for empty grid units in tables with collapsing border | |||
model. | |||
</action> | |||
<action context="Code" dev="JM" type="fix" importance="high"> | |||
Fixed memory leak in property cache (not cleaning stale PropertyCache$CacheEntry instances). | |||
</action> | |||
<action context="Renderers" dev="JM" type="fix"> | |||
Fixed text stroking in SVG when the stroke-width is zero. | |||
</action> | |||
<action context="Layout" dev="JM" type="fix"> | |||
Fixed the source for a division by zero when the content of an fo:leader with | |||
leader-pattern="use-content" collapses to zero width during layout. | |||
</action> | |||
<action context="Renderers" dev="JM" type="fix"> | |||
Fixed border trait parsing for the area tree XML when CMYK or ICC colors were used. | |||
</action> | |||
@@ -128,7 +168,7 @@ | |||
Fixed a ClassCastException when using an fo:wrapper as a child | |||
of an fo:block-container. | |||
</action> | |||
<action context="Fonts" dev="AC" type="add"> | |||
<action context="Fonts" dev="AC" type="add" importance="high"> | |||
Add support for font substitution. | |||
</action> | |||
<action context="Renderers" dev="JM" type="fix" fixes-bug="43650"> | |||
@@ -151,7 +191,7 @@ | |||
Add partial support for the "show-destination" property on fo:basic-link | |||
(PDF output only; see limitations on the compliance page) | |||
</action> | |||
<action context="Layout" dev="JM" type="add"> | |||
<action context="Layout" dev="JM" type="add" importance="high"> | |||
Added minimal support for integer keep values on the various keep properties on block-level | |||
FOs. For now, all integer values are treated the same (i.e. without strength distinction). | |||
Using integers allows to avoid overflows that can happen when "always" is used extensively. | |||
@@ -179,7 +219,7 @@ | |||
When a JPEG image is embedded, an optionally embedded color profile is filtered out | |||
as it's already embedded separately in the PDF file. | |||
</action> | |||
<action context="Fonts" dev="JM" type="add"> | |||
<action context="Fonts" dev="JM" type="add" importance="high"> | |||
Added support for addressing all glyphs available in a Type 1 font, not just the ones | |||
in the font's primary encoding. | |||
</action> | |||
@@ -678,7 +718,7 @@ | |||
<action context="Code" dev="JM" type="fix"> | |||
AFP Renderer: Bugfix for 1 bit images where the width is not a multiple of 8. | |||
</action> | |||
<action context="Code" dev="MM" type="add"> | |||
<action context="Code" dev="MM" type="add" importance="high"> | |||
Support for keep-together.within-line="always". | |||
</action> | |||
<action context="Code" dev="MM" type="fix"> |
@@ -23,6 +23,8 @@ import junit.framework.Test; | |||
import junit.framework.TestSuite; | |||
import org.apache.fop.fonts.TrueTypeAnsiTestCase; | |||
import org.apache.fop.image.loader.batik.ImageLoaderTestCase; | |||
import org.apache.fop.image.loader.batik.ImagePreloaderTestCase; | |||
import org.apache.fop.render.pdf.PDFAConformanceTestCase; | |||
import org.apache.fop.render.pdf.PDFCMapTestCase; | |||
import org.apache.fop.render.pdf.PDFEncodingTestCase; | |||
@@ -50,6 +52,8 @@ public class StandardTestSuite { | |||
suite.addTest(new TestSuite(PDFsRGBSettingsTestCase.class)); | |||
suite.addTest(new TestSuite(TrueTypeAnsiTestCase.class)); | |||
suite.addTest(RichTextFormatTestSuite.suite()); | |||
suite.addTest(new TestSuite(ImageLoaderTestCase.class)); | |||
suite.addTest(new TestSuite(ImagePreloaderTestCase.class)); | |||
//$JUnit-END$ | |||
return suite; | |||
} |
@@ -66,6 +66,7 @@ public class URIResolutionTestCase extends AbstractFOPTestCase { | |||
/** @see junit.framework.TestCase#TestCase(String) */ | |||
public URIResolutionTestCase(String name) { | |||
super(name); | |||
backupDir.mkdirs(); | |||
} | |||
/** |
@@ -22,14 +22,12 @@ package org.apache.fop; | |||
import junit.framework.Test; | |||
import junit.framework.TestSuite; | |||
import org.apache.fop.pdf.PDFObjectTestCase; | |||
import org.apache.fop.events.BasicEventTestCase; | |||
import org.apache.fop.pdf.PDFObjectTestCase; | |||
import org.apache.fop.traits.BorderPropsTestCase; | |||
import org.apache.fop.util.DataURIResolverTestCase; | |||
import org.apache.fop.util.ColorUtilTestCase; | |||
import org.apache.fop.util.ElementListUtilsTestCase; | |||
import org.apache.fop.util.PDFNumberTestCase; | |||
import org.apache.fop.util.ColorUtilTestCase; | |||
import org.apache.fop.util.UnitConvTestCase; | |||
import org.apache.fop.util.XMLResourceBundleTestCase; | |||
/** | |||
@@ -47,13 +45,12 @@ public class UtilityCodeTestSuite { | |||
//$JUnit-BEGIN$ | |||
suite.addTest(new TestSuite(PDFNumberTestCase.class)); | |||
suite.addTest(new TestSuite(PDFObjectTestCase.class)); | |||
suite.addTest(new TestSuite(UnitConvTestCase.class)); | |||
suite.addTest(new TestSuite(ColorUtilTestCase.class)); | |||
suite.addTest(new TestSuite(BorderPropsTestCase.class)); | |||
suite.addTest(new TestSuite(ElementListUtilsTestCase.class)); | |||
suite.addTest(new TestSuite(DataURIResolverTestCase.class)); | |||
suite.addTest(new TestSuite(BasicEventTestCase.class)); | |||
suite.addTest(new TestSuite(XMLResourceBundleTestCase.class)); | |||
suite.addTest(new TestSuite(URIResolutionTestCase.class)); | |||
//$JUnit-END$ | |||
return suite; | |||
} |
@@ -19,21 +19,23 @@ | |||
package org.apache.fop.image.loader.batik; | |||
import java.awt.image.Raster; | |||
import java.awt.image.RenderedImage; | |||
import java.io.File; | |||
import junit.framework.TestCase; | |||
import org.apache.fop.apps.FOUserAgent; | |||
import org.apache.fop.apps.FopFactory; | |||
import org.apache.xmlgraphics.image.loader.Image; | |||
import org.apache.xmlgraphics.image.loader.ImageFlavor; | |||
import org.apache.xmlgraphics.image.loader.ImageInfo; | |||
import org.apache.xmlgraphics.image.loader.ImageManager; | |||
import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor; | |||
import org.apache.xmlgraphics.image.loader.impl.ImageRendered; | |||
import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; | |||
import org.apache.xmlgraphics.image.writer.ImageWriterUtil; | |||
import org.apache.fop.apps.FOUserAgent; | |||
import org.apache.fop.apps.FopFactory; | |||
/** | |||
* Tests for bundled ImageLoader implementations. | |||
*/ | |||
@@ -59,10 +61,10 @@ public class ImageLoaderTestCase extends TestCase { | |||
ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext()); | |||
assertNotNull("ImageInfo must not be null", info); | |||
Image img = manager.getImage(info, ImageFlavor.XML_DOM, | |||
Image img = manager.getImage(info, XMLNamespaceEnabledImageFlavor.SVG_DOM, | |||
userAgent.getImageSessionContext()); | |||
assertNotNull("Image must not be null", img); | |||
assertEquals(ImageFlavor.XML_DOM, img.getFlavor()); | |||
assertEquals(XMLNamespaceEnabledImageFlavor.SVG_DOM, img.getFlavor()); | |||
ImageXMLDOM imgDom = (ImageXMLDOM)img; | |||
assertNotNull(imgDom.getDocument()); | |||
assertEquals("http://www.w3.org/2000/svg", imgDom.getRootNamespace()); | |||
@@ -101,10 +103,10 @@ public class ImageLoaderTestCase extends TestCase { | |||
ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext()); | |||
assertNotNull("ImageInfo must not be null", info); | |||
Image img = manager.getImage(info, ImageFlavor.XML_DOM, | |||
Image img = manager.getImage(info, XMLNamespaceEnabledImageFlavor.SVG_DOM, | |||
userAgent.getImageSessionContext()); | |||
assertNotNull("Image must not be null", img); | |||
assertEquals(ImageFlavor.XML_DOM, img.getFlavor()); | |||
assertEquals(XMLNamespaceEnabledImageFlavor.SVG_DOM, img.getFlavor()); | |||
ImageXMLDOM imgDom = (ImageXMLDOM)img; | |||
assertNotNull(imgDom.getDocument()); | |||
assertEquals("http://www.w3.org/2000/svg", imgDom.getRootNamespace()); | |||
@@ -160,4 +162,58 @@ public class ImageLoaderTestCase extends TestCase { | |||
assertEquals(612000, info.getSize().getHeightMpt()); | |||
} | |||
public void testSVGWithReferences() throws Exception { | |||
String uri = "test/resources/fop/svg/images.svg"; | |||
FopFactory ff = FopFactory.newInstance(); | |||
FOUserAgent userAgent = ff.newFOUserAgent(); | |||
ImageManager manager = ff.getImageManager(); | |||
ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext()); | |||
assertNotNull("ImageInfo must not be null", info); | |||
Image img = manager.getImage(info, XMLNamespaceEnabledImageFlavor.SVG_DOM, | |||
userAgent.getImageSessionContext()); | |||
assertNotNull("Image must not be null", img); | |||
assertEquals(XMLNamespaceEnabledImageFlavor.SVG_DOM, img.getFlavor()); | |||
ImageXMLDOM imgDom = (ImageXMLDOM)img; | |||
assertNotNull(imgDom.getDocument()); | |||
assertEquals("http://www.w3.org/2000/svg", imgDom.getRootNamespace()); | |||
info = imgDom.getInfo(); //Switch to the ImageInfo returned by the image | |||
assertEquals(400000, info.getSize().getWidthMpt()); | |||
assertEquals(400000, info.getSize().getHeightMpt()); | |||
assertEquals(400, info.getSize().getWidthPx()); | |||
assertEquals(400, info.getSize().getHeightPx()); | |||
img = manager.getImage(info, ImageFlavor.RENDERED_IMAGE, | |||
userAgent.getImageSessionContext()); | |||
assertNotNull("Image must not be null", img); | |||
assertEquals(ImageFlavor.RENDERED_IMAGE, img.getFlavor()); | |||
ImageRendered imgRed = (ImageRendered)img; | |||
RenderedImage renImg = imgRed.getRenderedImage(); | |||
assertNotNull(renImg); | |||
if (DEBUG_TARGET_DIR != null) { | |||
ImageWriterUtil.saveAsPNG(renImg, | |||
(int)userAgent.getTargetResolution(), | |||
new File(DEBUG_TARGET_DIR, "images.svg.png")); | |||
} | |||
assertEquals(400, renImg.getWidth()); | |||
assertEquals(400, renImg.getHeight()); | |||
info = imgRed.getInfo(); //Switch to the ImageInfo returned by the image | |||
assertEquals(400000, info.getSize().getWidthMpt()); | |||
assertEquals(400000, info.getSize().getHeightMpt()); | |||
Raster raster = renImg.getData(); | |||
// This pixel is white | |||
int[] pixel1 = raster.getPixel(1, 1, (int[] )null); | |||
// This pixel is from the embedded JPG and is not white | |||
int[] pixel80 = raster.getPixel(80, 80, (int[]) null); | |||
assertEquals(pixel1.length, pixel80.length); | |||
boolean same = true; | |||
for (int i = 0; i < pixel1.length; i++) { | |||
same &= (pixel1[i] == pixel80[i]); | |||
} | |||
assertFalse("Embedding JPG into SVG failed", same); | |||
} | |||
} |
@@ -34,6 +34,7 @@ import javax.xml.transform.sax.SAXResult; | |||
import javax.xml.transform.sax.SAXTransformerFactory; | |||
import javax.xml.transform.stream.StreamSource; | |||
import org.apache.commons.io.IOUtils; | |||
import org.apache.commons.io.output.NullOutputStream; | |||
import org.apache.fop.apps.FOUserAgent; | |||
@@ -51,28 +52,48 @@ public class MemoryEater { | |||
private FopFactory fopFactory = FopFactory.newInstance(); | |||
private Templates replicatorTemplates; | |||
private Stats stats; | |||
public MemoryEater() throws TransformerConfigurationException, MalformedURLException { | |||
File xsltFile = new File("test/xsl/fo-replicator.xsl"); | |||
Source xslt = new StreamSource(xsltFile); | |||
replicatorTemplates = tFactory.newTemplates(xslt); | |||
} | |||
private void eatMemory(File foFile, int replicatorRepeats) throws Exception { | |||
private void eatMemory(File foFile, int runRepeats, int replicatorRepeats) throws Exception { | |||
stats = new Stats(); | |||
for (int i = 0; i < runRepeats; i++) { | |||
eatMemory(i, foFile, replicatorRepeats); | |||
stats.progress(i, runRepeats); | |||
} | |||
stats.dumpFinalStats(); | |||
System.out.println(stats.getGoogleChartURL()); | |||
} | |||
private void eatMemory(int callIndex, File foFile, int replicatorRepeats) throws Exception { | |||
Source src = new StreamSource(foFile); | |||
Transformer transformer = replicatorTemplates.newTransformer(); | |||
transformer.setParameter("repeats", new Integer(replicatorRepeats)); | |||
OutputStream out = new NullOutputStream(); //write to /dev/nul | |||
FOUserAgent userAgent = fopFactory.newFOUserAgent(); | |||
userAgent.setBaseURL(foFile.getParentFile().toURL().toExternalForm()); | |||
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out); | |||
Result res = new SAXResult(fop.getDefaultHandler()); | |||
transformer.transform(src, res); | |||
try { | |||
FOUserAgent userAgent = fopFactory.newFOUserAgent(); | |||
userAgent.setBaseURL(foFile.getParentFile().toURL().toExternalForm()); | |||
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out); | |||
Result res = new SAXResult(fop.getDefaultHandler()); | |||
System.out.println("Generated " + fop.getResults().getPageCount() + " pages."); | |||
transformer.transform(src, res); | |||
stats.notifyPagesProduced(fop.getResults().getPageCount()); | |||
if (callIndex == 0) { | |||
System.out.println(foFile.getName() + " generates " | |||
+ fop.getResults().getPageCount() + " pages."); | |||
} | |||
stats.checkStats(); | |||
} finally { | |||
IOUtils.closeQuietly(out); | |||
} | |||
} | |||
private static void prompt() throws IOException { | |||
@@ -108,9 +129,7 @@ public class MemoryEater { | |||
long start = System.currentTimeMillis(); | |||
MemoryEater app = new MemoryEater(); | |||
for (int i = 0; i < runRepeats; i++) { | |||
app.eatMemory(testFile, replicatorRepeats); | |||
} | |||
app.eatMemory(testFile, runRepeats, replicatorRepeats); | |||
long duration = System.currentTimeMillis() - start; | |||
System.out.println("Success! Job took " + duration + " ms"); |
@@ -0,0 +1,121 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.memory; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
class Stats { | |||
private static final int INTERVAL = 2000; | |||
private long startTime = System.currentTimeMillis(); | |||
private long lastProgressDump = startTime; | |||
private int pagesProduced; | |||
private int totalPagesProduced; | |||
private int step; | |||
private int stepCount; | |||
private List samples = new java.util.LinkedList(); | |||
public void checkStats() { | |||
long now = System.currentTimeMillis(); | |||
if (now > lastProgressDump + INTERVAL) { | |||
dumpStats(); | |||
reset(); | |||
} | |||
} | |||
public void notifyPagesProduced(int count) { | |||
pagesProduced += count; | |||
totalPagesProduced += count; | |||
} | |||
public void reset() { | |||
pagesProduced = 0; | |||
lastProgressDump = System.currentTimeMillis(); | |||
} | |||
public void dumpStats() { | |||
long duration = System.currentTimeMillis() - lastProgressDump; | |||
if (stepCount != 0) { | |||
int progress = 100 * step / stepCount; | |||
System.out.println("Progress: " + progress + "%, " + (stepCount - step) + " left"); | |||
} | |||
long ppm = 60000 * pagesProduced / duration; | |||
System.out.println("Speed: " + ppm + "ppm"); | |||
samples.add(new Sample((int)ppm)); | |||
} | |||
public void dumpFinalStats() { | |||
long duration = System.currentTimeMillis() - startTime; | |||
System.out.println("Final statistics"); | |||
System.out.println("Pages produced: " +totalPagesProduced); | |||
long ppm = 60000 * totalPagesProduced / duration; | |||
System.out.println("Average speed: " + ppm + "ppm"); | |||
} | |||
public String getGoogleChartURL() { | |||
StringBuffer sb = new StringBuffer("http://chart.apis.google.com/chart?"); | |||
//http://chart.apis.google.com/chart?cht=ls&chd=t:60,40&chs=250x100&chl=Hello|World | |||
sb.append("cht=ls"); | |||
sb.append("&chd=t:"); | |||
boolean first = true; | |||
int maxY = 0; | |||
Iterator iter = samples.iterator(); | |||
while (iter.hasNext()) { | |||
Sample sample = (Sample)iter.next(); | |||
if (first) { | |||
first = false; | |||
} else { | |||
sb.append(','); | |||
} | |||
sb.append(sample.ppm); | |||
maxY = Math.max(maxY, sample.ppm); | |||
} | |||
int ceilY = ((maxY / 1000) + 1) * 1000; | |||
sb.append("&chs=1000x300"); //image size | |||
sb.append("&chds=0,").append(ceilY); //data scale | |||
sb.append("&chg=0,20"); //scale steps | |||
sb.append("&chxt=y"); | |||
sb.append("&chxl=0:|0|" + ceilY); | |||
return sb.toString(); | |||
} | |||
private static class Sample { | |||
private int ppm; | |||
public Sample(int ppm) { | |||
this.ppm = ppm; | |||
} | |||
} | |||
public void progress(int step, int stepCount) { | |||
this.step = step; | |||
this.stepCount = stepCount; | |||
} | |||
} |
@@ -1,116 +0,0 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.util; | |||
import java.io.ByteArrayInputStream; | |||
import javax.xml.transform.Source; | |||
import javax.xml.transform.URIResolver; | |||
import javax.xml.transform.stream.StreamSource; | |||
import org.apache.commons.io.IOUtils; | |||
import junit.framework.TestCase; | |||
/** | |||
* Test case for the RFC 2397 data URL/URI resolver. | |||
*/ | |||
public class DataURIResolverTestCase extends TestCase { | |||
private static final byte[] TESTDATA = new byte[] {0, 1, 2, 3, 4, 5}; | |||
/** | |||
* Tests DataURLUtil. | |||
* @throws Exception if an error occurs | |||
*/ | |||
public void testRFC2397Generator() throws Exception { | |||
String url = DataURLUtil.createDataURL(new ByteArrayInputStream(TESTDATA), null); | |||
assertEquals("Generated data URL is wrong", "data:;base64,AAECAwQF", url); | |||
url = DataURLUtil.createDataURL(new ByteArrayInputStream(TESTDATA), "application/pdf"); | |||
assertEquals("Generated data URL is wrong", "data:application/pdf;base64,AAECAwQF", url); | |||
} | |||
/** | |||
* Test the URIResolver contract if the protocol doesn't match. Resolver must return null | |||
* in this case. | |||
* @throws Exception if an error occurs | |||
*/ | |||
public void testNonMatchingContract() throws Exception { | |||
URIResolver resolver = new DataURIResolver(); | |||
Source src; | |||
src = resolver.resolve("http://xmlgraphics.apache.org/fop/index.html", null); | |||
assertNull(src); | |||
src = resolver.resolve("index.html", "http://xmlgraphics.apache.org/fop/"); | |||
assertNull(src); | |||
} | |||
private static boolean byteCmp(byte[] src, int srcOffset, byte[] cmp) { | |||
for (int i = 0, c = cmp.length; i < c; i++) { | |||
if (src[srcOffset + i] != cmp[i]) { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
/** | |||
* Test the DataURIResolver with correct values. | |||
* @throws Exception if an error occurs | |||
*/ | |||
public void testDataURLHandling() throws Exception { | |||
URIResolver resolver = new DataURIResolver(); | |||
Source src; | |||
src = resolver.resolve("data:;base64,AAECAwQF", null); | |||
assertNotNull(src); | |||
StreamSource streamSource = (StreamSource)src; | |||
byte[] data = IOUtils.toByteArray(streamSource.getInputStream()); | |||
assertTrue("Decoded data doesn't match the test data", byteCmp(TESTDATA, 0, data)); | |||
src = resolver.resolve( | |||
"data:application/octet-stream;interpreter=fop;base64,AAECAwQF", null); | |||
assertNotNull(src); | |||
streamSource = (StreamSource)src; | |||
assertNotNull(streamSource.getInputStream()); | |||
assertNull(streamSource.getReader()); | |||
data = IOUtils.toByteArray(streamSource.getInputStream()); | |||
assertTrue("Decoded data doesn't match the test data", byteCmp(TESTDATA, 0, data)); | |||
src = resolver.resolve("data:,FOP", null); | |||
assertNotNull(src); | |||
streamSource = (StreamSource)src; | |||
assertNull(streamSource.getInputStream()); | |||
assertNotNull(streamSource.getReader()); | |||
String text = IOUtils.toString(streamSource.getReader()); | |||
assertEquals("FOP", text); | |||
/* TODO Un-escaping of special URL chars like %20 hasn't been implemented, yet. | |||
src = resolver.resolve("data:,A%20brief%20note", null); | |||
assertNotNull(src); | |||
streamSource = (StreamSource)src; | |||
text = IOUtils.toString(streamSource.getReader()); | |||
assertEquals("A brief note", text); | |||
*/ | |||
} | |||
} |
@@ -1,46 +0,0 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.util; | |||
import junit.framework.TestCase; | |||
/** | |||
* Test class for UnitConv. | |||
*/ | |||
public class UnitConvTestCase extends TestCase { | |||
/** | |||
* Test all kinds of unit conversions. | |||
* @throws Exception if the test fails | |||
*/ | |||
public void testConversions() throws Exception { | |||
assertEquals("in2mm", 25.4, UnitConv.in2mm(1), 0.00001); | |||
assertEquals("mm2in", 1.0, UnitConv.mm2in(25.4), 0.00001); | |||
assertEquals("mm2pt", 841.890, UnitConv.mm2pt(297), 0.001 / 2); //height of an A4 page | |||
assertEquals("mm2mpt", 841890, UnitConv.mm2mpt(297), 1.0 / 2); | |||
assertEquals("pt2mm", 297, UnitConv.pt2mm(841.890), 0.0001); | |||
assertEquals("in2mpt", 792000, UnitConv.in2mpt(11.0), 1.0 / 2); //height of a letter page | |||
assertEquals("mpt2in", 11.0, UnitConv.mpt2in(792000), 0.01 / 2); //height of a letter page | |||
assertEquals("mm2px/72dpi", 841.8897764234434, UnitConv.mm2px(297.0, 72), 0); | |||
assertEquals("mm2px/300dpi", 3507.8740684310146, UnitConv.mm2px(297.0, 300), 0); | |||
} | |||
} |
@@ -0,0 +1,49 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
--> | |||
<!-- $Id$ --> | |||
<testcase> | |||
<info> | |||
<p> | |||
This test checks for Bugzilla 45667: NPE thrown by an empty inline | |||
in combination with hyphenate="true". | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> | |||
<fo:layout-master-set> | |||
<fo:simple-page-master master-name="LetterPage" page-width="6in" | |||
page-height="3in"> | |||
<fo:region-body region-name="PageBody" margin="0.7in" | |||
background-color="rgb(245,245,245)"/> | |||
</fo:simple-page-master> | |||
</fo:layout-master-set> | |||
<fo:page-sequence master-reference="LetterPage" xml:lang="en-US" hyphenate="true"> | |||
<fo:flow flow-name="PageBody"> | |||
<fo:block font="12pt sans-serif"> | |||
<!-- the following line caused a NullPointerException, | |||
if hyphenate="true" --> | |||
<fo:inline id="document.general.efficiently.dictionary"/> | |||
<!-- the following line is working fine --> | |||
Some <fo:inline font-weight="bold" color="red">inline text</fo:inline> formatting. | |||
</fo:block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
</fo> | |||
<checks /> <!-- only basic checks to see if no NPE occurred --> | |||
</testcase> |
@@ -69,6 +69,10 @@ | |||
</fo:instream-foreign-object></fo:leader> | |||
Content is svg 20 x 10 which is wider than the leader-length | |||
</fo:block> | |||
<fo:block> | |||
<fo:leader leader-length="36pt" leader-pattern="use-content"> </fo:leader> | |||
Content is " " | |||
</fo:block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
@@ -172,5 +176,9 @@ | |||
<eval expected="0" xpath="//flow/block[7]/lineArea/inlineparent/inlineparent[1]/@offset"/> | |||
<eval expected="20000" xpath="//flow/block[7]/lineArea/inlineparent/inlineparent[1]/viewport/@ipd"/> | |||
<eval expected="-1384" xpath="//flow/block[7]/lineArea/inlineparent/inlineparent[1]/viewport/@offset"/> | |||
<eval expected="11100" xpath="//flow/block[8]/lineArea/@bpd"/> | |||
<eval expected="36000" xpath="//flow/block[8]/lineArea/space[1]/@ipd"/> | |||
<eval expected="0" xpath="//flow/block[8]/lineArea/space[1]/@offset"/> | |||
</checks> | |||
</testcase> |
@@ -0,0 +1,76 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
--> | |||
<!-- $Id$ --> | |||
<testcase> | |||
<info> | |||
<p> | |||
This test checks for correct resolution of page-number-citation-last, in | |||
case a break-after is set on the last child block to the block carrying the id. | |||
(see also Bugzilla #45702) | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> | |||
<fo:layout-master-set> | |||
<fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm" margin="2cm"> | |||
<fo:region-body margin-top="0cm" region-name="xsl-region-body"/> | |||
</fo:simple-page-master> | |||
</fo:layout-master-set> | |||
<fo:page-sequence master-reference="A4" id="toc"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block> | |||
PS : from <fo:page-number-citation id="pnc.page-sequence" ref-id="page-sequence"/> to <fo:page-number-citation-last id="pncl.page-sequence" ref-id="page-sequence"/> | |||
</fo:block> | |||
<fo:block> | |||
toc : from <fo:page-number-citation id="pnc.toc" ref-id="toc"/> to <fo:page-number-citation-last id="pncl.toc" ref-id="toc"/> | |||
</fo:block> | |||
<fo:block> | |||
block-1 : from <fo:page-number-citation id="pnc.block-1" ref-id="block-1"/> to <fo:page-number-citation-last id="pncl.block-1" ref-id="block-1"/> | |||
</fo:block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
<fo:page-sequence master-reference="A4" id="page-sequence"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block id="block-1"> | |||
<fo:block padding="1pt">two blocks, with break-after specified on the last one</fo:block> | |||
<fo:block break-before="page">XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX | |||
XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX | |||
XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX | |||
XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX | |||
XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX | |||
XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX </fo:block> | |||
<fo:block break-before="page" break-after="page">XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX | |||
XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX | |||
XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX | |||
XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX | |||
XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX | |||
XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX </fo:block> | |||
</fo:block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
</fo> | |||
<checks> | |||
<eval expected="1" xpath="/areaTree/pageSequence[1]//text[@prod-id='pnc.toc']/word" /> | |||
<eval expected="1" xpath="/areaTree/pageSequence[1]//text[@prod-id='pncl.toc']/word" /> | |||
<eval expected="2" xpath="/areaTree/pageSequence[1]//text[@prod-id='pnc.page-sequence']/word" /> | |||
<eval expected="4" xpath="/areaTree/pageSequence[1]//text[@prod-id='pncl.page-sequence']/word" /> | |||
<eval expected="2" xpath="/areaTree/pageSequence[1]//text[@prod-id='pnc.block-1']/word" /> | |||
<eval expected="4" xpath="/areaTree/pageSequence[1]//text[@prod-id='pncl.block-1']/word" /> | |||
</checks> | |||
</testcase> |
@@ -0,0 +1,118 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
--> | |||
<!-- $Id$ --> | |||
<testcase> | |||
<info> | |||
<p> | |||
This test checks for the use of a 'last' conditional-page-master-reference | |||
for a first/only page (see: https://issues.apache.org/bugzilla/show_bug.cgi?id=40798) | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" | |||
font-family="Times" font-size="20pt"> | |||
<fo:layout-master-set> | |||
<fo:simple-page-master master-name="only-page-layout" | |||
page-height="297mm" page-width="210mm" | |||
margin-top="15mm" margin-bottom="15mm" | |||
margin-left="15mm" margin-right="15mm"> | |||
<fo:region-body region-name="frame-body" margin-top="10mm"/> | |||
<fo:region-before region-name="only-region" extent="10mm"/> | |||
</fo:simple-page-master> | |||
<fo:simple-page-master master-name="first-page-layout" | |||
page-height="297mm" page-width="210mm" | |||
margin-top="15mm" margin-bottom="15mm" | |||
margin-left="15mm" margin-right="15mm"> | |||
<fo:region-body region-name="frame-body" margin-top="10mm"/> | |||
<fo:region-before region-name="first-region" extent="10mm"/> | |||
</fo:simple-page-master> | |||
<fo:simple-page-master master-name="last-page-layout" | |||
page-height="297mm" page-width="210mm" | |||
margin-top="15mm" margin-bottom="15mm" | |||
margin-left="15mm" margin-right="15mm"> | |||
<fo:region-body region-name="frame-body" margin-top="10mm"/> | |||
<fo:region-before region-name="last-region" extent="10mm"/> | |||
</fo:simple-page-master> | |||
<fo:simple-page-master master-name="rest-page-layout" | |||
page-height="297mm" page-width="210mm" | |||
margin-top="15mm" margin-bottom="15mm" | |||
margin-left="15mm" margin-right="15mm"> | |||
<fo:region-body region-name="frame-body" margin-top="10mm"/> | |||
<fo:region-before region-name="rest-region" extent="10mm"/> | |||
</fo:simple-page-master> | |||
<fo:page-sequence-master master-name="whatever"> | |||
<fo:repeatable-page-master-alternatives maximum-repeats="1"> | |||
<fo:conditional-page-master-reference master-reference="only-page-layout" | |||
page-position="last"/> | |||
<fo:conditional-page-master-reference master-reference="first-page-layout" | |||
page-position="first"/> | |||
</fo:repeatable-page-master-alternatives> | |||
<fo:repeatable-page-master-alternatives maximum-repeats="no-limit"> | |||
<fo:conditional-page-master-reference master-reference="last-page-layout" | |||
page-position="last"/> | |||
<fo:conditional-page-master-reference master-reference="rest-page-layout" | |||
page-position="rest"/> | |||
</fo:repeatable-page-master-alternatives> | |||
</fo:page-sequence-master> | |||
</fo:layout-master-set> | |||
<fo:page-sequence master-reference="whatever"> | |||
<fo:static-content flow-name="first-region"> | |||
<fo:block id="header.first.1" text-align="center">first</fo:block> | |||
</fo:static-content> | |||
<fo:static-content flow-name="only-region"> | |||
<fo:block id="header.only.1" text-align="center">only</fo:block> | |||
</fo:static-content> | |||
<fo:flow flow-name="frame-body"> | |||
<fo:block>This is the only page</fo:block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
<fo:page-sequence master-reference="whatever"> | |||
<fo:static-content flow-name="only-region"> | |||
<fo:block id="header.only.2" text-align="center">only</fo:block> | |||
</fo:static-content> | |||
<fo:static-content flow-name="first-region"> | |||
<fo:block id="header.first.2" text-align="center">first</fo:block> | |||
</fo:static-content> | |||
<fo:static-content flow-name="last-region"> | |||
<fo:block id="header.last.2" text-align="center">last</fo:block> | |||
</fo:static-content> | |||
<fo:static-content flow-name="rest-region"> | |||
<fo:block id="header.rest.2" text-align="center">rest</fo:block> | |||
</fo:static-content> | |||
<fo:flow flow-name="frame-body"> | |||
<fo:block>This is the first page</fo:block> | |||
<fo:block break-before="page">This is a middle page</fo:block> | |||
<fo:block break-before="page">This is a middle page</fo:block> | |||
<fo:block break-before="page">This is the last page</fo:block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
</fo> | |||
<checks> | |||
<eval expected="header.only.1" xpath="(/areaTree/pageSequence[1]//regionBefore)[1]/block[1]/@prod-id" /> | |||
<eval expected="header.first.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[1]/block[1]/@prod-id" /> | |||
<eval expected="header.rest.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[2]/block[1]/@prod-id" /> | |||
<eval expected="header.rest.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[3]/block[1]/@prod-id" /> | |||
<eval expected="header.last.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[4]/block[1]/@prod-id" /> | |||
</checks> | |||
</testcase> |
@@ -0,0 +1,115 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
--> | |||
<!-- $Id$ --> | |||
<testcase> | |||
<info> | |||
<p> | |||
This test checks for the use of an 'only' conditional-page-master-reference (XSL 1.1) | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" | |||
font-family="Times" font-size="20pt"> | |||
<fo:layout-master-set> | |||
<fo:simple-page-master master-name="only-page-layout" | |||
page-height="297mm" page-width="210mm" | |||
margin-top="15mm" margin-bottom="15mm" | |||
margin-left="15mm" margin-right="15mm"> | |||
<fo:region-body region-name="frame-body" margin-top="10mm"/> | |||
<fo:region-before region-name="only-region" extent="10mm"/> | |||
</fo:simple-page-master> | |||
<fo:simple-page-master master-name="first-page-layout" | |||
page-height="297mm" page-width="210mm" | |||
margin-top="15mm" margin-bottom="15mm" | |||
margin-left="15mm" margin-right="15mm"> | |||
<fo:region-body region-name="frame-body" margin-top="10mm"/> | |||
<fo:region-before region-name="first-region" extent="10mm"/> | |||
</fo:simple-page-master> | |||
<fo:simple-page-master master-name="last-page-layout" | |||
page-height="297mm" page-width="210mm" | |||
margin-top="15mm" margin-bottom="15mm" | |||
margin-left="15mm" margin-right="15mm"> | |||
<fo:region-body region-name="frame-body" margin-top="10mm"/> | |||
<fo:region-before region-name="last-region" extent="10mm"/> | |||
</fo:simple-page-master> | |||
<fo:simple-page-master master-name="rest-page-layout" | |||
page-height="297mm" page-width="210mm" | |||
margin-top="15mm" margin-bottom="15mm" | |||
margin-left="15mm" margin-right="15mm"> | |||
<fo:region-body region-name="frame-body" margin-top="10mm"/> | |||
<fo:region-before region-name="rest-region" extent="10mm"/> | |||
</fo:simple-page-master> | |||
<fo:page-sequence-master master-name="whatever"> | |||
<fo:repeatable-page-master-alternatives maximum-repeats="no-limit"> | |||
<fo:conditional-page-master-reference master-reference="only-page-layout" | |||
page-position="only"/> | |||
<fo:conditional-page-master-reference master-reference="first-page-layout" | |||
page-position="first"/> | |||
<fo:conditional-page-master-reference master-reference="last-page-layout" | |||
page-position="last"/> | |||
<fo:conditional-page-master-reference master-reference="rest-page-layout" | |||
page-position="rest"/> | |||
</fo:repeatable-page-master-alternatives> | |||
</fo:page-sequence-master> | |||
</fo:layout-master-set> | |||
<fo:page-sequence master-reference="whatever"> | |||
<fo:static-content flow-name="first-region"> | |||
<fo:block id="header.first.1" text-align="center">first</fo:block> | |||
</fo:static-content> | |||
<fo:static-content flow-name="only-region"> | |||
<fo:block id="header.only.1" text-align="center">only</fo:block> | |||
</fo:static-content> | |||
<fo:flow flow-name="frame-body"> | |||
<fo:block>This is the only page</fo:block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
<fo:page-sequence master-reference="whatever"> | |||
<fo:static-content flow-name="only-region"> | |||
<fo:block id="header.only.2" text-align="center">only</fo:block> | |||
</fo:static-content> | |||
<fo:static-content flow-name="first-region"> | |||
<fo:block id="header.first.2" text-align="center">first</fo:block> | |||
</fo:static-content> | |||
<fo:static-content flow-name="last-region"> | |||
<fo:block id="header.last.2" text-align="center">last</fo:block> | |||
</fo:static-content> | |||
<fo:static-content flow-name="rest-region"> | |||
<fo:block id="header.rest.2" text-align="center">rest</fo:block> | |||
</fo:static-content> | |||
<fo:flow flow-name="frame-body"> | |||
<fo:block>This is the first page</fo:block> | |||
<fo:block break-before="page">This is a middle page</fo:block> | |||
<fo:block break-before="page">This is a middle page</fo:block> | |||
<fo:block break-before="page">This is the last page</fo:block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
</fo> | |||
<checks> | |||
<eval expected="header.only.1" xpath="(/areaTree/pageSequence[1]//regionBefore)[1]/block[1]/@prod-id" /> | |||
<eval expected="header.first.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[1]/block[1]/@prod-id" /> | |||
<eval expected="header.rest.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[2]/block[1]/@prod-id" /> | |||
<eval expected="header.rest.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[3]/block[1]/@prod-id" /> | |||
<eval expected="header.last.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[4]/block[1]/@prod-id" /> | |||
</checks> | |||
</testcase> |
@@ -434,69 +434,68 @@ | |||
<eval expected="(double,#800000,6000,collapse-outer)" xpath="//flow/block[2]/block[19]/@border-after"/> | |||
<eval expected="(solid,#800000,6000,collapse-outer)" xpath="//flow/block[2]/block[19]/@border-start"/> | |||
<eval expected="(solid,#800000,6000,collapse-inner)" xpath="//flow/block[2]/block[19]/@border-end"/> | |||
<!-- | |||
<eval expected="94000" xpath="//flow/block[2]/block[20]/@ipd"/> | |||
<eval expected="106000" xpath="//flow/block[2]/block[20]/@ipda"/> | |||
<eval expected="52200" xpath="//flow/block[2]/block[20]/@bpd"/> | |||
<eval expected="52200" xpath="//flow/block[2]/block[20]/@bpda"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[20]/@left-offset"/> | |||
<eval expected="241100" xpath="//flow/block[2]/block[20]/@top-offset"/> | |||
<eval expected="(double,#800000,0,collapse-outer)" xpath="//flow/block[2]/block[20]/@border-after"/> | |||
<eval expected="" xpath="//flow/block[2]/block[20]/@border-before"/> | |||
<eval expected="" xpath="//flow/block[2]/block[20]/@border-after"/> | |||
<eval expected="(solid,#800000,6000,collapse-inner)" xpath="//flow/block[2]/block[20]/@border-start"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[20]/@border-end"/> | |||
--> | |||
<eval expected="97000" xpath="//flow/block[2]/block[20]/@ipd"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[20]/@ipda"/> | |||
<eval expected="41300" xpath="//flow/block[2]/block[20]/@bpd"/> | |||
<eval expected="81300" xpath="//flow/block[2]/block[20]/@bpda"/> | |||
<eval expected="203000" xpath="//flow/block[2]/block[20]/@left-offset"/> | |||
<eval expected="115400" xpath="//flow/block[2]/block[20]/@top-offset"/> | |||
<eval expected="(double,#008000,40000,collapse-inner)" xpath="//flow/block[2]/block[20]/@border-before"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[20]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[21]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[21]/@ipda"/> | |||
<eval expected="97000" xpath="//flow/block[2]/block[21]/@ipd"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[21]/@ipda"/> | |||
<eval expected="41300" xpath="//flow/block[2]/block[21]/@bpd"/> | |||
<eval expected="81300" xpath="//flow/block[2]/block[21]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[21]/@left-offset"/> | |||
<eval expected="203000" xpath="//flow/block[2]/block[21]/@left-offset"/> | |||
<eval expected="115400" xpath="//flow/block[2]/block[21]/@top-offset"/> | |||
<eval expected="(double,#008000,40000,collapse-inner)" xpath="//flow/block[2]/block[21]/@border-before"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[21]/@border-end"/> | |||
<eval expected="70000" xpath="//flow/block[2]/block[22]/@ipd"/> | |||
<eval expected="130000" xpath="//flow/block[2]/block[22]/@ipda"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[22]/@bpd"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[22]/@bpda"/> | |||
<eval expected="230000" xpath="//flow/block[2]/block[22]/@left-offset"/> | |||
<eval expected="196700" xpath="//flow/block[2]/block[22]/@top-offset"/> | |||
<eval expected="(solid,#c0c0c0,60000,collapse-inner)" xpath="//flow/block[2]/block[22]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[23]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[23]/@ipda"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[21]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[22]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[22]/@ipda"/> | |||
<eval expected="41300" xpath="//flow/block[2]/block[22]/@bpd"/> | |||
<eval expected="81300" xpath="//flow/block[2]/block[22]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[22]/@left-offset"/> | |||
<eval expected="115400" xpath="//flow/block[2]/block[22]/@top-offset"/> | |||
<eval expected="(double,#008000,40000,collapse-inner)" xpath="//flow/block[2]/block[22]/@border-before"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[22]/@border-end"/> | |||
<eval expected="70000" xpath="//flow/block[2]/block[23]/@ipd"/> | |||
<eval expected="130000" xpath="//flow/block[2]/block[23]/@ipda"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[23]/@bpd"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[23]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[23]/@left-offset"/> | |||
<eval expected="230000" xpath="//flow/block[2]/block[23]/@left-offset"/> | |||
<eval expected="196700" xpath="//flow/block[2]/block[23]/@top-offset"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[23]/@border-end"/> | |||
<eval expected="97000" xpath="//flow/block[2]/block[24]/@ipd"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[24]/@ipda"/> | |||
<eval expected="49700" xpath="//flow/block[2]/block[24]/@bpd"/> | |||
<eval expected="54700" xpath="//flow/block[2]/block[24]/@bpda"/> | |||
<eval expected="203000" xpath="//flow/block[2]/block[24]/@left-offset"/> | |||
<eval expected="241100" xpath="//flow/block[2]/block[24]/@top-offset"/> | |||
<eval expected="(solid,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[24]/@border-after"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[24]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[25]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[25]/@ipda"/> | |||
<eval expected="(solid,#c0c0c0,60000,collapse-inner)" xpath="//flow/block[2]/block[23]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[24]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[24]/@ipda"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[24]/@bpd"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[24]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[24]/@left-offset"/> | |||
<eval expected="196700" xpath="//flow/block[2]/block[24]/@top-offset"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[24]/@border-end"/> | |||
<eval expected="97000" xpath="//flow/block[2]/block[25]/@ipd"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[25]/@ipda"/> | |||
<eval expected="49700" xpath="//flow/block[2]/block[25]/@bpd"/> | |||
<eval expected="54700" xpath="//flow/block[2]/block[25]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[25]/@left-offset"/> | |||
<eval expected="203000" xpath="//flow/block[2]/block[25]/@left-offset"/> | |||
<eval expected="241100" xpath="//flow/block[2]/block[25]/@top-offset"/> | |||
<eval expected="(solid,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[25]/@border-after"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[25]/@border-end"/> | |||
<eval expected="167500" xpath="//flow/block[2]/block[26]/@ipd"/> | |||
<eval expected="167500" xpath="//flow/block[2]/block[26]/@ipda"/> | |||
<eval expected="135400" xpath="//flow/block[2]/block[26]/@bpd"/> | |||
<eval expected="135400" xpath="//flow/block[2]/block[26]/@bpda"/> | |||
<eval expected="230000" xpath="//flow/block[2]/block[26]/@left-offset"/> | |||
<eval expected="155400" xpath="//flow/block[2]/block[26]/@top-offset"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[25]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[26]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[26]/@ipda"/> | |||
<eval expected="49700" xpath="//flow/block[2]/block[26]/@bpd"/> | |||
<eval expected="54700" xpath="//flow/block[2]/block[26]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[26]/@left-offset"/> | |||
<eval expected="241100" xpath="//flow/block[2]/block[26]/@top-offset"/> | |||
<eval expected="(solid,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[26]/@border-after"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[26]/@border-end"/> | |||
<eval expected="167500" xpath="//flow/block[2]/block[27]/@ipd"/> | |||
<eval expected="167500" xpath="//flow/block[2]/block[27]/@ipda"/> | |||
<eval expected="135400" xpath="//flow/block[2]/block[27]/@bpd"/> | |||
<eval expected="135400" xpath="//flow/block[2]/block[27]/@bpda"/> | |||
<eval expected="230000" xpath="//flow/block[2]/block[27]/@left-offset"/> | |||
<eval expected="155400" xpath="//flow/block[2]/block[27]/@top-offset"/> | |||
<!-- table 2 --> | |||
<eval expected="199300" xpath="//flow/block[4]/@bpd"/> |
@@ -279,184 +279,186 @@ | |||
<eval expected="(solid,#c0c0c0,6000,collapse-outer)" xpath="//flow/block[2]/block[2]/@border-before"/> | |||
<eval expected="(solid,#c0c0c0,6000,collapse-inner)" xpath="//flow/block[2]/block[2]/@border-start"/> | |||
<eval expected="(solid,#c0c0c0,6000,collapse-inner)" xpath="//flow/block[2]/block[2]/@border-end"/> | |||
<eval expected="92000" xpath="//flow/block[2]/block[3]/@ipd"/> | |||
<eval expected="108000" xpath="//flow/block[2]/block[3]/@ipda"/> | |||
<eval expected="43200" xpath="//flow/block[2]/block[3]/@bpd"/> | |||
<eval expected="61200" xpath="//flow/block[2]/block[3]/@bpda"/> | |||
<eval expected="3000" xpath="//flow/block[2]/block[3]/@left-offset"/> | |||
<eval expected="16400" xpath="//flow/block[2]/block[3]/@top-offset"/> | |||
<eval expected="(solid,#800000,12000,collapse-inner)" xpath="//flow/block[2]/block[3]/@border-before"/> | |||
<eval expected="(double,#800000,6000,collapse-inner)" xpath="//flow/block[2]/block[3]/@border-after"/> | |||
<eval expected="(solid,#800000,6000,collapse-outer)" xpath="//flow/block[2]/block[3]/@border-start"/> | |||
<eval expected="(dashed,#ff0000,10000,collapse-inner)" xpath="//flow/block[2]/block[3]/@border-end"/> | |||
<eval expected="80000" xpath="//flow/block[2]/block[4]/@ipd"/> | |||
<eval expected="120000" xpath="//flow/block[2]/block[4]/@ipda"/> | |||
<eval expected="30900" xpath="//flow/block[2]/block[4]/@bpd"/> | |||
<eval expected="42900" xpath="//flow/block[2]/block[4]/@bpda"/> | |||
<eval expected="15000" xpath="//flow/block[2]/block[4]/@left-offset"/> | |||
<eval expected="71600" xpath="//flow/block[2]/block[4]/@top-offset"/> | |||
<eval expected="(double,#ff00ff,6000,collapse-inner)" xpath="//flow/block[2]/block[4]/@border-before"/> | |||
<eval expected="(inset,#ff00ff,6000,collapse-inner)" xpath="//flow/block[2]/block[4]/@border-after"/> | |||
<eval expected="(solid,#ff00ff,30000,collapse-outer)" xpath="//flow/block[2]/block[4]/@border-start"/> | |||
<!-- block[3] is an empty cell --> | |||
<eval expected="92000" xpath="//flow/block[2]/block[4]/@ipd"/> | |||
<eval expected="108000" xpath="//flow/block[2]/block[4]/@ipda"/> | |||
<eval expected="43200" xpath="//flow/block[2]/block[4]/@bpd"/> | |||
<eval expected="61200" xpath="//flow/block[2]/block[4]/@bpda"/> | |||
<eval expected="3000" xpath="//flow/block[2]/block[4]/@left-offset"/> | |||
<eval expected="16400" xpath="//flow/block[2]/block[4]/@top-offset"/> | |||
<eval expected="(solid,#800000,12000,collapse-inner)" xpath="//flow/block[2]/block[4]/@border-before"/> | |||
<eval expected="(double,#800000,6000,collapse-inner)" xpath="//flow/block[2]/block[4]/@border-after"/> | |||
<eval expected="(solid,#800000,6000,collapse-outer)" xpath="//flow/block[2]/block[4]/@border-start"/> | |||
<eval expected="(dashed,#ff0000,10000,collapse-inner)" xpath="//flow/block[2]/block[4]/@border-end"/> | |||
<eval expected="95000" xpath="//flow/block[2]/block[5]/@ipd"/> | |||
<eval expected="105000" xpath="//flow/block[2]/block[5]/@ipda"/> | |||
<eval expected="52200" xpath="//flow/block[2]/block[5]/@bpd"/> | |||
<eval expected="52200" xpath="//flow/block[2]/block[5]/@bpda"/> | |||
<eval expected="105000" xpath="//flow/block[2]/block[5]/@left-offset"/> | |||
<eval expected="22400" xpath="//flow/block[2]/block[5]/@top-offset"/> | |||
<eval expected="(dashed,#ff0000,10000,collapse-inner)" xpath="//flow/block[2]/block[5]/@border-start"/> | |||
<eval expected="98000" xpath="//flow/block[2]/block[6]/@ipd"/> | |||
<eval expected="102000" xpath="//flow/block[2]/block[6]/@ipda"/> | |||
<eval expected="50200" xpath="//flow/block[2]/block[6]/@bpd"/> | |||
<eval expected="54200" xpath="//flow/block[2]/block[6]/@bpda"/> | |||
<eval expected="200000" xpath="//flow/block[2]/block[6]/@left-offset"/> | |||
<eval expected="20400" xpath="//flow/block[2]/block[6]/@top-offset"/> | |||
<eval expected="(solid,#ff0000,4000,collapse-inner)" xpath="//flow/block[2]/block[6]/@border-before"/> | |||
<eval expected="(double,#ff0000,4000,collapse-inner)" xpath="//flow/block[2]/block[6]/@border-end"/> | |||
<!-- block[5] is an empty cell --> | |||
<!-- 3.1: --> | |||
<eval expected="80000" xpath="//flow/block[2]/block[6]/@ipd"/> | |||
<eval expected="120000" xpath="//flow/block[2]/block[6]/@ipda"/> | |||
<eval expected="30900" xpath="//flow/block[2]/block[6]/@bpd"/> | |||
<eval expected="42900" xpath="//flow/block[2]/block[6]/@bpda"/> | |||
<eval expected="15000" xpath="//flow/block[2]/block[6]/@left-offset"/> | |||
<eval expected="71600" xpath="//flow/block[2]/block[6]/@top-offset"/> | |||
<eval expected="(double,#ff00ff,6000,collapse-inner)" xpath="//flow/block[2]/block[6]/@border-before"/> | |||
<eval expected="(inset,#ff00ff,6000,collapse-inner)" xpath="//flow/block[2]/block[6]/@border-after"/> | |||
<eval expected="(solid,#ff00ff,30000,collapse-outer)" xpath="//flow/block[2]/block[6]/@border-start"/> | |||
<eval expected="(dashed,#ff0000,10000,collapse-inner)" xpath="//flow/block[2]/block[6]/@border-end"/> | |||
<!-- 4x border-only cells for 2.2: --> | |||
<eval expected="95000" xpath="//flow/block[2]/block[7]/@ipd"/> | |||
<eval expected="105000" xpath="//flow/block[2]/block[7]/@ipda"/> | |||
<eval expected="34400" xpath="//flow/block[2]/block[7]/@bpd"/> | |||
<eval expected="39400" xpath="//flow/block[2]/block[7]/@bpda"/> | |||
<eval expected="52200" xpath="//flow/block[2]/block[7]/@bpd"/> | |||
<eval expected="52200" xpath="//flow/block[2]/block[7]/@bpda"/> | |||
<eval expected="105000" xpath="//flow/block[2]/block[7]/@left-offset"/> | |||
<eval expected="74600" xpath="//flow/block[2]/block[7]/@top-offset"/> | |||
<eval expected="(outset,#c0c0c0,5000,collapse-inner)" xpath="//flow/block[2]/block[7]/@border-after"/> | |||
<eval expected="22400" xpath="//flow/block[2]/block[7]/@top-offset"/> | |||
<eval expected="(dashed,#ff0000,10000,collapse-inner)" xpath="//flow/block[2]/block[7]/@border-start"/> | |||
<eval expected="98000" xpath="//flow/block[2]/block[8]/@ipd"/> | |||
<eval expected="102000" xpath="//flow/block[2]/block[8]/@ipda"/> | |||
<eval expected="16900" xpath="//flow/block[2]/block[8]/@bpd"/> | |||
<eval expected="56900" xpath="//flow/block[2]/block[8]/@bpda"/> | |||
<eval expected="50200" xpath="//flow/block[2]/block[8]/@bpd"/> | |||
<eval expected="54200" xpath="//flow/block[2]/block[8]/@bpda"/> | |||
<eval expected="200000" xpath="//flow/block[2]/block[8]/@left-offset"/> | |||
<eval expected="74600" xpath="//flow/block[2]/block[8]/@top-offset"/> | |||
<eval expected="(double,#008000,40000,collapse-inner)" xpath="//flow/block[2]/block[8]/@border-after"/> | |||
<eval expected="20400" xpath="//flow/block[2]/block[8]/@top-offset"/> | |||
<eval expected="(solid,#ff0000,4000,collapse-inner)" xpath="//flow/block[2]/block[8]/@border-before"/> | |||
<eval expected="(double,#ff0000,4000,collapse-inner)" xpath="//flow/block[2]/block[8]/@border-end"/> | |||
<eval expected="193000" xpath="//flow/block[2]/block[9]/@ipd"/> | |||
<eval expected="193000" xpath="//flow/block[2]/block[9]/@ipda"/> | |||
<eval expected="67100" xpath="//flow/block[2]/block[9]/@bpd"/> | |||
<eval expected="67100" xpath="//flow/block[2]/block[9]/@bpda"/> | |||
<eval expected="95000" xpath="//flow/block[2]/block[9]/@ipd"/> | |||
<eval expected="105000" xpath="//flow/block[2]/block[9]/@ipda"/> | |||
<eval expected="34400" xpath="//flow/block[2]/block[9]/@bpd"/> | |||
<eval expected="39400" xpath="//flow/block[2]/block[9]/@bpda"/> | |||
<eval expected="105000" xpath="//flow/block[2]/block[9]/@left-offset"/> | |||
<eval expected="24400" xpath="//flow/block[2]/block[9]/@top-offset"/> | |||
<eval expected="74600" xpath="//flow/block[2]/block[9]/@top-offset"/> | |||
<eval expected="(outset,#c0c0c0,5000,collapse-inner)" xpath="//flow/block[2]/block[9]/@border-after"/> | |||
<eval expected="(dashed,#ff0000,10000,collapse-inner)" xpath="//flow/block[2]/block[9]/@border-start"/> | |||
<eval expected="98000" xpath="//flow/block[2]/block[10]/@ipd"/> | |||
<eval expected="102000" xpath="//flow/block[2]/block[10]/@ipda"/> | |||
<eval expected="14400" xpath="//flow/block[2]/block[10]/@bpd"/> | |||
<eval expected="59400" xpath="//flow/block[2]/block[10]/@bpda"/> | |||
<eval expected="302000" xpath="//flow/block[2]/block[10]/@left-offset"/> | |||
<eval expected="72100" xpath="//flow/block[2]/block[10]/@top-offset"/> | |||
<eval expected="(ridge,#800000,5000,collapse-inner)" xpath="//flow/block[2]/block[10]/@border-before"/> | |||
<eval expected="16900" xpath="//flow/block[2]/block[10]/@bpd"/> | |||
<eval expected="56900" xpath="//flow/block[2]/block[10]/@bpda"/> | |||
<eval expected="200000" xpath="//flow/block[2]/block[10]/@left-offset"/> | |||
<eval expected="74600" xpath="//flow/block[2]/block[10]/@top-offset"/> | |||
<eval expected="(double,#008000,40000,collapse-inner)" xpath="//flow/block[2]/block[10]/@border-after"/> | |||
<eval expected="(double,#ff0000,4000,collapse-inner)" xpath="//flow/block[2]/block[10]/@border-start"/> | |||
<eval expected="78000" xpath="//flow/block[2]/block[11]/@ipd"/> | |||
<eval expected="122000" xpath="//flow/block[2]/block[11]/@ipda"/> | |||
<eval expected="56300" xpath="//flow/block[2]/block[11]/@bpd"/> | |||
<eval expected="66300" xpath="//flow/block[2]/block[11]/@bpda"/> | |||
<eval expected="2000" xpath="//flow/block[2]/block[11]/@left-offset"/> | |||
<eval expected="108500" xpath="//flow/block[2]/block[11]/@top-offset"/> | |||
<eval expected="(inset,#000000,6000,collapse-inner)" xpath="//flow/block[2]/block[11]/@border-before"/> | |||
<eval expected="(solid,#000000,4000,collapse-inner)" xpath="//flow/block[2]/block[11]/@border-after"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//flow/block[2]/block[11]/@border-start"/> | |||
<eval expected="(solid,#000000,40000,collapse-inner)" xpath="//flow/block[2]/block[11]/@border-end"/> | |||
<eval expected="77000" xpath="//flow/block[2]/block[12]/@ipd"/> | |||
<eval expected="123000" xpath="//flow/block[2]/block[12]/@ipda"/> | |||
<eval expected="28800" xpath="//flow/block[2]/block[12]/@bpd"/> | |||
<eval expected="93800" xpath="//flow/block[2]/block[12]/@bpda"/> | |||
<eval expected="120000" xpath="//flow/block[2]/block[12]/@left-offset"/> | |||
<eval expected="109000" xpath="//flow/block[2]/block[12]/@top-offset"/> | |||
<eval expected="(outset,#c0c0c0,5000,collapse-inner)" xpath="//flow/block[2]/block[12]/@border-before"/> | |||
<eval expected="(solid,#c0c0c0,60000,collapse-inner)" xpath="//flow/block[2]/block[12]/@border-after"/> | |||
<eval expected="(solid,#000000,40000,collapse-inner)" xpath="//flow/block[2]/block[12]/@border-start"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[12]/@border-end"/> | |||
<eval expected="95000" xpath="//flow/block[2]/block[13]/@ipd"/> | |||
<eval expected="105000" xpath="//flow/block[2]/block[13]/@ipda"/> | |||
<eval expected="36400" xpath="//flow/block[2]/block[13]/@bpd"/> | |||
<eval expected="52400" xpath="//flow/block[2]/block[13]/@bpda"/> | |||
<eval expected="(double,#ff0000,4000,collapse-inner)" xpath="//flow/block[2]/block[10]/@border-end"/> | |||
<eval expected="193000" xpath="//flow/block[2]/block[11]/@ipd"/> | |||
<eval expected="193000" xpath="//flow/block[2]/block[11]/@ipda"/> | |||
<eval expected="67100" xpath="//flow/block[2]/block[11]/@bpd"/> | |||
<eval expected="67100" xpath="//flow/block[2]/block[11]/@bpda"/> | |||
<eval expected="105000" xpath="//flow/block[2]/block[11]/@left-offset"/> | |||
<eval expected="24400" xpath="//flow/block[2]/block[11]/@top-offset"/> | |||
<eval expected="98000" xpath="//flow/block[2]/block[12]/@ipd"/> | |||
<eval expected="102000" xpath="//flow/block[2]/block[12]/@ipda"/> | |||
<eval expected="14400" xpath="//flow/block[2]/block[12]/@bpd"/> | |||
<eval expected="59400" xpath="//flow/block[2]/block[12]/@bpda"/> | |||
<eval expected="302000" xpath="//flow/block[2]/block[12]/@left-offset"/> | |||
<eval expected="72100" xpath="//flow/block[2]/block[12]/@top-offset"/> | |||
<eval expected="(ridge,#800000,5000,collapse-inner)" xpath="//flow/block[2]/block[12]/@border-before"/> | |||
<eval expected="(double,#008000,40000,collapse-inner)" xpath="//flow/block[2]/block[12]/@border-after"/> | |||
<eval expected="(double,#ff0000,4000,collapse-inner)" xpath="//flow/block[2]/block[12]/@border-start"/> | |||
<eval expected="78000" xpath="//flow/block[2]/block[13]/@ipd"/> | |||
<eval expected="122000" xpath="//flow/block[2]/block[13]/@ipda"/> | |||
<eval expected="56300" xpath="//flow/block[2]/block[13]/@bpd"/> | |||
<eval expected="66300" xpath="//flow/block[2]/block[13]/@bpda"/> | |||
<eval expected="2000" xpath="//flow/block[2]/block[13]/@left-offset"/> | |||
<eval expected="170800" xpath="//flow/block[2]/block[13]/@top-offset"/> | |||
<eval expected="(solid,#000000,4000,collapse-inner)" xpath="//flow/block[2]/block[13]/@border-before"/> | |||
<eval expected="(solid,#800000,12000,collapse-inner)" xpath="//flow/block[2]/block[13]/@border-after"/> | |||
<eval expected="108500" xpath="//flow/block[2]/block[13]/@top-offset"/> | |||
<eval expected="(inset,#000000,6000,collapse-inner)" xpath="//flow/block[2]/block[13]/@border-before"/> | |||
<eval expected="(solid,#000000,4000,collapse-inner)" xpath="//flow/block[2]/block[13]/@border-after"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//flow/block[2]/block[13]/@border-start"/> | |||
<eval expected="(solid,#c0c0c0,6000,collapse-inner)" xpath="//flow/block[2]/block[13]/@border-end"/> | |||
<eval expected="67000" xpath="//flow/block[2]/block[14]/@ipd"/> | |||
<eval expected="133000" xpath="//flow/block[2]/block[14]/@ipda"/> | |||
<eval expected="14400" xpath="//flow/block[2]/block[14]/@bpd"/> | |||
<eval expected="74400" xpath="//flow/block[2]/block[14]/@bpda"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[14]/@left-offset"/> | |||
<eval expected="142800" xpath="//flow/block[2]/block[14]/@top-offset"/> | |||
<eval expected="(solid,#c0c0c0,60000,collapse-inner)" xpath="//flow/block[2]/block[14]/@border-before"/> | |||
<eval expected="(solid,#c0c0c0,6000,collapse-inner)" xpath="//flow/block[2]/block[14]/@border-start"/> | |||
<eval expected="(solid,#c0c0c0,60000,collapse-inner)" xpath="//flow/block[2]/block[14]/@border-end"/> | |||
<eval expected="94000" xpath="//flow/block[2]/block[15]/@ipd"/> | |||
<eval expected="106000" xpath="//flow/block[2]/block[15]/@ipda"/> | |||
<eval expected="43200" xpath="//flow/block[2]/block[15]/@bpd"/> | |||
<eval expected="61200" xpath="//flow/block[2]/block[15]/@bpda"/> | |||
<eval expected="3000" xpath="//flow/block[2]/block[15]/@left-offset"/> | |||
<eval expected="211200" xpath="//flow/block[2]/block[15]/@top-offset"/> | |||
<eval expected="(solid,#800000,12000,collapse-inner)" xpath="//flow/block[2]/block[15]/@border-before"/> | |||
<eval expected="(double,#800000,6000,collapse-outer)" xpath="//flow/block[2]/block[15]/@border-after"/> | |||
<eval expected="(solid,#800000,6000,collapse-outer)" xpath="//flow/block[2]/block[15]/@border-start"/> | |||
<eval expected="(solid,#800000,6000,collapse-inner)" xpath="//flow/block[2]/block[15]/@border-end"/> | |||
<!-- | |||
<eval expected="94000" xpath="//flow/block[2]/block[16]/@ipd"/> | |||
<eval expected="106000" xpath="//flow/block[2]/block[16]/@ipda"/> | |||
<eval expected="52200" xpath="//flow/block[2]/block[16]/@bpd"/> | |||
<eval expected="52200" xpath="//flow/block[2]/block[16]/@bpda"/> | |||
<eval expected="(solid,#000000,40000,collapse-inner)" xpath="//flow/block[2]/block[13]/@border-end"/> | |||
<eval expected="77000" xpath="//flow/block[2]/block[14]/@ipd"/> | |||
<eval expected="123000" xpath="//flow/block[2]/block[14]/@ipda"/> | |||
<eval expected="28800" xpath="//flow/block[2]/block[14]/@bpd"/> | |||
<eval expected="93800" xpath="//flow/block[2]/block[14]/@bpda"/> | |||
<eval expected="120000" xpath="//flow/block[2]/block[14]/@left-offset"/> | |||
<eval expected="109000" xpath="//flow/block[2]/block[14]/@top-offset"/> | |||
<eval expected="(outset,#c0c0c0,5000,collapse-inner)" xpath="//flow/block[2]/block[14]/@border-before"/> | |||
<eval expected="(solid,#c0c0c0,60000,collapse-inner)" xpath="//flow/block[2]/block[14]/@border-after"/> | |||
<eval expected="(solid,#000000,40000,collapse-inner)" xpath="//flow/block[2]/block[14]/@border-start"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[14]/@border-end"/> | |||
<eval expected="95000" xpath="//flow/block[2]/block[15]/@ipd"/> | |||
<eval expected="105000" xpath="//flow/block[2]/block[15]/@ipda"/> | |||
<eval expected="36400" xpath="//flow/block[2]/block[15]/@bpd"/> | |||
<eval expected="52400" xpath="//flow/block[2]/block[15]/@bpda"/> | |||
<eval expected="2000" xpath="//flow/block[2]/block[15]/@left-offset"/> | |||
<eval expected="170800" xpath="//flow/block[2]/block[15]/@top-offset"/> | |||
<eval expected="(solid,#000000,4000,collapse-inner)" xpath="//flow/block[2]/block[15]/@border-before"/> | |||
<eval expected="(solid,#800000,12000,collapse-inner)" xpath="//flow/block[2]/block[15]/@border-after"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//flow/block[2]/block[15]/@border-start"/> | |||
<eval expected="(solid,#c0c0c0,6000,collapse-inner)" xpath="//flow/block[2]/block[15]/@border-end"/> | |||
<eval expected="67000" xpath="//flow/block[2]/block[16]/@ipd"/> | |||
<eval expected="133000" xpath="//flow/block[2]/block[16]/@ipda"/> | |||
<eval expected="14400" xpath="//flow/block[2]/block[16]/@bpd"/> | |||
<eval expected="74400" xpath="//flow/block[2]/block[16]/@bpda"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[16]/@left-offset"/> | |||
<eval expected="217200" xpath="//flow/block[2]/block[16]/@top-offset"/> | |||
<eval expected="(double,#800000,0,collapse-outer)" xpath="//flow/block[2]/block[16]/@border-after"/> | |||
<eval expected="(solid,#800000,6000,collapse-inner)" xpath="//flow/block[2]/block[16]/@border-start"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[16]/@border-end"/> | |||
--> | |||
<eval expected="97000" xpath="//flow/block[2]/block[16]/@ipd"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[16]/@ipda"/> | |||
<eval expected="41300" xpath="//flow/block[2]/block[16]/@bpd"/> | |||
<eval expected="81300" xpath="//flow/block[2]/block[16]/@bpda"/> | |||
<eval expected="203000" xpath="//flow/block[2]/block[16]/@left-offset"/> | |||
<eval expected="91500" xpath="//flow/block[2]/block[16]/@top-offset"/> | |||
<eval expected="(double,#008000,40000,collapse-inner)" xpath="//flow/block[2]/block[16]/@border-before"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[16]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[17]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[17]/@ipda"/> | |||
<eval expected="41300" xpath="//flow/block[2]/block[17]/@bpd"/> | |||
<eval expected="81300" xpath="//flow/block[2]/block[17]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[17]/@left-offset"/> | |||
<eval expected="91500" xpath="//flow/block[2]/block[17]/@top-offset"/> | |||
<eval expected="(double,#008000,40000,collapse-inner)" xpath="//flow/block[2]/block[17]/@border-before"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[17]/@border-end"/> | |||
<eval expected="70000" xpath="//flow/block[2]/block[18]/@ipd"/> | |||
<eval expected="130000" xpath="//flow/block[2]/block[18]/@ipda"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[18]/@bpd"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[18]/@bpda"/> | |||
<eval expected="230000" xpath="//flow/block[2]/block[18]/@left-offset"/> | |||
<eval expected="172800" xpath="//flow/block[2]/block[18]/@top-offset"/> | |||
<eval expected="(solid,#c0c0c0,60000,collapse-inner)" xpath="//flow/block[2]/block[18]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[19]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[19]/@ipda"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[19]/@bpd"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[19]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[19]/@left-offset"/> | |||
<eval expected="172800" xpath="//flow/block[2]/block[19]/@top-offset"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[19]/@border-end"/> | |||
<eval expected="97000" xpath="//flow/block[2]/block[20]/@ipd"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[20]/@ipda"/> | |||
<eval expected="49700" xpath="//flow/block[2]/block[20]/@bpd"/> | |||
<eval expected="54700" xpath="//flow/block[2]/block[20]/@bpda"/> | |||
<eval expected="203000" xpath="//flow/block[2]/block[20]/@left-offset"/> | |||
<eval expected="217200" xpath="//flow/block[2]/block[20]/@top-offset"/> | |||
<eval expected="(solid,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[20]/@border-after"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[20]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[21]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[21]/@ipda"/> | |||
<eval expected="49700" xpath="//flow/block[2]/block[21]/@bpd"/> | |||
<eval expected="54700" xpath="//flow/block[2]/block[21]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[21]/@left-offset"/> | |||
<eval expected="217200" xpath="//flow/block[2]/block[21]/@top-offset"/> | |||
<eval expected="(solid,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[21]/@border-after"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[21]/@border-end"/> | |||
<eval expected="167500" xpath="//flow/block[2]/block[22]/@ipd"/> | |||
<eval expected="167500" xpath="//flow/block[2]/block[22]/@ipda"/> | |||
<eval expected="135400" xpath="//flow/block[2]/block[22]/@bpd"/> | |||
<eval expected="135400" xpath="//flow/block[2]/block[22]/@bpda"/> | |||
<eval expected="230000" xpath="//flow/block[2]/block[22]/@left-offset"/> | |||
<eval expected="131500" xpath="//flow/block[2]/block[22]/@top-offset"/> | |||
<eval expected="142800" xpath="//flow/block[2]/block[16]/@top-offset"/> | |||
<eval expected="(solid,#c0c0c0,60000,collapse-inner)" xpath="//flow/block[2]/block[16]/@border-before"/> | |||
<eval expected="(solid,#c0c0c0,6000,collapse-inner)" xpath="//flow/block[2]/block[16]/@border-start"/> | |||
<eval expected="(solid,#c0c0c0,60000,collapse-inner)" xpath="//flow/block[2]/block[16]/@border-end"/> | |||
<eval expected="94000" xpath="//flow/block[2]/block[17]/@ipd"/> | |||
<eval expected="106000" xpath="//flow/block[2]/block[17]/@ipda"/> | |||
<eval expected="43200" xpath="//flow/block[2]/block[17]/@bpd"/> | |||
<eval expected="61200" xpath="//flow/block[2]/block[17]/@bpda"/> | |||
<eval expected="3000" xpath="//flow/block[2]/block[17]/@left-offset"/> | |||
<eval expected="211200" xpath="//flow/block[2]/block[17]/@top-offset"/> | |||
<eval expected="(solid,#800000,12000,collapse-inner)" xpath="//flow/block[2]/block[17]/@border-before"/> | |||
<eval expected="(double,#800000,6000,collapse-outer)" xpath="//flow/block[2]/block[17]/@border-after"/> | |||
<eval expected="(solid,#800000,6000,collapse-outer)" xpath="//flow/block[2]/block[17]/@border-start"/> | |||
<eval expected="(solid,#800000,6000,collapse-inner)" xpath="//flow/block[2]/block[17]/@border-end"/> | |||
<eval expected="94000" xpath="//flow/block[2]/block[18]/@ipd"/> | |||
<eval expected="106000" xpath="//flow/block[2]/block[18]/@ipda"/> | |||
<eval expected="52200" xpath="//flow/block[2]/block[18]/@bpd"/> | |||
<eval expected="52200" xpath="//flow/block[2]/block[18]/@bpda"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[18]/@left-offset"/> | |||
<eval expected="217200" xpath="//flow/block[2]/block[18]/@top-offset"/> | |||
<eval expected="" xpath="//flow/block[2]/block[18]/@border-after"/> | |||
<eval expected="(solid,#800000,6000,collapse-inner)" xpath="//flow/block[2]/block[18]/@border-start"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[18]/@border-end"/> | |||
<eval expected="97000" xpath="//flow/block[2]/block[19]/@ipd"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[19]/@ipda"/> | |||
<eval expected="41300" xpath="//flow/block[2]/block[19]/@bpd"/> | |||
<eval expected="81300" xpath="//flow/block[2]/block[19]/@bpda"/> | |||
<eval expected="203000" xpath="//flow/block[2]/block[19]/@left-offset"/> | |||
<eval expected="91500" xpath="//flow/block[2]/block[19]/@top-offset"/> | |||
<eval expected="(double,#008000,40000,collapse-inner)" xpath="//flow/block[2]/block[19]/@border-before"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[19]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[20]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[20]/@ipda"/> | |||
<eval expected="41300" xpath="//flow/block[2]/block[20]/@bpd"/> | |||
<eval expected="81300" xpath="//flow/block[2]/block[20]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[20]/@left-offset"/> | |||
<eval expected="91500" xpath="//flow/block[2]/block[20]/@top-offset"/> | |||
<eval expected="(double,#008000,40000,collapse-inner)" xpath="//flow/block[2]/block[20]/@border-before"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[20]/@border-end"/> | |||
<eval expected="70000" xpath="//flow/block[2]/block[21]/@ipd"/> | |||
<eval expected="130000" xpath="//flow/block[2]/block[21]/@ipda"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[21]/@bpd"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[21]/@bpda"/> | |||
<eval expected="230000" xpath="//flow/block[2]/block[21]/@left-offset"/> | |||
<eval expected="172800" xpath="//flow/block[2]/block[21]/@top-offset"/> | |||
<eval expected="(solid,#c0c0c0,60000,collapse-inner)" xpath="//flow/block[2]/block[21]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[22]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[22]/@ipda"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[22]/@bpd"/> | |||
<eval expected="44400" xpath="//flow/block[2]/block[22]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[22]/@left-offset"/> | |||
<eval expected="172800" xpath="//flow/block[2]/block[22]/@top-offset"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[22]/@border-end"/> | |||
<eval expected="97000" xpath="//flow/block[2]/block[23]/@ipd"/> | |||
<eval expected="103000" xpath="//flow/block[2]/block[23]/@ipda"/> | |||
<eval expected="49700" xpath="//flow/block[2]/block[23]/@bpd"/> | |||
<eval expected="54700" xpath="//flow/block[2]/block[23]/@bpda"/> | |||
<eval expected="203000" xpath="//flow/block[2]/block[23]/@left-offset"/> | |||
<eval expected="217200" xpath="//flow/block[2]/block[23]/@top-offset"/> | |||
<eval expected="(solid,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[23]/@border-after"/> | |||
<eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[2]/block[23]/@border-start"/> | |||
<eval expected="97500" xpath="//flow/block[2]/block[24]/@ipd"/> | |||
<eval expected="102500" xpath="//flow/block[2]/block[24]/@ipda"/> | |||
<eval expected="49700" xpath="//flow/block[2]/block[24]/@bpd"/> | |||
<eval expected="54700" xpath="//flow/block[2]/block[24]/@bpda"/> | |||
<eval expected="300000" xpath="//flow/block[2]/block[24]/@left-offset"/> | |||
<eval expected="217200" xpath="//flow/block[2]/block[24]/@top-offset"/> | |||
<eval expected="(solid,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[24]/@border-after"/> | |||
<eval expected="(dashed,#008000,5000,collapse-outer)" xpath="//flow/block[2]/block[24]/@border-end"/> | |||
<eval expected="167500" xpath="//flow/block[2]/block[25]/@ipd"/> | |||
<eval expected="167500" xpath="//flow/block[2]/block[25]/@ipda"/> | |||
<eval expected="135400" xpath="//flow/block[2]/block[25]/@bpd"/> | |||
<eval expected="135400" xpath="//flow/block[2]/block[25]/@bpda"/> | |||
<eval expected="230000" xpath="//flow/block[2]/block[25]/@left-offset"/> | |||
<eval expected="131500" xpath="//flow/block[2]/block[25]/@top-offset"/> | |||
<!-- table 2 --> | |||
<eval expected="199300" xpath="//flow/block[4]/@bpd"/> |
@@ -0,0 +1,192 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
--> | |||
<!-- $Id$ --> | |||
<testcase> | |||
<info> | |||
<p> | |||
This test checks the behaviour in the collapsing border model when table-cells are missing. | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> | |||
<fo:layout-master-set> | |||
<fo:simple-page-master master-name="page" page-height="5in" page-width="5in" margin="0.5in"> | |||
<fo:region-body/> | |||
</fo:simple-page-master> | |||
</fo:layout-master-set> | |||
<fo:page-sequence master-reference="page"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:table table-layout="fixed" width="100%" | |||
border-collapse="collapse" border="solid 4pt black"> | |||
<fo:table-column column-width="proportional-column-width(2)"/> | |||
<fo:table-column column-width="proportional-column-width(1)"/> | |||
<fo:table-column column-width="proportional-column-width(2)"/> | |||
<fo:table-body> | |||
<fo:table-row> | |||
<fo:table-cell border="solid 4pt red"> | |||
<fo:block>cell A1</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell border="solid 4pt green"> | |||
<fo:block>cell B1</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell border="solid 4pt red"> | |||
<fo:block>cell A2</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell border="solid 4pt green"> | |||
<fo:block>cell B2</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell border="solid 4pt blue"> | |||
<fo:block>cell C2</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell border="solid 4pt red"> | |||
<fo:block>cell A3</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell border="solid 4pt blue" column-number="3"> | |||
<fo:block>cell C3</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell border="solid 4pt blue" column-number="3"> | |||
<fo:block>cell C4</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell border="solid 4pt red"> | |||
<fo:block>cell A5</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell border="solid 4pt blue" column-number="3"> | |||
<fo:block>cell C5</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell border="solid 4pt green" column-number="2"> | |||
<fo:block>cell B6</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell border="solid 4pt blue"> | |||
<fo:block>cell C6</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
</fo:table-body> | |||
</fo:table> | |||
<fo:table table-layout="fixed" width="100%" space-before="1.7in" | |||
border-collapse="collapse" border="solid 4pt black"> | |||
<fo:table-column column-width="proportional-column-width(1)" number-columns-repeated="3"/> | |||
<fo:table-body> | |||
<fo:table-row> | |||
<fo:table-cell border="solid 4pt red"> | |||
<fo:block>cell A1 cell A1 cell A1 cell A1 cell A1 cell A1 cell A1 cell A1</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell border="solid 4pt green"> | |||
<fo:block>cell B1</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
</fo:table-body> | |||
</fo:table> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
</fo> | |||
<checks> | |||
<!-- empty cell in row 1 (C1) --> | |||
<eval expected="true" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@is-reference-area"/> | |||
<eval expected="absolute" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@positioning"/> | |||
<eval expected="14400" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@bpd"/> | |||
<eval expected="22400" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@bpda"/> | |||
<eval expected="111200" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@ipd"/> | |||
<eval expected="119200" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@ipda"/> | |||
<eval expected="-2000" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@top-offset"/> | |||
<eval expected="174800" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@left-offset"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@border-before"/> | |||
<eval expected="(solid,#008000,4000,collapse-inner)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@border-start"/> | |||
<eval expected="(solid,#0000ff,4000,collapse-inner)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@border-after"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[3]/@border-end"/> | |||
<!-- empty cell in row 3 (B3) --> | |||
<eval expected="16400" xpath="//pageViewport[@nr='1']//flow/block[1]/block[8]/@bpd"/> | |||
<eval expected="20400" xpath="//pageViewport[@nr='1']//flow/block[1]/block[8]/@bpda"/> | |||
<eval expected="53600" xpath="//pageViewport[@nr='1']//flow/block[1]/block[8]/@ipd"/> | |||
<eval expected="61600" xpath="//pageViewport[@nr='1']//flow/block[1]/block[8]/@ipda"/> | |||
<eval expected="34800" xpath="//pageViewport[@nr='1']//flow/block[1]/block[8]/@top-offset"/> | |||
<eval expected="117200" xpath="//pageViewport[@nr='1']//flow/block[1]/block[8]/@left-offset"/> | |||
<eval expected="(solid,#008000,4000,collapse-inner)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[8]/@border-before"/> | |||
<eval expected="(solid,#ff0000,4000,collapse-inner)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[8]/@border-start"/> | |||
<true xpath="not(boolean(//pageViewport[@nr='1']//flow/block[1]/block[8]/@border-after))" fail-msg="border-after in B3 must be absent"/> | |||
<eval expected="(solid,#0000ff,4000,collapse-inner)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[8]/@border-end"/> | |||
<!-- empty cell in row 4 (A4) --> | |||
<eval expected="14400" xpath="//pageViewport[@nr='1']//flow/block[1]/block[10]/@bpd"/> | |||
<eval expected="22400" xpath="//pageViewport[@nr='1']//flow/block[1]/block[10]/@bpda"/> | |||
<eval expected="113200" xpath="//pageViewport[@nr='1']//flow/block[1]/block[10]/@ipd"/> | |||
<eval expected="117200" xpath="//pageViewport[@nr='1']//flow/block[1]/block[10]/@ipda"/> | |||
<eval expected="53200" xpath="//pageViewport[@nr='1']//flow/block[1]/block[10]/@top-offset"/> | |||
<eval expected="2000" xpath="//pageViewport[@nr='1']//flow/block[1]/block[10]/@left-offset"/> | |||
<eval expected="(solid,#ff0000,4000,collapse-inner)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[10]/@border-before"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[10]/@border-start"/> | |||
<eval expected="(solid,#ff0000,4000,collapse-inner)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[10]/@border-after"/> | |||
<true xpath="not(boolean(//pageViewport[@nr='1']//flow/block[1]/block[10]/@border-end))" fail-msg="border-end in A4 must be absent"/> | |||
<!-- empty cell in row 4 (B4) --> | |||
<eval expected="18400" xpath="//pageViewport[@nr='1']//flow/block[1]/block[11]/@bpd"/> | |||
<eval expected="18400" xpath="//pageViewport[@nr='1']//flow/block[1]/block[11]/@bpda"/> | |||
<eval expected="55600" xpath="//pageViewport[@nr='1']//flow/block[1]/block[11]/@ipd"/> | |||
<eval expected="59600" xpath="//pageViewport[@nr='1']//flow/block[1]/block[11]/@ipda"/> | |||
<eval expected="55200" xpath="//pageViewport[@nr='1']//flow/block[1]/block[11]/@top-offset"/> | |||
<eval expected="115200" xpath="//pageViewport[@nr='1']//flow/block[1]/block[11]/@left-offset"/> | |||
<true xpath="not(boolean(//pageViewport[@nr='1']//flow/block[1]/block[11]/@border-before))" fail-msg="border-before in B4 must be absent"/> | |||
<true xpath="not(boolean(//pageViewport[@nr='1']//flow/block[1]/block[11]/@border-start))" fail-msg="border-start in B4 must be absent"/> | |||
<true xpath="not(boolean(//pageViewport[@nr='1']//flow/block[1]/block[11]/@border-after))" fail-msg="border-after in B4 must be absent"/> | |||
<eval expected="(solid,#0000ff,4000,collapse-inner)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[11]/@border-end"/> | |||
<!-- empty cell in row 6 (A6) --> | |||
<eval expected="14400" xpath="//pageViewport[@nr='1']//flow/block[1]/block[16]/@bpd"/> | |||
<eval expected="22400" xpath="//pageViewport[@nr='1']//flow/block[1]/block[16]/@bpda"/> | |||
<eval expected="111200" xpath="//pageViewport[@nr='1']//flow/block[1]/block[16]/@ipd"/> | |||
<eval expected="119200" xpath="//pageViewport[@nr='1']//flow/block[1]/block[16]/@ipda"/> | |||
<eval expected="90000" xpath="//pageViewport[@nr='1']//flow/block[1]/block[16]/@top-offset"/> | |||
<eval expected="2000" xpath="//pageViewport[@nr='1']//flow/block[1]/block[16]/@left-offset"/> | |||
<eval expected="(solid,#ff0000,4000,collapse-inner)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[16]/@border-before"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[16]/@border-start"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[16]/@border-after"/> | |||
<eval expected="(solid,#008000,4000,collapse-inner)" xpath="//pageViewport[@nr='1']//flow/block[1]/block[16]/@border-end"/> | |||
<!-- *** second table *** --> | |||
<!-- empty cell in row 1 (C1) --> | |||
<eval expected="28800" xpath="//pageViewport[@nr='1']//flow/block[2]/block[3]/@bpd"/> | |||
<eval expected="32800" xpath="//pageViewport[@nr='1']//flow/block[2]/block[3]/@bpda"/> | |||
<eval expected="92000" xpath="//pageViewport[@nr='1']//flow/block[2]/block[3]/@ipd"/> | |||
<eval expected="100000" xpath="//pageViewport[@nr='1']//flow/block[2]/block[3]/@ipda"/> | |||
<eval expected="-2000" xpath="//pageViewport[@nr='1']//flow/block[2]/block[3]/@top-offset"/> | |||
<eval expected="194000" xpath="//pageViewport[@nr='1']//flow/block[2]/block[3]/@left-offset"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr='1']//flow/block[2]/block[3]/@border-before"/> | |||
<eval expected="(solid,#008000,4000,collapse-inner)" xpath="//pageViewport[@nr='1']//flow/block[2]/block[3]/@border-start"/> | |||
<true xpath="not(boolean(//pageViewport[@nr='1']//flow/block[2]/block[3]/@border-after))" fail-msg="border-after in C1 must be absent"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr='1']//flow/block[2]/block[3]/@border-end"/> | |||
<!-- empty cell in row 1 (C1), continued on next page --> | |||
<eval expected="28800" xpath="//pageViewport[@nr='2']//flow/block[1]/block[3]/@bpd"/> | |||
<eval expected="32800" xpath="//pageViewport[@nr='2']//flow/block[1]/block[3]/@bpda"/> | |||
<eval expected="92000" xpath="//pageViewport[@nr='2']//flow/block[1]/block[3]/@ipd"/> | |||
<eval expected="100000" xpath="//pageViewport[@nr='2']//flow/block[1]/block[3]/@ipda"/> | |||
<true xpath="not(boolean(//pageViewport[@nr='2']//flow/block[1]/block[3]/@top-offset))" fail-msg="must not have a top-offset"/> | |||
<eval expected="194000" xpath="//pageViewport[@nr='2']//flow/block[1]/block[3]/@left-offset"/> | |||
<true xpath="not(boolean(//pageViewport[@nr='2']//flow/block[1]/block[3]/@border-before))" fail-msg="border-after in C1 must be absent"/> | |||
<eval expected="(solid,#008000,4000,collapse-inner)" xpath="//pageViewport[@nr='2']//flow/block[1]/block[3]/@border-start"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr='2']//flow/block[1]/block[3]/@border-after"/> | |||
<eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr='2']//flow/block[1]/block[3]/@border-end"/> | |||
</checks> | |||
</testcase> |