From 178483e30913d2065d5f7a154932b2870a83081e Mon Sep 17 00:00:00 2001
From: Jeremias Maerki _h_+~*YmoPh{4
zNP$m!qZs6ErVK$L@K6ju!wpn^w;jcy(DYP)w_k`u13T0}Clnx!E0H{LlvW)SG%`>F
zPu<~3n!l~!J_?Y6GnwH#!l0c5paIu3ht7%
- Apache Ant must be installed in order to
+ Apache Ant (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
instructions to install Ant in the Ant manual on the web.
+ These are some known restrictions compared to other supported output formats (not a complete list):
+
+ 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.
+ This section lists other known issues.
- Apache Ant must be installed in order to
+ Apache Ant (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
instructions to install Ant in the Ant manual on the web.
+ These are some known restrictions compared to other supported output formats (not a complete list):
+ 6@sm!Ag?3jyKVD5z;k$uAZ_!
z9hAy-ov~N7MZ>N9;=Eqx=B9asok%(Z8{Hb7#wPEny&q2+cy7!jom9!ic8f#B_}vxW
z_|?&>)#2G7nO~?qkJc5tiQ=M(xuO2T_x*8ly=zRyG2S_MmvhRe^7OVehlm>~T&%UN
zFOj;`GI>?gs~8Ga(pwOSI$hY87dzlL8kw*k-n&23SGM+mdRs$@b2upC)el-rVctXv
z9#GI=l=$7ut7&*K66|%;yL$4Dtn3eLlHJ;6e6G^0KfEOcU@&joXEF{P7oqSIdqk=!
z?oKZCvBo~u*vA_CSYsb+>|>36tg(+Z_OZr3*4W1y`&eTiYwTl<{V$D;&HaC`v625b
zjSa_f`>|JB?le3z<^&iKPXGI&0tUnXqy6Vo5XOY~*Z
+
+
+
+
+
+
+ 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. +
+fo:block object
.
*/
-public class Block extends FObjMixed {
+public class Block extends FObjMixed implements BreakPropertySet {
// used for FO validation
private boolean blockOrInlineItemFound = false;
diff --git a/src/java/org/apache/fop/fo/flow/BlockContainer.java b/src/java/org/apache/fop/fo/flow/BlockContainer.java
index 25b3f2a2a..b0bfb3a32 100644
--- a/src/java/org/apache/fop/fo/flow/BlockContainer.java
+++ b/src/java/org/apache/fop/fo/flow/BlockContainer.java
@@ -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
* fo:block-container
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;
diff --git a/src/java/org/apache/fop/fo/flow/ListBlock.java b/src/java/org/apache/fop/fo/flow/ListBlock.java
index dfadc9c02..8f72ded67 100644
--- a/src/java/org/apache/fop/fo/flow/ListBlock.java
+++ b/src/java/org/apache/fop/fo/flow/ListBlock.java
@@ -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
* fo:list-block
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;
diff --git a/src/java/org/apache/fop/fo/flow/ListItem.java b/src/java/org/apache/fop/fo/flow/ListItem.java
index 95760c00b..f748bc15a 100644
--- a/src/java/org/apache/fop/fo/flow/ListItem.java
+++ b/src/java/org/apache/fop/fo/flow/ListItem.java
@@ -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
* fo:list-item
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;
diff --git a/src/java/org/apache/fop/fo/flow/table/Table.java b/src/java/org/apache/fop/fo/flow/table/Table.java
index efd1f1c93..86196cb29 100644
--- a/src/java/org/apache/fop/fo/flow/table/Table.java
+++ b/src/java/org/apache/fop/fo/flow/table/Table.java
@@ -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
* fo:table
object.
*/
-public class Table extends TableFObj implements ColumnNumberManagerHolder {
+public class Table extends TableFObj implements ColumnNumberManagerHolder, BreakPropertySet {
/** properties */
private CommonBorderPaddingBackground commonBorderPaddingBackground;
diff --git a/src/java/org/apache/fop/fo/flow/table/TableAndCaption.java b/src/java/org/apache/fop/fo/flow/table/TableAndCaption.java
index 548a9c4fa..919e73bfb 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableAndCaption.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableAndCaption.java
@@ -32,7 +32,7 @@ import org.apache.fop.fo.ValidationException;
* fo:table-and-caption
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;
diff --git a/src/java/org/apache/fop/fo/flow/table/TableRow.java b/src/java/org/apache/fop/fo/flow/table/TableRow.java
index 4d11f8780..a40b550bc 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableRow.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableRow.java
@@ -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
* fo:table-row
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
index 000000000..2babe0f19
--- /dev/null
+++ b/src/java/org/apache/fop/fo/properties/BreakPropertySet.java
@@ -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();
+
+}
diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java
index 4843b308a..f25ca4e7e 100644
--- a/src/java/org/apache/fop/fonts/MultiByteFont.java
+++ b/src/java/org/apache/fop/fonts/MultiByteFont.java
@@ -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");
diff --git a/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java b/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java
index 8ad9fea44..6c43e4878 100644
--- a/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java
+++ b/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java
@@ -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();
diff --git a/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java b/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java
index ce6cde9d9..916b80d02 100644
--- a/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java
+++ b/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java
@@ -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;
+ }
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
index 17eb44049..b6dd4d082 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
@@ -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);
diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
index 1d6662cb2..8837b1a0f 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
@@ -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
diff --git a/src/java/org/apache/fop/layoutmgr/LayoutContext.java b/src/java/org/apache/fop/layoutmgr/LayoutContext.java
index 1be89304b..8b716dfde 100644
--- a/src/java/org/apache/fop/layoutmgr/LayoutContext.java
+++ b/src/java/org/apache/fop/layoutmgr/LayoutContext.java
@@ -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()
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
index f027922f7..d83cca642 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
@@ -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;
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java b/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
index c32c6eb3d..c1fc19050 100644
--- a/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
+++ b/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
@@ -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.");
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
index 143c63bb9..dc2b3cc46 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
@@ -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);
diff --git a/src/java/org/apache/fop/pdf/PDFNumber.java b/src/java/org/apache/fop/pdf/PDFNumber.java
index 55834f529..c2fc704da 100644
--- a/src/java/org/apache/fop/pdf/PDFNumber.java
+++ b/src/java/org/apache/fop/pdf/PDFNumber.java
@@ -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(
diff --git a/src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java b/src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java
index 7c4d66689..e3f510853 100644
--- a/src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java
+++ b/src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java
@@ -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);
}
/**
diff --git a/src/java/org/apache/fop/render/awt/viewer/PreviewPanel.java b/src/java/org/apache/fop/render/awt/viewer/PreviewPanel.java
index 05e03fda0..f8152a978 100644
--- a/src/java/org/apache/fop/render/awt/viewer/PreviewPanel.java
+++ b/src/java/org/apache/fop/render/awt/viewer/PreviewPanel.java
@@ -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);
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java b/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java
index b61ebc346..f05a16f1a 100644
--- a/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java
+++ b/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java
@@ -115,7 +115,6 @@ public class PDFGraphics2DAdapter extends AbstractGraphics2DAdapter {
pdfInfo.currentStream.add(graphics.getString());
renderer.restoreGraphicsState();
- pdfInfo.pdfState.pop();
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/rtf/BorderAttributesConverter.java b/src/java/org/apache/fop/render/rtf/BorderAttributesConverter.java
index 216802c8f..10c4a9c92 100644
--- a/src/java/org/apache/fop/render/rtf/BorderAttributesConverter.java
+++ b/src/java/org/apache/fop/render/rtf/BorderAttributesConverter.java
@@ -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);
+ }
}
}
}
diff --git a/src/java/org/apache/fop/render/rtf/FoUnitsConverter.java b/src/java/org/apache/fop/render/rtf/FoUnitsConverter.java
index caf11323f..33a2ff904 100644
--- a/src/java/org/apache/fop/render/rtf/FoUnitsConverter.java
+++ b/src/java/org/apache/fop/render/rtf/FoUnitsConverter.java
@@ -19,10 +19,9 @@
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;
+ }
}
diff --git a/src/java/org/apache/fop/render/rtf/PageAttributesConverter.java b/src/java/org/apache/fop/render/rtf/PageAttributesConverter.java
index c7f97ef4f..d50a81656 100644
--- a/src/java/org/apache/fop/render/rtf/PageAttributesConverter.java
+++ b/src/java/org/apache/fop/render/rtf/PageAttributesConverter.java
@@ -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");
diff --git a/src/java/org/apache/fop/render/rtf/RTFHandler.java b/src/java/org/apache/fop/render/rtf/RTFHandler.java
index 1adba9e2b..65c7bf681 100644
--- a/src/java/org/apache/fop/render/rtf/RTFHandler.java
+++ b/src/java/org/apache/fop/render/rtf/RTFHandler.java
@@ -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(
diff --git a/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java b/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java
index 792193b15..63c470b5d 100644
--- a/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java
+++ b/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java
@@ -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()));
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfAttributes.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfAttributes.java
index 2eb95b587..5ec5e907e 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfAttributes.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfAttributes.java
@@ -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
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java
index 182894ea5..6123ac563 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java
@@ -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
index 000000000..b3f11bc0a
--- /dev/null
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfLeader.java
@@ -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 + Besides the important changes listed below, the most important areas with + improvements in this release are: +
++ Please note that with this release, we've dropped support for Java 1.3. + FOP will, from now on, require at least Java 1.4. +
++ There have been a few changes in tables that make FOP both more strict and more + compliant to the Recommendation: +
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.
+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.
++ 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 + JAI Image I/O Tools + (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. +
+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.
+ This test checks for the correct behaviour of multiple breaks at the same break possibility. +
+