diff options
author | Vincent Hennebert <vhennebert@apache.org> | 2012-04-13 16:49:35 +0000 |
---|---|---|
committer | Vincent Hennebert <vhennebert@apache.org> | 2012-04-13 16:49:35 +0000 |
commit | a438a377ef974181a4b0a71f9d399e31f654588b (patch) | |
tree | 0eb9720c40f65c19437f731db0b34483e9f9b545 /src | |
parent | 55c1f8be3cf6da96f690f34743d47ecee95243bb (diff) | |
parent | 50b34f584998b9083b07ec018d84dd38b96e732c (diff) | |
download | xmlgraphics-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')
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">§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> </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">§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> </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><version>/fotree/disabled-testcases.xml</code> and - <code><version>/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><version>/fotree/disabled-testcases.xml</code> and <code><version>/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 > - 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 > 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> +<fop version="1.0"> + <complex-scripts disabled="true"/> + ... +</fop> + </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&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&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&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); |