]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Merged revisions 636407-637074,637076-637118,637120-637790,637792-637856,637858-63799...
authorJeremias Maerki <jeremias@apache.org>
Thu, 31 Jul 2008 09:06:10 +0000 (09:06 +0000)
committerJeremias Maerki <jeremias@apache.org>
Thu, 31 Jul 2008 09:06:10 +0000 (09:06 +0000)
https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/fop-0_95

........
  r666635 | jeremias | 2008-06-11 14:18:53 +0200 (Mi, 11 Jun 2008) | 1 line

  Fixed resolution handling inside AWT preview dialog.
........
  r666662 | jeremias | 2008-06-11 15:33:20 +0200 (Mi, 11 Jun 2008) | 1 line

  Some notes on RTF and print output.
........
  r668533 | jeremias | 2008-06-17 09:57:55 +0200 (Di, 17 Jun 2008) | 2 lines

  Bugzilla #45151:
  Note on the "compiling" page that Ant 1.7 is required. The README file already points to this page.
........
  r668534 | jeremias | 2008-06-17 09:58:40 +0200 (Di, 17 Jun 2008) | 2 lines

  Update known issues.
  Remove ApacheConEU logo.
........
  r668550 | jeremias | 2008-06-17 10:05:22 +0200 (Di, 17 Jun 2008) | 2 lines

  Bugzilla #45146:
  Removed duplicate LICENSE.txt and Notice.txt from the JAR.
........
  r668570 | jeremias | 2008-06-17 10:54:07 +0200 (Di, 17 Jun 2008) | 1 line

  Wrong line number reported in the case of a line overflow.
........
  r668641 | jeremias | 2008-06-17 14:59:25 +0200 (Di, 17 Jun 2008) | 1 line

  Fixed potential NPE.
........
  r669118 | jeremias | 2008-06-18 11:02:45 +0200 (Mi, 18 Jun 2008) | 4 lines

  Bugzilla #44412:
  Regression fix for empty pages caused by multiple collapsible breaks.
  No more empty block areas if a break-before occurs on the first child of an FO to match the behaviour of tables and other FO implementations (clarification by XSL WG pending).
  Added an accessor interface for break-before/-after to avoid long if..else lists in BlockStackingLayoutManager.
........
  r669173 | jeremias | 2008-06-18 16:07:27 +0200 (Mi, 18 Jun 2008) | 7 lines

  Bugzilla #44887:
  Fixed potential multi-threading problem concerning the use of DecimalFormat.

  Results from performance measurements in a separate test (operation repeated 100'000 times, exemplary):
  shared static variable: ~220ms (old choice, problematic!)
  always create new instance: ~480ms
  ThreadLocal: ~220ms (new choice)
........
  r669478 | jeremias | 2008-06-19 15:03:57 +0200 (Do, 19 Jun 2008) | 4 lines

  Bugzilla #44412:
  Improvements after Vincent's feedback:
  Removal of the somewhat ugly Reference.
  getBreakBefore() reduced to private visibility.
........
  r670551 | jeremias | 2008-06-23 14:54:27 +0200 (Mo, 23 Jun 2008) | 3 lines

  Use configured source and target resolution for foreign objects in RTF output.
  Fixed intrinsic size calculation for SVG images when source resolution is not 72 dpi.
  Fixed calculation of px2mm values in the SVG to G2D converter (used by RTF output).
........
  r673750 | adelmelle | 2008-07-03 20:25:01 +0200 (Do, 03 Jul 2008) | 1 line

  Fix for Bugzilla 45295 (already committed to the trunk with r672010, r672495 and r672496)
........
  r674304 | jeremias | 2008-07-06 17:09:10 +0200 (So, 06 Jul 2008) | 18 lines

  Bugzilla #43606:
  column-width accepts percent values (proportional-column-width and % working)
  Table width accepts percent values (100% of the page width as standard)
  Nested tables are working
  It is also possible to make nested tables with a higher depth than 3 without causing word to crash
  Submitted by: Maximilan Aster <maximilian.aster.at.boc-eu.com>

  Changes to the patch by Jeremias:
  - Patch simplified (reuse of ColumnSetup from the layoutmgr package)
  - Percentages and proportional-column-width didn't work properly in my tests -> fixed
  - Adjustments for FOP code conventions

  Bugzilla #43824:
  page-number-citation working but has to be refreshed inside word to show the correct values
  Submitted by: Maximilan Aster <maximilian.aster.at.boc-eu.com>

  Changes to the patch by Jeremias:
  - Adjustments for FOP code conventions
........
  r674314 | jeremias | 2008-07-06 18:40:08 +0200 (So, 06 Jul 2008) | 7 lines

  Bugzilla #43825:
  leader supports fixed percent values for leader-length, most other properties
  use-content, leader-pattern-width not implemented
  Submitted by: Maximilan Aster <maximilian.aster.at.boc-eu.com>

  Changes to the patch by Jeremias:
  - Adjustments for FOP code conventions
........
  r674317 | jeremias | 2008-07-06 18:44:43 +0200 (So, 06 Jul 2008) | 1 line

  Doc update after RTF changes.
........
  r675106 | jeremias | 2008-07-09 09:03:46 +0200 (Mi, 09 Jul 2008) | 2 lines

  Bugzilla #45366:
  Document missing feature.
........
  r675150 | jeremias | 2008-07-09 14:56:41 +0200 (Mi, 09 Jul 2008) | 2 lines

  Bugzilla #39980:
  Fixed image scaling for RTF output.
........
  r675151 | jeremias | 2008-07-09 14:57:06 +0200 (Mi, 09 Jul 2008) | 1 line

  Removed unused code.
........
  r675152 | jeremias | 2008-07-09 14:58:18 +0200 (Mi, 09 Jul 2008) | 1 line

  Don't generate commands for default values.
........
  r675707 | jeremias | 2008-07-10 21:58:27 +0200 (Do, 10 Jul 2008) | 1 line

  Bugfix: -imagein didn't work because the stylesheet didn't get copied into fop.jar.
........
  r680715 | jeremias | 2008-07-29 16:37:10 +0200 (Di, 29 Jul 2008) | 1 line

  Found a surplus "pop state" which somehow causes a regression (fill color doesn't get properly reset) between 0.94 and 0.95. Shows in Barcode4J's fop-extension-demo.fo. The line has already been there in 0.94 but only shows in 0.95 probably due to an additional save/restore state pair added in PDFRenderer for reference areas after the block-container area refactoring.
........
  r680820 | jeremias | 2008-07-29 22:02:14 +0200 (Di, 29 Jul 2008) | 2 lines

  Bugzilla #41306:
  The AWT Renderer is really not out-of-order capable.
........
  r681284 | jeremias | 2008-07-31 08:47:49 +0200 (Do, 31 Jul 2008) | 1 line

  Some updates to status.xml (I was not the only one working on the final release).
........
  r681290 | jeremias | 2008-07-31 09:44:51 +0200 (Do, 31 Jul 2008) | 2 lines

  Website updates for the 0.95 release.
  The projectInfo plug-in of Forrest is not ideal for doing a bugfix release. It's not possible to combine the changes for two releases.
........
  r681292 | jeremias | 2008-07-31 09:47:13 +0200 (Do, 31 Jul 2008) | 1 line

  Disabling the ApacheCon ad for the release build.
........

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@681307 13f79535-47bb-0310-9956-ffa450edef68

53 files changed:
README
build.xml
known-issues.xml
lib/avalon-framework-4.2.0.jar
src/documentation/content/xdocs/0.95/compiling.xml
src/documentation/content/xdocs/0.95/output.xml
src/documentation/content/xdocs/knownissues.xml
src/documentation/content/xdocs/site.xml
src/documentation/content/xdocs/tabs.xml
src/documentation/content/xdocs/trunk/compiling.xml
src/documentation/content/xdocs/trunk/output.xml
src/documentation/skinconf.xml
src/java/org/apache/fop/fo/flow/Block.java
src/java/org/apache/fop/fo/flow/BlockContainer.java
src/java/org/apache/fop/fo/flow/ListBlock.java
src/java/org/apache/fop/fo/flow/ListItem.java
src/java/org/apache/fop/fo/flow/table/Table.java
src/java/org/apache/fop/fo/flow/table/TableAndCaption.java
src/java/org/apache/fop/fo/flow/table/TableRow.java
src/java/org/apache/fop/fo/properties/BreakPropertySet.java [new file with mode: 0644]
src/java/org/apache/fop/fonts/MultiByteFont.java
src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java
src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java
src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
src/java/org/apache/fop/layoutmgr/LayoutContext.java
src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
src/java/org/apache/fop/pdf/PDFNumber.java
src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java
src/java/org/apache/fop/render/awt/viewer/PreviewPanel.java
src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java
src/java/org/apache/fop/render/rtf/BorderAttributesConverter.java
src/java/org/apache/fop/render/rtf/FoUnitsConverter.java
src/java/org/apache/fop/render/rtf/PageAttributesConverter.java
src/java/org/apache/fop/render/rtf/RTFHandler.java
src/java/org/apache/fop/render/rtf/TextAttributesConverter.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfAttributes.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfLeader.java [new file with mode: 0644]
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfPage.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfPageNumberCitation.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTable.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableRow.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java
src/java/org/apache/fop/render/rtf/rtflib/tools/PercentContext.java [new file with mode: 0644]
src/java/org/apache/fop/util/BreakUtil.java
status.xml
test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java
test/layoutengine/standard-testcases/block_break-before_bug44412.xml
test/layoutengine/standard-testcases/block_break-before_bug44412_2.xml [new file with mode: 0644]
test/resources/images/circles.svg [new file with mode: 0644]

diff --git a/README b/README
index 133232276b97017aa251c676321fce56df29ed7c..37ede8930a277e3cdb93afe9b40af9a31bdc058b 100644 (file)
--- a/README
+++ b/README
@@ -90,11 +90,11 @@ http://xmlgraphics.apache.org/fop/stable/running.html
   RELEASE NOTES
 ==============================================================================
 
-Version 0.95beta
-================
+Version 0.95
+============
 
-This is a pre-version of the third production grade release of the new FOP
-codebase. It contains many bug fixes and new features. See below for details.
+This is a production grade release of Apache FOP.
+It contains many bug fixes and new features. See below for details.
 
 Compliance
 ----------
@@ -128,6 +128,10 @@ http://xmlgraphics.apache.org/fop/0.95/changes_0.95.html.
 The long list of changes in this and earlier releases is available at
 http://xmlgraphics.apache.org/fop/changes.html.
 
+Changes since Version 0.95beta
+------------------------------
+Please refer to the list of changes on the web:
+http://xmlgraphics.apache.org/fop/changes.html
 
 
 Version 0.94
index ff76686b6edf294aa3c3171622ada29ae7ece5ec..60225fc2977cca4424a58d96359ab9a59025e1a7 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -401,6 +401,7 @@ list of possible build targets.
         <include name="**/*.icm"/>
         <include name="**/*.xml"/>
         <include name="**/*.LICENSE.txt"/>
+        <include name="**/*.xsl"/>
       </fileset>
       <fileset dir="${build.gensrc.dir}">
         <include name="**/*.xml"/>
index 27ae55494e28d3624d3eb2cc99d672862d80b621..2ef4b7102ef2d5f0ae22c81150618c6e12d6e5d2 100644 (file)
@@ -21,8 +21,9 @@
         MIF and SVG output support have not been restored, yet.
       </known-issue>
       <known-issue>
-        Java2D/AWT support has been improved, but some problems remain,
-        for example with block-containers.
+        RTF output is inferior to other output formats supported by FOP.
+        For details, please see the "Output Targets" page of the release
+        you're using.
       </known-issue>
       <known-issue>
         Auto table layout is not implemented, yet.
         Not all FO elements can be referenced by their "id", most notably:
         table-body, table-header, table-footer and table-row.
       </known-issue>
-      <known-issue>
-        The backgrounds of table-body, table-header, table-footer and 
-        table-column are not painted, yet.
-      </known-issue>
       <known-issue>
         Border and padding conditionality are not supported on table-cells, yet.
       </known-issue>
index b1aa6d7c9c2174137b9dcb166a99a69523cc8417..22a7ab341694297f3fe2acf4379662af954e7bad 100644 (file)
Binary files a/lib/avalon-framework-4.2.0.jar and b/lib/avalon-framework-4.2.0.jar differ
index 57761429f6e42ce5642968013acf3f88accc1054..98a6dfb6d6ec6bbeedfefc1d51e032d72439d507 100644 (file)
@@ -66,7 +66,7 @@
       <section id="env-ant">
         <title>Apache Ant</title>
         <p>
-          <a href="ext:ant">Apache Ant</a> must be installed in order to
+          <a href="ext:ant">Apache Ant</a> (Version 1.7 or later) must be installed in order to
           build FOP. Following best practices we don't include Ant with FOP anymore. You can find the
           <a href="ext:ant/manual/">instructions to install Ant in the Ant manual</a> on the web.
         </p>
index 628df12480b556dcd406303b7b146c40975ce43d..fbf277b9022ec65e1305d9ebbcf1ab251be7133b 100644 (file)
@@ -703,6 +703,24 @@ out = proc.getOutputStream();]]></source>
   <note>RTF output is currently unmaintained and lacks many features compared to other output
     formats. Using other editable formats like Open Document Format, instead of producing XSL-FO
     then RTF through FOP, might give better results.</note>
+  <p>
+    These are some known restrictions compared to other supported output formats (not a complete list):
+  </p>
+  <ul>
+    <li>
+      Not supported/implemented:
+      <ul>
+        <li>break-before/after (supported by the RTF library but not tied into the RTFHandler)</li>
+        <li>fo:page-number-citation-last</li>
+        <li>keeps (supported by the RTF library but not tied into the RTFHandler)</li>
+        <li>region-start/end (RTF limitation)</li>
+        <li>multiple columns</li>
+      </ul>
+    </li>
+    <li>Only a single page-master is supported</li>
+    <li>Not all variations of fo:leader are supported (RTF limitation)</li>
+    <li>percentages are not supported everywhere</li>
+  </ul>
 </section>
 <section id="xml">
   <title>XML (Area Tree XML)</title>
@@ -735,6 +753,16 @@ out = proc.getOutputStream();]]></source>
     It is possible to directly print the document from the command line.
     This is done with the same code that renders to the Java2D/AWT renderer.
   </p>
+  <section id="print-issues">
+    <title>Known issues</title>
+    <p>
+      If you run into the problem that the printed output is incomplete on Windows:
+      this often happens to users printing to a PCL printer.
+      There seems to be an incompatibility between Java and certain PCL printer drivers
+      on Windows. Since most network-enabled laser printers support PostScript, try
+      switching to the PostScript printer driver for that printer model.
+    </p>
+  </section>
 </section>
 <section id="bitmap">
   <title>Bitmap (TIFF/PNG)</title>
