aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2012-04-13 16:49:35 +0000
committerVincent Hennebert <vhennebert@apache.org>2012-04-13 16:49:35 +0000
commita438a377ef974181a4b0a71f9d399e31f654588b (patch)
tree0eb9720c40f65c19437f731db0b34483e9f9b545 /src
parent55c1f8be3cf6da96f690f34743d47ecee95243bb (diff)
parent50b34f584998b9083b07ec018d84dd38b96e732c (diff)
downloadxmlgraphics-fop-a438a377ef974181a4b0a71f9d399e31f654588b.tar.gz
xmlgraphics-fop-a438a377ef974181a4b0a71f9d399e31f654588b.zip
Merged changes from trunk up to rev. 1325806
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript@1325839 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/documentation/content/xdocs/compliance.ihtml16
-rw-r--r--src/documentation/content/xdocs/dev/release.xml122
-rw-r--r--src/documentation/content/xdocs/site.xml25
-rw-r--r--src/documentation/content/xdocs/trunk/complexscripts.xml628
-rw-r--r--src/documentation/content/xdocs/trunk/output.xml19
-rw-r--r--src/documentation/content/xdocs/trunk/running.xml3
-rw-r--r--src/documentation/skinconf.xml4
-rw-r--r--src/java/org/apache/fop/afp/AFPPaintingState.java42
-rw-r--r--src/java/org/apache/fop/afp/AFPResourceLevel.java2
-rw-r--r--src/java/org/apache/fop/afp/fonts/AFPFont.java5
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java4
-rw-r--r--src/java/org/apache/fop/afp/fonts/RasterFont.java20
-rw-r--r--src/java/org/apache/fop/afp/modca/ImageObject.java7
-rw-r--r--src/java/org/apache/fop/area/Area.java19
-rw-r--r--src/java/org/apache/fop/area/AreaTreeObject.java20
-rw-r--r--src/java/org/apache/fop/area/BodyRegion.java18
-rw-r--r--src/java/org/apache/fop/area/Page.java18
-rw-r--r--src/java/org/apache/fop/area/PageViewport.java25
-rw-r--r--src/java/org/apache/fop/area/RegionReference.java17
-rw-r--r--src/java/org/apache/fop/area/RegionViewport.java28
-rw-r--r--src/java/org/apache/fop/area/inline/InlineViewport.java6
-rw-r--r--src/java/org/apache/fop/events/Event.java31
-rw-r--r--src/java/org/apache/fop/events/EventFormatter.java91
-rw-r--r--src/java/org/apache/fop/fo/FONode.java46
-rw-r--r--src/java/org/apache/fop/fo/FObj.java2
-rw-r--r--src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java25
-rw-r--r--src/java/org/apache/fop/fo/flow/Inline.java6
-rw-r--r--src/java/org/apache/fop/fo/flow/Leader.java5
-rw-r--r--src/java/org/apache/fop/fo/flow/Marker.java2
-rw-r--r--src/java/org/apache/fop/fo/flow/RetrieveMarker.java2
-rw-r--r--src/java/org/apache/fop/fo/properties/PropertyCache.java32
-rw-r--r--src/java/org/apache/fop/fonts/FontInfo.java4
-rw-r--r--src/java/org/apache/fop/hyphenation/CharVector.java6
-rw-r--r--src/java/org/apache/fop/hyphenation/TernaryTree.java9
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractBreaker.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableStepper.java2
-rw-r--r--src/java/org/apache/fop/pdf/PDFFactory.java3
-rw-r--r--src/java/org/apache/fop/render/afp/AFPCustomizable.java24
-rw-r--r--src/java/org/apache/fop/render/afp/AFPDocumentHandler.java20
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java47
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java8
-rw-r--r--src/java/org/apache/fop/render/awt/AWTRenderer.java3
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFGraphicContext.java15
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DRenderer.java9
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java38
-rw-r--r--src/java/org/apache/fop/render/ps/NativeTextHandler.java17
-rw-r--r--src/java/org/apache/fop/render/rtf/RTFHandler.java17
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/IRtfTextContainer.java5
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfAttributes.java13
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfContainer.java24
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfElement.java2
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfHyperLink.java11
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfParagraph.java11
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfParagraphBreak.java71
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTable.java11
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableCell.java47
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableRow.java11
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfText.java14
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java82
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/tools/PercentContext.java29
-rw-r--r--src/java/org/apache/fop/render/txt/TXTRenderer.java15
-rw-r--r--src/java/org/apache/fop/tools/anttasks/FileCompare.java2
-rw-r--r--src/java/org/apache/fop/util/XMLResourceBundle.java2
63 files changed, 1432 insertions, 432 deletions
diff --git a/src/documentation/content/xdocs/compliance.ihtml b/src/documentation/content/xdocs/compliance.ihtml
index ddbbc83cf..fe3107142 100644
--- a/src/documentation/content/xdocs/compliance.ihtml
+++ b/src/documentation/content/xdocs/compliance.ihtml
@@ -3842,10 +3842,10 @@
"http://www.w3.org/TR/xsl/#page-height">&sect;7.27.13</a></td>
<td><a name="fo-property-page-height" id="fo-property-page-height">page-height</a></td>
<td class="basic">Basic</td>
- <td class="yes">yes</td>
- <td class="yes">yes</td>
- <td class="yes">yes</td>
- <td>&nbsp;</td>
+ <td class="partial">partial</td>
+ <td class="partial">partial</td>
+ <td class="partial">partial</td>
+ <td>value "indefinite" not yet supported</td>
</tr>
<tr>
<td align="center"><a href=
@@ -3862,10 +3862,10 @@
"http://www.w3.org/TR/xsl/#page-width">&sect;7.27.15</a></td>
<td><a name="fo-property-page-width" id="fo-property-page-width">page-width</a></td>
<td class="basic">Basic</td>
- <td class="yes">yes</td>
- <td class="yes">yes</td>
- <td class="yes">yes</td>
- <td>&nbsp;</td>
+ <td class="partial">partial</td>
+ <td class="partial">partial</td>
+ <td class="partial">partial</td>
+ <td>value "indefinite" not yet supported</td>
</tr>
<tr>
<td align="center"><a href=
diff --git a/src/documentation/content/xdocs/dev/release.xml b/src/documentation/content/xdocs/dev/release.xml
index 19e6eac2c..21ed60193 100644
--- a/src/documentation/content/xdocs/dev/release.xml
+++ b/src/documentation/content/xdocs/dev/release.xml
@@ -25,100 +25,72 @@
<body>
<section id="intro">
<title>Introduction</title>
- <p>This page documents the process of creating a Apache™ FOP release.
-FOP releases are coordinated by one member of the team (currently Christian Geisert), so others do not ordinarily need to use this information.
-The purpose of documenting it here is to facilitate consistency, ensure that the process is captured, and to allow others to comment on the process.</p>
- <p>The checklist below was assembled from Christian Geisert's notes. It will be expanded in the future as he has time.</p>
+ <p>This page documents the process of creating a Apache™ FOP release. FOP releases are coordinated by some designated member of the team.
+ The purpose of documenting it here is to facilitate consistency, ensure that the process is captured, and to allow others to comment on the process.</p>
+ <p>The checklist below is based on a combination of input from from Christian Geisert and Simon Pepping.</p>
</section>
<section id="checklist">
<title>Checklist</title>
<ul>
+ <li>Determine which open bugs must be solved before a release can take place (release critical bugs).
+ Make this bug depend on each release critical bug and write a short argument why the bug is release critical.</li>
<li>Determine whether this is a Release Candidate or a Release.</li>
<li>Determine whether further testing is required.</li>
<li>Commit any outstanding changes</li>
<li>Create a branch called <code>branches/fop-v_vv</code></li>
- <li>Edit release notes (<code>README</code> and
- <code>status.xml</code> in the root).</li>
- <li>Add the release to <code>news-data.xml</code>;
- remove links to release notes of older versions from this file.</li>
- <li>Update the FAQ (<code>faq.xml</code>) to the new release.</li>
- <li>Check and update the copyright year in NOTICE and build.xml.</li>
+ <li>Edit release notes (<code>README</code> and <code>status.xml</code> in the root).</li>
+ <li>Add the release to <code>news-data.xml</code>;
+ remove links to release notes of older versions from this file.</li>
+ <li>Update the FAQ (<code>faq.xml</code>) to the new release, e.g., update the answer for "When is the next release planned?".</li>
+ <li>Check and update the copyright year in NOTICE and build.xml.</li>
<li>Update the file <code>doap.rdf</code>, and the files
<code>index.xml</code>, <code>site.xml</code>,
<code>download.xml</code>, <code>fo.xml</code>,
- <code>maillist.xml</code>, <code>quickstartguide.xml</code>,
- <code>faq.xml</code> and <code>status.xml</code>
+ <code>maillist.xml</code>, and <code>quickstartguide.xml</code>
in directory <code>xdocs</code> for the new version.</li>
<li>Update the version numbers in the release column on the
compliance page (<code>compliance.xml</code>); update the compliance in the release column
to the current state (development column).</li>
<li>Update version number in <code>build.xml</code> (not to be merged back
into trunk).</li>
- <li>Copy trunk documentation directory to a new directory with
- the new version number, and update the .htaccess file for
- redirections.</li>
- <li>Copy <code>test/fotree/disabled-testcases.xml</code> and
- <code>test/layoutengine/disabled-testcases.xml</code> to the
- new version directory
- <code>&lt;version&gt;/fotree/disabled-testcases.xml</code> and
- <code>&lt;version&gt;/layoutengine/disabled-testcases.xml</code>.
- Copy <code>known-issues.xml</code> to the new version
- directory. Copy <code>knownissues-overview.xml</code> from the
- current to the new version directory, and update the <code>xi:include</code>
- links in it.</li>
- <li>Update the tab names and directories in tabs.xml</li>
+ <li>Copy trunk documentation directory to a new directory with the new version number, and update the <code>.htaccess</code> file for
+ redirections.</li>
+ <li>Copy <code>test/fotree/disabled-testcases.xml</code> and <code>test/layoutengine/disabled-testcases.xml</code> to the
+ new version directory <code>&lt;version&gt;/fotree/disabled-testcases.xml</code> and <code>&lt;version&gt;/layoutengine/disabled-testcases.xml</code>.
+ Copy <code>known-issues.xml</code> to the new version directory. Copy <code>knownissues-overview.xml</code> from the
+ current to the new version directory, and update the <code>xi:include</code> links in it.</li>
+ <li>Update the tab names and directories in <code>tabs.xml</code></li>
<li>Delete the previous version directory.</li>
- <li>Update index.xml in the new version directory.</li>
- <li>Update compiling.xml in the new version directory: change the intro for trunk to that for a release.</li>
- <li>Build the dist files (<code>build[.sh] dist</code>)
- and upload them to your web directory on
- <code>people.apache.org</code></li>
- <li>Ask on fop-dev to check the branch and the generated dist
- files for errors.</li>
+ <li>Update <code>index.xml</code> in the new version directory.</li>
+ <li>Update <code>compiling.xml</code> in the new version directory: change the introduction for trunk to that for a release.</li>
+ <li>Build the dist files (<code>build[.sh] dist</code>) and upload them to your web directory on <code>people.apache.org</code></li>
+ <li>Ask on <code>fop-dev</code> ML to check the branch and the generated dist files for errors.</li>
<li>Tag the source tree with the release ID. For example, if the release is 1.0:
<code>svn copy https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/fop-1_0 https://svn.apache.org/repos/asf/xmlgraphics/fop/tags/fop-1_0</code></li>
- <li>Make a fresh checkout with the just created tag:
- <code>svn co https://svn.apache.org/repos/asf/xmlgraphics/fop/tags/fop-1_0</code></li>
- <li>Copy jimi and jai to lib/ (jimi-1.0.jar, jai_core.jar, jai_codec.jar)</li>
- <li>Copy jce-jdk13-119.jar from <link href="http://www.bouncycastle.org/latest_releases.html">
- from http://www.bouncycastle.org/latest_releases.html</link> to lib/</li>
- <li>Copy the hyphenation patterns jar file
- <code>fop-hyph.jar</code> to lib/ (e.g. from
- <code>http://sourceforge.net/projects/offo</code></li>
- <li>Alternatively, create a build-local.properties file that points to the above libs.</li>
- <li>Run build[.sh] dist. Do this using Sun JDK 1.4.2_08 or later. A Forrest installation is needed.</li>
- <li>Create signatures. Don't forget to upload your KEY:
- <code>gpg -a -b --force-v3-sigs fop-1.0-src.tar.gz</code> etc.</li>
- <li>Upload the dist and signature files to your web directory
- on people.apache.org (An account on minotaur is needed):
- <code>scp fop-1.0*.tar.gz*
- chrisg@people.apache.org:public_html/</code></li>
- <li>Check permissions:
- <code>chmod 664 ... ; chgrp xmlgraphics ...</code></li>
- <li>Add MD5 sums: <code>md5 fop-1.0-src.tar.gz &gt;
- fop-1.0-src.tar.gz.md5</code> etc.</li>
+ <li>Make a fresh checkout with the just created tag: <code>svn co https://svn.apache.org/repos/asf/xmlgraphics/fop/tags/fop-1_0</code></li>
+ <li>Copy the hyphenation patterns jar file <code>fop-hyph.jar</code> to <code>lib</code> (e.g. from <code>http://sourceforge.net/projects/offo</code></li>
+ <li>Alternatively, create a <code>build-local.properties</code> file that points to the above libraries.</li>
+ <li>Run <code>build[.sh] dist</code>. Do this using Sun JDK 1.5 or later. A Forrest installation is needed.</li>
+ <li>Create signatures. Don't forget to upload your KEY: <code>gpg -a -b --force-v3-sigs fop-1.0-src.tar.gz</code> etc.</li>
+ <li>Upload the dist and signature files to your web directory on people.apache.org (An account on minotaur is needed):
+ <code>scp fop-1.0*.tar.gz* chrisg@people.apache.org:public_html/</code></li>
+ <li>Check permissions: <code>chmod 664 ... ; chgrp xmlgraphics ...</code></li>
+ <li>Add MD5 sums: <code>md5 fop-1.0-src.tar.gz &gt; fop-1.0-src.tar.gz.md5</code> etc.</li>
<li>Make a test download.</li>
- <li>Start a vote for the release on
- <code>general@xmlgraphics.a.o</code>. The message should point
- to the release files and list the MD5 sums (<code>cat
- *.md5</code>). The vote is open for 72hrs.</li>
- <li>When the release is accepted, copy the release files,
- their md5 sum files and the signature files to
- /www/www.apache.org/dist/xmlgraphics/fop/ in the
- subdirectories <code>source</code> and
- <code>binaries</code>. Create links to all files in the
- <code>fop</code> directory. Remove the links to the files of
- the previous version.</li>
- <li>Update HEADER.html and README.html in people.apache.org:/www/www.apache.org/dist/xmlgraphics/fop/</li>
+ <li>Start a vote for the release on <code>general@xmlgraphics.apache.org</code>. The message should point
+ to the release files and list the MD5 sums (<code>cat *.md5</code>). The vote should remain open for 72hrs.</li>
+ <li>When the release is accepted, copy the release files, their md5 sum files and the signature files to
+ <code>/www/www.apache.org/dist/xmlgraphics/fop/</code> in the subdirectories <code>source</code> and
+ <code>binaries</code>. Create links to all files in the <code>fop</code> directory. Remove the links to the files of
+ the previous version.</li>
+ <li>Update <code>HEADER.html</code> and <code>README.html</code> in <code>people.apache.org:/www/www.apache.org/dist/xmlgraphics/fop/</code>.</li>
<li>Wait 24 hours (for the mirrors to catch up).</li>
- <li>Merge the changes of the subversion release branch back
- into trunk (not the version number in the build file) and
- delete the branch.</li>
+ <li>Merge the changes of the subversion release branch back into trunk (not the version number in the build file) and
+ delete the branch.</li>
<li>Deploy the updated documentation to the FOP website.</li>
- <li>Post announcements on fop-dev and fop-user and other related mailing lists.</li>
- <li>Ask a Bugzilla admin (Christian Geisert) to add a bugzilla
- entry for the new release id, or create an issue at
- <code>https://issues.apache.org/jira/browse/INFRA</code>.</li>
+ <li>Post announcements on <code>fop-dev</code> and <code>fop-user</code> and other related mailing lists.</li>
+ <li>Ask an FOP bugzilla admin to add a bugzilla entry for the new release id, or create an issue at <code>https://issues.apache.org/jira/browse/INFRA</code>.</li>
+ <li>Deploy the maven bundle.</li>
</ul>
</section>
<section id="other-checklists">
@@ -129,6 +101,7 @@ The purpose of documenting it here is to facilitate consistency, ensure that the
<li><jump href="http://svn.apache.org/repos/asf/ant/core/trunk/ReleaseInstructions">Apache Ant</jump></li>
<li><jump href="http://jakarta.apache.org/cactus/participating/release_checklist.html">Apache Cactus</jump></li>
</ul>
+ <p/>
<p>Following are links with information about mirroring:</p>
<ul>
<li><jump href="http://www.apache.org/dev/mirrors.html">Apache Mirroring</jump></li>
@@ -137,7 +110,7 @@ The purpose of documenting it here is to facilitate consistency, ensure that the
</section>
<section id="announcements">
<title>Announcing the release</title>
- <p>Here's a collected list of places where to announce new FOP releases:</p>
+ <p>Here's a suggested list of places where to announce new FOP releases:</p>
<ul>
<li>fop-dev@xmlgraphics.apache.org</li>
<li>fop-users@xmlgraphics.apache.org</li>
@@ -145,15 +118,14 @@ The purpose of documenting it here is to facilitate consistency, ensure that the
<li>general@xml.apache.org</li>
<li>announce@apache.org (from your apache.org address)</li>
<li>xsl-list@lists.mulberrytech.com (subscriber-only)</li>
- <li>XSL-FO@yahoogroups.com (subscriber-only)</li>
+ <li>xsl-fo@yahoogroups.com (subscriber-only)</li>
<li>www-xsl-fo@w3.org</li>
<li>docbook-apps@lists.oasis-open.org (subscriber-only)</li>
<li>dita-users@yahoogroups.com (subscriber-only) (http://dita-ot.sourceforge.net/)</li>
<li>http://xslfo-zone.com/news/index.jsp</li>
<li>http://www.w3.org/Style/XSL/</li>
<li>http://freshmeat.net/projects/fop/</li>
- <li>any others?</li>
</ul>
</section>
</body>
-</document> \ No newline at end of file
+</document>
diff --git a/src/documentation/content/xdocs/site.xml b/src/documentation/content/xdocs/site.xml
index d7ca6f5e1..322f5e52c 100644
--- a/src/documentation/content/xdocs/site.xml
+++ b/src/documentation/content/xdocs/site.xml
@@ -151,19 +151,26 @@
<ant label="Ant Task" href="anttask.html"/>
</using>
+ <!--
+ NOTA BENE NOTA BENE NOTA BENE
+ The following features should be maintained in alphabetic order by
+ (displayed) label value.
+ NOTA BENE NOTA BENE NOTA BENE
+ -->
<features label="Features">
- <output label="Output Targets" href="output.html"/>
- <if label="Intermediate Format" href="intermediate.html"/>
- <pdfencryption label="PDF Encryption" href="pdfencryption.html"/>
- <pdfa label="PDF/A" href="pdfa.html"/>
- <pdfx label="PDF/X" href="pdfx.html"/>
- <graphics label="Graphics" href="graphics.html"/>
+ <accessibility label="Accessibility" href="accessibility.html"/>
+ <complexscripts label="Complex Scripts" href="complexscripts.html"/>
+ <events label="Events" href="events.html"/>
+ <extensions label="Extensions" href="extensions.html"/>
<fonts label="Fonts" href="fonts.html"/>
+ <graphics label="Graphics" href="graphics.html"/>
<hyphenation label="Hyphenation" href="hyphenation.html"/>
- <extensions label="Extensions" href="extensions.html"/>
- <events label="Events" href="events.html"/>
+ <if label="Intermediate Format" href="intermediate.html"/>
<metadata label="Metadata" href="metadata.html"/>
- <accessibility label="Accessibility" href="accessibility.html"/>
+ <output label="Output Targets" href="output.html"/>
+ <pdfa label="PDF/A" href="pdfa.html"/>
+ <pdfx label="PDF/X" href="pdfx.html"/>
+ <pdfencryption label="PDF Encryption" href="pdfencryption.html"/>
</features>
</trunk>
diff --git a/src/documentation/content/xdocs/trunk/complexscripts.xml b/src/documentation/content/xdocs/trunk/complexscripts.xml
new file mode 100644
index 000000000..084fa100a
--- /dev/null
+++ b/src/documentation/content/xdocs/trunk/complexscripts.xml
@@ -0,0 +1,628 @@
+<?xml version="1.0" encoding="UTF-8" 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>Apache™ FOP: Complex Scripts</title>
+ </header>
+ <body id="complex_scripts">
+ <section id="overview">
+ <title>Overview</title>
+ <p>
+ This page describes the
+ <a href="http://en.wikipedia.org/wiki/Complex_scripts">complex scripts</a>
+ features of Apache™ FOP, which include:
+ </p>
+ <ul>
+ <li>Support for languages written with right-to-left scripts, such as Arabic and Hebrew scripts.</li>
+ <li>Support for languages written with South Asian and Southeast Asian scripts, such as Devanagari,
+ Khmer, Tamil, Thai, and others.</li>
+ <li>Support for advanced substitution, reordering, and positioning of glyphs according to language
+ and script sensitive rules.</li>
+ <li>Support for advanced number to string formatting.</li>
+ </ul>
+ </section>
+ <section>
+ <title>Disabling complex scripts</title>
+ <p>Complex script features are enabled by default. If some application of FOP does not
+ require this support, then it can be disabled in three ways:</p>
+ <ol>
+ <li>
+ <strong>Command line:</strong> The command line option <code>-nocs</code> turns off complex script
+ features: <code>fop -nocs -fo mydocument.fo -pdf mydocument.pdf</code>
+ </li>
+ <li>
+ <strong>Embedding:</strong> <code>userAgent.setComplexScriptFeaturesEnabled(false);</code>
+ </li>
+ <li>
+ <strong>Optional setting in fop.xconf file:</strong>
+ <pre>
+&lt;fop version="1.0"&gt;
+ &lt;complex-scripts disabled="true"/&gt;
+ ...
+&lt;/fop&gt;
+ </pre>
+ </li>
+ </ol>
+ <p>
+ When complex scripts features are enabled, additional information related to bidirectional
+ level resolution, the association between characters and glyphs, and glyph position adjustments
+ are added to the internal, parsed representation of the XSL-FO tree and its corresponding
+ formatted area tree. This additional information will somewhat increase the memory requirements for
+ processing documents that use these features.
+ </p>
+ <note>A document author need not make explicit use of any complex scripts feature in order
+ for this additional information to be created. For example, if the author makes use of a font
+ that contains OpenType GSUB and/or GPOS tables, then those tables will be automatically used
+ unless complex scripts features are disabled.</note>
+ </section>
+ <section id="source">
+ <title>Changes to your XSL-FO input files</title>
+ <p>
+ In most circumstances, XSL-FO content does not need to change in order to make use of
+ complex scripts features; however, in certain contexts, fully automatic processing is not
+ sufficient. In these cases, an author may make use of the following XSL-FO constructs:
+ </p>
+ <ul>
+ <li>The <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#script"><code>script</code></a> property.</li>
+ <li>The <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#language"><code>language</code></a> property.</li>
+ <li>The <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#writing-mode"><code>writing-mode</code></a> property.</li>
+ <li>The number to string conversion properties:
+ <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#format"><code>format</code></a>,
+ <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#grouping-separator"><code>grouping-separator</code></a>,
+ <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#grouping-size"><code>grouping-size</code></a>,
+ <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#letter-value"><code>letter-value</code></a>,
+ and <code>fox:number-conversion-features</code>.</li>
+ <li>The <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#fo_bidi-override"><code>fo:bidi-override</code></a> element.</li>
+ <li>Explicit bidirectional control characters: U+200E LRM, U+200F RLM, U+202A LRE,
+ U+202B RLE, U+202C PDF, U+202D LRO, U+202E RLO.</li>
+ <li>Explicit join control characters: U+200C ZWNJ and U+200D ZWJ.</li>
+ </ul>
+ </section>
+ <section id="details">
+ <title>Authoring Details</title>
+ <p>The complex scripts related effects of the above enumerated XSL-FO constructs are more
+ fully described in the following sub-sections.</p>
+ <section id="script_property">
+ <title>Script Property</title>
+ <p>In order to apply font specific complex script features, it is necessary to know
+ the script that applies to the text undergoing layout processing. This script is determined
+ using the following algorithm:
+ </p>
+ <ol>
+ <li>If the FO element that governs the text specifies a
+ <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#script"><code>script</code></a>
+ property and its value is not the empty string or <code>"auto"</code>, then that script is used.</li>
+ <li>Otherwise, the dominant script of the text is determined automatically by finding the
+ script whose constituent characters appear most frequently in the text.</li>
+ </ol>
+ <p>In case the automatic algorithm does not produce the desired results, an author may
+ explicitly specify a <code>script</code> property with the desired script. If specified,
+ it must be one of the four-letter script code specified in
+ <a href="http://unicode.org/iso15924/iso15924-codes.html">ISO 15924 Code List</a> or
+ in the <a href="#extended_script_codes">Extended Script Codes</a> table. Comparison
+ of script codes is performed in a case-insensitive manner, so it does not matter what case
+ is used when specifying these codes in an XSL-FO document.</p>
+ <section id="standard_script_codes">
+ <title>Standard Script Codes</title>
+ <p>The following table enumerates the standard ISO 15924 4-letter codes recognized by FOP.</p>
+ <table class="ForrestTable tw30">
+ <tr>
+ <th style="text-align:center">Code</th>
+ <th style="text-align:left">Script</th>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>arab</code></td>
+ <td>Arabic</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>beng</code></td>
+ <td>Bengali</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>bopo</code></td>
+ <td>Bopomofo</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>cyrl</code></td>
+ <td>Cyrillic</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>deva</code></td>
+ <td>Devanagari</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>ethi</code></td>
+ <td>Ethiopic</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>geor</code></td>
+ <td>Georgian</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>grek</code></td>
+ <td>Greek</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>gujr</code></td>
+ <td>Gujarati</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>guru</code></td>
+ <td>Gurmukhi</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>hang</code></td>
+ <td>Hangul</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>hani</code></td>
+ <td>Han</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>hebr</code></td>
+ <td>Hebrew</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>hira</code></td>
+ <td>Hiragana</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>kana</code></td>
+ <td>Katakana</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>knda</code></td>
+ <td>Kannada</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>khmr</code></td>
+ <td>Khmer</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>laoo</code></td>
+ <td>Lao</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>latn</code></td>
+ <td>Latin</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>mlym</code></td>
+ <td>Malayalam</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>mymr</code></td>
+ <td>Burmese</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>mong</code></td>
+ <td>Mongolian</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>orya</code></td>
+ <td>Oriya</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>sinh</code></td>
+ <td>Sinhalese</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>taml</code></td>
+ <td>Tamil</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>telu</code></td>
+ <td>Telugu</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>thai</code></td>
+ <td>Thai</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>tibt</code></td>
+ <td>Tibetan</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>zmth</code></td>
+ <td>Math</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>zsym</code></td>
+ <td>Symbol</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>zyyy</code></td>
+ <td>Undetermined</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>zzzz</code></td>
+ <td>Uncoded</td>
+ </tr>
+ </table>
+ </section>
+ <section id="extended_script_codes">
+ <title>Extended Script Codes</title>
+ <p>The following table enumerates a number of non-standard extended script codes recognized by FOP.</p>
+ <table class="ForrestTable tw70">
+ <colgrp>
+ <col style="width:10%"/>
+ <col style="width:20%"/>
+ <col style="width:80%"/>
+ </colgrp>
+ <tr>
+ <th>Code</th>
+ <th>Script</th>
+ <th>Comments</th>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>bng2</code></td>
+ <td>Bengali</td>
+ <td>OpenType Indic Version 2 (May 2008 and following) behavior.</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>dev2</code></td>
+ <td>Devanagari</td>
+ <td>OpenType Indic Version 2 (May 2008 and following) behavior.</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>gur2</code></td>
+ <td>Gurmukhi</td>
+ <td>OpenType Indic Version 2 (May 2008 and following) behavior.</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>gjr2</code></td>
+ <td>Gujarati</td>
+ <td>OpenType Indic Version 2 (May 2008 and following) behavior.</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>knd2</code></td>
+ <td>Kannada</td>
+ <td>OpenType Indic Version 2 (May 2008 and following) behavior.</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>mlm2</code></td>
+ <td>Malayalam</td>
+ <td>OpenType Indic Version 2 (May 2008 and following) behavior.</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>ory2</code></td>
+ <td>Oriya</td>
+ <td>OpenType Indic Version 2 (May 2008 and following) behavior.</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>tml2</code></td>
+ <td>Tamil</td>
+ <td>OpenType Indic Version 2 (May 2008 and following) behavior.</td>
+ </tr>
+ <tr>
+ <td style="text-align:center"><code>tel2</code></td>
+ <td>Telugu</td>
+ <td>OpenType Indic Version 2 (May 2008 and following) behavior.</td>
+ </tr>
+ </table>
+ <warning>
+ Explicit use of one of the above extended script codes is not portable,
+ and should be limited to use with FOP only.
+ </warning>
+ <note>
+ When performing automatic script determination, FOP selects the OpenType Indic
+ Version 2 script codes by default. If the author requires Version 1 behavior, then
+ an explicit, non-extension script code should be specified in a governing <code>script</code>
+ property.
+ </note>
+ </section>
+ </section>
+ <section id="language_property">
+ <title>Language Property</title>
+ <p>Certain fonts that support complex script features can make use of language information in order for
+ language specific processing rules to be applied. For example, a font designed for the Arabic script may support
+ typographic variations according to whether the written language is Arabic, Farsi (Persian), Sindhi, Urdu, or
+ another language written with the Arabic script. In order to apply these language specific features, the author
+ may explicitly mark the text with a <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#language"><code>language</code></a>
+ property.</p>
+ <p>When specifying the <code>language</code> property, the value of the property must be either an
+ <a href="http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes">ISO639-2 3-letter code</a> or an
+ <a href="http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes">ISO639-1 2-letter code</a>. Comparison of language
+ codes is performed in a case-insensitive manner, so it does not matter what case is used when specifying these
+ codes in an XSL-FO document.</p>
+ </section>
+ <section id="writing_mode_property">
+ <title>Writing Mode Property</title>
+ </section>
+ <section id="number_conversion_properties">
+ <title>Number Conversion Properties</title>
+ </section>
+ <section id="bidi_override_element">
+ <title>Bidi Override Element</title>
+ </section>
+ <section id="bidi_controls">
+ <title>Bidi Control Characters</title>
+ </section>
+ <section id="join_controls">
+ <title>Join Control Characters</title>
+ </section>
+ </section>
+ <section id="supported_scripts">
+ <title>Supported Scripts</title>
+ <p>Support for specific complex scripts is enumerated in the following table. Support
+ for those marked as not being supported is expected to be added in future revisions.</p>
+ <table>
+ <colgrp>
+ <col style="width: 15%"/>
+ <col style="width: 10%"/>
+ <col style="width: 10%"/>
+ <col style="width: 65%"/>
+ </colgrp>
+ <tr>
+ <th style="text-align:left">Script</th>
+ <th>Support</th>
+ <th>Tested</th>
+ <th style="text-align:left">Comments</th>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Arabic_alphabet">Arabic</a></td>
+ <td class="yes">full</td>
+ <td class="yes">full</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Bengali_alphabet">Bengali</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Burmese_alphabet">Burmese</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Devanagari_alphabet">Devanagari</a></td>
+ <td class="partial">partial</td>
+ <td class="partial">partial</td>
+ <td style="text-align:left">join controls (ZWJ, ZWNJ) not yet supported</td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Khmer_alphabet">Khmer</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Gujarati_alphabet">Gujarati</a></td>
+ <td class="partial">partial</td>
+ <td class="no">none</td>
+ <td style="text-align:left">pre-alpha</td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Gurmukhī_alphabet">Gurmukhi</a></td>
+ <td class="partial">partial</td>
+ <td class="no">none</td>
+ <td style="text-align:left">pre-alpha</td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Hebrew_alphabet">Hebrew</a></td>
+ <td class="yes">full</td>
+ <td class="partial">partial</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Kannada_alphabet">Kannada</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Lao_alphabet">Lao</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Malayalam_alphabet">Malayalam</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Mongolian_script">Mongolian</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Oriya_script">Oriya</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Tamil_alphabet">Tamil</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Telugu_alphabet">Telugu</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Tibetan_alphabet">Tibetan</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/Thai_alphabet">Thai</a></td>
+ <td class="no">none</td>
+ <td class="no">none</td>
+ <td></td>
+ </tr>
+ </table>
+ </section>
+ <section id="supported_fonts">
+ <title>Supported Fonts</title>
+ <p>Support for specific fonts is enumerated in the following sub-sections. If a given
+ font is not listed, then it has not been tested with these complex scripts features.</p>
+ <section id="fonts_arabic">
+ <title>Arabic Fonts</title>
+ <table>
+ <colgrp>
+ <col style="width: 15%"/>
+ <col style="width: 10%"/>
+ <col style="width: 10%"/>
+ <col style="width: 65%"/>
+ </colgrp>
+ <tr>
+ <th style="text-align:left">Font</th>
+ <th style="text-align:left">Version</th>
+ <th style="text-align:center">Glyphs</th>
+ <th style="text-align:left">Comments</th>
+ </tr>
+ <tr>
+ <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=24">Arial Unicode MS</a></td>
+ <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1081">1.01</a></td>
+ <td style="text-align:center">50377</td>
+ <td>limited GPOS support</td>
+ </tr>
+ <tr>
+ <td><a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;id=ArabicFonts">Lateef</a></td>
+ <td class="yes" style="text-align:left">1.0</td>
+ <td style="text-align:center">1147</td>
+ <td>language features for Kurdish (KUR), Sindhi (SND), Urdu (URD)</td>
+ </tr>
+ <tr>
+ <td><a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;id=ArabicFonts">Scheherazade</a></td>
+ <td class="yes" style="text-align:left">1.0</td>
+ <td style="text-align:center">1197</td>
+ <td>language features for Kurdish (KUR), Sindhi (SND), Urdu (URD)</td>
+ </tr>
+ <tr>
+ <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=261">Simplified Arabic</a></td>
+ <td class="no" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=867">1.01</a></td>
+ <td/>
+ <td>contains invalid, out of order coverage table entries</td>
+ </tr>
+ <tr>
+ <td><a href="http://www.microsoft.com/typography/fonts/font.aspx?FID=261">Simplified Arabic</a></td>
+ <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1645">5.00</a></td>
+ <td style="text-align:center">414</td>
+ <td>lacks GPOS support</td>
+ </tr>
+ <tr>
+ <td><a href="http://www.microsoft.com/typography/fonts/font.aspx?FID=261">Simplified Arabic</a></td>
+ <td class="yes" style="text-align:left">5.92</td>
+ <td style="text-align:center">473</td>
+ <td>includes GPOS for advanced position adjustment</td>
+ </tr>
+ <tr>
+ <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=264">Traditional Arabic</a></td>
+ <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/family.aspx?FMID=877">1.01</a></td>
+ <td style="text-align:center">530</td>
+ <td>lacks GPOS support</td>
+ </tr>
+ <tr>
+ <td><a href="http://www.microsoft.com/typography/fonts/font.aspx?FID=264">Traditional Arabic</a></td>
+ <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1658">5.00</a></td>
+ <td style="text-align:center">530</td>
+ <td>lacks GPOS support</td>
+ </tr>
+ <tr>
+ <td><a href="http://www.microsoft.com/typography/fonts/font.aspx?FID=264">Traditional Arabic</a></td>
+ <td class="yes" style="text-align:left">5.92</td>
+ <td style="text-align:center">589</td>
+ <td>includes GPOS for advanced position adjustment</td>
+ </tr>
+ </table>
+ </section>
+ <section id="devanagari_fonts">
+ <title>Devanagari Fonts</title>
+ <table>
+ <colgrp>
+ <col style="width: 15%"/>
+ <col style="width: 10%"/>
+ <col style="width: 10%"/>
+ <col style="width: 65%"/>
+ </colgrp>
+ <tr>
+ <th style="text-align:left">Font</th>
+ <th style="text-align:left">Version</th>
+ <th style="text-align:center">Glyphs</th>
+ <th style="text-align:left">Comments</th>
+ </tr>
+ <tr>
+ <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=370">Aparajita</a></td>
+ <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1700">1.00</a></td>
+ <td style="text-align:center">706</td>
+ <td/>
+ </tr>
+ <tr>
+ <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=374">Kokila</a></td>
+ <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1749">1.00</a></td>
+ <td style="text-align:center">706</td>
+ <td/>
+ </tr>
+ <tr>
+ <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=243">Mangal</a></td>
+ <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1759">5.01</a></td>
+ <td style="text-align:center">885</td>
+ <td>designed for use in user interfaces</td>
+ </tr>
+ <tr>
+ <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=384">Utsaah</a></td>
+ <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1811">1.00</a></td>
+ <td style="text-align:center">706</td>
+ <td/>
+ </tr>
+ </table>
+ </section>
+ </section>
+ <section id="limitations">
+ <title>Other Limitations</title>
+ <p>
+ Complex scripts support in Apache FOP is relatively new, so there are certain
+ limitations. Please help us identify and close any gaps.
+ </p>
+ <ul>
+ <li>Only the PDF output format fully supports complex scripts features at the present time.</li>
+ <li>Shaping context does not extend across an element boundary. This limitation prevents the use of
+ <code>fo:character</code>, <code>fo:inline</code> or <code>fo:wrapper</code> in order to colorize
+ individual Arabic letters without affecting shaping behavior across the element boundary.</li>
+ </ul>
+ </section>
+ <section id="links">
+ <title>Related Links</title>
+ <p>
+ In addition to the XSL-FO specification, a number of external resources provide
+ guidance about authoring documents that employ complex scripts and the features
+ described above:
+ </p>
+ <ul>
+ <li><a href="http://www.unicode.org/">The Unicode Standard</a></li>
+ <li><a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#fo_bidi-override">Unicode Bidirectional Algorithm</a></li>
+ <li><a href="http://www.microsoft.com/typography/otspec/ttochap1.htm">OpenType Advanced Typographic Extensions</a></li>
+ <li><a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=CmplxRndExamples">Examples of Complex Rendering</a></li>
+ </ul>
+ </section>
+ </body>
+</document>
diff --git a/src/documentation/content/xdocs/trunk/output.xml b/src/documentation/content/xdocs/trunk/output.xml
index 9b6a3edc9..7d6147be9 100644
--- a/src/documentation/content/xdocs/trunk/output.xml
+++ b/src/documentation/content/xdocs/trunk/output.xml
@@ -797,6 +797,17 @@ Note that the value of the encoding attribute in the example is the double-byte
<source><![CDATA[
<images mode="b+w" bits-per-pixel="1" dithering-quality="maximum"/>]]></source>
<p>
+ When the boolean attribute pseg (default false) is set to true, non-inline FS11 and FS45 IOCA images are wrapped in page segment.
+ This option is provided to support printers/print servers that require this MO:DCA structure.
+ </p>
+ <source><![CDATA[
+ <images mode="b+w" bits-per-pixel="8" pseg="true"/>]]></source>
+ <p>
+ Setting the boolean attribute fs45 to true (default false) will force all images to FS45.
+ </p>
+ <source><![CDATA[
+ <images mode="b+w" bits-per-pixel="8" fs45="true"/>]]></source>
+ <p>
By default, JPEG images are rasterized to a bitmap and the bitmap is included in the AFP doc.
However it is possible to encode in a lossless way to maintain maximum quality. But due
to lack of support for compression schemes like LZW (patent concerns), bitmap data is currently
@@ -1308,6 +1319,7 @@ Note that the value of the encoding attribute in the example is the double-byte
a quick-and-dirty view of the document text. The renderer is very limited,
so do not be surprised if it gives unsatisfactory results.
</p>
+ <!-- OBSOLETE OBSOLETE OBSOLETE
<p>
The Text renderer works with a fixed size page buffer. The size of this
buffer is controlled with the textCPI and textLPI public variables.
@@ -1318,6 +1330,7 @@ Note that the value of the encoding attribute in the example is the double-byte
Graphic elements (lines, borders, etc) are assigned a lower priority
than text, so text will overwrite any graphic element representations.
</p>
+ -->
<p>
Because FOP lays the text onto a grid during layout, there are frequently
extra or missing spaces between characters and lines, which is generally
@@ -1326,8 +1339,8 @@ Note that the value of the encoding attribute in the example is the double-byte
</p>
<ul>
<li>font-family="Courier"</li>
- <li>font-size="7.3pt"</li>
- <li>line-height="10.5pt"</li>
+ <li>font-size="10pt"</li>
+ <li>line-height="10pt"</li>
</ul>
</section>
<section id="sandbox">
@@ -1377,4 +1390,4 @@ Note that the value of the encoding attribute in the example is the double-byte
</section>
</body>
-</document> \ No newline at end of file
+</document>
diff --git a/src/documentation/content/xdocs/trunk/running.xml b/src/documentation/content/xdocs/trunk/running.xml
index 6bfa6bb3f..5e30bb25e 100644
--- a/src/documentation/content/xdocs/trunk/running.xml
+++ b/src/documentation/content/xdocs/trunk/running.xml
@@ -117,6 +117,7 @@ Fop [options] [-fo|-xml] infile [-xsl file] [-awt|-pdf|-mif|-rtf|-tiff|-png|-pcl
-q quiet mode
-c cfg.xml use additional configuration file cfg.xml
-l lang the language to use for user information
+ -nocs disable complex script features
-r relaxed/less strict validation (where available)
-dpi xxx target resolution in dots per inch (dpi) where xxx is a number
-s for area tree XML, down to block areas only
@@ -366,4 +367,4 @@ Fop [options] [-fo|-xml] infile [-xsl file] [-awt|-pdf|-mif|-rtf|-tiff|-png|-pcl
<p>If you have problems running FOP, please see the <a href="../gethelp.html">"How to get Help" page</a>.</p>
</section>
</body>
-</document> \ No newline at end of file
+</document>
diff --git a/src/documentation/skinconf.xml b/src/documentation/skinconf.xml
index 49348eb27..c98041ed9 100644
--- a/src/documentation/skinconf.xml
+++ b/src/documentation/skinconf.xml
@@ -148,6 +148,10 @@ See main/fresh-site/src/documentation/skinconf.xml for details.
<!-- The normal content should be at natural size -->
#content { font-size: 100%; }
+ .tw30 { width: 30% !important; }
+ .tw70 { width: 70% !important; }
+ .tw80 { width: 80% !important; }
+
p.quote {
margin-left: 2em;
padding: .5em;
diff --git a/src/java/org/apache/fop/afp/AFPPaintingState.java b/src/java/org/apache/fop/afp/AFPPaintingState.java
index 1c87b27d2..7e6b940a5 100644
--- a/src/java/org/apache/fop/afp/AFPPaintingState.java
+++ b/src/java/org/apache/fop/afp/AFPPaintingState.java
@@ -84,6 +84,13 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
/** determines whether to stroke text in GOCA mode or to use text operators where possible */
private boolean strokeGocaText = false;
+
+ /** use page segment with F11 and F45 images*/
+ private boolean pSeg;
+
+ /** use FS45 images*/
+ private boolean fs45;
+
/** the current page */
private transient AFPPagePaintingState pagePaintingState = new AFPPagePaintingState();
@@ -356,6 +363,41 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
return this.strokeGocaText;
}
+ /**
+ * Whether FS11 and SF45 non-inline images should be wrapped in a page segment
+ * @return true iff images should be wrapped
+ */
+ public boolean getWrapPSeg() {
+ return pSeg;
+ }
+
+ /**
+ * Sets whether FS11 and FS45 non-inline images should be wrapped in a page segment
+ * @param pSeg true iff images should be wrapped
+ */
+ public void setWrapPSeg(boolean pSeg) {
+ this.pSeg = pSeg;
+ }
+
+
+ /**
+ * gets whether images should be FS45
+ * @return true iff images should be FS45
+ */
+ public boolean getFS45() {
+ return fs45;
+ }
+
+ /**
+ * sets whether images should be FS45
+ * @param fs45 true iff images should be FS45
+ */
+ public void setFS45(boolean fs45) {
+ this.fs45 = fs45;
+ }
+
+
+
/** {@inheritDoc} */
@Override
protected AbstractData instantiateData() {
diff --git a/src/java/org/apache/fop/afp/AFPResourceLevel.java b/src/java/org/apache/fop/afp/AFPResourceLevel.java
index 327a99bd5..d884b56a6 100644
--- a/src/java/org/apache/fop/afp/AFPResourceLevel.java
+++ b/src/java/org/apache/fop/afp/AFPResourceLevel.java
@@ -186,7 +186,7 @@ public class AFPResourceLevel {
}
AFPResourceLevel rl = (AFPResourceLevel)obj;
- return (level == level)
+ return (level == rl.level)
&& (extFilePath == rl.extFilePath
|| extFilePath != null && extFilePath.equals(rl.extFilePath));
}
diff --git a/src/java/org/apache/fop/afp/fonts/AFPFont.java b/src/java/org/apache/fop/afp/fonts/AFPFont.java
index f64410fdd..8a4ae3dc1 100644
--- a/src/java/org/apache/fop/afp/fonts/AFPFont.java
+++ b/src/java/org/apache/fop/afp/fonts/AFPFont.java
@@ -19,6 +19,7 @@
package org.apache.fop.afp.fonts;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -62,8 +63,8 @@ public abstract class AFPFont extends Typeface {
}
/** {@inheritDoc} */
- public Set getFamilyNames() {
- Set s = new java.util.HashSet();
+ public Set<String> getFamilyNames() {
+ Set<String> s = new HashSet<String>();
s.add(this.name);
return s;
}
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
index e6c4e6907..4988bb949 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
@@ -285,12 +285,12 @@ public abstract class CharacterSetBuilder {
CharacterSetOrientation[] characterSetOrientations
= processFontOrientation(structuredFieldReader);
- int metricNormalizationFactor;
+ double metricNormalizationFactor;
if (fontControl.isRelative()) {
metricNormalizationFactor = 1;
} else {
int dpi = fontControl.getDpi();
- metricNormalizationFactor = 1000 * 72000
+ metricNormalizationFactor = 1000.0d * 72000.0d
/ fontDescriptor.getNominalFontSizeInMillipoints() / dpi;
}
diff --git a/src/java/org/apache/fop/afp/fonts/RasterFont.java b/src/java/org/apache/fop/afp/fonts/RasterFont.java
index da5060ccc..30704b2b0 100644
--- a/src/java/org/apache/fop/afp/fonts/RasterFont.java
+++ b/src/java/org/apache/fop/afp/fonts/RasterFont.java
@@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
+import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -39,9 +40,8 @@ public class RasterFont extends AFPFont {
/** Static logging instance */
protected static final Log LOG = LogFactory.getLog("org.apache.fop.afp.fonts");
- private final SortedMap/*<Integer,CharacterSet>*/ charSets
- = new java.util.TreeMap/*<Integer,CharacterSet>*/();
- private Map/*<Integer,CharacterSet>*/ substitutionCharSets;
+ private final SortedMap<Integer, CharacterSet> charSets = new TreeMap<Integer, CharacterSet>();
+ private Map<Integer, CharacterSet> substitutionCharSets;
private CharacterSet charSet = null;
@@ -92,8 +92,8 @@ public class RasterFont extends AFPFont {
// No match or substitution found, but there exist entries
// for other sizes
// Get char set with nearest, smallest font size
- SortedMap smallerSizes = charSets.headMap(requestedSize);
- SortedMap largerSizes = charSets.tailMap(requestedSize);
+ SortedMap<Integer, CharacterSet> smallerSizes = charSets.headMap(requestedSize);
+ SortedMap<Integer, CharacterSet> largerSizes = charSets.tailMap(requestedSize);
int smallerSize = smallerSizes.isEmpty() ? 0
: ((Integer)smallerSizes.lastKey()).intValue();
int largerSize = largerSizes.isEmpty() ? Integer.MAX_VALUE
@@ -112,7 +112,7 @@ public class RasterFont extends AFPFont {
// Add the substitute mapping, so subsequent calls will
// find it immediately
if (substitutionCharSets == null) {
- substitutionCharSets = new HashMap();
+ substitutionCharSets = new HashMap<Integer, CharacterSet>();
}
substitutionCharSets.put(requestedSize, csm);
// do not output the warning if the font size is closer to an integer less than 0.1
@@ -140,9 +140,9 @@ public class RasterFont extends AFPFont {
* @return the first character in this font.
*/
public int getFirstChar() {
- Iterator it = charSets.values().iterator();
+ Iterator<CharacterSet> it = charSets.values().iterator();
if (it.hasNext()) {
- CharacterSet csm = (CharacterSet) it.next();
+ CharacterSet csm = it.next();
return csm.getFirstChar();
} else {
String msg = "getFirstChar() - No character set found for font:" + getFontName();
@@ -157,9 +157,9 @@ public class RasterFont extends AFPFont {
*/
public int getLastChar() {
- Iterator it = charSets.values().iterator();
+ Iterator<CharacterSet> it = charSets.values().iterator();
if (it.hasNext()) {
- CharacterSet csm = (CharacterSet) it.next();
+ CharacterSet csm = it.next();
return csm.getLastChar();
} else {
String msg = "getLastChar() - No character set found for font:" + getFontName();
diff --git a/src/java/org/apache/fop/afp/modca/ImageObject.java b/src/java/org/apache/fop/afp/modca/ImageObject.java
index c6cfa3808..adb56e626 100644
--- a/src/java/org/apache/fop/afp/modca/ImageObject.java
+++ b/src/java/org/apache/fop/afp/modca/ImageObject.java
@@ -75,10 +75,11 @@ public class ImageObject extends AbstractDataObject {
int dataHeightRes = imageObjectInfo.getDataWidthRes();
ImageDataDescriptor imageDataDescriptor
= factory.createImageDataDescriptor(dataWidth, dataHeight, dataWidthRes, dataHeightRes);
- if (imageObjectInfo.getBitsPerPixel() == 1) {
- imageDataDescriptor.setFunctionSet(ImageDataDescriptor.FUNCTION_SET_FS10);
- } else if (MimeConstants.MIME_AFP_IOCA_FS45.equals(imageObjectInfo.getMimeType())) {
+
+ if (MimeConstants.MIME_AFP_IOCA_FS45.equals(imageObjectInfo.getMimeType())) {
imageDataDescriptor.setFunctionSet(ImageDataDescriptor.FUNCTION_SET_FS45);
+ } else if (imageObjectInfo.getBitsPerPixel() == 1) {
+ imageDataDescriptor.setFunctionSet(ImageDataDescriptor.FUNCTION_SET_FS10);
}
getObjectEnvironmentGroup().setDataDescriptor(imageDataDescriptor);
getObjectEnvironmentGroup().setMapImageObject(
diff --git a/src/java/org/apache/fop/area/Area.java b/src/java/org/apache/fop/area/Area.java
index bdd886e2c..240a0ab10 100644
--- a/src/java/org/apache/fop/area/Area.java
+++ b/src/java/org/apache/fop/area/Area.java
@@ -21,6 +21,7 @@ package org.apache.fop.area;
import java.io.Serializable;
import java.util.Map;
+import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -116,9 +117,9 @@ public class Area extends AreaTreeObject implements Serializable {
protected int bidiLevel = -1;
/**
- * Traits for this area stored in a HashMap
+ * Traits for this area.
*/
- protected transient Map<Integer, Object> traits = null;
+ protected TreeMap<Integer, Object> traits;
/**
* logging instance
@@ -134,6 +135,15 @@ public class Area extends AreaTreeObject implements Serializable {
return this.areaClass;
}
+ /** {@inheritDoc} */
+ public Object clone() throws CloneNotSupportedException {
+ Area area = (Area) super.clone();
+ if (traits != null) {
+ area.traits = (TreeMap<Integer, Object>) traits.clone();
+ }
+ return area;
+ }
+
/**
* Set the area class of this area.
*
@@ -390,8 +400,9 @@ public class Area extends AreaTreeObject implements Serializable {
* @param prop the value of the trait
*/
public void addTrait(Integer traitCode, Object prop) {
+ // use treemap since the typical number of traits are less than four
if (traits == null) {
- traits = new java.util.HashMap<Integer, Object>(20);
+ traits = new TreeMap<Integer, Object>();
}
traits.put(traitCode, prop);
}
@@ -403,7 +414,7 @@ public class Area extends AreaTreeObject implements Serializable {
*/
public void setTraits ( Map traits ) {
if ( traits != null ) {
- this.traits = new java.util.HashMap ( traits );
+ this.traits = new TreeMap<Integer, Object>( traits );
} else {
this.traits = null;
}
diff --git a/src/java/org/apache/fop/area/AreaTreeObject.java b/src/java/org/apache/fop/area/AreaTreeObject.java
index ebd88b887..91e76c3d4 100644
--- a/src/java/org/apache/fop/area/AreaTreeObject.java
+++ b/src/java/org/apache/fop/area/AreaTreeObject.java
@@ -19,7 +19,9 @@
package org.apache.fop.area;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -30,7 +32,7 @@ import org.apache.fop.fo.extensions.ExtensionAttachment;
/**
* Abstract base class for all area tree objects.
*/
-public abstract class AreaTreeObject {
+public abstract class AreaTreeObject implements Cloneable {
/** Foreign attributes */
protected Map<QName, String> foreignAttributes = null;
@@ -38,6 +40,18 @@ public abstract class AreaTreeObject {
/** Extension attachments */
protected List<ExtensionAttachment> extensionAttachments = null;
+ /** {@inheritDoc} */
+ public Object clone() throws CloneNotSupportedException {
+ AreaTreeObject ato = (AreaTreeObject) super.clone();
+ if (foreignAttributes != null) {
+ ato.foreignAttributes = (Map) ((HashMap) foreignAttributes).clone();
+ }
+ if (extensionAttachments != null) {
+ ato.extensionAttachments = (List) ((ArrayList) extensionAttachments).clone();
+ }
+ return ato;
+ }
+
/**
* Sets a foreign attribute.
* @param name the qualified name of the attribute
@@ -45,7 +59,7 @@ public abstract class AreaTreeObject {
*/
public void setForeignAttribute(QName name, String value) {
if (this.foreignAttributes == null) {
- this.foreignAttributes = new java.util.HashMap<QName, String>();
+ this.foreignAttributes = new HashMap<QName, String>();
}
this.foreignAttributes.put(name, value);
}
@@ -88,7 +102,7 @@ public abstract class AreaTreeObject {
private void prepareExtensionAttachmentContainer() {
if (this.extensionAttachments == null) {
- this.extensionAttachments = new java.util.ArrayList<ExtensionAttachment>();
+ this.extensionAttachments = new ArrayList<ExtensionAttachment>();
}
}
diff --git a/src/java/org/apache/fop/area/BodyRegion.java b/src/java/org/apache/fop/area/BodyRegion.java
index 2fd0b014b..61de7852b 100644
--- a/src/java/org/apache/fop/area/BodyRegion.java
+++ b/src/java/org/apache/fop/area/BodyRegion.java
@@ -151,19 +151,11 @@ public class BodyRegion extends RegionReference {
}
}
- /**
- * Clone this object.
- *
- * @return a shallow copy of this object
- */
- public Object clone() {
- BodyRegion br = new BodyRegion(getRegionClass(), getRegionName(), regionViewport,
- getColumnCount(), getColumnGap());
- br.setCTM(getCTM());
- br.setIPD(getIPD());
- br.beforeFloat = beforeFloat;
- br.mainReference = mainReference;
- br.footnote = footnote;
+ /** {@inheritDoc} */
+ public Object clone() throws CloneNotSupportedException {
+ BodyRegion br = (BodyRegion) super.clone();
+ br.mainReference = new MainReference(br);
return br;
}
+
}
diff --git a/src/java/org/apache/fop/area/Page.java b/src/java/org/apache/fop/area/Page.java
index 9bf670a0e..209476199 100644
--- a/src/java/org/apache/fop/area/Page.java
+++ b/src/java/org/apache/fop/area/Page.java
@@ -54,7 +54,7 @@ import static org.apache.fop.fo.Constants.FO_REGION_START;
* The page is cloneable so the page master can make copies of
* the top level page and regions.
*/
-public class Page extends AreaTreeObject implements Serializable, Cloneable {
+public class Page extends AreaTreeObject implements Serializable {
private static final long serialVersionUID = 6272157047421543866L;
@@ -72,10 +72,9 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable {
private boolean fakeNonEmpty = false;
/**
- * Empty constructor, for cloning
+ * Empty constructor
*/
- public Page() {
- }
+ public Page() { }
/**
* Constructor
@@ -258,14 +257,9 @@ public class Page extends AreaTreeObject implements Serializable, Cloneable {
}
}
- /**
- * Clone this page.
- * This returns a new page with a clone of all the regions.
- *
- * @return a new clone of this page
- */
- public Object clone() {
- Page p = new Page();
+ /** {@inheritDoc} */
+ public Object clone() throws CloneNotSupportedException {
+ Page p = (Page) super.clone();
if (regionBefore != null) {
p.regionBefore = (RegionViewport)regionBefore.clone();
}
diff --git a/src/java/org/apache/fop/area/PageViewport.java b/src/java/org/apache/fop/area/PageViewport.java
index 9ec46a53d..f38964ebc 100644
--- a/src/java/org/apache/fop/area/PageViewport.java
+++ b/src/java/org/apache/fop/area/PageViewport.java
@@ -32,6 +32,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.flow.Marker;
import org.apache.fop.fo.pagination.SimplePageMaster;
import org.apache.fop.traits.WritingModeTraitsGetter;
@@ -50,7 +51,7 @@ import static org.apache.fop.fo.Constants.FO_REGION_BODY;
* This is the level that creates the page.
* The page (reference area) is then rendered inside the page object
*/
-public class PageViewport extends AreaTreeObject implements Resolvable, Cloneable {
+public class PageViewport extends AreaTreeObject implements Resolvable {
private Page page;
private Rectangle viewArea;
@@ -130,8 +131,9 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl
/**
* Copy constructor.
* @param original the original PageViewport to copy from
+ * @throws FOPException when cloning of the page is not supported
*/
- public PageViewport(PageViewport original) {
+ public PageViewport(PageViewport original) throws FOPException {
if (original.extensionAttachments != null) {
setExtensionAttachments(original.extensionAttachments);
}
@@ -141,7 +143,11 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl
this.pageIndex = original.pageIndex;
this.pageNumber = original.pageNumber;
this.pageNumberString = original.pageNumberString;
- this.page = (Page)original.page.clone();
+ try {
+ this.page = (Page) original.page.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new FOPException(e);
+ }
this.viewArea = new Rectangle(original.viewArea);
this.simplePageMasterName = original.simplePageMasterName;
this.blank = original.blank;
@@ -557,13 +563,12 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl
}
}
- /**
- * Clone this page.
- * Used by the page master to create a copy of an original page.
- * @return a copy of this page and associated viewports
- */
- public Object clone() {
- return new PageViewport(this);
+ /** {@inheritDoc} */
+ public Object clone() throws CloneNotSupportedException {
+ PageViewport pvp = (PageViewport) super.clone();
+ pvp.page = (Page) page.clone();
+ pvp.viewArea = (Rectangle) viewArea.clone();
+ return pvp;
}
/**
diff --git a/src/java/org/apache/fop/area/RegionReference.java b/src/java/org/apache/fop/area/RegionReference.java
index 4158f924a..e6b46fee4 100644
--- a/src/java/org/apache/fop/area/RegionReference.java
+++ b/src/java/org/apache/fop/area/RegionReference.java
@@ -29,7 +29,7 @@ import org.apache.fop.fo.pagination.Region;
* This area is the direct child of a region-viewport-area. It is cloneable
* so the page master can make copies from the original page and regions.
*/
-public class RegionReference extends Area implements Cloneable {
+public class RegionReference extends Area {
private static final long serialVersionUID = -298980963268244238L;
@@ -134,17 +134,10 @@ public class RegionReference extends Area implements Cloneable {
addChildArea(block);
}
- /**
- * Clone this region.
- * This is used when cloning the page by the page master.
- *
- * @return a copy of this region reference area
- */
- public Object clone() {
- RegionReference rr = new RegionReference(regionClass, regionName, regionViewport);
- rr.ctm = ctm;
- rr.setIPD(getIPD());
- rr.blocks = (ArrayList<Area>)blocks.clone();
+ /** {@inheritDoc} */
+ public Object clone() throws CloneNotSupportedException {
+ RegionReference rr = (RegionReference) super.clone();
+ rr.blocks = (ArrayList) blocks.clone();
return rr;
}
diff --git a/src/java/org/apache/fop/area/RegionViewport.java b/src/java/org/apache/fop/area/RegionViewport.java
index 7eeadbffd..1b1c5ae7d 100644
--- a/src/java/org/apache/fop/area/RegionViewport.java
+++ b/src/java/org/apache/fop/area/RegionViewport.java
@@ -22,7 +22,7 @@ package org.apache.fop.area;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
-import java.util.HashMap;
+import java.util.TreeMap;
import org.apache.fop.traits.WritingModeTraitsGetter;
@@ -32,7 +32,7 @@ import org.apache.fop.traits.WritingModeTraitsGetter;
* region-reference-area as its child. These areas are described
* in the fo:region-body description in the XSL Recommendation.
*/
-public class RegionViewport extends Area implements Cloneable, Viewport {
+public class RegionViewport extends Area implements Viewport {
private static final long serialVersionUID = 505781815165102572L;
@@ -108,7 +108,7 @@ public class RegionViewport extends Area implements Cloneable, Viewport {
out.writeFloat((float) viewArea.getWidth());
out.writeFloat((float) viewArea.getHeight());
out.writeBoolean(clip);
- out.writeObject(traits);
+ out.writeObject((TreeMap)traits);
out.writeObject(regionReference);
}
@@ -117,25 +117,15 @@ public class RegionViewport extends Area implements Cloneable, Viewport {
viewArea = new Rectangle2D.Float(in.readFloat(), in.readFloat(),
in.readFloat(), in.readFloat());
clip = in.readBoolean();
- traits = (HashMap)in.readObject();
+ traits = (TreeMap)in.readObject();
setRegionReference((RegionReference) in.readObject());
}
- /**
- * Clone this region viewport.
- * Used when creating a copy from the page master.
- *
- * @return a new copy of this region viewport
- */
- public Object clone() {
- RegionViewport rv = new RegionViewport((Rectangle2D)viewArea.clone());
- rv.regionReference = (RegionReference)regionReference.clone();
- if (traits != null) {
- rv.traits = new HashMap(traits);
- }
- if (foreignAttributes != null) {
- rv.foreignAttributes = new HashMap(foreignAttributes);
- }
+ /** {@inheritDoc} */
+ public Object clone() throws CloneNotSupportedException {
+ RegionViewport rv = (RegionViewport) super.clone();
+ rv.regionReference = (RegionReference) regionReference.clone();
+ rv.viewArea = (Rectangle2D) viewArea.clone();
return rv;
}
diff --git a/src/java/org/apache/fop/area/inline/InlineViewport.java b/src/java/org/apache/fop/area/inline/InlineViewport.java
index 202a7dad4..c2e1243c0 100644
--- a/src/java/org/apache/fop/area/inline/InlineViewport.java
+++ b/src/java/org/apache/fop/area/inline/InlineViewport.java
@@ -22,7 +22,7 @@ package org.apache.fop.area.inline;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
-import java.util.HashMap;
+import java.util.TreeMap;
import org.apache.fop.area.Area;
import org.apache.fop.area.Viewport;
@@ -132,7 +132,7 @@ public class InlineViewport extends InlineArea implements Viewport {
out.writeFloat((float) contentPosition.getHeight());
}
out.writeBoolean(clip);
- out.writeObject(traits);
+ out.writeObject((TreeMap)traits);
out.writeObject(content);
}
@@ -145,7 +145,7 @@ public class InlineViewport extends InlineArea implements Viewport {
in.readFloat());
}
this.clip = in.readBoolean();
- this.traits = (HashMap) in.readObject();
+ this.traits = (TreeMap) in.readObject();
this.content = (Area) in.readObject();
}
diff --git a/src/java/org/apache/fop/events/Event.java b/src/java/org/apache/fop/events/Event.java
index ffec9473e..6c4553228 100644
--- a/src/java/org/apache/fop/events/Event.java
+++ b/src/java/org/apache/fop/events/Event.java
@@ -21,27 +21,28 @@ package org.apache.fop.events;
import java.util.Collections;
import java.util.EventObject;
+import java.util.Locale;
import java.util.Map;
import org.apache.fop.events.model.EventSeverity;
/**
* This is the default event class used by this package. Each event has a unique event identifier
- * (a String), a severity indicator and a map of name/value pairs.
+ * (a String), a severity indicator, a locale (for formatting event messages), and a map of
+ * name/value pairs.
*/
public class Event extends EventObject {
private static final long serialVersionUID = -1310594422868258083L;
private String eventGroupID;
-
private String eventKey;
-
private EventSeverity severity;
+ private Locale locale;
private Map<String, Object> params;
/**
- * Creates a new Event.
+ * Creates a new Event using default locale.
* @param source the object that creates the event
* @param eventID the unique identifier of the event
* @param severity the severity level
@@ -49,6 +50,19 @@ public class Event extends EventObject {
*/
public Event(Object source, String eventID, EventSeverity severity, Map<String, Object> params)
{
+ this ( source, eventID, severity, Locale.getDefault(), params );
+ }
+
+ /**
+ * Creates a new Event.
+ * @param source the object that creates the event
+ * @param eventID the unique identifier of the event
+ * @param severity the severity level
+ * @param locale to use when formatting event (or null, which means use default locale)
+ * @param params the event parameters (a map of name/value pairs)
+ */
+ public Event(Object source, String eventID, EventSeverity severity, Locale locale, Map<String, Object> params)
+ {
super(source);
int pos = eventID.lastIndexOf('.');
if (pos < 0 || pos == eventID.length() - 1) {
@@ -58,6 +72,7 @@ public class Event extends EventObject {
eventKey = eventID.substring(pos + 1);
}
setSeverity(severity);
+ this.locale = locale;
this.params = params;
}
@@ -107,6 +122,14 @@ public class Event extends EventObject {
}
/**
+ * Returns the locale.
+ * @return the locale
+ */
+ public Locale getLocale() {
+ return this.locale;
+ }
+
+ /**
* Returns a parameter.
* @param key the key to the parameter
* @return the parameter value or null if no value with this key is found
diff --git a/src/java/org/apache/fop/events/EventFormatter.java b/src/java/org/apache/fop/events/EventFormatter.java
index 072cddd24..32fd7f110 100644
--- a/src/java/org/apache/fop/events/EventFormatter.java
+++ b/src/java/org/apache/fop/events/EventFormatter.java
@@ -47,25 +47,28 @@ public final class EventFormatter {
//utility class
}
+ private static ResourceBundle getBundle ( String groupID, Locale locale ) {
+ ResourceBundle bundle;
+ String baseName = ( groupID != null ) ? groupID : EventFormatter.class.getName();
+ try {
+ ClassLoader classLoader = EventFormatter.class.getClassLoader();
+ bundle = XMLResourceBundle.getXMLBundle ( baseName, locale, classLoader );
+ } catch ( MissingResourceException e ) {
+ if ( log.isTraceEnabled() ) {
+ log.trace ( "No XMLResourceBundle for " + baseName + " available." );
+ }
+ bundle = null;
+ }
+ return bundle;
+ }
+
/**
* Formats an event using the default locale.
* @param event the event
* @return the formatted message
*/
- public static String format(Event event) {
- ResourceBundle bundle = null;
- String groupID = event.getEventGroupID();
- if (groupID != null) {
- try {
- bundle = XMLResourceBundle.getXMLBundle(
- groupID,
- EventFormatter.class.getClassLoader());
- } catch (MissingResourceException mre) {
- throw new IllegalStateException("No XMLResourceBundle for " + groupID
- + " available.");
- }
- }
- return format(event, bundle);
+ public static String format ( Event event ) {
+ return format ( event, event.getLocale() );
}
/**
@@ -75,31 +78,19 @@ public final class EventFormatter {
* @return the formatted message
*/
public static String format(Event event, Locale locale) {
- ResourceBundle bundle = null;
- String groupID = event.getEventGroupID();
- if (groupID != null) {
- try {
- bundle = XMLResourceBundle.getXMLBundle(
- groupID, locale,
- EventFormatter.class.getClassLoader());
- } catch (MissingResourceException mre) {
- if (log.isTraceEnabled()) {
- log.trace("No XMLResourceBundle for " + groupID + " available.");
- }
- }
- }
- if (bundle == null) {
- bundle = XMLResourceBundle.getXMLBundle(
- EventFormatter.class.getName(),
- locale,
- EventFormatter.class.getClassLoader());
- }
- return format(event, bundle);
+ return format ( event, getBundle ( event.getEventGroupID(), locale ) );
}
- private static String format(Event event, ResourceBundle bundle) {
- String template = bundle.getString(event.getEventKey());
- return format(event, processIncludes(template, bundle));
+ private static String format ( Event event, ResourceBundle bundle ) {
+ assert event != null;
+ String key = event.getEventKey();
+ String template;
+ if ( bundle != null ) {
+ template = bundle.getString ( key );
+ } else {
+ template = "Missing bundle. Can't lookup event key: '" + key + "'.";
+ }
+ return format ( event, processIncludes ( template, bundle ) );
}
private static String processIncludes(String template, ResourceBundle bundle) {
@@ -118,14 +109,16 @@ public final class EventFormatter {
private static int processIncludesInner(CharSequence template, StringBuffer sb,
ResourceBundle bundle) {
int replacements = 0;
- Matcher m = INCLUDES_PATTERN.matcher(template);
- while (m.find()) {
- String include = m.group();
- include = include.substring(2, include.length() - 2);
- m.appendReplacement(sb, bundle.getString(include));
- replacements++;
+ if ( bundle != null ) {
+ Matcher m = INCLUDES_PATTERN.matcher(template);
+ while (m.find()) {
+ String include = m.group();
+ include = include.substring(2, include.length() - 2);
+ m.appendReplacement(sb, bundle.getString(include));
+ replacements++;
+ }
+ m.appendTail(sb);
}
- m.appendTail(sb);
return replacements;
}
@@ -141,6 +134,8 @@ public final class EventFormatter {
Map params = new java.util.HashMap(event.getParams());
params.put("source", event.getSource());
params.put("severity", event.getSeverity());
+ params.put("groupID", event.getEventGroupID());
+ params.put("locale", event.getLocale());
return format.format(params);
}
@@ -157,8 +152,12 @@ public final class EventFormatter {
}
public void write(StringBuffer sb, Map params) {
- // TODO there's no defaultBundle anymore
-// sb.append(defaultBundle.getString(getKey(params)));
+ String groupID = (String) params.get("groupID");
+ Locale locale = (Locale) params.get("locale");
+ ResourceBundle bundle = getBundle ( groupID, locale );
+ if ( bundle != null ) {
+ sb.append(bundle.getString(getKey(params)));
+ }
}
private String getKey(Map params) {
diff --git a/src/java/org/apache/fop/fo/FONode.java b/src/java/org/apache/fop/fo/FONode.java
index 99d133f16..c66259f11 100644
--- a/src/java/org/apache/fop/fo/FONode.java
+++ b/src/java/org/apache/fop/fo/FONode.java
@@ -405,6 +405,27 @@ public abstract class FONode implements Cloneable {
}
/**
+ * Helper function to obtain standard usage prefix for FOP related
+ * namespace URIs.
+ * @param namespaceURI URI of node found
+ * (e.g., "http://www.w3.org/1999/XSL/Format")
+ * @return the prefix or null if none
+ */
+ public static String getNodePrefix(String namespaceURI) {
+ if (namespaceURI.equals(FOElementMapping.URI)) {
+ return "fo";
+ } else if (namespaceURI.equals(ExtensionElementMapping.URI)) {
+ return "fox";
+ } else if (namespaceURI.equals(InternalElementMapping.URI)) {
+ return "foi";
+ } else if (namespaceURI.equals(SVGElementMapping.URI)) {
+ return "svg";
+ } else {
+ return null;
+ }
+ }
+
+ /**
* Helper function to standardize the names of all namespace URI - local
* name pairs in text messages.
* For readability, using fo:, fox:, svg:, for those namespaces even
@@ -416,14 +437,9 @@ public abstract class FONode implements Cloneable {
* with the unabbreviated URI otherwise.
*/
public static String getNodeString(String namespaceURI, String localName) {
- if (namespaceURI.equals(FOElementMapping.URI)) {
- return "fo:" + localName;
- } else if (namespaceURI.equals(ExtensionElementMapping.URI)) {
- return "fox:" + localName;
- } else if (namespaceURI.equals(InternalElementMapping.URI)) {
- return "foi:" + localName; // used FOP internally for accessibility
- } else if (namespaceURI.equals(SVGElementMapping.URI)) {
- return "svg:" + localName;
+ String prefix = getNodePrefix ( namespaceURI );
+ if ( prefix != null ) {
+ return prefix + ":" + localName;
} else {
return "(Namespace URI: \"" + namespaceURI + "\", "
+ "Local Name: \"" + localName + "\")";
@@ -527,16 +543,22 @@ public abstract class FONode implements Cloneable {
*
* @param loc org.xml.sax.Locator object of the error (*not* parent node)
* @param parentName the name of the parent element
- * @param nsURI namespace URI of incoming invalid node
- * @param lName local name (i.e., no prefix) of incoming node
+ * @param nsURI namespace URI of incoming offending node
+ * @param lName local name (i.e., no prefix) of incoming offending node
* @param ruleViolated name of the rule violated (used to lookup a resource in a bundle)
* @throws ValidationException the validation error provoked by the method call
*/
protected void invalidChildError(Locator loc, String parentName, String nsURI, String lName,
String ruleViolated)
throws ValidationException {
- getFOValidationEventProducer().invalidChild(this, parentName,
- new QName(nsURI, lName), ruleViolated, loc);
+ String prefix = getNodePrefix ( nsURI );
+ QName qn; // qualified name of offending node
+ if ( prefix != null ) {
+ qn = new QName(nsURI, prefix, lName);
+ } else {
+ qn = new QName(nsURI, lName);
+ }
+ getFOValidationEventProducer().invalidChild(this, parentName, qn, ruleViolated, loc);
}
/**
diff --git a/src/java/org/apache/fop/fo/FObj.java b/src/java/org/apache/fop/fo/FObj.java
index f1d78acf1..241a442ab 100644
--- a/src/java/org/apache/fop/fo/FObj.java
+++ b/src/java/org/apache/fop/fo/FObj.java
@@ -501,7 +501,7 @@ public abstract class FObj extends FONode implements Constants {
* @param lName local name (i.e., no prefix) of incoming node
* @return true if a member, false if not
*/
- boolean isNeutralItem(String nsURI, String lName) {
+ protected boolean isNeutralItem(String nsURI, String lName) {
return (FO_URI.equals(nsURI)
&& ("multi-switch".equals(lName)
|| "multi-properties".equals(lName)
diff --git a/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java b/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java
index 51ae7441d..62c821504 100644
--- a/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java
+++ b/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java
@@ -103,17 +103,30 @@ public abstract class AbstractRetrieveMarker extends FObjMixed {
pList,
newPropertyList);
addChildTo(newChild, newParent);
- if (newChild.getNameId() == FO_TABLE) {
+ switch ( newChild.getNameId() ) {
+ case FO_TABLE:
Table t = (Table) child;
cloneSubtree(t.getColumns().iterator(),
- newChild, marker, newPropertyList);
+ newChild, marker, newPropertyList);
cloneSingleNode(t.getTableHeader(),
- newChild, marker, newPropertyList);
+ newChild, marker, newPropertyList);
cloneSingleNode(t.getTableFooter(),
- newChild, marker, newPropertyList);
+ newChild, marker, newPropertyList);
+ cloneSubtree(child.getChildNodes(),
+ newChild, marker, newPropertyList);
+ break;
+ case FO_LIST_ITEM:
+ ListItem li = (ListItem) child;
+ cloneSingleNode(li.getLabel(),
+ newChild, marker, newPropertyList);
+ cloneSingleNode(li.getBody(),
+ newChild, marker, newPropertyList);
+ break;
+ default:
+ cloneSubtree(child.getChildNodes(),
+ newChild, marker, newPropertyList);
+ break;
}
- cloneSubtree(child.getChildNodes(), newChild,
- marker, newPropertyList);
} else if (child instanceof FOText) {
FOText ft = (FOText) newChild;
ft.bind(parentPropertyList);
diff --git a/src/java/org/apache/fop/fo/flow/Inline.java b/src/java/org/apache/fop/fo/flow/Inline.java
index debf6bbf6..941850cdd 100644
--- a/src/java/org/apache/fop/fo/flow/Inline.java
+++ b/src/java/org/apache/fop/fo/flow/Inline.java
@@ -116,9 +116,9 @@ public class Inline extends InlineLevel {
}
} else if (!isBlockOrInlineItem(nsURI, localName)) {
invalidChildError(loc, nsURI, localName);
- } else if (!canHaveBlockLevelChildren && isBlockItem(nsURI, localName)) {
- invalidChildError(loc, getParent().getName(), nsURI, getName(),
- "rule.inlineContent");
+ } else if (!canHaveBlockLevelChildren && isBlockItem(nsURI, localName)
+ && !isNeutralItem(nsURI, localName)) {
+ invalidChildError(loc, getName(), nsURI, localName, "rule.inlineContent");
} else {
blockOrInlineItemFound = true;
}
diff --git a/src/java/org/apache/fop/fo/flow/Leader.java b/src/java/org/apache/fop/fo/flow/Leader.java
index ce166b114..4062d6562 100644
--- a/src/java/org/apache/fop/fo/flow/Leader.java
+++ b/src/java/org/apache/fop/fo/flow/Leader.java
@@ -79,7 +79,8 @@ public class Leader extends InlineLevel {
leaderLength = pList.get(PR_LEADER_LENGTH).getLengthRange();
leaderPattern = pList.get(PR_LEADER_PATTERN).getEnum();
leaderPatternWidth = pList.get(PR_LEADER_PATTERN_WIDTH).getLength();
- ruleThickness = pList.get(PR_RULE_THICKNESS).getLength();
+ // use default rule thickness as a default
+ ruleThickness = getPropertyMakerFor(PR_RULE_THICKNESS).make(pList).getLength();
switch(leaderPattern) {
case EN_SPACE:
// use Space
@@ -88,6 +89,8 @@ public class Leader extends InlineLevel {
// the following properties only apply
// for leader-pattern = "rule"
ruleStyle = pList.get(PR_RULE_STYLE).getEnum();
+ // use specified rule thickness to override default (established above)
+ ruleThickness = pList.get(PR_RULE_THICKNESS).getLength();
break;
case EN_DOTS:
break;
diff --git a/src/java/org/apache/fop/fo/flow/Marker.java b/src/java/org/apache/fop/fo/flow/Marker.java
index bff5fac0c..de806e986 100644
--- a/src/java/org/apache/fop/fo/flow/Marker.java
+++ b/src/java/org/apache/fop/fo/flow/Marker.java
@@ -59,7 +59,7 @@ public class Marker extends FObjMixed {
/** {@inheritDoc} */
public void bind(PropertyList pList) throws FOPException {
if (findAncestor(FO_FLOW) < 0) {
- invalidChildError(locator, getParent().getName(), FO_URI, getName(),
+ invalidChildError(locator, getParent().getName(), FO_URI, getLocalName(),
"rule.markerDescendantOfFlow");
}
diff --git a/src/java/org/apache/fop/fo/flow/RetrieveMarker.java b/src/java/org/apache/fop/fo/flow/RetrieveMarker.java
index 5ddc1f304..5fc70c7f2 100644
--- a/src/java/org/apache/fop/fo/flow/RetrieveMarker.java
+++ b/src/java/org/apache/fop/fo/flow/RetrieveMarker.java
@@ -60,7 +60,7 @@ public class RetrieveMarker extends AbstractRetrieveMarker {
PropertyList pList)
throws FOPException {
if (findAncestor(FO_STATIC_CONTENT) < 0) {
- invalidChildError(locator, getParent().getName(), FO_URI, getName(),
+ invalidChildError(locator, getParent().getName(), FO_URI, getLocalName(),
"rule.retrieveMarkerDescendantOfStaticContent");
} else {
super.processNode(elementName, locator, attlist, pList);
diff --git a/src/java/org/apache/fop/fo/properties/PropertyCache.java b/src/java/org/apache/fop/fo/properties/PropertyCache.java
index d08164b6c..f35ab2dad 100644
--- a/src/java/org/apache/fop/fo/properties/PropertyCache.java
+++ b/src/java/org/apache/fop/fo/properties/PropertyCache.java
@@ -76,20 +76,28 @@ public final class PropertyCache<T> {
* (case insensitive).
*/
public PropertyCache() {
- this.useCache = Boolean.valueOf(
- System.getProperty("org.apache.fop.fo.properties.use-cache", "true"))
- .booleanValue();
- if (useCache) {
- map = new ConcurrentHashMap<Integer, WeakReference<T>>();
- putCounter = new AtomicInteger();
- cleanupLock = new ReentrantLock();
- hashCodeCollisionCounter = new AtomicInteger();
+ boolean useCache;
+ try {
+ useCache = Boolean.valueOf(
+ System.getProperty("org.apache.fop.fo.properties.use-cache", "true"))
+ .booleanValue();
+ } catch ( SecurityException e ) {
+ useCache = true;
+ LOG.info("Unable to access org.apache.fop.fo.properties.use-cache"
+ + " due to security restriction; defaulting to 'true'.");
+ }
+ if ( useCache ) {
+ this.map = new ConcurrentHashMap<Integer, WeakReference<T>>();
+ this.putCounter = new AtomicInteger();
+ this.cleanupLock = new ReentrantLock();
+ this.hashCodeCollisionCounter = new AtomicInteger();
} else {
- map = null;
- putCounter = null;
- cleanupLock = null;
- hashCodeCollisionCounter = null;
+ this.map = null;
+ this.putCounter = null;
+ this.cleanupLock = null;
+ this.hashCodeCollisionCounter = null;
}
+ this.useCache = useCache;
}
/**
diff --git a/src/java/org/apache/fop/fonts/FontInfo.java b/src/java/org/apache/fop/fonts/FontInfo.java
index a38a5b480..cb1827e51 100644
--- a/src/java/org/apache/fop/fonts/FontInfo.java
+++ b/src/java/org/apache/fop/fonts/FontInfo.java
@@ -474,7 +474,7 @@ public class FontInfo {
FontTriplet key = null;
String f = null;
int newWeight = weight;
- if (newWeight <= 400) {
+ if (newWeight < 400) {
while (f == null && newWeight > 100) {
newWeight -= 100;
key = createFontKey(family, style, newWeight);
@@ -486,7 +486,7 @@ public class FontInfo {
key = createFontKey(family, style, newWeight);
f = getInternalFontKey(key);
}
- } else if (newWeight == 500) {
+ } else if (newWeight == 400 || newWeight == 500) {
key = createFontKey(family, style, 400);
f = getInternalFontKey(key);
} else if (newWeight > 500) {
diff --git a/src/java/org/apache/fop/hyphenation/CharVector.java b/src/java/org/apache/fop/hyphenation/CharVector.java
index e957be87e..de95a7699 100644
--- a/src/java/org/apache/fop/hyphenation/CharVector.java
+++ b/src/java/org/apache/fop/hyphenation/CharVector.java
@@ -101,9 +101,9 @@ public class CharVector implements Cloneable, Serializable {
}
/** {@inheritDoc} */
- public Object clone() {
- CharVector cv = new CharVector((char[])array.clone(), blockSize);
- cv.n = this.n;
+ public Object clone() throws CloneNotSupportedException {
+ CharVector cv = (CharVector) super.clone();
+ cv.array = (char[])array.clone();
return cv;
}
diff --git a/src/java/org/apache/fop/hyphenation/TernaryTree.java b/src/java/org/apache/fop/hyphenation/TernaryTree.java
index 2a9b7705d..04def1927 100644
--- a/src/java/org/apache/fop/hyphenation/TernaryTree.java
+++ b/src/java/org/apache/fop/hyphenation/TernaryTree.java
@@ -48,7 +48,7 @@ import java.util.Stack;
* patterns which will be keys in this tree. The strings patterns
* are usually small (from 2 to 5 characters), but each char in the
* tree is stored in a node. Thus memory usage is the main concern.
- * We will sacrify 'elegance' to keep memory requirenments to the
+ * We will sacrify 'elegance' to keep memory requirements to the
* minimum. Using java's char type as pointer (yes, I know pointer
* it is a forbidden word in java) we can keep the size of the node
* to be just 8 bytes (3 pointers and the data char). This gives
@@ -406,16 +406,13 @@ public class TernaryTree implements Cloneable, Serializable {
}
/** {@inheritDoc} */
- public Object clone() {
- TernaryTree t = new TernaryTree();
+ public Object clone() throws CloneNotSupportedException {
+ TernaryTree t = (TernaryTree) super.clone();
t.lo = (char[])this.lo.clone();
t.hi = (char[])this.hi.clone();
t.eq = (char[])this.eq.clone();
t.sc = (char[])this.sc.clone();
t.kv = (CharVector)this.kv.clone();
- t.root = this.root;
- t.freenode = this.freenode;
- t.length = this.length;
return t;
}
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
index 253790623..dc87f9f1d 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
@@ -752,7 +752,7 @@ public abstract class AbstractBreaker {
Position positionAtBreak = elementAtBreak.getPosition();
if (!(positionAtBreak instanceof SpaceResolver.SpaceHandlingBreakPosition)) {
throw new UnsupportedOperationException(
- "Don't know how to restart at position" + positionAtBreak);
+ "Don't know how to restart at position " + positionAtBreak);
}
/* Retrieve the original position wrapped into this space position */
positionAtBreak = positionAtBreak.getPosition();
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java
index 7e37eeb59..c58febd0e 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java
@@ -200,7 +200,7 @@ public class TableStepper {
LinkedList footnoteList = new LinkedList();
//Put all involved grid units into a list
- List cellParts = new java.util.ArrayList(columnCount);
+ List cellParts = new java.util.ArrayList(activeCells.size());
for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
ActiveCell activeCell = (ActiveCell) iter.next();
CellPart part = activeCell.createCellPart();
diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java
index 3c4680fa9..9b2968c33 100644
--- a/src/java/org/apache/fop/pdf/PDFFactory.java
+++ b/src/java/org/apache/fop/pdf/PDFFactory.java
@@ -1063,6 +1063,9 @@ public class PDFFactory {
} else if (targetLo.startsWith("http://")) {
// HTTP URL?
return new PDFUri(target);
+ } else if (targetLo.startsWith("https://")) {
+ // HTTPS URL?
+ return new PDFUri(target);
} else if (targetLo.startsWith("file://")) {
// Non PDF files. Try to /Launch them.
target = target.substring("file://".length());
diff --git a/src/java/org/apache/fop/render/afp/AFPCustomizable.java b/src/java/org/apache/fop/render/afp/AFPCustomizable.java
index 684ac057c..6eca86458 100644
--- a/src/java/org/apache/fop/render/afp/AFPCustomizable.java
+++ b/src/java/org/apache/fop/render/afp/AFPCustomizable.java
@@ -90,6 +90,30 @@ public interface AFPCustomizable {
void setResolution(int resolution);
/**
+ * Sets whether FS11 and FS45 non-inline images should be wrapped in a page segment
+ * @param pSeg true iff images should be wrapped
+ */
+ void setWrapPSeg(boolean pSeg);
+
+ /**
+ * set true if images should be FS45
+ * @param fs45 true iff images should be FS45
+ */
+ void setFS45(boolean fs45);
+
+ /**
+ * gets whether FS11 and FS45 non-inline images should be wrapped in a page segment
+ * @return true iff images should be wrapped
+ */
+ boolean getWrapPSeg();
+
+ /**
+ * gets whether images should be FS45
+ * @return true iff images should be FS45
+ */
+ boolean getFS45();
+
+ /**
* Returns the output/device resolution.
*
* @return the resolution in dpi
diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
index cddcc7b84..0c778303c 100644
--- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
+++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
@@ -468,6 +468,26 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
}
/** {@inheritDoc} */
+ public void setWrapPSeg(boolean pSeg) {
+ paintingState.setWrapPSeg(pSeg);
+ }
+
+ /** {@inheritDoc} */
+ public void setFS45(boolean fs45) {
+ paintingState.setFS45(fs45);
+ }
+
+ /** {@inheritDoc} */
+ public boolean getWrapPSeg() {
+ return paintingState.getWrapPSeg();
+ }
+
+ /** {@inheritDoc} */
+ public boolean getFS45() {
+ return paintingState.getFS45();
+ }
+
+ /** {@inheritDoc} */
public void setDefaultResourceGroupFilePath(String filePath) {
resourceManager.setDefaultResourceGroupFilePath(filePath);
}
diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java
index 0b4b6ea98..e5f41d232 100644
--- a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java
@@ -149,6 +149,25 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
private static final class RenderedImageEncoder {
+ private enum FunctionSet {
+
+ FS10(MimeConstants.MIME_AFP_IOCA_FS10),
+ FS11(MimeConstants.MIME_AFP_IOCA_FS11),
+ FS45(MimeConstants.MIME_AFP_IOCA_FS45);
+
+ private String mimeType;
+
+ FunctionSet(String mimeType) {
+ this.mimeType = mimeType;
+ }
+
+ private String getMimeType() {
+ return mimeType;
+ }
+ };
+
+
+
private ImageRendered imageRendered;
private Dimension targetSize;
@@ -223,7 +242,7 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
throws IOException {
RenderedImage renderedImage = imageRendered.getRenderedImage();
- int functionSet = useFS10 ? 10 : 11;
+ FunctionSet functionSet = useFS10 ? FunctionSet.FS10 : FunctionSet.FS11;
if (usePageSegments) {
assert resampledDim != null;
@@ -285,7 +304,7 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
log.debug("Encoding image directly...");
imageObjectInfo.setBitsPerPixel(encodedColorModel.getPixelSize());
if (pixelSize == 32) {
- functionSet = 45; //IOCA FS45 required for CMYK
+ functionSet = FunctionSet.FS45; //IOCA FS45 required for CMYK
}
//Lossy or loss-less?
@@ -315,23 +334,17 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
log.debug("Encoding image via RGB...");
imageData = encodeViaRGB(renderedImage, imageObjectInfo, paintingState, baos);
}
-
- switch (functionSet) {
- case 10:
- imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS10);
- break;
- case 11:
- imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS11);
- break;
- case 45:
- imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS45);
- break;
- default:
- throw new IllegalStateException("Invalid IOCA function set: " + functionSet);
+ // Should image be FS45?
+ if (paintingState.getFS45()) {
+ functionSet = FunctionSet.FS45;
}
-
+ //Wrapping 300+ resolution FS11 IOCA in a page segment is apparently necessary(?)
+ imageObjectInfo.setCreatePageSegment(
+ (functionSet.equals(FunctionSet.FS11) || functionSet.equals(FunctionSet.FS45))
+ && paintingState.getWrapPSeg()
+ );
+ imageObjectInfo.setMimeType(functionSet.getMimeType());
imageObjectInfo.setData(imageData);
-
return imageObjectInfo;
}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
index 23449ce4e..bf7fbde4a 100644
--- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
@@ -415,6 +415,14 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
customizable.canEmbedJpeg(allowEmbedding);
customizable.setBitmapEncodingQuality(ieq);
+ //FS11 and FS45 page segment wrapping
+ boolean pSeg = imagesCfg.getAttributeAsBoolean("pseg", false);
+ customizable.setWrapPSeg(pSeg);
+
+ //FS45 image forcing
+ boolean fs45 = imagesCfg.getAttributeAsBoolean("fs45", false);
+ customizable.setFS45(fs45);
+
// shading (filled rectangles)
Configuration shadingCfg = cfg.getChild("shading");
AFPShadingMode shadingMode = AFPShadingMode.valueOf(
diff --git a/src/java/org/apache/fop/render/awt/AWTRenderer.java b/src/java/org/apache/fop/render/awt/AWTRenderer.java
index c36655204..826dde233 100644
--- a/src/java/org/apache/fop/render/awt/AWTRenderer.java
+++ b/src/java/org/apache/fop/render/awt/AWTRenderer.java
@@ -103,8 +103,9 @@ public class AWTRenderer extends Java2DRenderer implements Pageable {
/**
* {@inheritDoc}
+ * @throws FOPException thrown by java2DRenderer
*/
- public void renderPage(PageViewport pageViewport) throws IOException {
+ public void renderPage(PageViewport pageViewport) throws IOException, FOPException {
super.renderPage(pageViewport);
if (statusListener != null) {
diff --git a/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java b/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java
index 6e431e513..8c3f998a9 100644
--- a/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java
+++ b/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java
@@ -22,7 +22,7 @@ package org.apache.fop.render.intermediate;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
-import java.util.List;
+import java.util.ArrayList;
import org.apache.xmlgraphics.java2d.GraphicContext;
@@ -33,7 +33,7 @@ public class IFGraphicContext extends GraphicContext {
private static final AffineTransform[] EMPTY_TRANSFORM_ARRAY = new AffineTransform[0];
- private List groupList = new java.util.ArrayList();
+ private ArrayList groupList = new ArrayList();
/**
* Default constructor.
@@ -48,17 +48,20 @@ public class IFGraphicContext extends GraphicContext {
*/
protected IFGraphicContext(IFGraphicContext graphicContext) {
super(graphicContext);
- //We don't clone groupDepth!
+ // N.B. do not perform deep copy on groupList; doing so causes
+ // a junit regression... have not investigated cause... [GA]
+ // groupList = (ArrayList) graphicContext.groupList.clone();
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public Object clone() {
- return new IFGraphicContext(this);
+ return new IFGraphicContext ( this );
}
/** @param group a group */
public void pushGroup(Group group) {
- //this.groupDepth++;
this.groupList.add(group);
for (int i = 0, c = group.getTransforms().length; i < c; i++) {
transform(group.getTransforms()[i]);
diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
index 45c91b2ee..8b60df746 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
@@ -267,10 +267,15 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
* @param pageViewport the <code>PageViewport</code> object supplied by
* the Area Tree
* @throws IOException In case of an I/O error
+ * @throws FOPException if cloning of pageViewport is not supported
* @see org.apache.fop.render.Renderer
*/
- public void renderPage(PageViewport pageViewport) throws IOException {
- rememberPage((PageViewport)pageViewport.clone());
+ public void renderPage(PageViewport pageViewport) throws IOException, FOPException {
+ try {
+ rememberPage((PageViewport)pageViewport.clone());
+ } catch (CloneNotSupportedException e) {
+ throw new FOPException(e);
+ }
//The clone() call is necessary as we store the page for later. Otherwise, the
//RenderPagesModel calls PageViewport.clear() to release memory as early as possible.
currentPageNumber++;
diff --git a/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java b/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java
index 2236778b5..af49fea4c 100644
--- a/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java
+++ b/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java
@@ -82,7 +82,7 @@ public class PDFDocumentNavigationHandler implements IFDocumentNavigationHandler
}
}
- private void renderBookmark(Bookmark bookmark, PDFOutline parent) {
+ private void renderBookmark(Bookmark bookmark, PDFOutline parent) throws IFException {
if (parent == null) {
parent = getPDFDoc().getOutlineRoot();
}
@@ -141,7 +141,7 @@ public class PDFDocumentNavigationHandler implements IFDocumentNavigationHandler
}
}
- private PDFAction getAction(AbstractAction action) {
+ private PDFAction getAction(AbstractAction action) throws IFException {
if (action == null) {
return null;
}
@@ -181,21 +181,27 @@ public class PDFDocumentNavigationHandler implements IFDocumentNavigationHandler
}
}
- private void updateTargetLocation(PDFGoTo pdfGoTo, GoToXYAction action) {
+ private void updateTargetLocation(PDFGoTo pdfGoTo, GoToXYAction action)
+ throws IFException {
PageReference pageRef = this.documentHandler.getPageReference(action.getPageIndex());
- //Convert target location from millipoints to points and adjust for different
- //page origin
- Point2D p2d = null;
- p2d = new Point2D.Double(
- action.getTargetLocation().x / 1000.0,
- (pageRef.getPageDimension().height - action.getTargetLocation().y) / 1000.0);
- String pdfPageRef = pageRef.getPageRef();
- pdfGoTo.setPageReference(pdfPageRef);
- pdfGoTo.setPosition(p2d);
-
- //Queue this object now that it's complete
- getPDFDoc().addObject(pdfGoTo);
- this.completeActions.put(action.getID(), pdfGoTo);
+ if ( pageRef == null ) {
+ throw new
+ IFException("Can't resolve page reference @ index: " + action.getPageIndex(), null);
+ } else {
+ //Convert target location from millipoints to points and adjust for different
+ //page origin
+ Point2D p2d = null;
+ p2d = new Point2D.Double(
+ action.getTargetLocation().x / 1000.0,
+ (pageRef.getPageDimension().height - action.getTargetLocation().y) / 1000.0);
+ String pdfPageRef = pageRef.getPageRef();
+ pdfGoTo.setPageReference(pdfPageRef);
+ pdfGoTo.setPosition(p2d);
+
+ //Queue this object now that it's complete
+ getPDFDoc().addObject(pdfGoTo);
+ this.completeActions.put(action.getID(), pdfGoTo);
+ }
}
}
diff --git a/src/java/org/apache/fop/render/ps/NativeTextHandler.java b/src/java/org/apache/fop/render/ps/NativeTextHandler.java
index e1171b3e1..33adcb8d7 100644
--- a/src/java/org/apache/fop/render/ps/NativeTextHandler.java
+++ b/src/java/org/apache/fop/render/ps/NativeTextHandler.java
@@ -31,7 +31,6 @@ import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontSetup;
-import org.apache.fop.fonts.FontTriplet;
/**
* Specialized TextHandler implementation that the PSGraphics2D class delegates to to paint text
@@ -160,26 +159,14 @@ public class NativeTextHandler implements PSTextHandler {
}
private Font createFont(java.awt.Font f) {
- String fontFamily = f.getFamily();
- if (fontFamily.equals("sanserif")) {
- fontFamily = "sans-serif";
- }
- int fontSize = 1000 * f.getSize();
- String style = f.isItalic() ? "italic" : "normal";
- int weight = f.isBold() ? Font.WEIGHT_BOLD : Font.WEIGHT_NORMAL;
-
- FontTriplet triplet = fontInfo.findAdjustWeight(fontFamily, style, weight);
- if (triplet == null) {
- triplet = fontInfo.findAdjustWeight("sans-serif", style, weight);
- }
- return fontInfo.getFontInstance(triplet, fontSize);
+ return fontInfo.getFontInstanceForAWTFont(f);
}
private void establishCurrentFont() throws IOException {
if ((currentFontName != this.font.getFontName())
|| (currentFontSize != this.font.getFontSize())) {
PSGenerator gen = getPSGenerator();
- gen.writeln(this.font.getFontName() + " "
+ gen.writeln("/" + this.font.getFontTriplet().getName() + " "
+ gen.formatDouble(font.getFontSize() / 1000f) + " F");
currentFontName = this.font.getFontName();
currentFontSize = this.font.getFontSize();
diff --git a/src/java/org/apache/fop/render/rtf/RTFHandler.java b/src/java/org/apache/fop/render/rtf/RTFHandler.java
index 95c4fec12..956ea8b57 100644
--- a/src/java/org/apache/fop/render/rtf/RTFHandler.java
+++ b/src/java/org/apache/fop/render/rtf/RTFHandler.java
@@ -119,6 +119,7 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfList;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem.RtfListItemLabel;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfPage;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraphBreak;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell;
@@ -430,8 +431,14 @@ public class RTFHandler extends FOEventHandler {
true, this);
RtfTextrun textrun = container.getTextrun();
+ RtfParagraphBreak par = textrun.addParagraphBreak();
+
+ RtfTableCell cellParent = (RtfTableCell)textrun.getParentOfClass(RtfTableCell.class);
+ if (cellParent != null && par != null) {
+ int iDepth = cellParent.findChildren(textrun);
+ cellParent.setLastParagraph(par, iDepth);
+ }
- textrun.addParagraphBreak();
int breakValue = toRtfBreakValue(bl.getBreakAfter());
textrun.popBlockAttributes(breakValue);
@@ -878,6 +885,14 @@ public class RTFHandler extends FOEventHandler {
if (bDefer) {
return;
}
+ try {
+ RtfTableCell cell = (RtfTableCell)builderContext.getContainer(RtfTableCell.class, false, this);
+ cell.finish();
+
+ } catch (Exception e) {
+ log.error("endCell: " + e.getMessage());
+ throw new RuntimeException(e.getMessage());
+ }
builderContext.popContainer();
builderContext.getTableContext().selectNextColumn();
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/IRtfTextContainer.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/IRtfTextContainer.java
index 5d0ab30d8..4a7779cc4 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/IRtfTextContainer.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/IRtfTextContainer.java
@@ -28,6 +28,8 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
import java.io.IOException;
+import org.apache.fop.apps.FOPException;
+
/**
* <p>Interface for RtfElements that can contain RtfText elements.</p>
*
@@ -61,6 +63,7 @@ public interface IRtfTextContainer {
/**
* Text containers usually provide default attributes for all texts that they contain.
* @return a copy of the container's attributes.
+ * @throws FOPException if attributes cannot be obtained
*/
- RtfAttributes getTextContainerAttributes();
+ RtfAttributes getTextContainerAttributes() throws FOPException;
}
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfAttributes.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfAttributes.java
index b5d4db114..f1f25f3b4 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfAttributes.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfAttributes.java
@@ -39,8 +39,8 @@ import org.xml.sax.helpers.AttributesImpl;
* <p>This work was authored by Bertrand Delacretaz (bdelacretaz@codeconsult.ch).</p>
*/
-public class RtfAttributes
-implements java.lang.Cloneable {
+public class RtfAttributes implements Cloneable {
+
private HashMap values = new HashMap();
/**
@@ -108,12 +108,9 @@ implements java.lang.Cloneable {
return values.toString() + "(" + super.toString() + ")";
}
- /**
- * implement cloning
- * @return cloned Object
- */
- public Object clone() {
- final RtfAttributes result = new RtfAttributes();
+ /** {@inheritDoc} */
+ public Object clone() throws CloneNotSupportedException {
+ RtfAttributes result = (RtfAttributes) super.clone();
result.values = (HashMap)values.clone();
// Added by Normand Masse
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfContainer.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfContainer.java
index 349cdd097..4e86f0091 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfContainer.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfContainer.java
@@ -112,6 +112,30 @@ public class RtfContainer extends RtfElement {
return children.size();
}
+ private int findChildren(RtfElement aChild, int iStart) {
+ for (Iterator it = this.getChildren().iterator(); it.hasNext();) {
+ final RtfElement e = (RtfElement)it.next();
+ if (aChild == e) {
+ return iStart;
+ } else if (e instanceof RtfContainer) {
+ int iFound = ((RtfContainer)e).findChildren(aChild, (iStart + 1));
+ if (iFound != -1) {
+ return iFound;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Find the passed child in the current container
+ * @param aChild the child element
+ * @return the depth (nested level) inside the current container
+ */
+ public int findChildren(RtfElement aChild) {
+ return findChildren(aChild, 0);
+ }
+
/**
* Add by Boris Poudérous on 07/22/2002
* Set the children list
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfElement.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfElement.java
index c582287a3..1b13fd783 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfElement.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfElement.java
@@ -299,7 +299,7 @@ public abstract class RtfElement {
/** find the first parent where c.isAssignableFrom(parent.getClass()) is true
* @return null if not found
*/
- RtfElement getParentOfClass(Class c) {
+ public RtfElement getParentOfClass(Class c) {
RtfElement result = null;
RtfElement current = this;
while (current.parent != null) {
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfHyperLink.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfHyperLink.java
index 0ca76715b..baca88926 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfHyperLink.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfHyperLink.java
@@ -29,6 +29,8 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
import java.io.IOException;
import java.io.Writer;
+import org.apache.fop.apps.FOPException;
+
/**
* <p>Creates an hyperlink.
* This class belongs to the <fo:basic-link> tag processing.</p>
@@ -157,12 +159,17 @@ implements IRtfTextContainer,
/**
* IRtfTextContainer requirement:
* @return a copy of our attributes
+ * @throws FOPException if attributes cannot be cloned
*/
- public RtfAttributes getTextContainerAttributes() {
+ public RtfAttributes getTextContainerAttributes() throws FOPException {
if (attrib == null) {
return null;
}
- return (RtfAttributes) this.attrib.clone ();
+ try {
+ return (RtfAttributes) this.attrib.clone ();
+ } catch (CloneNotSupportedException e) {
+ throw new FOPException(e);
+ }
}
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfParagraph.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfParagraph.java
index b4ff23b74..30f573dd5 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfParagraph.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfParagraph.java
@@ -30,6 +30,8 @@ import java.io.IOException;
import java.io.Writer;
import java.util.List;
+import org.apache.fop.apps.FOPException;
+
/**
* <p>Model of an RTF paragraph, which can contain RTF text elements.</p>
*
@@ -93,12 +95,17 @@ implements IRtfTextContainer, IRtfPageBreakContainer, IRtfHyperLinkContainer,
/**
* IRtfTextContainer requirement: return a copy of our attributes
* @return a copy of this paragraphs attributes
+ * @throws FOPException if attributes cannot be cloned
*/
- public RtfAttributes getTextContainerAttributes() {
+ public RtfAttributes getTextContainerAttributes() throws FOPException {
if (attrib == null) {
return null;
}
- return (RtfAttributes)this.attrib.clone();
+ try {
+ return (RtfAttributes)this.attrib.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new FOPException(e);
+ }
}
/**
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfParagraphBreak.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfParagraphBreak.java
new file mode 100644
index 000000000..851deb84b
--- /dev/null
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfParagraphBreak.java
@@ -0,0 +1,71 @@
+/*
+ * 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.render.rtf.rtflib.rtfdoc;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/** Class which represents a paragraph break.*/
+
+public class RtfParagraphBreak extends RtfElement {
+ private static final String DEFAULT_PARAGRAPH = "par";
+
+ private String controlWord = DEFAULT_PARAGRAPH;
+
+ RtfParagraphBreak(RtfContainer parent, Writer w)
+ throws IOException {
+ super(parent, w);
+ }
+
+ /**
+ * @return true if this element would generate no "useful" RTF content
+ */
+ public boolean isEmpty() {
+ return false;
+ }
+
+ /**
+ * write RTF code of all our children
+ * @throws IOException for I/O problems
+ */
+ protected void writeRtfContent() throws IOException {
+ if (controlWord != null ) {
+ writeControlWord(controlWord);
+ }
+ }
+
+ /**
+ * Whether or not the break can be skipped.
+ * If the paragraph marks a table cell end it is not possible
+ * @return boolean
+ */
+ public boolean canHide() {
+ return this.controlWord.equals ( DEFAULT_PARAGRAPH );
+ }
+
+ /**
+ * Sets a different control word for this paragraph. If this method
+ * is used the paragraph will always be displayed (@see canHide))
+ * @param controlWord the new control word
+ */
+ public void switchControlWord(String controlWord) {
+ this.controlWord = controlWord;
+ }
+}
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTable.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTable.java
index 9b74f5b45..018cbd845 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTable.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTable.java
@@ -29,6 +29,8 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
import java.io.IOException;
import java.io.Writer;
+import org.apache.fop.apps.FOPException;
+
/**
* <p>Container for RtfRow elements.</p>
*
@@ -86,11 +88,16 @@ public class RtfTable extends RtfContainer {
* @param attrs attributs of new RtfTableRow
* @return new RtfTableRow
* @throws IOException for I/O problems
+ * @throws FOPException if attributes cannot be cloned
*/
- public RtfTableRow newTableRow(RtfAttributes attrs) throws IOException {
+ public RtfTableRow newTableRow(RtfAttributes attrs) throws IOException, FOPException {
RtfAttributes attr = null;
if (attrib != null) {
- attr = (RtfAttributes) attrib.clone ();
+ try {
+ attr = (RtfAttributes) attrib.clone ();
+ } catch (CloneNotSupportedException e) {
+ throw new FOPException(e);
+ }
attr.set (attrs);
} else {
attr = attrs;
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableCell.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableCell.java
index 1e2a64b51..faa0852ed 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableCell.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableCell.java
@@ -48,6 +48,11 @@ public class RtfTableCell
private boolean setCenter;
private boolean setRight;
private int id;
+ private RtfParagraphBreak lastBreak = null;
+ private int lastBreakDepth = Integer.MIN_VALUE;
+
+ private static final String TABLE_CELL_PARAGRAPH = "cell";
+ private static final String TABLE_CELL_NESTED_PARAGRAPH = "nestcell";
/** default cell width (in twips ??) */
public static final int DEFAULT_CELL_WIDTH = 2000;
@@ -312,7 +317,9 @@ public class RtfTableCell
if (getRow().getTable().isNestedTable()) {
//nested table
- writeControlWordNS("nestcell");
+ if (lastBreak == null) {
+ writeControlWordNS("nestcell");
+ }
writeGroupMark(true);
writeControlWord("nonesttables");
writeControlWord("par");
@@ -352,7 +359,9 @@ public class RtfTableCell
//writeControlWord("par");
}
- writeControlWord("cell");
+ if (lastBreak == null) {
+ writeControlWord("cell");
+ }
}
}
@@ -535,4 +544,38 @@ public class RtfTableCell
return null;
}
+
+ /**
+ * The table cell decides whether or not a newly added paragraph break
+ * will be used to write the cell-end control word.
+ * For nested tables it is not necessary.
+ *
+ * @param parBreak the paragraph break element
+ * @param breakDepth The depth is necessary for picking the correct break element.
+ * If it is deeper inside the whole cell it will be used, and if there is something on
+ * the same level (depth) it is also set because the method is called for all breaks
+ * in the correct order.
+ */
+ public void setLastParagraph(RtfParagraphBreak parBreak, int breakDepth) {
+ if (parBreak != null && breakDepth >= lastBreakDepth) {
+ lastBreak = parBreak;
+ lastBreakDepth = breakDepth;
+ }
+ }
+
+ /**
+ * The last paragraph break was just stored before,
+ * now the control word is really switched
+ */
+ public void finish() {
+ //If it is nested and contains another table do not set it
+ if (getRow().getTable().isNestedTable() && table != null) {
+ lastBreak = null;
+ } else if (lastBreak != null) {
+ lastBreak.switchControlWord(
+ getRow().getTable().isNestedTable()
+ ? TABLE_CELL_NESTED_PARAGRAPH
+ : TABLE_CELL_PARAGRAPH);
+ }
+ }
}
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableRow.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableRow.java
index 74634da7f..19bda2e14 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableRow.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableRow.java
@@ -30,6 +30,8 @@ import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
+import org.apache.fop.apps.FOPException;
+
/**
* <p>Container for RtfTableCell elements.</p>
*
@@ -106,15 +108,20 @@ public class RtfTableRow extends RtfContainer implements ITableAttributes {
* @param cellWidth width of new cell
* @return new RtfTableCell
* @throws IOException for I/O problems
+ * @throws FOPException if attributes cannot be cloned
*/
public RtfTableCell newTableCellMergedHorizontally (int cellWidth,
- RtfAttributes attrs) throws IOException {
+ RtfAttributes attrs) throws IOException, FOPException {
highestCell++;
// Added by Normand Masse
// Inherit attributes from base cell for merge
RtfAttributes wAttributes = null;
if (attrs != null) {
- wAttributes = (RtfAttributes)attrs.clone();
+ try {
+ wAttributes = (RtfAttributes)attrs.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new FOPException(e);
+ }
}
cell = new RtfTableCell(this, writer, cellWidth, wAttributes, highestCell);
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfText.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfText.java
index 4df178af1..89c7d2899 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfText.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfText.java
@@ -29,6 +29,8 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
import java.io.IOException;
import java.io.Writer;
+import org.apache.fop.apps.FOPException;
+
/**
* <p>Model of a text run (a piece of text with attributes) in an RTF document.</p>
*
@@ -240,12 +242,18 @@ public class RtfText extends RtfElement {
}
/** IRtfTextContainer requirement:
- * @return a copy of our attributes */
- public RtfAttributes getTextContainerAttributes() {
+ * @return a copy of our attributes
+ * @throws FOPException if attributes cannot be cloned
+ */
+ public RtfAttributes getTextContainerAttributes() throws FOPException {
if (attrib == null) {
return null;
}
- return (RtfAttributes)this.attrib.clone();
+ try {
+ return (RtfAttributes)this.attrib.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new FOPException(e);
+ }
}
/** direct access to our text */
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java
index 9a407fe30..afa4416ed 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java
@@ -144,30 +144,6 @@ public class RtfTextrun extends RtfContainer {
}
}
- /** Class which represents a paragraph break.*/
- private class RtfParagraphBreak extends RtfElement {
-
- RtfParagraphBreak(RtfContainer parent, Writer w)
- throws IOException {
- super(parent, w);
- }
-
- /**
- * @return true if this element would generate no "useful" RTF content
- */
- public boolean isEmpty() {
- return false;
- }
-
- /**
- * write RTF code of all our children
- * @throws IOException for I/O problems
- */
- protected void writeRtfContent() throws IOException {
- writeControlWord("par");
- }
- }
-
/** Create an RTF container as a child of given container */
RtfTextrun(RtfContainer parent, Writer w, RtfAttributes attrs) throws IOException {
super(parent, w, attrs);
@@ -291,32 +267,35 @@ public class RtfTextrun extends RtfContainer {
* Inserts paragraph break before all close group marks.
*
* @throws IOException for I/O problems
+ * @return The paragraph break element
*/
- public void addParagraphBreak() throws IOException {
- // get copy of children list
- List children = getChildren();
- Stack tmp = new Stack();
-
- // delete all previous CloseGroupMark
- int deletedCloseGroupCount = 0;
-
- ListIterator lit = children.listIterator(children.size());
- while (lit.hasPrevious()
- && (lit.previous() instanceof RtfCloseGroupMark)) {
- tmp.push(Integer.valueOf(((RtfCloseGroupMark)lit.next()).getBreakType()));
- lit.remove();
- deletedCloseGroupCount++;
- }
-
- if (children.size() != 0) {
- // add paragraph break and restore all deleted close group marks
- setChildren(children);
- new RtfParagraphBreak(this, writer);
- for (int i = 0; i < deletedCloseGroupCount; i++) {
- addCloseGroupMark(((Integer)tmp.pop()).intValue());
- }
- }
- }
+ public RtfParagraphBreak addParagraphBreak() throws IOException {
+ // get copy of children list
+ List children = getChildren();
+ Stack tmp = new Stack();
+ RtfParagraphBreak par = null;
+
+ // delete all previous CloseGroupMark
+ int deletedCloseGroupCount = 0;
+
+ ListIterator lit = children.listIterator(children.size());
+ while (lit.hasPrevious()
+ && (lit.previous() instanceof RtfCloseGroupMark)) {
+ tmp.push(Integer.valueOf(((RtfCloseGroupMark)lit.next()).getBreakType()));
+ lit.remove();
+ deletedCloseGroupCount++;
+ }
+
+ if (children.size() != 0) {
+ // add paragraph break and restore all deleted close group marks
+ setChildren(children);
+ par = new RtfParagraphBreak(this, writer);
+ for (int i = 0; i < deletedCloseGroupCount; i++) {
+ addCloseGroupMark(((Integer)tmp.pop()).intValue());
+ }
+ }
+ return par;
+ }
/**
* Inserts a leader.
@@ -486,6 +465,8 @@ public class RtfTextrun extends RtfContainer {
* child.
* -If the RtfTextrun is the last child of its parent, write a
* RtfParagraphBreak only, if it is not the last child.
+ * -If the RtfParagraphBreak can not be hidden (e.g. a table cell requires it)
+ * it is also written
*/
boolean bHide = false;
bHide = bRtfParagraphBreak;
@@ -494,7 +475,8 @@ public class RtfTextrun extends RtfContainer {
|| bFirst
|| (bSuppressLastPar && bLast && lastParagraphBreak != null
&& e == lastParagraphBreak)
- || bBookmark);
+ || bBookmark)
+ && ((RtfParagraphBreak)e).canHide();
if (!bHide) {
newLine();
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/tools/PercentContext.java b/src/java/org/apache/fop/render/rtf/rtflib/tools/PercentContext.java
index 7e2633409..643757b71 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/tools/PercentContext.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/tools/PercentContext.java
@@ -29,6 +29,7 @@ import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableColumn;
import org.apache.fop.fo.pagination.PageSequence;
/**
@@ -59,6 +60,13 @@ public class PercentContext implements PercentBaseContext {
if (fobj == null) {
return 0;
}
+
+ // Special handler for TableColumn width specifications, needs to be
+ // relative to the parent!
+ if ( ( fobj instanceof TableColumn ) && ( fobj.getParent() instanceof FObj ) ) {
+ fobj = (FObj) fobj.getParent();
+ }
+
switch (lengthBase) {
case LengthBase.CONTAINING_BLOCK_WIDTH:
case LengthBase.PARENT_AREA_WIDTH:
@@ -66,12 +74,27 @@ public class PercentContext implements PercentBaseContext {
Object width = lengthMap.get(fobj);
if (width != null) {
return Integer.parseInt(width.toString());
- } else {
- return -1;
+ } else if (fobj.getParent() != null) {
+ // If the object itself has no width the parent width will be used
+ // because it is the base width of this object
+ width = lengthMap.get(fobj.getParent());
+ if (width != null) {
+ return Integer.parseInt(width.toString());
+ }
}
+ return 0;
case LengthBase.TABLE_UNITS:
Object unit = tableUnitMap.get(fobj);
- return (unit != null) ? ((Integer)unit).intValue() : 0;
+ if (unit != null) {
+ return ((Integer)unit).intValue();
+ } else if (fobj.getParent() != null) {
+ // If the object itself has no width the parent width will be used
+ unit = tableUnitMap.get(fobj.getParent());
+ if (unit != null) {
+ return ((Integer)unit).intValue();
+ }
+ }
+ return 0;
default:
log.error(new Exception("Unsupported base type for LengthBase:" + lengthBase));
return 0;
diff --git a/src/java/org/apache/fop/render/txt/TXTRenderer.java b/src/java/org/apache/fop/render/txt/TXTRenderer.java
index 6c58561a8..dd3d883f6 100644
--- a/src/java/org/apache/fop/render/txt/TXTRenderer.java
+++ b/src/java/org/apache/fop/render/txt/TXTRenderer.java
@@ -72,6 +72,9 @@ public class TXTRenderer extends AbstractPathOrientedRenderer {
/** Buffer for background and images. */
private StringBuffer[] decoData;
+ /** Leading of line containing Courier font size of 10pt. */
+ public static final int LINE_LEADING = 1070;
+
/** Height of one symbol in Courier font size of 10pt. */
public static final int CHAR_HEIGHT = 7860;
@@ -192,7 +195,7 @@ public class TXTRenderer extends AbstractPathOrientedRenderer {
*/
protected void renderText(TextArea area) {
int col = Helper.ceilPosition(this.currentIPPosition, CHAR_WIDTH);
- int row = Helper.ceilPosition(this.currentBPPosition, CHAR_HEIGHT);
+ int row = Helper.ceilPosition(this.currentBPPosition - LINE_LEADING, CHAR_HEIGHT + 2*LINE_LEADING);
String s = area.getText();
@@ -216,7 +219,7 @@ public class TXTRenderer extends AbstractPathOrientedRenderer {
double height = bounds.getHeight();
pageWidth = Helper.ceilPosition((int) width, CHAR_WIDTH);
- pageHeight = Helper.ceilPosition((int) height, CHAR_HEIGHT);
+ pageHeight = Helper.ceilPosition((int) height, CHAR_HEIGHT + 2*LINE_LEADING);
// init buffers
charData = new StringBuffer[pageHeight];
@@ -460,9 +463,9 @@ public class TXTRenderer extends AbstractPathOrientedRenderer {
*/
public void renderImage(Image image, Rectangle2D pos) {
int x1 = Helper.ceilPosition(currentIPPosition, CHAR_WIDTH);
- int y1 = Helper.ceilPosition(currentBPPosition, CHAR_HEIGHT);
+ int y1 = Helper.ceilPosition(currentBPPosition - LINE_LEADING, CHAR_HEIGHT + 2*LINE_LEADING);
int width = Helper.ceilPosition((int) pos.getWidth(), CHAR_WIDTH);
- int height = Helper.ceilPosition((int) pos.getHeight(), CHAR_HEIGHT);
+ int height = Helper.ceilPosition((int) pos.getHeight(), CHAR_HEIGHT + 2*LINE_LEADING);
fillRect(x1, y1, width, height, IMAGE_CHAR);
}
@@ -559,9 +562,9 @@ public class TXTRenderer extends AbstractPathOrientedRenderer {
protected void drawBackAndBorders(Area area, float startx, float starty,
float width, float height) {
bm.setWidth(Helper.ceilPosition(toMilli(width), CHAR_WIDTH));
- bm.setHeight(Helper.ceilPosition(toMilli(height), CHAR_HEIGHT));
+ bm.setHeight(Helper.ceilPosition(toMilli(height), CHAR_HEIGHT + 2*LINE_LEADING));
bm.setStartX(Helper.ceilPosition(toMilli(startx), CHAR_WIDTH));
- bm.setStartY(Helper.ceilPosition(toMilli(starty), CHAR_HEIGHT));
+ bm.setStartY(Helper.ceilPosition(toMilli(starty), CHAR_HEIGHT + 2*LINE_LEADING));
super.drawBackAndBorders(area, startx, starty, width, height);
}
diff --git a/src/java/org/apache/fop/tools/anttasks/FileCompare.java b/src/java/org/apache/fop/tools/anttasks/FileCompare.java
index 462049907..4906bdc6c 100644
--- a/src/java/org/apache/fop/tools/anttasks/FileCompare.java
+++ b/src/java/org/apache/fop/tools/anttasks/FileCompare.java
@@ -126,7 +126,7 @@ public class FileCompare {
*/
private static boolean compareFileSize(File oldFile, File newFile) {
return oldFile.length() == newFile.length();
- } // end: compareBytes
+ }
private boolean filesExist(File oldFile, File newFile) {
if (!oldFile.exists()) {
diff --git a/src/java/org/apache/fop/util/XMLResourceBundle.java b/src/java/org/apache/fop/util/XMLResourceBundle.java
index a7444147c..7c391f16a 100644
--- a/src/java/org/apache/fop/util/XMLResourceBundle.java
+++ b/src/java/org/apache/fop/util/XMLResourceBundle.java
@@ -117,7 +117,7 @@ public class XMLResourceBundle extends ResourceBundle {
if (baseName == null) {
throw new NullPointerException("baseName must not be null");
}
-
+ assert locale != null;
ResourceBundle bundle;
if (!locale.equals(Locale.getDefault())) {
bundle = handleGetXMLBundle(baseName, "_" + locale, false, loader);