index caf96ceaa80b77b9cc2ebd0eafac3b1bb226774b..ea39b297468246f62249153502ac14b10f2e907d 100644 (file)
@@ -66,6 +66,7 @@
   <section>
     <title>Other known issues</title>
     <p>This section lists other known issues.</p>
+    <!-- See <root>/known-issues.xml for the source document of this section! -->
     <xi:include href="cocoon://knownissues-raw-static.xml#xpointer(/document/body/*)"/>
   </section>
 </section>
index b0a3214e7892b1ce9f3e9b05096132ccad18b37c..5ebdef32262ca660ae8246354997070cae1288f3 100644 (file)
   <!--
   BEGIN Version 0.95 documentation tab
   -->
-  <trunk label="FOP 0.95beta" href="0.95/" tab="stableversion">
+  <trunk label="FOP 0.95" href="0.95/" tab="stableversion">
     <about label="About" href="index.html"/>
-    <release label="Release Notes" href="releaseNotes_0.95beta.html"/>
-    <changes label="Changes" href="changes_0.95beta.html"/>
+    <release label="Release Notes" href="releaseNotes_0.95.html"/>
+    <changes label="Changes (0.95)" href="changes_0.95.html"/>
+    <changes-beta label="Changes (0.95beta)" href="changes_0.95beta.html"/>
     <knownissues label="Known Issues" href="knownissues_overview.html"/>
     <upgrading label="Upgrading" href="upgrading.html"/>
     
index a42fc9bd715cfd755ca8f7cc3d9b1216f542e945..3db01d4fa4500d979af23f63cf23715fc0b19ee4 100644 (file)
@@ -22,7 +22,7 @@
 <tabs software="FOP" title="FOP" copyright="@year@ The Apache Software Foundation" xmlns:xlink="http://www.w3.org/1999/xlink">
   <tab label="Home" dir=""/>
   <tab label="Version 0.94" dir="0.94/"/>
-  <tab label="Version 0.95beta" dir="0.95/"/>
+  <tab label="Version 0.95" dir="0.95/"/>
   <tab label="FOP Trunk" dir="trunk/"/>
   <tab label="Development" dir="dev/"/>
 </tabs>
index 57761429f6e42ce5642968013acf3f88accc1054..98a6dfb6d6ec6bbeedfefc1d51e032d72439d507 100644 (file)
@@ -66,7 +66,7 @@
       <section id="env-ant">
         <title>Apache Ant</title>
         <p>
-          <a href="ext:ant">Apache Ant</a> must be installed in order to
+          <a href="ext:ant">Apache Ant</a> (Version 1.7 or later) must be installed in order to
           build FOP. Following best practices we don't include Ant with FOP anymore. You can find the
           <a href="ext:ant/manual/">instructions to install Ant in the Ant manual</a> on the web.
         </p>
index 22d916d312c5fd6be11faf5e4721e52641d30453..b9916e1983ccaedb229bd5a283370ed5e47ce346 100644 (file)
@@ -728,6 +728,24 @@ out = proc.getOutputStream();]]></source>
   <note>RTF output is currently unmaintained and lacks many features compared to other output
     formats. Using other editable formats like Open Document Format, instead of producing XSL-FO
     then RTF through FOP, might give better results.</note>
+  <p>
+    These are some known restrictions compared to other supported output formats (not a complete list):
+  </p>
+  <ul>
+    <li>
+      Not supported/implemented:
+      <ul>
+        <li>break-before/after (supported by the RTF library but not tied into the RTFHandler)</li>
+        <li>fo:page-number-citation-last</li>
+        <li>keeps (supported by the RTF library but not tied into the RTFHandler)</li>
+        <li>region-start/end (RTF limitation)</li>
+        <li>multiple columns</li>
+      </ul>
+    </li>
+    <li>Only a single page-master is supported</li>
+    <li>Not all variations of fo:leader are supported (RTF limitation)</li>
+    <li>percentages are not supported everywhere</li>
+  </ul>
 </section>
 <section id="xml">
   <title>XML (Area Tree XML)</title>
@@ -760,6 +778,16 @@ out = proc.getOutputStream();]]></source>
     It is possible to directly print the document from the command line.
     This is done with the same code that renders to the Java2D/AWT renderer.
   </p>
+  <section id="print-issues">
+    <title>Known issues</title>
+    <p>
+      If you run into the problem that the printed output is incomplete on Windows:
+      this often happens to users printing to a PCL printer.
+      There seems to be an incompatibility between Java and certain PCL printer drivers
+      on Windows. Since most network-enabled laser printers support PostScript, try
+      switching to the PostScript printer driver for that printer model.
+    </p>
+  </section>
 </section>
 <section id="bitmap">
   <title>Bitmap (TIFF/PNG)</title>
@@ -911,3 +939,4 @@ out = proc.getOutputStream();]]></source>
 </document>
 
 
+
index 20b12808edbd35d75bf3fefae8bd46b65c4c67d1..b9a12fa59f8a01d98f45e7a3b16643cbd4b4427a 100644 (file)
@@ -378,6 +378,7 @@ which will be used to configure the chosen Forrest skin.
       <height>125</height>
     </credit>
     -->
+    <!--
     <credit box-location="alt2">
       <name>ApacheCon US 2008</name>
       <url>http://us.apachecon.com/</url>
@@ -385,6 +386,7 @@ which will be used to configure the chosen Forrest skin.
       <width>125</width>
       <height>125</height>
     </credit>
+    -->
     
     <credit role="pdf">
       <name>PDF created by Apache FOP</name>
index d1df9c21dbf77e476d13711e2bcda1e0b13b115c..4645734b2445cab99009ad43d803fd594285ed69 100644 (file)
@@ -32,6 +32,7 @@ import org.apache.fop.fo.FObjMixed;
 import org.apache.fop.fo.NullCharIterator;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.properties.BreakPropertySet;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.CommonFont;
 import org.apache.fop.fo.properties.CommonHyphenation;
@@ -44,7 +45,7 @@ import org.apache.fop.fo.properties.SpaceProperty;
   * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_block">
   * <code>fo:block object</code></a>.
   */
-public class Block extends FObjMixed {
+public class Block extends FObjMixed implements BreakPropertySet {
 
     // used for FO validation
     private boolean blockOrInlineItemFound = false;
index 25b3f2a2a26424b5efbcc08860021ff420309039..b0bfb3a32818be37b36083a7514908b3924a7219 100644 (file)
@@ -28,6 +28,7 @@ import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.properties.BreakPropertySet;
 import org.apache.fop.fo.properties.CommonAbsolutePosition;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.CommonMarginBlock;
@@ -38,7 +39,7 @@ import org.apache.fop.fo.properties.LengthRangeProperty;
  * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_block-container">
  * <code>fo:block-container</code></a> object.
  */
-public class BlockContainer extends FObj {
+public class BlockContainer extends FObj implements BreakPropertySet {
     // The value of properties relevant for fo:block-container.
     private CommonAbsolutePosition commonAbsolutePosition;
     private CommonBorderPaddingBackground commonBorderPaddingBackground;
index dfadc9c02642c676d0466751e1fa3efcdc00ab97..8f72ded6716df2dcd3a967014ea1437a243fd592 100644 (file)
@@ -27,6 +27,7 @@ import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.properties.BreakPropertySet;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.CommonMarginBlock;
 import org.apache.fop.fo.properties.KeepProperty;
@@ -35,7 +36,7 @@ import org.apache.fop.fo.properties.KeepProperty;
  * Class modelling the <a href=http://www.w3.org/TR/xsl/#fo_list-block">
  * <code>fo:list-block</code></a> object.
  */
-public class ListBlock extends FObj {
+public class ListBlock extends FObj implements BreakPropertySet {
     // The value of properties relevant for fo:list-block.
     private CommonBorderPaddingBackground commonBorderPaddingBackground;
     private CommonMarginBlock commonMarginBlock;
index 95760c00bcfc95d434bcf9d3c19c344e4125b857..f748bc15a147bdc2b27c7f2a78eeebb085c8296d 100644 (file)
@@ -26,6 +26,7 @@ import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.properties.BreakPropertySet;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.CommonMarginBlock;
 import org.apache.fop.fo.properties.KeepProperty;
@@ -34,7 +35,7 @@ import org.apache.fop.fo.properties.KeepProperty;
  * Class modelling the <a href=http://www.w3.org/TR/xsl/#fo_list-item">
  * <code>fo:list-item</code></a> object.
  */
-public class ListItem extends FObj {
+public class ListItem extends FObj implements BreakPropertySet {
     // The value of properties relevant for fo:list-item.
     private CommonBorderPaddingBackground commonBorderPaddingBackground;
     private CommonMarginBlock commonMarginBlock;
index efd1f1c93caa12e8964ec12eb8364387213a2eec..86196cb29ef22788ea4fc19db1c6ebfbc0c7d8e3 100644 (file)
@@ -31,6 +31,7 @@ import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.StaticPropertyList;
 import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.properties.BreakPropertySet;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.CommonMarginBlock;
 import org.apache.fop.fo.properties.KeepProperty;
@@ -42,7 +43,7 @@ import org.apache.fop.fo.properties.TableColLength;
  * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_table">
  * <code>fo:table</code></a> object.
  */
-public class Table extends TableFObj implements ColumnNumberManagerHolder {
+public class Table extends TableFObj implements ColumnNumberManagerHolder, BreakPropertySet {
 
     /** properties */
     private CommonBorderPaddingBackground commonBorderPaddingBackground;
index 548a9c4fab16b8e88b5ed14766c3fe4a30fcd9cd..919e73bfb30ff9b38bdfc3f3ca8badbe10b01cc3 100644 (file)
@@ -32,7 +32,7 @@ import org.apache.fop.fo.ValidationException;
  * <code>fo:table-and-caption</code></a> property.
  * @todo needs implementation
  */
-public class TableAndCaption extends FObj {
+public class TableAndCaption extends FObj /*implements BreakPropertySet*/ {
     // The value of properties relevant for fo:table-and-caption.
     // Unused but valid items, commented out for performance:
     //     private CommonAccessibility commonAccessibility;
index 4d11f87809aea34881d065477467a3ccce9deeda..a40b550bc6ec09476bf6df483be25ea90f0209c8 100644 (file)
@@ -27,6 +27,7 @@ import org.apache.fop.datatypes.Length;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.properties.BreakPropertySet;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.KeepProperty;
 import org.apache.fop.fo.properties.LengthRangeProperty;
@@ -35,7 +36,7 @@ import org.apache.fop.fo.properties.LengthRangeProperty;
  * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_table-row">
  * <code>fo:table-row</code></a> object.
  */
-public class TableRow extends TableCellContainer {
+public class TableRow extends TableCellContainer implements BreakPropertySet {
     // The value of properties relevant for fo:table-row.
     private LengthRangeProperty blockProgressionDimension;
     private CommonBorderPaddingBackground commonBorderPaddingBackground;
diff --git a/src/java/org/apache/fop/fo/properties/BreakPropertySet.java b/src/java/org/apache/fop/fo/properties/BreakPropertySet.java
new file mode 100644 (file)
index 0000000..2babe0f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.fo.properties;
+
+/**
+ * Defines property access methods for the break-before and break-after properties.
+ */
+public interface BreakPropertySet {
+
+    /** @return the "break-after" property. */
+    int getBreakAfter();
+
+    /** @return the "break-before" property. */
+    int getBreakBefore();
+    
+}
index 4843b308a6c6c45f703a40b7c5a34b5200a98e41..f25ca4e7e81348e43c3e45a852755934440ec208 100644 (file)
@@ -29,7 +29,6 @@ import java.util.Map;
 public class MultiByteFont extends CIDFont {
 
     private static int uniqueCounter = -1;
-    private static final DecimalFormat COUNTER_FORMAT = new DecimalFormat("00000");
 
     private String ttcName = null;
     private String encoding = "Identity-H";
@@ -58,7 +57,8 @@ public class MultiByteFont extends CIDFont {
                 uniqueCounter = 0; //We need maximum 5 character then we start again
             }
         }
-        String cntString = COUNTER_FORMAT.format(uniqueCounter);
+        DecimalFormat counterFormat = new DecimalFormat("00000");
+        String cntString = counterFormat.format(uniqueCounter);
 
         //Subset prefix as described in chapter 5.5.3 of PDF 1.4
         StringBuffer sb = new StringBuffer("E");
index 8ad9fea440e573fff1de0ee6b0f33b6d9ca3a07f..6c43e4878bab9ae6259154fdec327f638817d89e 100644 (file)
@@ -68,10 +68,10 @@ public class ImageConverterSVG2G2D extends AbstractImageConverter {
         }
 
         //Prepare
-        float pxToMillimeter = (float)UnitConv.mm2in(72); //default: 72dpi
+        float pxToMillimeter = UnitConv.IN2MM / 72; //default: 72dpi
         Number ptm = (Number)hints.get(ImageProcessingHints.SOURCE_RESOLUTION);
         if (ptm != null) {
-            pxToMillimeter = (float)UnitConv.mm2in(ptm.doubleValue());
+            pxToMillimeter = (float)(UnitConv.IN2MM / ptm.doubleValue());
         }
         UserAgent ua = createBatikUserAgent(pxToMillimeter);
         GVTBuilder builder = new GVTBuilder();
index ce6cde9d98973e30777cfa8d3b419dfef10072e0..916b80d02af71f5c36be5d50db69c17d09a38c10 100644 (file)
@@ -46,6 +46,7 @@ import org.apache.xmlgraphics.image.loader.impl.AbstractImagePreloader;
 import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
 import org.apache.xmlgraphics.image.loader.util.ImageUtil;
 import org.apache.xmlgraphics.util.MimeConstants;
+import org.apache.xmlgraphics.util.UnitConv;
 
 import org.apache.fop.svg.SimpleSVGUserAgent;
 import org.apache.fop.util.UnclosableInputStream;
@@ -119,7 +120,7 @@ public class PreloaderSVG extends AbstractImagePreloader {
                     in.mark(length + 1);
                     SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(
                             getParserName());
-                    doc = (SVGDocument) factory.createSVGDocument(src.getSystemId(), in);
+                    doc = factory.createSVGDocument(src.getSystemId(), in);
                 }
                 ImageInfo info = createImageInfo(uri, context, doc);
 
@@ -154,7 +155,7 @@ public class PreloaderSVG extends AbstractImagePreloader {
 
         private ImageInfo createImageInfo(String uri, ImageContext context, SVGDocument doc) {
             Element e = doc.getRootElement();
-            float pxUnitToMillimeter = 25.4f / context.getSourceResolution();
+            float pxUnitToMillimeter = UnitConv.IN2MM / context.getSourceResolution();
             UserAgent userAg = new SimpleSVGUserAgent(pxUnitToMillimeter,
                         new AffineTransform()) {
 
@@ -184,9 +185,12 @@ public class PreloaderSVG extends AbstractImagePreloader {
             float height = UnitProcessor.svgVerticalLengthToUserSpace(
                     s, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE, uctx);
 
+            int widthMpt = (int)Math.round(px2mpt(width, context.getSourceResolution()));
+            int heightMpt = (int)Math.round(px2mpt(height, context.getSourceResolution()));
+
             ImageInfo info = new ImageInfo(uri, MimeConstants.MIME_SVG);
             ImageSize size = new ImageSize();
-            size.setSizeInMillipoints(Math.round(width * 1000), Math.round(height * 1000));
+            size.setSizeInMillipoints(widthMpt, heightMpt);
             //Set the resolution to that of the FOUserAgent
             size.setResolution(context.getSourceResolution());
             size.calcPixelsFromSize();
@@ -210,4 +214,8 @@ public class PreloaderSVG extends AbstractImagePreloader {
 
     }
 
+    private static double px2mpt(double px, double resolution) {
+        return px * 1000 * UnitConv.IN2PT / resolution;
+    }
+
 }
index 17eb440499538942d9c8c6c015e6774177ee6b4a..b6dd4d082c2d4f2caca9971f61136e75b2c9ff77 100644 (file)
@@ -251,12 +251,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
         List returnList = new LinkedList();
 
         if (!breakBeforeServed) {
-            try {
+            breakBeforeServed = true;
+            if (!context.suppressBreakBefore()) {
                 if (addKnuthElementsForBreakBefore(returnList, context)) {
                     return returnList;
                 }
-            } finally {
-                breakBeforeServed = true;
             }
         }
 
@@ -281,6 +280,10 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
                 childLC.setStackLimitBP(MinOptMax.subtract(context.getStackLimitBP(), stackLimit));
                 childLC.setRefIPD(relDims.ipd);
                 childLC.setWritingMode(getBlockContainerFO().getWritingMode());
+                if (curLM == this.childLMs.get(0)) {
+                    childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
+                    //Handled already by the parent (break collapsing, see above)
+                }
 
                 // get elements from curLM
                 returnedList = curLM.getNextKnuthElements(childLC, alignment);
index 1d6662cb248573b3a8d24f64ce4bd29eb5766e77..8837b1a0f595f18dafaeeeb5eceb5d9bb30236ce 100644 (file)
@@ -31,11 +31,13 @@ import org.apache.fop.area.Area;
 import org.apache.fop.area.Block;
 import org.apache.fop.area.BlockParent;
 import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.properties.BreakPropertySet;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.SpaceProperty;
 import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
 import org.apache.fop.layoutmgr.inline.LineLayoutManager;
 import org.apache.fop.traits.MinOptMax;
+import org.apache.fop.util.BreakUtil;
 import org.apache.fop.util.ListUtil;
 
 /**
@@ -255,12 +257,11 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
         List returnList = new LinkedList();
 
         if (!breakBeforeServed) {
-            try {
+            breakBeforeServed = true;
+            if (!context.suppressBreakBefore()) {
                 if (addKnuthElementsForBreakBefore(returnList, context)) {
                     return returnList;
                 }
-            } finally {
-                breakBeforeServed = true;
             }
         }
 
@@ -294,6 +295,10 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
                 childLC.setStackLimitBP(context.getStackLimitBP());
                 childLC.setRefIPD(referenceIPD);
             }
+            if (curLM == this.childLMs.get(0)) {
+                childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
+                //Handled already by the parent (break collapsing, see above)
+            }
 
             // get elements from curLM
             returnedList = curLM.getNextKnuthElements(childLC, alignment);
@@ -1004,18 +1009,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
      */
     protected boolean addKnuthElementsForBreakBefore(List returnList,
             LayoutContext context) {
-        int breakBefore = -1;
-        if (fobj instanceof org.apache.fop.fo.flow.Block) {
-            breakBefore = ((org.apache.fop.fo.flow.Block) fobj).getBreakBefore();
-        } else if (fobj instanceof org.apache.fop.fo.flow.BlockContainer) {
-            breakBefore = ((org.apache.fop.fo.flow.BlockContainer) fobj).getBreakBefore();
-        } else if (fobj instanceof org.apache.fop.fo.flow.ListBlock) {
-            breakBefore = ((org.apache.fop.fo.flow.ListBlock) fobj).getBreakBefore();
-        } else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
-            breakBefore = ((org.apache.fop.fo.flow.ListItem) fobj).getBreakBefore();
-        } else if (fobj instanceof org.apache.fop.fo.flow.table.Table) {
-            breakBefore = ((org.apache.fop.fo.flow.table.Table) fobj).getBreakBefore();
-        }
+        int breakBefore = getBreakBefore();
         if (breakBefore == EN_PAGE
                 || breakBefore == EN_COLUMN
                 || breakBefore == EN_EVEN_PAGE
@@ -1029,6 +1023,27 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
         }
     }
 
+    /**
+     * Returns the break-before value of the current formatting object.
+     * @return the break-before value (Constants.EN_*)
+     */
+    private int getBreakBefore() {
+        int breakBefore = EN_AUTO;
+        if (fobj instanceof BreakPropertySet) {
+            breakBefore = ((BreakPropertySet)fobj).getBreakBefore();
+        }
+        if (true /* uncomment to only partially merge: && breakBefore != EN_AUTO*/) {
+            LayoutManager lm = getChildLM();
+            //It is assumed this is only called when the first LM is active.
+            if (lm instanceof BlockStackingLayoutManager) {
+                BlockStackingLayoutManager bslm = (BlockStackingLayoutManager)lm;
+                breakBefore = BreakUtil.compareBreakClasses(
+                        breakBefore, bslm.getBreakBefore());
+            }
+        }
+        return breakBefore;
+    }
+    
     /**
      * Creates Knuth elements for break-after and adds them to the return list.
      * @param returnList return list to add the additional elements to
@@ -1038,16 +1053,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
     protected boolean addKnuthElementsForBreakAfter(List returnList,
             LayoutContext context) {
         int breakAfter = -1;
-        if (fobj instanceof org.apache.fop.fo.flow.Block) {
-            breakAfter = ((org.apache.fop.fo.flow.Block) fobj).getBreakAfter();
-        } else if (fobj instanceof org.apache.fop.fo.flow.BlockContainer) {
-            breakAfter = ((org.apache.fop.fo.flow.BlockContainer) fobj).getBreakAfter();
-        } else if (fobj instanceof org.apache.fop.fo.flow.ListBlock) {
-            breakAfter = ((org.apache.fop.fo.flow.ListBlock) fobj).getBreakAfter();
-        } else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
-            breakAfter = ((org.apache.fop.fo.flow.ListItem) fobj).getBreakAfter();
-        } else if (fobj instanceof org.apache.fop.fo.flow.table.Table) {
-            breakAfter = ((org.apache.fop.fo.flow.table.Table) fobj).getBreakAfter();
+        if (fobj instanceof BreakPropertySet) {
+            breakAfter = ((BreakPropertySet)fobj).getBreakAfter();
         }
         if (breakAfter == EN_PAGE
                 || breakAfter == EN_COLUMN
index 1be89304bf8d1835c2b62993a27371ed4aee5706..8b716dfde1c63e55d1af2b1c79767a798919cc4f 100644 (file)
@@ -47,12 +47,10 @@ public class LayoutContext {
     public static final int CHECK_REF_AREA = 0x08;
 
     /**
-     * If this flag is set, it indicates that any leading fo:character
-     * objects with suppress-at-line-break="suppress" should not generate
-     * areas. This is the case at the beginning of each new LineArea
-     * except the first.
+     * If this flag is set, it indicates that any break-before values other than "auto" should
+     * not cause a mandatory break as this break was already handled by a parent layout manager.
      */
-    public static final int SUPPRESS_LEADING_SPACE = 0x10;
+    public static final int SUPPRESS_BREAK_BEFORE = 0x10;
     public static final int FIRST_AREA = 0x20;
     public static final int TRY_HYPHENATE = 0x40;
     public static final int LAST_AREA = 0x80;
@@ -227,8 +225,8 @@ public class LayoutContext {
         return ((this.flags & LAST_AREA) != 0);
     }
 
-    public boolean suppressLeadingSpace() {
-        return ((this.flags & SUPPRESS_LEADING_SPACE) != 0);
+    public boolean suppressBreakBefore() {
+        return ((this.flags & SUPPRESS_BREAK_BEFORE) != 0);
     }
 
     /**
@@ -655,7 +653,7 @@ public class LayoutContext {
         + "\nSpace Adjust: \t" + getSpaceAdjust()
         + "\nIPD Adjust: \t" + getIPDAdjust()
         + "\nResolve Leading Space: \t" + resolveLeadingSpace()
-        + "\nSuppress Leading Space: \t" + suppressLeadingSpace()
+        + "\nSuppress Break Before: \t" + suppressBreakBefore()
         + "\nIs First Area: \t" + isFirstArea()
         + "\nStarts New Area: \t" + startsNewArea()
         + "\nIs Last Area: \t" + isLastArea()
index f027922f7560d9f0b8a0227e9d452d4afcf16872..d83cca64232de63fe7aff5a60ebca37e5a6a96be 100644 (file)
@@ -197,12 +197,11 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager
         List returnList = new LinkedList();
 
         if (!breakBeforeServed) {
-            try {
+            breakBeforeServed = true;
+            if (!context.suppressBreakBefore()) {
                 if (addKnuthElementsForBreakBefore(returnList, context)) {
                     return returnList;
                 }
-            } finally {
-                breakBeforeServed = true;
             }
         }
 
index c32c6eb3d22663063a98c4372b26b2bc3559a0f2..c1fc1905095dfe8a8817d9ac2a1a99a832f984cf 100644 (file)
@@ -184,10 +184,22 @@ public class ColumnSetup {
      * @return the computed base unit (in millipoint)
      */
     protected double computeTableUnit(TableLayoutManager tlm) {
+        return computeTableUnit(tlm, tlm.getContentAreaIPD());
+    }
+
+    /**
+     * Works out the base unit for resolving proportional-column-width()
+     * [p-c-w(x) = x * base_unit_ipd]
+     *
+     * @param percentBaseContext the percent base context for relative values
+     * @param contentAreaIPD the IPD of the available content area
+     * @return the computed base unit (in millipoints)
+     */
+    public float computeTableUnit(PercentBaseContext percentBaseContext, int contentAreaIPD) {
 
         int sumCols = 0;
         float factors = 0;
-        double unit = 0;
+        float unit = 0;
 
         /* calculate the total width (specified absolute/percentages),
          * and work out the total number of factors to use to distribute
@@ -196,7 +208,7 @@ public class ColumnSetup {
         for (Iterator i = colWidths.iterator(); i.hasNext();) {
             Length colWidth = (Length) i.next();
             if (colWidth != null) {
-                sumCols += colWidth.getValue(tlm);
+                sumCols += colWidth.getValue(percentBaseContext);
                 if (colWidth instanceof RelativeNumericProperty) {
                     factors += ((RelativeNumericProperty) colWidth).getTableUnits();
                 } else if (colWidth instanceof TableColLength) {
@@ -209,8 +221,8 @@ public class ColumnSetup {
          * factors (if any)
          */
         if (factors > 0) {
-            if (sumCols < tlm.getContentAreaIPD()) {
-                unit = (tlm.getContentAreaIPD() - sumCols) / factors;
+            if (sumCols < contentAreaIPD) {
+                unit = (contentAreaIPD - sumCols) / factors;
             } else {
                 log.warn("No space remaining to distribute over columns.");
             }
index 143c63bb94cb9e7170b1914047628aa91979e396..dc2b3cc4691194c918e57e1569dd7bb5a9e0e96a 100644 (file)
@@ -267,12 +267,14 @@ public class TableLayoutManager extends BlockStackingLayoutManager
         }
         addKnuthElementsForSpaceAfter(returnList, alignment);
 
-        //addKnuthElementsForBreakBefore(returnList, context);
-        int breakBefore = BreakUtil.compareBreakClasses(getTable().getBreakBefore(),
-                childLC.getBreakBefore());
-        if (breakBefore != Constants.EN_AUTO) {
-            returnList.add(0, new BreakElement(getAuxiliaryPosition(), 0,
-                    -KnuthElement.INFINITE, breakBefore, context));
+        if (!context.suppressBreakBefore()) {
+            //addKnuthElementsForBreakBefore(returnList, context);
+            int breakBefore = BreakUtil.compareBreakClasses(getTable().getBreakBefore(),
+                    childLC.getBreakBefore());
+            if (breakBefore != Constants.EN_AUTO) {
+                returnList.add(0, new BreakElement(getAuxiliaryPosition(), 0,
+                        -KnuthElement.INFINITE, breakBefore, context));
+            }
         }
 
         //addKnuthElementsForBreakAfter(returnList, context);
index 55834f529915ea8d88a364cb6094a1c6da4476f6..c2fc704dad53d0f442f4f49e8f56fa60ddf99574 100644 (file)
@@ -67,11 +67,33 @@ public class PDFNumber extends PDFObject {
         return doubleOut(doubleDown, 6);
     }
 
-    // Static cache. Possible concurrency implications. See comment in doubleOut(double, int).
-    private static DecimalFormat[] decimalFormatCache = new DecimalFormat[17];
-
     private static final String BASE_FORMAT = "0.################";
 
+    private static class DecimalFormatThreadLocal extends ThreadLocal {
+        
+        private int dec;
+        
+        public DecimalFormatThreadLocal(int dec) {
+            this.dec = dec;
+        }
+        
+        protected synchronized Object initialValue() {
+            String s = "0";
+            if (dec > 0) {
+                s = BASE_FORMAT.substring(0, dec + 2);
+            }
+            DecimalFormat df = new DecimalFormat(s, new DecimalFormatSymbols(Locale.US));
+            return df;
+        }
+    };
+    //DecimalFormat is not thread-safe!
+    private static final ThreadLocal[] DECIMAL_FORMAT_CACHE = new DecimalFormatThreadLocal[17];
+    static {
+        for (int i = 0, c = DECIMAL_FORMAT_CACHE.length; i < c; i++) {
+            DECIMAL_FORMAT_CACHE[i] = new DecimalFormatThreadLocal(i);
+        }
+    }
+    
     /**
      * Output a double value to a string suitable for PDF.
      * In this method it is possible to set the maximum
@@ -82,29 +104,15 @@ public class PDFNumber extends PDFObject {
      * @return the value as a string
      */
     public static String doubleOut(double doubleDown, int dec) {
-        if (dec < 0 || dec >= decimalFormatCache.length) {
+        if (dec < 0 || dec >= DECIMAL_FORMAT_CACHE.length) {
             throw new IllegalArgumentException("Parameter dec must be between 1 and "
-                    + (decimalFormatCache.length + 1));
+                    + (DECIMAL_FORMAT_CACHE.length + 1));
         }
-        if (decimalFormatCache[dec] == null) {
-            //We don't care about the rare case where a DecimalFormat might be replaced in
-            //a multi-threaded environment, so we don't synchronize the access to the static
-            //array (mainly for performance reasons). After all, the DecimalFormat instances
-            //read-only objects so it doesn't matter which instance is used as long as one
-            //is available.
-            String s = "0";
-            if (dec > 0) {
-                s = BASE_FORMAT.substring(0, dec + 2);
-            }
-            DecimalFormat df = new DecimalFormat(s, new DecimalFormatSymbols(Locale.US));
-            decimalFormatCache[dec] = df;
-        }
-        return decimalFormatCache[dec].format(doubleDown);
+        DecimalFormat df = (DecimalFormat)DECIMAL_FORMAT_CACHE[dec].get();
+        return df.format(doubleDown);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     protected String toPDFString() {
         if (getNumber() == null) {
             throw new IllegalArgumentException(
index 7c4d66689a7dd2b714ff1a0aeb0e6a179ece7ad8..e3f51085348ee82b1b7313e9e70d4f0248b061b4 100644 (file)
@@ -38,7 +38,6 @@ import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.awt.print.PrinterException;
 import java.awt.print.PrinterJob;
-
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.util.Locale;
@@ -60,8 +59,8 @@ import javax.swing.JToolBar;
 import javax.swing.KeyStroke;
 import javax.swing.SwingUtilities;
 
-import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.render.awt.AWTRenderer;
 
 /**
@@ -76,6 +75,8 @@ public class PreviewDialog extends JFrame implements StatusListener {
     protected AWTRenderer renderer;
     /** The FOUserAgent associated with this window */
     protected FOUserAgent foUserAgent;
+    /** The originally configured target resolution */
+    protected float configuredTargetResolution;
     /**
      * Renderable instance that can be used to reload and re-render a document after
      * modifications.
@@ -107,6 +108,7 @@ public class PreviewDialog extends JFrame implements StatusListener {
     public PreviewDialog(FOUserAgent foUserAgent, Renderable renderable) {
         renderer = (AWTRenderer) foUserAgent.getRendererOverride();
         this.foUserAgent = foUserAgent;
+        this.configuredTargetResolution = this.foUserAgent.getTargetResolution();
         this.renderable = renderable;
         translator = new Translator();
 
@@ -551,23 +553,23 @@ public class PreviewDialog extends JFrame implements StatusListener {
     }
 
     private void scaleActionPerformed(ActionEvent e) {
-        try {
-            int index = scale.getSelectedIndex();
-            if (index == 0) {
-                setScale(previewPanel.getScaleToFitWindow() * 100);
-            } else if (index == 1) {
-                setScale(previewPanel.getScaleToFitWidth() * 100);
-            } else {
-                String item = (String)scale.getSelectedItem();
-                setScale(Double.parseDouble(item.substring(0, item.indexOf('%'))));
-            }
-        } catch (FOPException fopEx) {
-            fopEx.printStackTrace();
+        int index = scale.getSelectedIndex();
+        if (index == 0) {
+            setScaleToFitWindow();
+        } else if (index == 1) {
+            setScaleToFitWidth();
+        } else {
+            String item = (String)scale.getSelectedItem();
+            setScale(Double.parseDouble(item.substring(0, item.indexOf('%'))));
         }
     }
 
     /** Prints the document */
     public void startPrinterJob(boolean showDialog) {
+        //Restore originally configured target resolution
+        float saveResolution = foUserAgent.getTargetResolution();
+        foUserAgent.setTargetResolution(this.configuredTargetResolution);
+        
         PrinterJob pj = PrinterJob.getPrinterJob();
         pj.setPageable(renderer);
         if (!showDialog || pj.printDialog()) {
@@ -577,6 +579,8 @@ public class PreviewDialog extends JFrame implements StatusListener {
                 e.printStackTrace();
             }
         }
+        
+        foUserAgent.setTargetResolution(saveResolution);
     }
 
     /**
index 05e03fda0503daaee0273506b2f0bbc78f88536d..f8152a978d47c1ec2d35e83f178d5e564124a2a7 100644 (file)
@@ -23,6 +23,7 @@ import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.GridLayout;
 import java.awt.Point;
+import java.awt.Toolkit;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
@@ -36,11 +37,12 @@ import javax.swing.JViewport;
 import javax.swing.SwingUtilities;
 import javax.swing.border.EmptyBorder;
 
+import org.apache.xmlgraphics.util.UnitConv;
+
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;
 import org.apache.fop.area.PageViewport;
-
 import org.apache.fop.render.awt.AWTRenderer;
 
 
@@ -155,6 +157,8 @@ public class PreviewPanel extends JPanel {
         this.renderable = renderable;
         this.renderer = renderer;
         this.foUserAgent = foUserAgent;
+        //Override target resolution for the computer screen
+        this.foUserAgent.setTargetResolution(Toolkit.getDefaultToolkit().getScreenResolution());
 
         gridPanel = new JPanel();
         gridPanel.setLayout(new GridLayout(0, 1)); // rows, cols
@@ -393,8 +397,10 @@ public class PreviewPanel extends JPanel {
     public double getScaleToFit(double viewWidth, double viewHeight) throws FOPException {
         PageViewport pageViewport = renderer.getPageViewport(currentPage);
         Rectangle2D pageSize = pageViewport.getViewArea();
-        double widthScale = viewWidth / (pageSize.getWidth() / 1000f);
-        double heightScale = viewHeight / (pageSize.getHeight() / 1000f);
+        float screenResolution = Toolkit.getDefaultToolkit().getScreenResolution();
+        float screenFactor = screenResolution / UnitConv.IN2PT;
+        double widthScale = viewWidth / (pageSize.getWidth() / 1000f) / screenFactor;
+        double heightScale = viewHeight / (pageSize.getHeight() / 1000f) / screenFactor;
         return Math.min(displayMode == CONT_FACING ? widthScale / 2 : widthScale, heightScale);
     }
 
index b61ebc346182fe2d986d1b83fec3b0ae888dc5fc..f05a16f1a1d8a80f546f37f01e7212abf3391166 100644 (file)
@@ -115,7 +115,6 @@ public class PDFGraphics2DAdapter extends AbstractGraphics2DAdapter {
 
         pdfInfo.currentStream.add(graphics.getString());
         renderer.restoreGraphicsState();
-        pdfInfo.pdfState.pop();
     }
 
     /** {@inheritDoc} */
index 216802c8feabfac87139fef48aad9a0ea2b0f797..10c4a9c92b12ed3fc0b8917bd2f0605a72f51eb1 100644 (file)
@@ -75,10 +75,12 @@ public final class BorderAttributesConverter {
 
             // Add padding to corresponding space (space-before or space-after)
             // if side == START or END, do nothing
-            if (side == CommonBorderPaddingBackground.BEFORE) {
-                attributes.addIntegerValue(padding, RtfText.SPACE_BEFORE);
-            } else if (side == CommonBorderPaddingBackground.AFTER) {
-                attributes.addIntegerValue(padding, RtfText.SPACE_AFTER);
+            if (padding != 0) {
+                if (side == CommonBorderPaddingBackground.BEFORE) {
+                    attributes.addIntegerValue(padding, RtfText.SPACE_BEFORE);
+                } else if (side == CommonBorderPaddingBackground.AFTER) {
+                    attributes.addIntegerValue(padding, RtfText.SPACE_AFTER);
+                }
             }
         }
     }
index caf11323fdd50e3e146069db9019beb117215aa9..33a2ff90472ccb6df4df788c9f97ffa7d46e7df0 100644 (file)
 
 package org.apache.fop.render.rtf;
 
-import java.util.Map;
 import java.util.HashMap;
+import java.util.Map;
 
-//FOP
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.fo.properties.FixedLength;
 
@@ -143,4 +142,8 @@ final class FoUnitsConverter {
         // RTF font size units are in half-points
         return (int)(result * 2.0);
     }
+
+    public float convertMptToTwips(int width) {
+        return width * POINT_TO_TWIPS / 1000;
+    }
 }
index c7f97ef4fcb048ce6154409867f484b3dadd4808..d50a8165671d1e9fbcec1e82a10bae11f1935a70 100644 (file)
@@ -21,6 +21,7 @@ package org.apache.fop.render.rtf;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.impl.SimpleLog;
+
 import org.apache.fop.datatypes.Length;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.expr.NumericOp;
@@ -58,6 +59,8 @@ final class PageAttributesConverter {
 
             attrib.setTwips(RtfPage.PAGE_WIDTH, pagemaster.getPageWidth());
             attrib.setTwips(RtfPage.PAGE_HEIGHT, pagemaster.getPageHeight());
+            //Sets the document level property
+            attrib.set(RtfPage.ITAP, "0");
 
             Object widthRaw = attrib.getValue(RtfPage.PAGE_WIDTH);
             Object heightRaw = attrib.getValue(RtfPage.PAGE_HEIGHT);
@@ -102,7 +105,7 @@ final class PageAttributesConverter {
             if (after != null) {
                 afterBottom = (Length) NumericOp.addition(pageBottom, after.getExtent());
             }
-            attrib.setTwips(RtfPage.FOOTERY, beforeTop);
+            attrib.setTwips(RtfPage.FOOTERY, afterBottom);
         } catch (Exception e) {
             log.error("Exception in convertPageAttributes: "
                 + e.getMessage() + "- page attributes ignored");
index 1adba9e2b4b1bad7d246ede1d19d2018c26c7bfb..65c7bf6819853212995d99240f5f577b8ee01abd 100644 (file)
@@ -20,6 +20,8 @@
 package org.apache.fop.render.rtf;
 
 // Java
+import java.awt.Dimension;
+import java.awt.Rectangle;
 import java.awt.geom.Point2D;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -51,12 +53,13 @@ import org.apache.xmlgraphics.image.loader.util.ImageUtil;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.datatypes.LengthBase;
-import org.apache.fop.datatypes.SimplePercentBaseContext;
+import org.apache.fop.datatypes.PercentBaseContext;
 import org.apache.fop.events.ResourceEventProducer;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.FOEventHandler;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FOText;
+import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.XMLObj;
 import org.apache.fop.fo.flow.AbstractGraphics;
 import org.apache.fop.fo.flow.BasicLink;
@@ -74,6 +77,7 @@ import org.apache.fop.fo.flow.ListItem;
 import org.apache.fop.fo.flow.ListItemBody;
 import org.apache.fop.fo.flow.ListItemLabel;
 import org.apache.fop.fo.flow.PageNumber;
+import org.apache.fop.fo.flow.PageNumberCitation;
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableBody;
 import org.apache.fop.fo.flow.table.TableFooter;
@@ -89,8 +93,10 @@ import org.apache.fop.fo.pagination.Region;
 import org.apache.fop.fo.pagination.SimplePageMaster;
 import org.apache.fop.fo.pagination.StaticContent;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
-import org.apache.fop.fo.properties.FixedLength;
+import org.apache.fop.fo.properties.EnumLength;
 import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.layoutmgr.inline.ImageLayout;
+import org.apache.fop.layoutmgr.table.ColumnSetup;
 import org.apache.fop.render.DefaultFontResolver;
 import org.apache.fop.render.RendererEventProducer;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfAfterContainer;
@@ -110,6 +116,7 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFootnote;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfHyperLink;
 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.RtfPage;
 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;
@@ -117,6 +124,7 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTextrun;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem.RtfListItemLabel;
 import org.apache.fop.render.rtf.rtflib.tools.BuilderContext;
+import org.apache.fop.render.rtf.rtflib.tools.PercentContext;
 import org.apache.fop.render.rtf.rtflib.tools.TableContext;
 
 /**
@@ -150,6 +158,10 @@ public class RTFHandler extends FOEventHandler {
 
     private SimplePageMaster pagemaster;
 
+    private int nestedTableDepth = 1;
+
+    private PercentContext percentManager = new PercentContext();
+
     /**
      * Creates a new RTF structure handler.
      * @param userAgent the FOUserAgent for this process
@@ -173,9 +185,7 @@ public class RTFHandler extends FOEventHandler {
         eventProducer.ioError(this, ioe);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startDocument() throws SAXException {
         // TODO sections should be created
         try {
@@ -187,9 +197,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endDocument() throws SAXException {
         try {
             rtfFile.flush();
@@ -199,9 +207,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startPageSequence(PageSequence pageSeq)  {
         try {
             //This is needed for region handling
@@ -240,6 +246,14 @@ public class RTFHandler extends FOEventHandler {
 
             builderContext.pushContainer(sect);
 
+            //Calculate usable page width for this flow
+            int useAblePageWidth = pagemaster.getPageWidth().getValue()
+                - pagemaster.getCommonMarginBlock().marginLeft.getValue()
+                - pagemaster.getCommonMarginBlock().marginRight.getValue()
+                - sect.getRtfAttributes().getValueAsInteger(RtfPage.MARGIN_LEFT).intValue()
+                - sect.getRtfAttributes().getValueAsInteger(RtfPage.MARGIN_RIGHT).intValue();
+            percentManager.setDimension(pageSeq, useAblePageWidth);
+
             bHeaderSpecified = false;
             bFooterSpecified = false;
         } catch (IOException ioe) {
@@ -247,9 +261,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endPageSequence(PageSequence pageSeq) {
         if (bDefer) {
             //If endBlock was called while SAX parsing, and the passed FO is Block
@@ -267,9 +279,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startFlow(Flow fl) {
         if (bDefer) {
             return;
@@ -357,9 +367,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endFlow(Flow fl) {
         if (bDefer) {
             return;
@@ -384,9 +392,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startBlock(Block bl) {
         if (bDefer) {
             return;
@@ -414,10 +420,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endBlock(Block bl) {
 
         if (bDefer) {
@@ -443,9 +446,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startBlockContainer(BlockContainer blc) {
         if (bDefer) {
             return;
@@ -472,9 +473,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endBlockContainer(BlockContainer bl) {
         if (bDefer) {
             return;
@@ -499,9 +498,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startTable(Table tbl) {
         if (bDefer) {
             return;
@@ -519,6 +516,8 @@ public class RTFHandler extends FOEventHandler {
                 = TableAttributesConverter.convertTableAttributes(tbl);
 
             RtfTable table = tc.newTable(atts, tableContext);
+            table.setNestedTableDepth(nestedTableDepth);
+            nestedTableDepth++;
 
             CommonBorderPaddingBackground border = tbl.getCommonBorderPaddingBackground();
             RtfAttributes borderAttributes = new RtfAttributes();
@@ -545,53 +544,32 @@ public class RTFHandler extends FOEventHandler {
         builderContext.pushTableContext(tableContext);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endTable(Table tbl) {
         if (bDefer) {
             return;
         }
 
+        nestedTableDepth--;
         builderContext.popTableContext();
         builderContext.popContainer();
     }
 
-    /**
-    *
-    * @param tc TableColumn that is starting;
-    */
-
+    /** {@inheritDoc} */
     public void startColumn(TableColumn tc) {
         if (bDefer) {
             return;
         }
 
         try {
-            /**
-             * Pass a SimplePercentBaseContext to getValue in order to
-             * avoid a NullPointerException, which occurs when you use
-             * proportional-column-width function in column-width attribute.
-             * Of course the results won't be correct, but at least the
-             * rest of the document will be rendered. Usage of the
-             * TableLayoutManager is not welcome due to design reasons and
-             * it also does not provide the correct values.
-             * TODO: Make proportional-column-width working for rtf output
-             */
-             SimplePercentBaseContext context
-                = new SimplePercentBaseContext(null,
-                                               LengthBase.TABLE_UNITS,
-                                               100000);
-
-            Integer iWidth
-                = new Integer(tc.getColumnWidth().getValue(context) / 1000);
+            int iWidth = tc.getColumnWidth().getValue(percentManager);
+            percentManager.setDimension(tc, iWidth);
 
-            String strWidth = iWidth.toString() + FixedLength.POINT;
-            Float width = new Float(
-                    FoUnitsConverter.getInstance().convertToTwips(strWidth));
+            //convert to twips
+            Float width = new Float(FoUnitsConverter.getInstance().convertMptToTwips(iWidth));
             builderContext.getTableContext().setNextColumnWidth(width);
             builderContext.getTableContext().setNextColumnRowSpanning(
-                    new Integer(0), null);
+                  new Integer(0), null);
             builderContext.getTableContext().setNextFirstSpanningCol(false);
         } catch (Exception e) {
             log.error("startColumn: " + e.getMessage());
@@ -599,49 +577,34 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-     /**
-     *
-     * @param tc TableColumn that is ending;
-     */
-
+    /** {@inheritDoc} */
     public void endColumn(TableColumn tc) {
         if (bDefer) {
             return;
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startHeader(TableHeader header) {
         startPart(header);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endHeader(TableHeader header) {
         endPart(header);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startFooter(TableFooter footer) {
         startPart(footer);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endFooter(TableFooter footer) {
         endPart(footer);
     }
 
-    /**
-     *
-     * @param inl Inline that is starting.
-     */
+    /** {@inheritDoc} */
     public void startInline(Inline inl) {
         if (bDefer) {
             return;
@@ -669,10 +632,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     *
-     * @param inl Inline that is ending.
-     */
+    /** {@inheritDoc} */
     public void endInline(Inline inl) {
         if (bDefer) {
             return;
@@ -735,10 +695,7 @@ public class RTFHandler extends FOEventHandler {
         startPart(body);
     }
 
-
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endBody(TableBody body) {
         endPart(body);
     }
@@ -775,9 +732,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endRow(TableRow tr) {
         if (bDefer) {
             return;
@@ -814,9 +769,7 @@ public class RTFHandler extends FOEventHandler {
         builderContext.getTableContext().decreaseRowSpannings();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startCell(TableCell tc) {
         if (bDefer) {
             return;
@@ -868,7 +821,6 @@ public class RTFHandler extends FOEventHandler {
             //process number-columns-spanned attribute
             if (numberColumnsSpanned > 0) {
                 // Get the number of columns spanned
-                RtfTable table = row.getTable();
                 tctx.setCurrentFirstSpanningCol(true);
 
                 // We widthdraw one cell because the first cell is already created
@@ -876,6 +828,8 @@ public class RTFHandler extends FOEventHandler {
                  for (int i = 0; i < numberColumnsSpanned - 1; ++i) {
                     tctx.selectNextColumn();
 
+                    //aggregate width for further elements
+                    width += tctx.getColumnWidth();
                     tctx.setCurrentFirstSpanningCol(false);
                     RtfTableCell hCell = row.newTableCellMergedHorizontally(
                             0, null);
@@ -890,10 +844,12 @@ public class RTFHandler extends FOEventHandler {
                                 cell.getRtfAttributes());
                     } else {
                         tctx.setCurrentColumnRowSpanning(
-                                new Integer(numberRowsSpanned), null);
+                                new Integer(numberRowsSpanned), cell.getRtfAttributes());
                     }
                 }
             }
+            //save width of the cell, convert from twips to mpt
+            percentManager.setDimension(tc, (int)width * 50);
 
             builderContext.pushContainer(cell);
         } catch (IOException ioe) {
@@ -904,9 +860,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endCell(TableCell tc) {
         if (bDefer) {
             return;
@@ -917,9 +871,7 @@ public class RTFHandler extends FOEventHandler {
     }
 
     // Lists
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startList(ListBlock lb) {
         if (bDefer) {
             return;
@@ -944,9 +896,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endList(ListBlock lb) {
         if (bDefer) {
             return;
@@ -955,9 +905,7 @@ public class RTFHandler extends FOEventHandler {
         builderContext.popContainer();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startListItem(ListItem li) {
         if (bDefer) {
             return;
@@ -995,9 +943,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endListItem(ListItem li) {
         if (bDefer) {
             return;
@@ -1006,9 +952,7 @@ public class RTFHandler extends FOEventHandler {
         builderContext.popContainer();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startListLabel() {
         if (bDefer) {
             return;
@@ -1028,9 +972,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endListLabel() {
         if (bDefer) {
             return;
@@ -1039,46 +981,32 @@ public class RTFHandler extends FOEventHandler {
         builderContext.popContainer();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startListBody() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endListBody() {
     }
 
     // Static Regions
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startStatic() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endStatic() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startMarkup() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endMarkup() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startLink(BasicLink basicLink) {
         if (bDefer) {
             return;
@@ -1109,9 +1037,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endLink() {
         if (bDefer) {
             return;
@@ -1120,9 +1046,7 @@ public class RTFHandler extends FOEventHandler {
         builderContext.popContainer();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void image(ExternalGraphic eg) {
         if (bDefer) {
             return;
@@ -1153,16 +1077,14 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void foreignObject(InstreamForeignObject ifo) {
         if (bDefer) {
             return;
         }
 
         try {
-            XMLObj child = (XMLObj) ifo.getChildXMLObj();
+            XMLObj child = ifo.getChildXMLObj();
             Document doc = child.getDOMDocument();
             String ns = child.getNamespaceURI();
 
@@ -1191,7 +1113,8 @@ public class RTFHandler extends FOEventHandler {
 
             FOUserAgent userAgent = ifo.getUserAgent();
             ImageManager manager = userAgent.getFactory().getImageManager();
-            Image converted = manager.convertImage(image, FLAVORS);
+            Map hints = ImageUtil.getDefaultHints(ua.getImageSessionContext());
+            Image converted = manager.convertImage(image, FLAVORS, hints);
             putGraphic(ifo, converted);
 
         } catch (ImageException ie) {
@@ -1242,7 +1165,7 @@ public class RTFHandler extends FOEventHandler {
             throws IOException {
         byte[] rawData = null;
 
-        ImageInfo info = image.getInfo();
+        final ImageInfo info = image.getInfo();
 
         if (image instanceof ImageRawStream) {
             ImageRawStream rawImage = (ImageRawStream)image;
@@ -1261,6 +1184,25 @@ public class RTFHandler extends FOEventHandler {
             return;
         }
 
+        //Set up percentage calculations
+        this.percentManager.setDimension(abstractGraphic);
+        PercentBaseContext pContext = new PercentBaseContext() {
+
+            public int getBaseLength(int lengthBase, FObj fobj) {
+                switch (lengthBase) {
+                case LengthBase.IMAGE_INTRINSIC_WIDTH:
+                    return info.getSize().getWidthMpt();
+                case LengthBase.IMAGE_INTRINSIC_HEIGHT:
+                    return info.getSize().getHeightMpt();
+                default:
+                    return percentManager.getBaseLength(lengthBase, fobj);
+                }
+            }
+
+        };
+        ImageLayout layout = new ImageLayout(abstractGraphic, pContext,
+                image.getInfo().getSize().getDimensionMpt());
+
         final IRtfTextrunContainer c
             = (IRtfTextrunContainer)builderContext.getContainer(
                 IRtfTextrunContainer.class, true, this);
@@ -1273,63 +1215,23 @@ public class RTFHandler extends FOEventHandler {
         }
         rtfGraphic.setImageData(rawData);
 
-        //set scaling
-        if (abstractGraphic.getScaling() == Constants.EN_UNIFORM) {
-            rtfGraphic.setScaling ("uniform");
-        }
-
-        //get width
-        int width = 0;
-        if (abstractGraphic.getWidth().getEnum() == Constants.EN_AUTO) {
-            width = info.getSize().getWidthMpt();
-        } else {
-            width = abstractGraphic.getWidth().getValue();
-        }
-
-        //get height
-        int height = 0;
-        if (abstractGraphic.getWidth().getEnum() == Constants.EN_AUTO) {
-            height = info.getSize().getHeightMpt();
-        } else {
-            height = abstractGraphic.getHeight().getValue();
-        }
-
-        //get content-width
-        int contentwidth = 0;
-        if (abstractGraphic.getContentWidth().getEnum()
-                == Constants.EN_AUTO) {
-            contentwidth = info.getSize().getWidthMpt();
-        } else if (abstractGraphic.getContentWidth().getEnum()
-                == Constants.EN_SCALE_TO_FIT) {
-            contentwidth = width;
-        } else {
-            //TODO: check, if the value is a percent value
-            contentwidth = abstractGraphic.getContentWidth().getValue();
-        }
-
-        //get content-width
-        int contentheight = 0;
-        if (abstractGraphic.getContentHeight().getEnum()
-                == Constants.EN_AUTO) {
-
-            contentheight = info.getSize().getHeightMpt();
-
-        } else if (abstractGraphic.getContentHeight().getEnum()
-                == Constants.EN_SCALE_TO_FIT) {
-
-            contentheight = height;
-        } else {
-            //TODO: check, if the value is a percent value
-            contentheight = abstractGraphic.getContentHeight().getValue();
-        }
-
-        //set width in rtf
-        //newGraphic.setWidth((long) (contentwidth / 1000f) + FixedLength.POINT);
-        rtfGraphic.setWidth((long) (contentwidth / 50f) + "twips");
-
-        //set height in rtf
-        //newGraphic.setHeight((long) (contentheight / 1000f) + FixedLength.POINT);
-        rtfGraphic.setHeight((long) (contentheight / 50f) + "twips");
+        FoUnitsConverter converter = FoUnitsConverter.getInstance();
+        Dimension viewport = layout.getViewportSize();
+        Rectangle placement = layout.getPlacement();
+        int cropLeft = Math.round(converter.convertMptToTwips(-placement.x));
+        int cropTop = Math.round(converter.convertMptToTwips(-placement.y));
+        int cropRight = Math.round(converter.convertMptToTwips(
+                -1 * (viewport.width - placement.x - placement.width)));
+        int cropBottom = Math.round(converter.convertMptToTwips(
+                -1 * (viewport.height - placement.y - placement.height)));
+        rtfGraphic.setCropping(cropLeft, cropTop, cropRight, cropBottom);
+
+        int width = Math.round(converter.convertMptToTwips(viewport.width));
+        int height = Math.round(converter.convertMptToTwips(viewport.height));
+        width += cropLeft + cropRight;
+        height += cropTop + cropBottom;
+        rtfGraphic.setWidthTwips(width);
+        rtfGraphic.setHeightTwips(height);
 
         //TODO: make this configurable:
         //      int compression = m_context.m_options.getRtfExternalGraphicCompressionRate ();
@@ -1342,15 +1244,11 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void pageRef() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startFootnote(Footnote footnote) {
         if (bDefer) {
             return;
@@ -1375,9 +1273,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endFootnote(Footnote footnote) {
         if (bDefer) {
             return;
@@ -1386,9 +1282,7 @@ public class RTFHandler extends FOEventHandler {
         builderContext.popContainer();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startFootnoteBody(FootnoteBody body) {
         if (bDefer) {
             return;
@@ -1409,9 +1303,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endFootnoteBody(FootnoteBody body) {
         if (bDefer) {
             return;
@@ -1432,10 +1324,28 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void leader(Leader l) {
+        if (bDefer) {
+            return;
+        }
+
+        try {
+            percentManager.setDimension(l);
+            RtfAttributes rtfAttr = TextAttributesConverter.convertLeaderAttributes(
+                    l, percentManager);
+
+            IRtfTextrunContainer container
+                  = (IRtfTextrunContainer)builderContext.getContainer(
+                      IRtfTextrunContainer.class, true, this);
+            RtfTextrun textrun = container.getTextrun();
+
+            textrun.addLeader(rtfAttr);
+
+        } catch (Exception e) {
+            log.error("startLeader: " + e.getMessage());
+            throw new RuntimeException(e.getMessage());
+        }
     }
 
     /**
@@ -1469,10 +1379,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     *
-     * @param pagenum PageNumber that is starting.
-     */
+    /** {@inheritDoc} */
     public void startPageNumber(PageNumber pagenum) {
         if (bDefer) {
             return;
@@ -1497,16 +1404,64 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     *
-     * @param pagenum PageNumber that is ending.
-     */
+    /** {@inheritDoc} */
     public void endPageNumber(PageNumber pagenum) {
         if (bDefer) {
             return;
         }
     }
 
+    /** {@inheritDoc} */
+    public void startPageNumberCitation(PageNumberCitation l) {
+        if (bDefer) {
+            return;
+        }
+        try {
+
+            IRtfTextrunContainer container
+                  = (IRtfTextrunContainer)builderContext.getContainer(
+                      IRtfTextrunContainer.class, true, this);
+            RtfTextrun textrun = container.getTextrun();
+
+            textrun.addPageNumberCitation(l.getRefId());
+
+        } catch (Exception e) {
+            log.error("startPageNumberCitation: " + e.getMessage());
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    private void prepareTable(Table tab) {
+        // Allows to receive the available width of the table
+        percentManager.setDimension(tab);
+
+        // Table gets expanded by half of the border on each side inside Word
+        // When using wide borders the table gets cut off
+        int tabDiff = tab.getCommonBorderPaddingBackground().getBorderStartWidth(false) / 2
+                + tab.getCommonBorderPaddingBackground().getBorderEndWidth(false);
+
+        // check for "auto" value
+        if (!(tab.getInlineProgressionDimension().getMaximum(null).getLength()
+                    instanceof EnumLength)) {
+            // value specified
+            percentManager.setDimension(tab,
+                    tab.getInlineProgressionDimension().getMaximum(null)
+                        .getLength().getValue(percentManager)
+                    - tabDiff);
+        } else {
+            // set table width again without border width
+            percentManager.setDimension(tab, percentManager.getBaseLength(
+                    LengthBase.CONTAINING_BLOCK_WIDTH, tab) - tabDiff);
+        }
+
+        ColumnSetup columnSetup = new ColumnSetup(tab);
+        //int sumOfColumns = columnSetup.getSumOfColumnWidths(percentManager);
+        float tableWidth = percentManager.getBaseLength(LengthBase.CONTAINING_BLOCK_WIDTH, tab);
+        float tableUnit = columnSetup.computeTableUnit(percentManager, Math.round(tableWidth));
+        percentManager.setTableUnit(tab, Math.round(tableUnit));
+
+    }
+
     /**
      * Calls the appropriate event handler for the passed FObj.
      *
@@ -1659,6 +1614,16 @@ public class RTFHandler extends FOEventHandler {
             } else {
                 endCell( (TableCell) foNode);
             }
+        } else if (foNode instanceof Leader) {
+            if (bStart) {
+                leader((Leader) foNode);
+            }
+        } else if (foNode instanceof PageNumberCitation) {
+            if (bStart) {
+                startPageNumberCitation((PageNumberCitation) foNode);
+            } else {
+                endPageNumberCitation((PageNumberCitation) foNode);
+            }
         } else {
             RTFEventProducer eventProducer = RTFEventProducer.Provider.get(
                     getUserAgent().getEventBroadcaster());
@@ -1701,9 +1666,12 @@ public class RTFHandler extends FOEventHandler {
 
             //recurse all table-columns
             if (table.getColumns() != null) {
-                for (Iterator it = table.getColumns().iterator(); it.hasNext();) {
-                    recurseFONode( (FONode) it.next() );
-                }
+              //Calculation for column-widths which are not set
+              prepareTable(table);
+
+              for (Iterator it = table.getColumns().iterator(); it.hasNext();) {
+                  recurseFONode( (FONode) it.next() );
+              }
             } else {
                 //TODO Implement implicit column setup handling!
                 RTFEventProducer eventProducer = RTFEventProducer.Provider.get(
index 792193b15ece19581b6a9289d3ba92602dd2e8e0..63c470b5db9e3e4d39fd8715862a72fc3babd1d5 100644 (file)
@@ -21,25 +21,30 @@ package org.apache.fop.render.rtf;
 
 import java.awt.Color;
 
-//FOP
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.datatypes.Length;
+import org.apache.fop.datatypes.PercentBaseContext;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FOText;
 import org.apache.fop.fo.flow.Block;
 import org.apache.fop.fo.flow.BlockContainer;
 import org.apache.fop.fo.flow.Inline;
+import org.apache.fop.fo.flow.Leader;
 import org.apache.fop.fo.flow.PageNumber;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.CommonFont;
 import org.apache.fop.fo.properties.CommonMarginBlock;
 import org.apache.fop.fo.properties.CommonTextDecoration;
-import org.apache.fop.render.rtf.BorderAttributesConverter;
+import org.apache.fop.fo.properties.PercentLength;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.IBorderAttributes;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfColorTable;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFontManager;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfLeader;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfText;
 
 /**  Converts FO properties to RtfAttributes
@@ -53,6 +58,8 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfText;
  */
 final class TextAttributesConverter {
 
+    private static Log log = LogFactory.getLog(TextAttributesConverter.class);
+
     /**
      * Constructor is private, because it's just a utility class.
      */
@@ -137,6 +144,131 @@ final class TextAttributesConverter {
         return attrib;
     }
 
+
+    /**
+     * Converts FO properties used by RtfLeader to RtfAttributes.
+     * @param fobj Leader
+     * @param context PercentBaseContext
+     * @return RtfAttributes
+     * @throws FOPException
+     */
+    public static RtfAttributes convertLeaderAttributes(Leader fobj, PercentBaseContext context)
+                throws FOPException {
+        boolean tab = false;
+        FOPRtfAttributes attrib = new FOPRtfAttributes();
+        attrib.set(RtfText.ATTR_FONT_FAMILY,
+        RtfFontManager.getInstance().getFontNumber(fobj.getCommonFont().getFirstFontFamily()));
+
+        if (fobj.getLeaderLength() != null) {
+            attrib.set(RtfLeader.LEADER_WIDTH, convertMptToTwips(fobj.getLeaderLength().getMaximum(
+                    context).getLength().getValue(context)));
+
+            if (fobj.getLeaderLength().getMaximum(context) instanceof PercentLength) {
+                if (((PercentLength)fobj.getLeaderLength().getMaximum(context)).getString().equals(
+                            "100.0%")) {
+                    // Use Tab instead of white spaces
+                    attrib.set(RtfLeader.LEADER_USETAB, 1);
+                    tab = true;
+                }
+            }
+        }
+
+        attrFontColor(fobj.getColor(), attrib);
+
+        if (fobj.getLeaderPatternWidth() != null) {
+            //TODO calculate pattern width not possible for white spaces, because its using
+            //underlines for tab it would work with LEADER_PATTERN_WIDTH (expndtw)
+        }
+
+        switch(fobj.getLeaderPattern()) {
+        case Constants.EN_DOTS:
+            if (tab) {
+                attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_TAB_DOTTED);
+            } else {
+                attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_DOTTED);
+            }
+            break;
+        case Constants.EN_SPACE:
+            //nothing has to be set for spaces
+            break;
+        case Constants.EN_RULE:
+            //Things like start-indent, space-after, ... not supported?
+            //Leader class does not offer these properties
+            //TODO aggregate them with the leader width or
+            // create a second - blank leader - before
+
+            if (fobj.getRuleThickness() != null) {
+                //TODO See inside RtfLeader, better calculation for
+                //white spaces would be necessary
+                //attrib.set(RtfLeader.LEADER_RULE_THICKNESS,
+                //    fobj.getRuleThickness().getValue(context));
+                log.warn("RTF: fo:leader rule-thickness not supported");
+            }
+
+            switch (fobj.getRuleStyle()) {
+            case Constants.EN_SOLID:
+                if (tab) {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_TAB_THICK);
+                } else {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_THICK);
+                }
+                break;
+            case Constants.EN_DASHED:
+                if (tab) {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_TAB_MIDDLEDOTTED);
+                } else {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_MIDDLEDOTTED);
+                }
+                break;
+            case Constants.EN_DOTTED:
+                if (tab) {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_TAB_DOTTED);
+                } else {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_DOTTED);
+                }
+                break;
+            case Constants.EN_DOUBLE:
+                if (tab) {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_TAB_EQUAL);
+                } else {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_EQUAL);
+                }
+                break;
+            case Constants.EN_GROOVE:
+                if (tab) {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_TAB_HYPHENS);
+                } else {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_HYPHENS);
+                }
+                break;
+            case Constants.EN_RIDGE:
+                if (tab) {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_TAB_UNDERLINE);
+                } else {
+                    attrib.set(RtfLeader.LEADER_TABLEAD, RtfLeader.LEADER_UNDERLINE);
+                }
+                break;
+            default:
+                break;
+            }
+            break;
+        case Constants.EN_USECONTENT:
+            log.warn("RTF: fo:leader use-content not supported");
+            break;
+        default:
+            break;
+        }
+
+        if (fobj.getLeaderAlignment() == Constants.EN_REFERENCE_AREA) {
+            log.warn("RTF: fo:leader reference-area not supported");
+        }
+        return attrib;
+    }
+
+    private static int convertMptToTwips(int mpt) {
+        return Math.round(FoUnitsConverter.getInstance().convertMptToTwips(mpt));
+    }
+
     private static void attrFont(CommonFont font, FOPRtfAttributes rtfAttr) {
         rtfAttr.set(RtfText.ATTR_FONT_FAMILY,
                 RtfFontManager.getInstance().getFontNumber(font.getFirstFontFamily()));
index 2eb95b587ce9ffb5caba72eb979d94f787f51903..5ec5e907e6c139f894b00bf601f0679270036555 100644 (file)
@@ -28,6 +28,7 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
 
 import java.util.HashMap;
 import java.util.Iterator;
+
 import org.xml.sax.Attributes;
 import org.xml.sax.helpers.AttributesImpl;
 
@@ -163,6 +164,15 @@ implements java.lang.Cloneable {
         return values.get(name);
     }
 
+    /**
+     * Returns a value as an Integer. The value is simply cast to an Integer.
+     * @param name String containing attribute name
+     * @return the value of an attribute, null if not found
+     */
+    public Integer getValueAsInteger(String name) {
+        return (Integer)values.get(name);
+    }
+
     /**
      * @param name String containing attribute name
      * @return true if given attribute is set
index 182894ea586855cb32df6ba77a6ca5e47c45d233..6123ac5637435efca372559463e60ee2a6cb2929 100644 (file)
@@ -269,6 +269,9 @@ public class RtfExternalGraphic extends RtfElement {
      */
     protected boolean scaleUniform = false;
 
+    /** cropping on left/top/right/bottom edges for \piccrop*N */
+    private int[] cropValues = new int[4];
+
     /**
      * Graphic compression rate
      */
@@ -406,6 +409,7 @@ public class RtfExternalGraphic extends RtfElement {
 
         computeImageSize();
         writeSizeInfo();
+        writeAttributes(getRtfAttributes(), null);
 
         for (int i = 0; i < imagedata.length; i++) {
             int iData = imagedata [i];
@@ -519,6 +523,19 @@ public class RtfExternalGraphic extends RtfElement {
                 writeControlWord("picscaley" + widthDesired * 100 / width);
             }
         }
+
+        if (this.cropValues[0] != 0) {
+            writeOneAttribute("piccropl", new Integer(this.cropValues[0]));
+        }
+        if (this.cropValues[1] != 0) {
+            writeOneAttribute("piccropt", new Integer(this.cropValues[1]));
+        }
+        if (this.cropValues[2] != 0) {
+            writeOneAttribute("piccropr", new Integer(this.cropValues[2]));
+        }
+        if (this.cropValues[3] != 0) {
+            writeOneAttribute("piccropb", new Integer(this.cropValues[3]));
+        }
     }
 
     //////////////////////////////////////////////////
@@ -545,6 +562,24 @@ public class RtfExternalGraphic extends RtfElement {
         this.perCentW = ImageUtil.isPercent(theWidth);
     }
 
+    /**
+     * Sets the desired width of the image.
+     * @param twips The desired image width (in twips)
+     */
+    public void setWidthTwips(int twips) {
+        this.widthDesired = twips;
+        this.perCentW = false;
+    }
+
+    /**
+     * Sets the desired height of the image.
+     * @param twips The desired image height (in twips)
+     */
+    public void setHeightTwips(int twips) {
+        this.heightDesired = twips;
+        this.perCentH = false;
+    }
+
     /**
      * Sets the flag whether the image size shall be adjusted.
      *
@@ -553,9 +588,34 @@ public class RtfExternalGraphic extends RtfElement {
      * false   no adjustment
      */
     public void setScaling(String value) {
-        if (value.equalsIgnoreCase("uniform")) {
-            this.scaleUniform = true;
-        }
+        setUniformScaling("uniform".equalsIgnoreCase(value));
+    }
+
+    /**
+     * Sets the flag whether the image size shall be adjusted.
+     *
+     * @param uniform
+     *                true    image width or height shall be adjusted automatically\n
+     *                false   no adjustment
+     */
+    public void setUniformScaling(boolean uniform) {
+        this.scaleUniform = uniform;
+    }
+
+    /**
+     * Sets cropping values for all four edges for the \piccrop*N commands.
+     * A positive value crops toward the center of the picture;
+     * a negative value crops away from the center, adding a space border around the picture
+     * @param left left cropping value (in twips)
+     * @param top top cropping value (in twips)
+     * @param right right cropping value (in twips)
+     * @param bottom bottom cropping value (in twips)
+     */
+    public void setCropping(int left, int top, int right, int bottom) {
+        this.cropValues[0] = left;
+        this.cropValues[1] = top;
+        this.cropValues[2] = right;
+        this.cropValues[3] = bottom;
     }
 
     /**
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfLeader.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfLeader.java
new file mode 100644 (file)
index 0000000..b3f11bc
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * 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;
+import java.util.Iterator;
+
+/**
+ * Generates the leader in RTF.
+ */
+public class RtfLeader extends RtfContainer {
+
+    /*
+     * Format : \tqr \style \tx## { \pard \format \tab }
+     *  ## represents the width \style represents the style (tldot, tlth, ...)
+     * \format represents standard formats (color, fontsize, ...)
+     *
+     *
+     * \pard \zwnj {\fsxx <format> } \zwnj
+     *
+     * <format>: \\ulcN Underline color. \\uld Dotted underline. \\uldash Dashed
+     * underline. \\uldashd Dash-dotted underline. \\uldashdd Dash-dot-dotted
+     * underline. \\uldb Double underline. \\ulhwave Heavy wave underline.
+     * \\ulldash Long dashed underline. \\ulnone Stops all underlining. \\ulth
+     * Thick underline. \\ulthd Thick dotted underline. \\ulthdash Thick dashed
+     * underline. \\ulthdashd Thick dash-dotted underline. \\ulthdashdd Thick
+     * dash-dot-dotted underline. \\ulthldash Thick long dashed underline.
+     * \\ululdbwave Double wave underline.
+     */
+
+    private RtfAttributes attrs = null;
+
+    /** Private attribute: tab style */
+    public static final String LEADER_TABLEAD = "tablead";
+
+    /** Private attribute: tab usage indicator */
+    public static final String LEADER_USETAB = "tabuse";
+
+    /** Private attribute: leader width */
+    public static final String LEADER_WIDTH = "lwidth";
+
+    // +++++++++++++++ Styles Underline ++++++++++++++++++++++
+
+    /** Dotted underline */
+    public static final String LEADER_DOTTED = "uld"; // dotted
+
+    /** Dashed underline */
+    public static final String LEADER_MIDDLEDOTTED = "uldash"; // dashed
+
+    /** Heavy wave underline */
+    public static final String LEADER_HYPHENS = "ulhwave"; // groove
+
+    /** Dash-dot-dotted underline */
+    public static final String LEADER_UNDERLINE = "ulthdashdd"; // ridge
+
+    /** Double underline */
+    public static final String LEADER_EQUAL = "uldb"; // double
+
+    /** Thick underline */
+    public static final String LEADER_THICK = "ulth"; // solid
+
+    // +++++++++++++++ Styles Tabulator +++++++++++++++++++++++
+
+    /** Leader dots */
+    public static final String LEADER_TAB_DOTTED = "tldot"; // dotted
+
+    /** Leader middle dots */
+    public static final String LEADER_TAB_MIDDLEDOTTED = "tlmdot"; // dashed
+
+    /** Leader hyphens */
+    public static final String LEADER_TAB_HYPHENS = "tlhyph"; // groove
+
+    /** Leader underline */
+    public static final String LEADER_TAB_UNDERLINE = "tlul"; // ridge
+
+    /** Leader equal sign */
+    public static final String LEADER_TAB_EQUAL = "tleq"; // double
+
+    /** Leader thick line */
+    public static final String LEADER_TAB_THICK = "tlth"; // solid
+
+    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+    /** Resets to default properties */
+    public static final String LEADER_IGNORE_STYLE = "pard";
+
+    /** Font size determines rule thickness */
+    public static final String LEADER_RULE_THICKNESS = "fs"; // thickness = fontsize
+
+    /** Expansion or compression of the space between characters in twips */
+    public static final String LEADER_PATTERN_WIDTH = "expndtw";
+
+    /** Zero-width break opportunity */
+    public static final String LEADER_ZERO_WIDTH = "zwbo";
+
+    /** Standard leader width */
+    public static final int LEADER_STANDARD_WIDTH = 30;
+
+    /** Move up 4 half-points */
+    public static final String LEADER_UP = "up4";
+
+    /** Negative expansion */
+    public static final String LEADER_EXPAND = "expnd-2"; // negative value
+                                                            // for compression
+
+    /** Tab */
+    public static final String LEADER_TAB_VALUE = "tab";
+
+    /** Right-aligned tab */
+    public static final String LEADER_TAB_RIGHT = "tqr";
+
+    /** Tab width */
+    public static final String LEADER_TAB_WIDTH = "tx";
+
+    RtfLeader(RtfContainer parent, Writer w, RtfAttributes attrs) throws IOException {
+        super(parent, w);
+        this.attrs = attrs;
+    }
+
+    /** {@inheritDoc} */
+    protected void writeRtfContent() throws IOException {
+
+        int thickness = LEADER_STANDARD_WIDTH;
+        String tablead = null;
+        String tabwidth = null;
+        for (Iterator it = attrs.nameIterator(); it.hasNext();) {
+            final String name = (String)it.next();
+            if (attrs.isSet(name)) {
+                if (name.equals(LEADER_TABLEAD)) {
+                    tablead = attrs.getValue(LEADER_TABLEAD).toString();
+                } else if (name.equals(LEADER_WIDTH)) {
+                    tabwidth = attrs.getValue(LEADER_WIDTH).toString();
+                }
+            }
+        }
+
+        if (attrs.getValue(LEADER_RULE_THICKNESS) != null) {
+            thickness += Integer.parseInt(attrs.getValue(LEADER_RULE_THICKNESS).toString())
+                            / 1000 * 2;
+            attrs.unset(LEADER_RULE_THICKNESS);
+        }
+
+        //Remove private attributes
+        attrs.unset(LEADER_WIDTH);
+        attrs.unset(LEADER_TABLEAD);
+
+        // If leader is 100% we use a tabulator, because its more
+        // comfortable, specially for the table of content
+        if (attrs.getValue(LEADER_USETAB) != null) {
+            attrs.unset(LEADER_USETAB);
+            writeControlWord(LEADER_TAB_RIGHT);
+
+            if (tablead != null) {
+                writeControlWord(tablead);
+            }
+            writeControlWord(LEADER_TAB_WIDTH + tabwidth);
+
+            writeGroupMark(true);
+
+            writeControlWord(LEADER_IGNORE_STYLE);
+            writeAttributes(attrs, null);
+            writeControlWord(LEADER_EXPAND);
+            writeControlWord(LEADER_TAB_VALUE);
+
+            writeGroupMark(false);
+
+        }
+        // Using white spaces with different underline formats
+        else {
+            writeControlWord(LEADER_IGNORE_STYLE);
+            writeControlWord(LEADER_ZERO_WIDTH);
+            writeGroupMark(true);
+
+            writeControlWord(LEADER_RULE_THICKNESS + thickness);
+
+            writeControlWord(LEADER_UP);
+
+            super.writeAttributes(attrs, null);
+            if (tablead != null) {
+                writeControlWord(tablead);
+            }
+
+            // Calculation for the necessary amount of white spaces
+            // Depending on font-size 15 -> 1cm = 7,5 spaces
+            // TODO for rule-thickness this has to be done better
+
+            for (double d = (Integer.parseInt(tabwidth) / 560) * 7.5; d >= 1; d--) {
+                RtfStringConverter.getInstance().writeRtfString(writer, " ");
+            }
+
+            writeGroupMark(false);
+            writeControlWord(LEADER_ZERO_WIDTH);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public boolean isEmpty() {
+        return false;
+    }
+
+}
index fb2df3facaf08768c9d6bed0e1b6ad58e46f0891..6579005743271401899a04d56be5be8a3870f141 100644 (file)
@@ -60,11 +60,13 @@ extends RtfContainer {
     public static final String HEADERY = "headery";
     /** constant for footer position */
     public static final String FOOTERY = "footery";
-
+    /** constant for itap level */
+    public static final String ITAP = "itap";
+    
     /** String array of RtfPage attributes */
     public static final String[] PAGE_ATTR = new String[]{
         PAGE_WIDTH, PAGE_HEIGHT, LANDSCAPE, MARGIN_TOP, MARGIN_BOTTOM,
-        MARGIN_LEFT, MARGIN_RIGHT, HEADERY, FOOTERY
+        MARGIN_LEFT, MARGIN_RIGHT, HEADERY, FOOTERY, ITAP
     };
 
     /**    RtfPage creates new page attributes with the parent container, the writer
index 92ba2bb7f41134d8dcf3a01c4ec21f202dd39098..44c03c316ed09e7866ed0d0a8deecf3ceaf45557 100644 (file)
@@ -26,8 +26,8 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
  * the FOP project.
  */
 
-import java.io.Writer;
 import java.io.IOException;
+import java.io.Writer;
 
 /**
  * @author Christopher Scott, scottc@westinghouse.com
@@ -50,9 +50,9 @@ public class RtfPageNumberCitation extends RtfContainer {
     private String id = null;
 
     /** Create an RTF page number citation as a child of given container with default attributes */
-    RtfPageNumberCitation (IRtfPageNumberCitationContainer parent, Writer w, String id)
+    RtfPageNumberCitation (RtfContainer parent, Writer w, String id)
             throws IOException {
-        super((RtfContainer)parent, w);
+        super(parent, w);
         this.id = id;
     }
 
@@ -92,7 +92,7 @@ public class RtfPageNumberCitation extends RtfContainer {
             writeStarControlWord(pageRef);
             writeGroupMark(false);
             writeGroupMark(true);
-            writeControlWord(RTF_FIELD_RESULT);
+            writeControlWord(RTF_FIELD_RESULT + '#'); //To see where the page-number would be
             writeGroupMark(false);
             writeGroupMark(false);
         }
index eda5644a2db731efd608d95ed817f34c89797ccf..3747103d139a599ba697eadf5d8557c48bcce0aa 100644 (file)
@@ -26,8 +26,8 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
  * the FOP project.
  */
 
-import java.io.Writer;
 import java.io.IOException;
+import java.io.Writer;
 
 /**  Container for RtfRow elements
  *  @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
@@ -43,6 +43,9 @@ public class RtfTable extends RtfContainer {
      *  number-columns-spanned attribute */
     private ITableColumnsInfo tableContext;
 
+    /** Shows the table depth necessary for nested tables */
+    private int nestedTableDepth = 0;
+
     /** Create an RTF element as a child of given container */
     RtfTable(IRtfTableContainer parent, Writer w, ITableColumnsInfo tc)
             throws IOException {
@@ -212,6 +215,22 @@ public class RtfTable extends RtfContainer {
         return null;
     }
 
+    /**
+     * Sets the nested table depth.
+     * @param nestedTableDepth the nested table depth
+     */
+    public void setNestedTableDepth(int nestedTableDepth) {
+        this.nestedTableDepth = nestedTableDepth;
+    }
+
+    /**
+     * Returns the nested table depth.
+     * @return the nested table depth
+     */
+    public int getNestedTableDepth() {
+        return this.nestedTableDepth;
+    }
+
     /**
      * Sets the RtfAttributes for the borders of the table.
      * @param attributes Border attributes of the table.
index fe936e3f57a5b917f9919b4216b30f766fc271b5..f5e5978ecf2992af09a7dca0ba94ce977f02065a 100644 (file)
@@ -133,11 +133,11 @@ public class RtfTableRow extends RtfContainer implements ITableAttributes {
      * @throws IOException for I/O problems
      */
     protected void writeRtfContent() throws IOException {
-
         if (getTable().isNestedTable()) {
             //nested table
             writeControlWord("intbl");
-            writeControlWord("itap2");
+            //itap is the depth (level) of the current nested table
+            writeControlWord("itap" + getTable().getNestedTableDepth());
         } else {
             //normal (not nested) table
             writeRowAndCellsDefintions();
index e0703d7ba724b195e266bb72ecc5cc97b22c4779..a9ba432b18d062372189c3504a7b00d60bcd0269 100644 (file)
@@ -22,8 +22,8 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
 // Java
 import java.io.IOException;
 import java.io.Writer;
-import java.util.List;
 import java.util.Iterator;
+import java.util.List;
 import java.util.ListIterator;
 
 // FOP
@@ -175,6 +175,15 @@ public class RtfTextrun extends RtfContainer {
         addOpenGroupMark(attrs);
     }
 
+    /**
+     * Inserts a page number citation.
+     * @param refId the identifier being referenced
+     * @throws IOException for I/O problems
+     */
+    public void addPageNumberCitation(String refId) throws IOException {
+        RtfPageNumberCitation r = new RtfPageNumberCitation(this, writer, refId);
+    }
+
     /**
      * Pop inline attributes.
      *
@@ -242,6 +251,15 @@ public class RtfTextrun extends RtfContainer {
         }
     }
 
+    /**
+     * Inserts a leader.
+     * @param attrs Attributes for the leader
+     * @throws IOException for I/O problems
+     */
+    public void addLeader(RtfAttributes attrs) throws IOException {
+        new RtfLeader(this, writer, attrs);
+    }
+
     /**
      * Inserts a page number.
      * @param attr Attributes for the page number to insert.
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
new file mode 100644 (file)
index 0000000..ef9b248
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * 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.tools;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.datatypes.LengthBase;
+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.pagination.PageSequence;
+
+/**
+ * PercentBaseContext implementation to track base widths for percentage calculations.
+ */
+public class PercentContext implements PercentBaseContext {
+    private static Log log = LogFactory.getLog(PercentContext.class);
+
+    /** Map containing the FObj and its width */
+    private Map lengthMap = new java.util.HashMap();
+
+    /** Map containing the Tables and their table units */
+    private Map tableUnitMap = new java.util.HashMap();
+
+    /** Variable to check if a base width is set */
+    private boolean baseWidthSet = false;
+
+    /**
+     * Returns the available width for a specific FObj
+     *
+     * @param lengthBase
+     *                lengthBase not used
+     * @param fobj
+     *                the FObj
+     * @return Available Width
+     */
+    public int getBaseLength(int lengthBase, FObj fobj) {
+        if (fobj == null) {
+            return 0;
+        }
+        switch (lengthBase) {
+        case LengthBase.CONTAINING_BLOCK_WIDTH:
+        case LengthBase.PARENT_AREA_WIDTH:
+        case LengthBase.CONTAINING_REFAREA_WIDTH:
+            Object width = lengthMap.get(fobj);
+            if (width != null) {
+                return Integer.parseInt(width.toString());
+            } else {
+                return -1;
+            }
+        case LengthBase.TABLE_UNITS:
+            Object unit = tableUnitMap.get(fobj);
+            return (unit != null) ? ((Integer)unit).intValue() : 0;
+        default:
+            log.error(new Exception("Unsupported base type for LengthBase:" + lengthBase));
+            return 0;
+        }
+    }
+
+    /**
+     * Elements having a width property can call this function if their width is
+     * calculated in RTFHandler
+     *
+     * @param fobj the FObj
+     * @param width width of the FObj (in millipoints)
+     */
+    public void setDimension(FObj fobj, int width) {
+        // TODO ACCEPT only objects above for setting a width
+        if (fobj instanceof PageSequence) {
+            baseWidthSet = true;
+        }
+        // width in mpt
+        lengthMap.put(fobj, new Integer(width));
+    }
+
+    /**
+     * Records the calculated table unit for a given table.
+     * @param table the table for which the table unit is set
+     * @param tableUnit the table unit value (in millipoints)
+     */
+    public void setTableUnit(Table table, int tableUnit) {
+        tableUnitMap.put(table, new Integer(tableUnit));
+    }
+
+    /**
+     * Searches for the parent object of fobj.
+     */
+    private Integer findParent(FONode fobj) {
+        if (fobj.getRoot() != fobj) {
+            if (lengthMap.containsKey(fobj)) {
+                return new Integer(lengthMap.get(fobj).toString());
+            } else {
+                return findParent(fobj.getParent());
+            }
+        } else {
+            log.error("Base Value for element " + fobj.getName() + " not found");
+            return new Integer(-1);
+        }
+    }
+
+    /**
+     * Elements willing to use this context have to register themselves by
+     * calling this function.
+     *
+     * @param fobj the FObj
+     */
+    public void setDimension(FObj fobj) {
+        if (baseWidthSet) {
+            Integer width = findParent(fobj.getParent());
+            if (width.intValue() != -1) {
+                lengthMap.put(fobj, width);
+            }
+        }
+    }
+}
index 0e419016ec8fc61dec01b21dd4c354cb9143f8e4..7302f270c976441740b07e7835668d8b90da6f62 100644 (file)
@@ -36,7 +36,8 @@ public final class BreakUtil {
         case Constants.EN_PAGE:      return 2;
         case Constants.EN_EVEN_PAGE: return 3;
         case Constants.EN_ODD_PAGE:  return 3;
-        default: throw new IllegalArgumentException();
+        default: throw new IllegalArgumentException(
+                "Illegal value for breakClass: " + breakClass);
         }
     }
 
index 3e37d89a0cdb61b0fe5dee16effa3be254bc777e..1a9cdb85efe137da2092a95c747daa75f7b20149 100644 (file)
       </action>
     </release>
     <release version="0.95" date="TBD">
+      <notes>
+        <section>
+          <title>Notes</title>
+          <p>
+            Besides the important changes listed below, the most important areas with
+            improvements in this release are:
+          </p>
+          <ul>
+            <li>
+              Many bugfixes in tables, plus some new features (full support for keeps and
+              breaks, border conditionality, background on columns and header/footer/body)
+            </li>
+            <li>
+              Improvements and bugfixes for font handling and font
+              auto-detection/-registration.
+            </li>
+            <li>
+              Performance improvements and memory optimizations for the property handling
+              in the FO tree.
+            </li>
+          </ul>
+          <p>
+            Please note that with this release, we've dropped support for Java 1.3.
+            FOP will, from now on, <strong>require at least Java 1.4</strong>.
+          </p>
+          <p>
+            There have been a few changes in tables that make FOP both more strict and more
+            compliant to the Recommendation:
+            <ul>
+              <li>XSL-FO 1.1 explicitly states that a row-spanning fo:table-cell element is not
+                allowed to span further than its enclosing fo:table-header/footer/body element
+                (see bottom of <link href="http://www.w3.org/TR/xsl11/#fo_table">section
+                  6.7.3</link>). From now on FOP will give a validation error if a document
+                contains such an erroneous cell.
+              </li>
+              <li>
+                <p>If an fo:table element contains explicit fo:table-column children, then those
+                  elements set the total number of columns in the table. This means that a
+                  validation error will now occur if a row contains more cells than available
+                  columns. This change allows to improve performance, since the rendering of the
+                  table may start as soon as the table-column elements have been parsed.</p>
+                <p>If more flexibility is needed, then the fo:table-column elements may be just
+                  omitted. The final number of columns will then be set by the row that has the
+                  most cells.</p>
+              </li>
+            </ul>
+          </p>
+          <p>
+            The image libraries Jimi and JAI are no longer needed (and used) for image loading.
+            Instead we rely completely on the Image I/O API that has been introduced with
+            Java 1.4. If you still need support for bitmap image formats that do not work
+            out-of-the-box, we recommend adding
+            <link href="http://jai-imageio.dev.java.net/">JAI Image I/O Tools</link>
+            (an Image I/O compatible image codec package) to the classpath. JAI is still required
+            for building the FOP distribution but it is optional for normal builds and at run-time.
+          </p>
+          <note>
+            This final 0.95 release contains all the 
+            <a href="changes_0.95beta.html">changes made for Apache FOP 0.95beta</a>.
+          </note>
+        </section>
+      </notes>
       <action context="Renderers" dev="JM" type="fix">
-        Fixed positioning of absolutely positioned block-containers in multi-column documents.
+        Fixed a color selection problem which occurred after an image has been painted
+        through the Graphics2DAdapter in PDF output.
+      </action>
+      <action context="Renderers" dev="JM" type="fix" fixes-bug="41306">
+        Fixed page ordering problem with AWTRenderer.
+      </action>
+      <action context="Renderers" dev="JM" type="fix" fixes-bug="39980">
+        Fixed image scaling for RTF output.
+      </action>
+      <action context="API" dev="JM" type="fix">
+        Fixed the -imagein command-line option.
+      </action>
+      <action context="Renderers" dev="JM" type="add" fixes-bug="43825" due-to="Maximilian Aster">
+        Added support for fo:leader for RTF output (no full support!). Fixes problems with empty leaders
+        being used to force empty lines among other issues.
+      </action>
+      <action context="Renderers" dev="JM" type="add" fixes-bug="43824" due-to="Maximilian Aster">
+        Added support for page-number-citation for RTF output.
+      </action>
+      <action context="Renderers" dev="JM" type="fix" fixes-bug="43606" due-to="Maximilian Aster">
+        Fixed handling of proportional-column-width() and percentages for table column in RTF
+        output.
+      </action>
+      <action context="Layout" dev="AD" type="fix" fixes-bug="45295">
+        Fixed NullPointerException when page-number-citations are used inside a marker.
+      </action>
+      <action context="Images" dev="JM" type="fix">
+        Fixed two bugs concerning resolution handling with SVG images and their
+        conversion to bitmaps for RTF output.
+      </action>
+      <action context="Code" dev="JM" type="fix" fixes-bug="44887" importance="high">
+        Fixed potential multi-threading problem concerning the use of DecimalFormat.
+      </action>
+      <action context="Layout" dev="JM" type="fix" fixes-bug="44412">
+        Regression bugfix: Multiple collapsible breaks don't cause empty pages anymore.
       </action>
       <action context="Renderers" dev="JM" type="fix">
+        Fixed resolution handling inside AWT preview dialog.
+      </action>
+      <action context="Renderers" dev="JM" type="fix" importance="high">
+        Fixed positioning of absolutely positioned block-containers in multi-column documents.
+      </action>
+      <action context="Renderers" dev="JM" type="fix" importance="high">
         Fixed rendering of fixed block-containers in AFP output.
       </action>
+      <action context="Layout" dev="VH" type="fix" fixes-bug="41621" importance="high">
+        Various bugfixes for table layout.
+      </action>
       <action context="Renderers" dev="JM" type="fix">
         Fixed regression causing bad positioning of block-containers if used as descendant
         of a table-cell.
index c6c4015cccbef430762ca11f1ee79cede76bb1f9..457aa91d46e689330767219e1eca27db99bdac30 100644 (file)
@@ -88,6 +88,51 @@ public class ImageLoaderTestCase extends TestCase {
         assertEquals(16000, info.getSize().getHeightMpt());
     }
 
+    public void testSVGNoViewbox() throws Exception {
+        String uri = "test/resources/images/circles.svg";
+
+        FopFactory ff = FopFactory.newInstance();
+        ff.setSourceResolution(96);
+        ff.setTargetResolution(300);
+
+        FOUserAgent userAgent = ff.newFOUserAgent();
+
+        ImageManager manager = ff.getImageManager();
+        ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext());
+        assertNotNull("ImageInfo must not be null", info);
+
+        Image img = manager.getImage(info, ImageFlavor.XML_DOM,
+                userAgent.getImageSessionContext());
+        assertNotNull("Image must not be null", img);
+        assertEquals(ImageFlavor.XML_DOM, img.getFlavor());
+        ImageXMLDOM imgDom = (ImageXMLDOM)img;
+        assertNotNull(imgDom.getDocument());
+        assertEquals("http://www.w3.org/2000/svg", imgDom.getRootNamespace());
+        info = imgDom.getInfo(); //Switch to the ImageInfo returned by the image
+        assertEquals(96, info.getSize().getDpiHorizontal(), 0);
+        assertEquals(340158, info.getSize().getWidthMpt());
+        assertEquals(340158, info.getSize().getHeightMpt());
+        assertEquals(454, info.getSize().getWidthPx());
+        assertEquals(454, info.getSize().getHeightPx());
+
+        img = manager.getImage(info, ImageFlavor.RENDERED_IMAGE,
+                    userAgent.getImageSessionContext());
+        assertNotNull("Image must not be null", img);
+        assertEquals(ImageFlavor.RENDERED_IMAGE, img.getFlavor());
+        ImageRendered imgRed = (ImageRendered)img;
+        assertNotNull(imgRed.getRenderedImage());
+        if (DEBUG_TARGET_DIR != null) {
+            ImageWriterUtil.saveAsPNG(imgRed.getRenderedImage(),
+                    (int)userAgent.getTargetResolution(),
+                    new File(DEBUG_TARGET_DIR, "circles.svg.png"));
+        }
+        assertEquals(1418, imgRed.getRenderedImage().getWidth());
+        assertEquals(1418, imgRed.getRenderedImage().getHeight());
+        info = imgRed.getInfo(); //Switch to the ImageInfo returned by the image
+        assertEquals(340158, info.getSize().getWidthMpt());
+        assertEquals(340158, info.getSize().getHeightMpt());
+    }
+
     public void testWMF() throws Exception {
         String uri = "test/resources/images/testChart.wmf";
 
index 9ef4150b5a520d3d118c8a92999ff31886dce951..cc5bcd3c88ccbb8c33dc7636526980cb94521702 100644 (file)
@@ -20,8 +20,7 @@
   <info>
     <p>
       This test checks Bugzilla #44412 where a break-before on the first child of an otherwise
-      empty block is set. It is expected that the parent block creates two areas, the first with
-      only border-before on the first page and zero bpd.
+      empty block is set.
     </p>
   </info>
   <fo>
     </fo:root>
   </fo>
   <checks>
-    <eval expected="2" xpath="count(//block[@prod-id = 'b1'])"/>
-    <eval expected="4000 4000 4000 0" xpath="(//block[@prod-id = 'b1'])[1]/@bap"/>
-    <eval expected="4000 4000 0 4000" xpath="(//block[@prod-id = 'b1'])[2]/@bap"/>
-    <eval expected="0" xpath="(//block[@prod-id = 'b1'])[1]/@bpd"/>
-    <eval expected="43200" xpath="(//block[@prod-id = 'b1'])[2]/@bpd"/>
+    <eval expected="1" xpath="count(//block[@prod-id = 'b1'])"/>
+    <eval expected="4000 4000 4000 4000" xpath="(//block[@prod-id = 'b1'])[1]/@bap"/>
+    <eval expected="43200" xpath="(//block[@prod-id = 'b1'])[1]/@bpd"/>
     
     <element-list category="breaker" index="0">
       <box w="14400"/>
-      <penalty w="0" p="0"/>
-      <box w="0" aux="true"/>
-      <penalty w="0" p="INF"/>
-      <glue w="4000"/> <!-- border-before -->
-      <box w="0"/> <!-- first block area of the "b1" block with zero bpd -->
-      
       <skip>3</skip>
     </element-list>
   </checks>
diff --git a/test/layoutengine/standard-testcases/block_break-before_bug44412_2.xml b/test/layoutengine/standard-testcases/block_break-before_bug44412_2.xml
new file mode 100644 (file)
index 0000000..3f54f80
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks for the correct behaviour of multiple breaks at the same break possibility.
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="page" page-height="5in" page-width="5in" margin="20pt">
+          <fo:region-body/>
+          <fo:region-after extent="1.2em"/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="page" id="ps1" initial-page-number="1" force-page-count="no-force">
+        <fo:static-content flow-name="xsl-region-after">
+          <fo:block>page: <fo:page-number/></fo:block>
+        </fo:static-content>
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block id="b1">Before the break</fo:block>
+          <fo:block break-before="page" break-after="column">
+            <fo:block id="b2" break-before="page">
+              This text should be on page 2.
+            </fo:block>
+            <fo:block>
+              <fo:block id="b3" break-after="page">
+                Inner block with break-after.
+              </fo:block>
+            </fo:block>  
+          </fo:block>
+          <fo:block id="b4">This text should be on page 3.</fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+      <fo:page-sequence master-reference="page" id="ps2" initial-page-number="1" force-page-count="no-force">
+        <fo:static-content flow-name="xsl-region-after">
+          <fo:block>page: <fo:page-number/></fo:block>
+        </fo:static-content>
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block id="b11">Before the break</fo:block>
+          <fo:block-container break-before="page" break-after="column">
+            <fo:block-container break-before="page">
+              <fo:block id="b12">This text should be on page 2.</fo:block>
+            </fo:block-container>
+            <fo:block>
+              <fo:block id="b13" break-after="page">
+                Inner block with break-after.
+              </fo:block>
+            </fo:block>  
+          </fo:block-container>
+          <fo:block id="b14">This text should be on page 3.</fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+      <fo:page-sequence master-reference="page" id="ps3" initial-page-number="1" force-page-count="no-force">
+        <fo:static-content flow-name="xsl-region-after">
+          <fo:block>page: <fo:page-number/></fo:block>
+        </fo:static-content>
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block id="b21">Before the break</fo:block>
+          <fo:block break-before="page" break-after="column">
+            <fo:table table-layout="fixed" width="100%" break-before="page">
+              <fo:table-column column-width="proportional-column-width(1)"/>
+              <fo:table-body>
+                <fo:table-row>
+                  <fo:table-cell>
+                    <fo:block id="b22">This text should be on page 2.</fo:block>
+                  </fo:table-cell>
+                </fo:table-row>
+              </fo:table-body>
+            </fo:table>
+            <fo:block>
+              <fo:table table-layout="fixed" width="100%" break-after="page">
+                <fo:table-column column-width="proportional-column-width(1)"/>
+                <fo:table-body>
+                  <fo:table-row>
+                    <fo:table-cell>
+                      <fo:block id="b23">Inner block in table with break-after.</fo:block>
+                    </fo:table-cell>
+                  </fo:table-row>
+                </fo:table-body>
+              </fo:table>
+            </fo:block>  
+          </fo:block>
+          <fo:block id="b24">This text should be on page 3.</fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+      <fo:page-sequence master-reference="page" id="ps4" initial-page-number="1" force-page-count="no-force">
+        <fo:static-content flow-name="xsl-region-after">
+          <fo:block>page: <fo:page-number/></fo:block>
+        </fo:static-content>
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block id="b31">Before the break</fo:block>
+          <fo:block break-before="page" break-after="column">
+            <fo:list-block break-before="page">
+              <fo:list-item>
+                <fo:list-item-label end-indent="label-end()">
+                  <fo:block>+</fo:block>
+                </fo:list-item-label>
+                <fo:list-item-body start-indent="body-start()">
+                  <fo:block id="b32">This text should be on page 2.</fo:block>
+                </fo:list-item-body>
+              </fo:list-item>
+              <fo:list-item break-after="page">
+                <fo:list-item-label end-indent="label-end()">
+                  <fo:block>+</fo:block>
+                </fo:list-item-label>
+                <fo:list-item-body start-indent="body-start()">
+                  <fo:block id="b33">Inner block in list-item with break-after.</fo:block>
+                </fo:list-item-body>
+              </fo:list-item>
+            </fo:list-block>
+          </fo:block>
+          <fo:block id="b34">This text should be on page 3.</fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="1" xpath="//block[@prod-id = 'b1']/ancestor::pageViewport/@nr"/>
+    <eval expected="2" xpath="//block[@prod-id = 'b2']/ancestor::pageViewport/@nr"/>
+    <eval expected="2" xpath="//block[@prod-id = 'b3']/ancestor::pageViewport/@nr"/>
+    <eval expected="3" xpath="//block[@prod-id = 'b4']/ancestor::pageViewport/@nr"/>
+
+    <eval expected="1" xpath="//block[@prod-id = 'b11']/ancestor::pageViewport/@nr"/>
+    <eval expected="2" xpath="//block[@prod-id = 'b12']/ancestor::pageViewport/@nr"/>
+    <eval expected="2" xpath="//block[@prod-id = 'b13']/ancestor::pageViewport/@nr"/>
+    <eval expected="3" xpath="//block[@prod-id = 'b14']/ancestor::pageViewport/@nr"/>
+
+    <eval expected="1" xpath="//block[@prod-id = 'b21']/ancestor::pageViewport/@nr"/>
+    <eval expected="2" xpath="//block[@prod-id = 'b22']/ancestor::pageViewport/@nr"/>
+    <eval expected="2" xpath="//block[@prod-id = 'b23']/ancestor::pageViewport/@nr"/>
+    <eval expected="3" xpath="//block[@prod-id = 'b24']/ancestor::pageViewport/@nr"/>
+  </checks>
+</testcase>
diff --git a/test/resources/images/circles.svg b/test/resources/images/circles.svg
new file mode 100644 (file)
index 0000000..8b71e82
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12cm" height="12cm">
+  <g style="fill-opacity:0.7; stroke:black; stroke-width:0.1cm;">
+    <circle cx="6cm" cy="2cm" r="100" style="fill:red;" transform="translate(0,50)" />
+    <circle cx="6cm" cy="2cm" r="100" style="fill:blue;" transform="translate(70,150)" />
+    <circle cx="6cm" cy="2cm" r="100" style="fill:green;" transform="translate(-70,150)"/>
+  </g>
+</svg>
\ No newline at end of file