aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org/apache/fop')
-rw-r--r--src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java13
-rw-r--r--src/java/org/apache/fop/afp/AFPEventProducer.java9
-rw-r--r--src/java/org/apache/fop/afp/AFPEventProducer.xml1
-rw-r--r--src/java/org/apache/fop/afp/AFPGraphics2D.java4
-rw-r--r--src/java/org/apache/fop/afp/AFPResourceLevel.java7
-rw-r--r--src/java/org/apache/fop/afp/AFPResourceManager.java4
-rw-r--r--src/java/org/apache/fop/afp/AFPStreamer.java4
-rw-r--r--src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java13
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSet.java8
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java25
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java40
-rw-r--r--src/java/org/apache/fop/afp/fonts/DoubleByteFont.java32
-rw-r--r--src/java/org/apache/fop/afp/fonts/OutlineFont.java8
-rw-r--r--src/java/org/apache/fop/afp/modca/IncludedResourceObject.java2
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPGraphicsConfiguration.java152
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPGraphicsDevice.java80
-rw-r--r--src/java/org/apache/fop/afp/util/AFPResourceAccessor.java86
-rw-r--r--src/java/org/apache/fop/apps/FOUserAgent.java7
-rw-r--r--src/java/org/apache/fop/apps/Fop.java6
-rw-r--r--src/java/org/apache/fop/apps/FopConfParser.java14
-rw-r--r--src/java/org/apache/fop/apps/FopFactory.java72
-rw-r--r--src/java/org/apache/fop/apps/FopFactoryBuilder.java25
-rw-r--r--src/java/org/apache/fop/apps/FopFactoryConfig.java63
-rw-r--r--src/java/org/apache/fop/apps/io/ResourceResolverFactory.java55
-rw-r--r--src/java/org/apache/fop/apps/io/TempResourceResolver.java4
-rw-r--r--src/java/org/apache/fop/cli/CommandLineOptions.java29
-rw-r--r--src/java/org/apache/fop/fonts/DefaultFontConfig.java2
-rw-r--r--src/java/org/apache/fop/fonts/DefaultFontConfigurator.java1
-rw-r--r--src/java/org/apache/fop/fonts/FontCache.java16
-rw-r--r--src/java/org/apache/fop/fonts/FontManager.java4
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractBreaker.java35
-rw-r--r--src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java16
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java6
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java15
-rw-r--r--src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java9
-rw-r--r--src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/KnuthSequence.java51
-rw-r--r--src/java/org/apache/fop/layoutmgr/LayoutContext.java82
-rw-r--r--src/java/org/apache/fop/layoutmgr/PageBreaker.java13
-rw-r--r--src/java/org/apache/fop/layoutmgr/PageProvider.java80
-rw-r--r--src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java17
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java93
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java52
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java7
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java4
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java9
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java8
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java53
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java47
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java6
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java4
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java18
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java33
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java4
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java4
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java15
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java4
-rw-r--r--src/java/org/apache/fop/pdf/PDFArray.java9
-rw-r--r--src/java/org/apache/fop/pdf/PDFDocument.java20
-rw-r--r--src/java/org/apache/fop/pdf/PDFProfile.java3
-rw-r--r--src/java/org/apache/fop/pdf/PDFStructElem.java63
-rw-r--r--src/java/org/apache/fop/pdf/StandardStructureAttributes.java69
-rw-r--r--src/java/org/apache/fop/pdf/StandardStructureTypes.java132
-rw-r--r--src/java/org/apache/fop/pdf/StreamCacheFactory.java1
-rw-r--r--src/java/org/apache/fop/pdf/StructureType.java34
-rw-r--r--src/java/org/apache/fop/pdf/VersionController.java17
-rw-r--r--src/java/org/apache/fop/render/AbstractRendererMaker.java6
-rw-r--r--src/java/org/apache/fop/render/PrintRendererConfigurator.java5
-rw-r--r--src/java/org/apache/fop/render/afp/AFPFontConfig.java7
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFDocumentHandlerConfigurator.java5
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLGraphics2D.java5
-rw-r--r--src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java180
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java2
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererConfig.java2
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java34
-rw-r--r--src/java/org/apache/fop/render/ps/PSRendererOption.java2
-rw-r--r--src/java/org/apache/fop/svg/PDFGraphics2D.java3
-rw-r--r--src/java/org/apache/fop/util/ColorSpaceCache.java6
87 files changed, 1166 insertions, 930 deletions
diff --git a/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java b/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
index 51f7f2bed..7e3ed0591 100644
--- a/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
+++ b/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
@@ -221,14 +221,17 @@ class StructureTreeEventTrigger extends FOEventHandler {
@Override
public void startCell(TableCell tc) {
AttributesImpl attributes = new AttributesImpl();
- int colSpan = tc.getNumberColumnsSpanned();
- if (colSpan > 1) {
- addNoNamespaceAttribute(attributes, "number-columns-spanned",
- Integer.toString(colSpan));
- }
+ addSpanAttribute(attributes, "number-columns-spanned", tc.getNumberColumnsSpanned());
+ addSpanAttribute(attributes, "number-rows-spanned", tc.getNumberRowsSpanned());
startElement(tc, attributes);
}
+ private void addSpanAttribute(AttributesImpl attributes, String attributeName, int span) {
+ if (span > 1) {
+ addNoNamespaceAttribute(attributes, attributeName, Integer.toString(span));
+ }
+ }
+
@Override
public void endCell(TableCell tc) {
endElement(tc);
diff --git a/src/java/org/apache/fop/afp/AFPEventProducer.java b/src/java/org/apache/fop/afp/AFPEventProducer.java
index 93eb9c042..01d5c4ad7 100644
--- a/src/java/org/apache/fop/afp/AFPEventProducer.java
+++ b/src/java/org/apache/fop/afp/AFPEventProducer.java
@@ -113,4 +113,13 @@ public interface AFPEventProducer extends EventProducer {
* @event.severity ERROR
*/
void invalidConfiguration(Object source, Exception e);
+
+ /**
+ * The characterset is missing metric information for the specified character
+ * @param source the event source
+ * @param character the character with missing metric information.
+ * @param charSet the character set containing missing metric information
+ * @event.severity WARN
+ */
+ void charactersetMissingMetrics(Object source, char character, String charSet);
}
diff --git a/src/java/org/apache/fop/afp/AFPEventProducer.xml b/src/java/org/apache/fop/afp/AFPEventProducer.xml
index 042eb5ed8..e17a4ea40 100644
--- a/src/java/org/apache/fop/afp/AFPEventProducer.xml
+++ b/src/java/org/apache/fop/afp/AFPEventProducer.xml
@@ -8,4 +8,5 @@
<message key="fontConfigMissing">The mandatory configuation node: '{missingConfig}' was not found at {location}.</message>
<message key="characterSetNameInvalid">The character set given has an invalid name. [ Reason: {msg} ]</message>
<message key="codePageNotFound">The code page for an AFP font cannot be found.[ Reason: {e}]</message>
+ <message key="charactersetMissingMetrics">Metric information is missing for the glyph `{character}` in the characterset `{charSet}`. Using space increment width.</message>
</catalogue>
diff --git a/src/java/org/apache/fop/afp/AFPGraphics2D.java b/src/java/org/apache/fop/afp/AFPGraphics2D.java
index 7172b0ee3..937cf68b0 100644
--- a/src/java/org/apache/fop/afp/AFPGraphics2D.java
+++ b/src/java/org/apache/fop/afp/AFPGraphics2D.java
@@ -52,13 +52,13 @@ import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
import org.apache.xmlgraphics.java2d.GraphicContext;
+import org.apache.xmlgraphics.java2d.GraphicsConfigurationWithTransparency;
import org.apache.xmlgraphics.java2d.StrokingTextHandler;
import org.apache.xmlgraphics.java2d.TextHandler;
import org.apache.xmlgraphics.util.UnitConv;
import org.apache.fop.afp.goca.GraphicsSetLineType;
import org.apache.fop.afp.modca.GraphicsObject;
-import org.apache.fop.afp.svg.AFPGraphicsConfiguration;
import org.apache.fop.afp.util.CubicBezierApproximator;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.render.afp.AFPImageHandlerRenderedImage;
@@ -111,7 +111,7 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand
private AFPPaintingState paintingState = null;
/** AFP graphics configuration */
- private final AFPGraphicsConfiguration graphicsConfig = new AFPGraphicsConfiguration();
+ private final GraphicsConfigurationWithTransparency graphicsConfig = new GraphicsConfigurationWithTransparency();
/** The AFP FontInfo */
private FontInfo fontInfo;
diff --git a/src/java/org/apache/fop/afp/AFPResourceLevel.java b/src/java/org/apache/fop/afp/AFPResourceLevel.java
index 860ca3d26..d56763050 100644
--- a/src/java/org/apache/fop/afp/AFPResourceLevel.java
+++ b/src/java/org/apache/fop/afp/AFPResourceLevel.java
@@ -66,9 +66,8 @@ public class AFPResourceLevel {
}
}
- /** the external resource group file path */
private URI extUri = null;
- private ResourceType resourceType;
+ private final ResourceType resourceType;
/**
* Sets the resource placement level within the AFP output
@@ -84,7 +83,7 @@ public class AFPResourceLevel {
/**
* Main constructor
*
- * @param level the resource level
+ * @param resourceType the resource type
*/
public AFPResourceLevel(ResourceType resourceType) {
this.resourceType = resourceType;
@@ -156,7 +155,7 @@ public class AFPResourceLevel {
/**
* Sets the URI of the external resource group.
*
- * @param filePath the URI of the external resource group
+ * @param uri the URI of the external resource group
*/
public void setExternalUri(URI uri) {
this.extUri = uri;
diff --git a/src/java/org/apache/fop/afp/AFPResourceManager.java b/src/java/org/apache/fop/afp/AFPResourceManager.java
index 885e13e5b..e9c8eda67 100644
--- a/src/java/org/apache/fop/afp/AFPResourceManager.java
+++ b/src/java/org/apache/fop/afp/AFPResourceManager.java
@@ -115,9 +115,9 @@ public class AFPResourceManager {
}
/**
- * Sets the default resource group file path
+ * Sets the default resource group URI.
*
- * @param filePath the default resource group file path
+ * @param uri the default resource group URI
*/
public void setDefaultResourceGroupUri(URI uri) {
diff --git a/src/java/org/apache/fop/afp/AFPStreamer.java b/src/java/org/apache/fop/afp/AFPStreamer.java
index 072dc1796..fb2b282f6 100644
--- a/src/java/org/apache/fop/afp/AFPStreamer.java
+++ b/src/java/org/apache/fop/afp/AFPStreamer.java
@@ -99,9 +99,9 @@ public class AFPStreamer implements Streamable {
}
/**
- * Sets the default resource group file path
+ * Sets the default resource group URI.
*
- * @param filePath the default resource group file path
+ * @param uri the default resource group URI
*/
public void setDefaultResourceGroupUri(URI uri) {
this.defaultResourceGroupUri = uri;
diff --git a/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java b/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
index 1a2611d8d..7b57a2b8c 100644
--- a/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
+++ b/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
@@ -19,6 +19,8 @@
package org.apache.fop.afp.fonts;
+import org.apache.fop.afp.AFPEventProducer;
+
/**
* A font defined as a set of lines and curves as opposed to a bitmap font. An
* outline font can be scaled to any size and otherwise transformed more easily
@@ -29,16 +31,25 @@ public abstract class AbstractOutlineFont extends AFPFont {
/** The character set for this font */
protected CharacterSet charSet = null;
+ private final AFPEventProducer eventProducer;
+
/**
* Constructor for an outline font.
*
* @param name the name of the font
* @param embeddable sets whether or not this font is to be embedded
* @param charSet the chracter set
+ * @param eventProducer The object to handle any events which occur from the object.
*/
- public AbstractOutlineFont(String name, boolean embeddable, CharacterSet charSet) {
+ public AbstractOutlineFont(String name, boolean embeddable, CharacterSet charSet,
+ AFPEventProducer eventProducer) {
super(name, embeddable);
this.charSet = charSet;
+ this.eventProducer = eventProducer;
+ }
+
+ AFPEventProducer getAFPEventProducer() {
+ return eventProducer;
}
/**
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSet.java b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
index 49e7f99ba..d54d478bc 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSet.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
@@ -363,4 +363,12 @@ public class CharacterSet {
return getCharacterSetOrientation().getEmSpaceIncrement();
}
+ /**
+ * Returns the nominal character increment.
+ * @return the nominal character increment
+ */
+ public int getNominalCharIncrement() {
+ return getCharacterSetOrientation().getNominalCharIncrement();
+ }
+
}
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
index 7331178f5..2565942b5 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
@@ -236,9 +236,9 @@ public abstract class CharacterSetBuilder {
CharacterSetType charsetType, AFPResourceAccessor accessor, AFPEventProducer eventProducer)
throws IOException {
// check for cached version of the characterset
- String descriptor = characterSetName + "_" + encoding + "_" + codePageName;
- CharacterSet characterSet = (CharacterSet) characterSetsCache.get(descriptor);
-
+ URI charSetURI = accessor.resolveURI(characterSetName);
+ String cacheKey = charSetURI.toASCIIString() + "_" + characterSetName + "_" + codePageName;
+ CharacterSet characterSet = (CharacterSet) characterSetsCache.get(cacheKey);
if (characterSet != null) {
return characterSet;
}
@@ -257,6 +257,8 @@ public abstract class CharacterSetBuilder {
* chracter global identifier.
*/
Map<String, String> codePage;
+ // TODO: This could have performance implications if several threads want to use the
+ // codePagesCache to retrieve different codepages.
synchronized (codePagesCache) {
codePage = codePagesCache.get(codePageName);
@@ -308,7 +310,7 @@ public abstract class CharacterSetBuilder {
} finally {
closeInputStream(inputStream);
}
- characterSetsCache.put(descriptor, characterSet);
+ characterSetsCache.put(cacheKey, characterSet);
return characterSet;
}
@@ -446,20 +448,15 @@ public abstract class CharacterSetBuilder {
position++;
if (position == 26) {
-
position = 0;
int orientation = determineOrientation(fnoData[2]);
- // Space Increment
- int space = ((fnoData[8] & 0xFF ) << 8) + (fnoData[9] & 0xFF);
- // Em-Space Increment
- int em = ((fnoData[14] & 0xFF ) << 8) + (fnoData[15] & 0xFF);
-
- CharacterSetOrientation cso = new CharacterSetOrientation(orientation);
- cso.setSpaceIncrement(space);
- cso.setEmSpaceIncrement(em);
- orientations.add(cso);
+ int spaceIncrement = getUBIN(fnoData, 8);
+ int emIncrement = getUBIN(fnoData, 14);
+ int nominalCharacterIncrement = getUBIN(fnoData, 20);
+ orientations.add(new CharacterSetOrientation(orientation, spaceIncrement,
+ emIncrement, nominalCharacterIncrement));
}
}
return orientations.toArray(EMPTY_CSO_ARRAY);
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java b/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
index 7ac8ae96b..a730525d2 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
@@ -60,7 +60,7 @@ public class CharacterSetOrientation {
/**
* The character widths in the character set (indexed using Unicode codepoints)
*/
- private int[] charsWidths = null;
+ private int[] charsWidths;
/**
* The height of lowercase letters
@@ -77,25 +77,26 @@ public class CharacterSetOrientation {
*/
private char lastChar;
-
- /**
- * The character set orientation
- */
- private int orientation = 0;
-
+ /** The character set orientation */
+ private final int orientation;
/** space increment */
- private int spaceIncrement;
+ private final int spaceIncrement;
/** em space increment */
- private int emSpaceIncrement = -1;
-
+ private final int emSpaceIncrement;
+ /** Nominal Character Increment */
+ private final int nomCharIncrement;
/**
* Constructor for the CharacterSetOrientation, the orientation is
* expressed as the degrees rotation (i.e 0, 90, 180, 270)
* @param orientation the character set orientation
*/
- public CharacterSetOrientation(int orientation) {
+ public CharacterSetOrientation(int orientation, int spaceIncrement, int emSpaceIncrement,
+ int nomCharIncrement) {
this.orientation = orientation;
+ this.spaceIncrement = spaceIncrement;
+ this.emSpaceIncrement = emSpaceIncrement;
+ this.nomCharIncrement = nomCharIncrement;
charsWidths = new int[256];
Arrays.fill(charsWidths, -1);
}
@@ -284,14 +285,6 @@ public class CharacterSetOrientation {
}
/**
- * Sets the space increment.
- * @param value the space increment
- */
- public void setSpaceIncrement(int value) {
- this.spaceIncrement = value;
- }
-
- /**
* Returns the em space increment.
* @return the em space increment
*/
@@ -300,11 +293,10 @@ public class CharacterSetOrientation {
}
/**
- * Sets the em space increment.
- * @param value the em space increment
+ * Returns the nominal character increment.
+ * @return the nominal character increment
*/
- public void setEmSpaceIncrement(int value) {
- this.emSpaceIncrement = value;
+ public int getNominalCharIncrement() {
+ return this.nomCharIncrement;
}
-
}
diff --git a/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java b/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
index a81805bc5..78da6ea82 100644
--- a/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
+++ b/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
@@ -23,6 +23,11 @@ import java.lang.Character.UnicodeBlock;
import java.util.HashSet;
import java.util.Set;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.afp.AFPEventProducer;
+
/**
* Implementation of AbstractOutlineFont that supports double-byte fonts (CID Keyed font (Type 0)).
* The width of characters that are not prescribed a width metrics in the font resource use
@@ -31,7 +36,9 @@ import java.util.Set;
*/
public class DoubleByteFont extends AbstractOutlineFont {
- //private static final Log LOG = LogFactory.getLog(DoubleByteFont.class);
+ private static final Log log = LogFactory.getLog(DoubleByteFont.class);
+
+ private final Set<Integer> charsProcessed;
//See also http://unicode.org/reports/tr11/ which we've not closely looked at, yet
//TODO the Unicode block listed here is probably not complete (ex. Hiragana, Katakana etc.)
@@ -49,9 +56,12 @@ public class DoubleByteFont extends AbstractOutlineFont {
* @param name the name of the font
* @param embeddable whether or not this font is embeddable
* @param charSet the character set
+ * @param eventProducer Handles any AFP related events
*/
- public DoubleByteFont(String name, boolean embeddable, CharacterSet charSet) {
- super(name, embeddable, charSet);
+ public DoubleByteFont(String name, boolean embeddable, CharacterSet charSet,
+ AFPEventProducer eventProducer) {
+ super(name, embeddable, charSet, eventProducer);
+ charsProcessed = new HashSet<Integer>();
}
/** {@inheritDoc} */
@@ -60,16 +70,30 @@ public class DoubleByteFont extends AbstractOutlineFont {
try {
charWidth = charSet.getWidth(toUnicodeCodepoint(character));
} catch (IllegalArgumentException e) {
+ if (!charsProcessed.contains(character)) {
+ charsProcessed.add(character);
+ getAFPEventProducer().charactersetMissingMetrics(this, (char)character,
+ charSet.getName().trim());
+ }
// We shall try and handle characters that have no mapped width metric in font resource
charWidth = -1;
}
if (charWidth == -1) {
- charWidth = inferCharWidth(character);
+ charWidth = getDefaultCharacterWidth(character);
}
return charWidth * size;
}
+ private int getDefaultCharacterWidth(int character) {
+ int nominalCharIncrement = charSet.getNominalCharIncrement();
+ if (nominalCharIncrement > 0) {
+ return nominalCharIncrement;
+ } else {
+ return inferCharWidth(character);
+ }
+ }
+
private int inferCharWidth(int character) {
//Is this character an ideograph?
diff --git a/src/java/org/apache/fop/afp/fonts/OutlineFont.java b/src/java/org/apache/fop/afp/fonts/OutlineFont.java
index 103d96eca..e9cdf5ba4 100644
--- a/src/java/org/apache/fop/afp/fonts/OutlineFont.java
+++ b/src/java/org/apache/fop/afp/fonts/OutlineFont.java
@@ -19,6 +19,8 @@
package org.apache.fop.afp.fonts;
+import org.apache.fop.afp.AFPEventProducer;
+
/**
* Default implementation of AbstractOutlineFont.
*/
@@ -29,9 +31,11 @@ public class OutlineFont extends AbstractOutlineFont {
* @param name font's name
* @param embeddable whether or not this font is embeddable
* @param charSet font's character set
+ * @param eventProducer Handles any AFP related events
*/
- public OutlineFont(String name, boolean embeddable, CharacterSet charSet) {
- super(name, embeddable, charSet);
+ public OutlineFont(String name, boolean embeddable, CharacterSet charSet,
+ AFPEventProducer eventProducer) {
+ super(name, embeddable, charSet, eventProducer);
}
}
diff --git a/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java b/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java
index 9ab84a640..8bfcf4624 100644
--- a/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java
+++ b/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java
@@ -34,7 +34,7 @@ import org.apache.fop.afp.util.AFPResourceUtil;
*/
public class IncludedResourceObject extends AbstractNamedAFPObject {
- private AFPResourceAccessor resourceAccessor;
+ private final AFPResourceAccessor resourceAccessor;
private URI uri;
/**
diff --git a/src/java/org/apache/fop/afp/svg/AFPGraphicsConfiguration.java b/src/java/org/apache/fop/afp/svg/AFPGraphicsConfiguration.java
deleted file mode 100644
index 0a051e675..000000000
--- a/src/java/org/apache/fop/afp/svg/AFPGraphicsConfiguration.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.afp.svg;
-
-import java.awt.GraphicsDevice;
-import java.awt.Rectangle;
-import java.awt.Transparency;
-import java.awt.geom.AffineTransform;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.svg.GraphicsConfiguration;
-
-/**
- * Our implementation of the class that returns information about
- * roughly what we can handle and want to see (alpha for example).
- */
-public class AFPGraphicsConfiguration extends GraphicsConfiguration {
- // We use this to get a good colormodel..
- private static final BufferedImage BI_WITH_ALPHA
- = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
- // We use this to get a good colormodel..
- private static final BufferedImage BI_WITHOUT_ALPHA
- = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
-
- /**
- * Construct a buffered image with an alpha channel, unless
- * transparencty is OPAQUE (no alpha at all).
- *
- * @param width the width of the image
- * @param height the height of the image
- * @param transparency the alpha value of the image
- * @return the new buffered image
- */
- public BufferedImage createCompatibleImage(int width, int height,
- int transparency) {
- if (transparency == Transparency.OPAQUE) {
- return new BufferedImage(width, height,
- BufferedImage.TYPE_INT_RGB);
- } else {
- return new BufferedImage(width, height,
- BufferedImage.TYPE_INT_ARGB);
- }
- }
-
- /**
- * Construct a buffered image with an alpha channel.
- *
- * @param width the width of the image
- * @param height the height of the image
- * @return the new buffered image
- */
- public BufferedImage createCompatibleImage(int width, int height) {
- return new BufferedImage(width, height,
- BufferedImage.TYPE_INT_ARGB);
- }
-
- /**
- * TODO: This should return the page bounds in Pts,
- * I couldn't figure out how to get this for the current
- * page (this still works for now,
- * but it should be fixed...).
- *
- * @return the bounds of the page
- */
- public Rectangle getBounds() {
- return null;
- }
-
- /**
- * Return a good default color model for this 'device'.
- * @return the colour model for the configuration
- */
- public ColorModel getColorModel() {
- return BI_WITH_ALPHA.getColorModel();
- }
-
- /**
- * Return a good color model given <code>transparency</code>
- *
- * @param transparency the alpha value for the colour model
- * @return the colour model for the configuration
- */
- public ColorModel getColorModel(int transparency) {
- if (transparency == Transparency.OPAQUE) {
- return BI_WITHOUT_ALPHA.getColorModel();
- } else {
- return BI_WITH_ALPHA.getColorModel();
- }
- }
-
- private static final Log LOG
- = LogFactory.getLog(AFPGraphicsConfiguration.class);
-
- private AffineTransform defaultTransform = null;
- private AffineTransform normalizingTransform = null;
- private final GraphicsDevice graphicsDevice = new AFPGraphicsDevice(this);;
-
- /**
- * The default transform (1:1).
- *
- * @return the default transform for the configuration
- */
- public AffineTransform getDefaultTransform() {
- LOG.debug("getDefaultTransform()");
- if (defaultTransform == null) {
- defaultTransform = new AffineTransform();
- }
- return defaultTransform;
- }
-
- /**
- * The normalizing transform (1:1) (since we currently
- * render images at 72dpi, which we might want to change
- * in the future).
- *
- * @return the normalizing transform for the configuration
- */
- public AffineTransform getNormalizingTransform() {
- LOG.debug("getNormalizingTransform()");
- if (normalizingTransform == null) {
- normalizingTransform = new AffineTransform(2, 0, 0, 2, 0, 0);
- }
- return normalizingTransform;
- }
-
- /** {@inheritDoc} */
- public GraphicsDevice getDevice() {
- LOG.debug("getDevice()");
- return graphicsDevice;
- }
-}
diff --git a/src/java/org/apache/fop/afp/svg/AFPGraphicsDevice.java b/src/java/org/apache/fop/afp/svg/AFPGraphicsDevice.java
deleted file mode 100644
index daa25aaa0..000000000
--- a/src/java/org/apache/fop/afp/svg/AFPGraphicsDevice.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.afp.svg;
-
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsDevice;
-
-/**
- * This implements the GraphicsDevice interface as appropriate for
- * an AFPGraphics2D.
- */
-public class AFPGraphicsDevice extends GraphicsDevice {
-
- /**
- * The Graphics Config that created us...
- */
- protected GraphicsConfiguration gc;
-
- /**
- * Create a new AF{ graphics device.
- *
- * @param gc The graphics configuration we should reference
- */
- public AFPGraphicsDevice(AFPGraphicsConfiguration gc) {
- this.gc = gc;
- }
-
- /**
- * Return an array of our one GraphicsConfig
- *
- * @return an array containing the one graphics configuration
- */
- public GraphicsConfiguration[] getConfigurations() {
- return new GraphicsConfiguration[] {gc};
- }
-
- /**
- * Return out sole GraphicsConfig.
- *
- * @return the graphics configuration that created this object
- */
- public GraphicsConfiguration getDefaultConfiguration() {
- return this.gc;
- }
-
- /**
- * Generate an IdString..
- *
- * @return the ID string for this device, uses toString
- */
- public String getIDstring() {
- return toString();
- }
-
- /**
- * Let the caller know that we are "a printer"
- *
- * @return the type which is always printer
- */
- public int getType() {
- return GraphicsDevice.TYPE_PRINTER;
- }
-}
diff --git a/src/java/org/apache/fop/afp/util/AFPResourceAccessor.java b/src/java/org/apache/fop/afp/util/AFPResourceAccessor.java
index 02691527e..46b09be21 100644
--- a/src/java/org/apache/fop/afp/util/AFPResourceAccessor.java
+++ b/src/java/org/apache/fop/afp/util/AFPResourceAccessor.java
@@ -24,6 +24,9 @@ import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.apache.fop.apps.io.InternalResourceResolver;
/**
@@ -31,46 +34,97 @@ import org.apache.fop.apps.io.InternalResourceResolver;
*/
public final class AFPResourceAccessor {
+ private static final Log log = LogFactory.getLog(AFPResourceAccessor.class);
+
private final InternalResourceResolver resourceResolver;
- private final String baseURI;
+ private final URI baseURI;
+ private final URIResolver uriResolver;
/**
* Constructor for resource to be accessed via the {@link org.apache.fop.apps.FOUserAgent}. This
* contructor takes a base URI for resolving font resource URIs. So, if fonts need to be
- * accessed, you can set the {@link FontManager}'s base URI instead of the one on the
- * {@link org.apache.fop.apps.FopFactory}.
+ * accessed, you can set the {@link org.apache.fop.fonts.FontManager}'s base URI instead of the
+ * one on the {@link org.apache.fop.apps.FopFactory}.
*
- * @param InternalResourceResolver resource resolver
+ * @param resourceResolver the resolver of resources
* @param baseURI the custom base URI to resolve relative URIs against (may be null)
*/
public AFPResourceAccessor(InternalResourceResolver resourceResolver, String baseURI) {
this.resourceResolver = resourceResolver;
- this.baseURI = baseURI;
+ URI actualBaseURI = null;
+ URIResolver uriResolver;
+ if (baseURI == null) {
+ actualBaseURI = null;
+ uriResolver = new NullBaseURIResolver();
+ } else {
+ try {
+ actualBaseURI = InternalResourceResolver.getBaseURI(baseURI);
+ uriResolver = new BaseURIResolver();
+ } catch (URISyntaxException use) {
+ log.error("The URI given \"" + baseURI + "\" is invalid: " + use.getMessage());
+ actualBaseURI = null;
+ uriResolver = new NullBaseURIResolver();
+ }
+ }
+ this.baseURI = actualBaseURI;
+ this.uriResolver = uriResolver;
}
/**
* Constructor for resource to be accessed via the {@link org.apache.fop.apps.FOUserAgent}.
*
- * @param InternalResourceResolver resource resolver
+ * @param resourceResolver the resolver of resources
*/
public AFPResourceAccessor(InternalResourceResolver resourceResolver) {
this(resourceResolver, null);
}
- private URI getResourceURI(URI uri) {
- if (baseURI == null) {
+ /**
+ * Creates an {@link InputStream} given a URI.
+ *
+ * @param uri the URI of the InputStream
+ * @return an InputStream
+ * @throws IOException if an I/O error occurs while creating the InputStream.
+ */
+ public InputStream createInputStream(URI uri) throws IOException {
+ return resourceResolver.getResource(uriResolver.resolveURI(uri));
+ }
+
+ /**
+ * Returns the resolved URI, given the URI of a resource.
+ *
+ * @param uri the resource URI
+ * @return the resolved URI
+ */
+ public URI resolveURI(String uri) {
+ return uriResolver.resolveURI(uri);
+ }
+
+ private interface URIResolver {
+ URI resolveURI(URI uri);
+
+ URI resolveURI(String uri);
+ }
+
+ private final class NullBaseURIResolver implements URIResolver {
+
+ public URI resolveURI(URI uri) {
return uri;
}
- try {
- URI baseURI = InternalResourceResolver.getBaseURI(this.baseURI);
- return baseURI.resolve(uri);
- } catch (URISyntaxException use) {
- return uri;
+
+ public URI resolveURI(String uri) {
+ return URI.create("./" + uri.trim());
}
}
- /** {@inheritDoc} */
- public InputStream createInputStream(URI uri) throws IOException {
- return resourceResolver.getResource(getResourceURI(uri));
+ private final class BaseURIResolver implements URIResolver {
+
+ public URI resolveURI(URI uri) {
+ return baseURI.resolve(uri);
+ }
+
+ public URI resolveURI(String uri) {
+ return baseURI.resolve(uri.trim());
+ }
}
}
diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java
index b4c69c6e3..0ed5b7228 100644
--- a/src/java/org/apache/fop/apps/FOUserAgent.java
+++ b/src/java/org/apache/fop/apps/FOUserAgent.java
@@ -166,7 +166,7 @@ public class FOUserAgent {
* requires an output stream and you want to configure this very rendering run,
* i.e. if you want to set some metadata like the title and author of the document
* you want to render. In that case, create a new {@link FOUserAgent} instance
- * using {@link #newFOUserAgent()}.
+ * using {@link org.apache.fop.apps.FopFactory#newFOUserAgent() newFOUserAgent()}.
* <p>
* MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
* use the constants defined in {@link MimeConstants}.
@@ -184,7 +184,7 @@ public class FOUserAgent {
* Returns a new {@link Fop} instance. Use this factory method if you want to configure this
* very rendering run, i.e. if you want to set some metadata like the title and author of the
* document you want to render. In that case, create a new {@link FOUserAgent}
- * instance using {@link #newFOUserAgent()}.
+ * instance using {@link org.apache.fop.apps.FopFactory#newFOUserAgent() newFOUserAgent()}.
* <p>
* MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
* use the constants defined in {@link MimeConstants}.
@@ -791,9 +791,8 @@ public class FOUserAgent {
return factory.getColorSpaceCache();
}
- /** @see {@link FopFactory#getHyphenationPatternNames()} */
+ /** @see FopFactory#getHyphenationPatternNames() */
public Map<String, String> getHyphenationPatternNames() {
return factory.getHyphenationPatternNames();
}
}
-
diff --git a/src/java/org/apache/fop/apps/Fop.java b/src/java/org/apache/fop/apps/Fop.java
index fc82ac1cb..5e3261221 100644
--- a/src/java/org/apache/fop/apps/Fop.java
+++ b/src/java/org/apache/fop/apps/Fop.java
@@ -52,7 +52,7 @@ public class Fop {
private OutputStream stream = null;
// FOUserAgent object to set processing options
- private FOUserAgent foUserAgent = null;
+ private final FOUserAgent foUserAgent;
// FOTreeBuilder object to maintain reference for access to results
private FOTreeBuilder foTreeBuilder = null;
@@ -81,6 +81,10 @@ public class Fop {
/**
* Get the FOUserAgent instance associated with the rendering run represented by this instance.
* @return the user agent
+ *
+ * @deprecated this getter doesn't need to exist. By virtue of the fact that the client has
+ * an instance of this object, it means they also have the {@link FOUserAgent} since this's
+ * constructor is only used in {@link FOUserAgent}
*/
public FOUserAgent getUserAgent() {
return foUserAgent;
diff --git a/src/java/org/apache/fop/apps/FopConfParser.java b/src/java/org/apache/fop/apps/FopConfParser.java
index bf39a53f0..c6e3dbd19 100644
--- a/src/java/org/apache/fop/apps/FopConfParser.java
+++ b/src/java/org/apache/fop/apps/FopConfParser.java
@@ -142,12 +142,20 @@ public class FopConfParser {
log.debug("Initializing FopFactory Configuration");
}
- // TODO: This makes this variable both strict FO and user-config validation, is that right?
- boolean strict = false;
// strict fo validation
if (cfg.getChild("strict-validation", false) != null) {
try {
- strict = cfg.getChild("strict-validation").getValueAsBoolean();
+ boolean strict = cfg.getChild("strict-validation").getValueAsBoolean();
+ fopFactoryBuilder.setStrictFOValidation(strict);
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(log, e, false);
+ }
+ }
+
+ boolean strict = false;
+ if (cfg.getChild("strict-configuration", false) != null) {
+ try {
+ strict = cfg.getChild("strict-configuration").getValueAsBoolean();
fopFactoryBuilder.setStrictUserConfigValidation(strict);
} catch (ConfigurationException e) {
LogUtil.handleException(log, e, false);
diff --git a/src/java/org/apache/fop/apps/FopFactory.java b/src/java/org/apache/fop/apps/FopFactory.java
index 4508ea7fa..80c957f9f 100644
--- a/src/java/org/apache/fop/apps/FopFactory.java
+++ b/src/java/org/apache/fop/apps/FopFactory.java
@@ -295,7 +295,7 @@ public final class FopFactory implements ImageContext {
* @return the config object
* @throws FOPException when an error occurs while creating the configuration object
*/
- public RendererConfig getRendererConfig(FOUserAgent userAgent, Configuration cfg,
+ synchronized RendererConfig getRendererConfig(FOUserAgent userAgent, Configuration cfg,
RendererConfigParser configCreator) throws FOPException {
RendererConfig config = rendererConfig.get(configCreator.getMimeType());
if (config == null) {
@@ -325,48 +325,41 @@ public final class FopFactory implements ImageContext {
return config.isAccessibilityEnabled();
}
- /**
- * Returns the image manager.
- * @return the image manager
- */
+ /** @see FopFactoryConfig#getImageManager() */
public ImageManager getImageManager() {
return config.getImageManager();
}
- /**
- * Returns the overriding LayoutManagerMaker instance, if any.
- * @return the overriding LayoutManagerMaker or null
- */
+ /** @see FopFactoryConfig#getLayoutManagerMakerOverride() */
public LayoutManagerMaker getLayoutManagerMakerOverride() {
return config.getLayoutManagerMakerOverride();
}
- /** @return the hyphenation pattern names */
+ /** @see FopFactoryConfig#getHyphenationPatternNames() */
public Map<String, String> getHyphenationPatternNames() {
return config.getHyphenationPatternNames();
}
- /**
- * Returns whether FOP is strictly validating input XSL
- * @return true of strict validation turned on, false otherwise
- */
+ /** @see FopFactoryConfig#validateStrictly() */
public boolean validateStrictly() {
return config.validateStrictly();
}
- /**
- * @return true if the indent inheritance should be broken when crossing reference area
- * boundaries (for more info, see the javadoc for the relative member variable)
- */
+ /** @see FopFactoryConfig#isBreakIndentInheritanceOnReferenceAreaBoundary() */
public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
return config.isBreakIndentInheritanceOnReferenceAreaBoundary();
}
- /** @return the resolution for resolution-dependent input */
+ /** @see FopFactoryConfig#getSourceResolution() */
public float getSourceResolution() {
return config.getSourceResolution();
}
+ /** @see FopFactoryConfig#getTargetResolution() */
+ public float getTargetResolution() {
+ return config.getTargetResolution();
+ }
+
/**
* Returns the conversion factor from pixel units to millimeters. This
* depends on the desired source resolution.
@@ -377,11 +370,6 @@ public final class FopFactory implements ImageContext {
return UnitConv.IN2MM / getSourceResolution();
}
- /** @return the resolution for resolution-dependant output */
- public float getTargetResolution() {
- return config.getTargetResolution();
- }
-
/**
* Returns the conversion factor from pixel units to millimeters. This
* depends on the desired target resolution.
@@ -392,42 +380,26 @@ public final class FopFactory implements ImageContext {
return 25.4f / getTargetResolution();
}
- /**
- * Gets the default page-height to use as fallback,
- * in case page-height="auto"
- *
- * @return the page-height, as a String
- */
+ /** @see FopFactoryConfig#getPageHeight() */
public String getPageHeight() {
return config.getPageHeight();
}
- /**
- * Gets the default page-width to use as fallback,
- * in case page-width="auto"
- *
- * @return the page-width, as a String
- */
+ /** @see FopFactoryConfig#getPageWidth() */
public String getPageWidth() {
return config.getPageWidth();
}
- /**
- * Indicates whether a namespace URI is on the ignored list.
- * @param namespaceURI the namespace URI
- * @return true if the namespace is ignored by FOP
- */
+ /** @see FopFactoryConfig#isNamespaceIgnored(String) */
public boolean isNamespaceIgnored(String namespaceURI) {
return config.isNamespaceIgnored(namespaceURI);
}
- /** @return the set of namespaces that are ignored by FOP */
+ /** @see FopFactoryConfig#getIgnoredNamespaces() */
public Set<String> getIgnoredNamespace() {
return config.getIgnoredNamespaces();
}
- //------------------------------------------- Configuration stuff
-
/**
* Get the user configuration.
* @return the user configuration
@@ -436,20 +408,12 @@ public final class FopFactory implements ImageContext {
return config.getUserConfig();
}
- /**
- * Is the user configuration to be validated?
- * @return if the user configuration should be validated
- */
+ /** @see FopFactoryConfig#validateUserConfigStrictly() */
public boolean validateUserConfigStrictly() {
return config.validateUserConfigStrictly();
}
- //------------------------------------------- Font related stuff
-
- /**
- * Returns the font manager.
- * @return the font manager
- */
+ /** @see FopFactoryConfig#getFontManager() */
public FontManager getFontManager() {
return config.getFontManager();
}
diff --git a/src/java/org/apache/fop/apps/FopFactoryBuilder.java b/src/java/org/apache/fop/apps/FopFactoryBuilder.java
index 6c3da57f3..cfc47496c 100644
--- a/src/java/org/apache/fop/apps/FopFactoryBuilder.java
+++ b/src/java/org/apache/fop/apps/FopFactoryBuilder.java
@@ -61,7 +61,7 @@ public final class FopFactoryBuilder {
/**
* A builder class for {@link FopFactory} which can be used for setting configuration. This is
* a helper constructor that uses the default URI resolver implementation that FOP packages
- * provide ({@link DefaultResourceResolver}).
+ * provide ({@link org.apache.fop.apps.io.ResourceResolverFactory.DefaultResourceResolver}).
*
* @param defaultBaseURI the default base URI for resolving URIs against
*/
@@ -97,6 +97,17 @@ public final class FopFactoryBuilder {
* @deprecated Exposing the {@link FopFactoryConfig} is only to maintain backwards compatibility
*/
public FopFactoryConfig buildConfig() {
+ return buildConfiguration();
+ }
+
+ /**
+ * Builds the configuration object used by the FopFactory.
+ *
+ * @return the config for the {@link FopFactory}
+ */
+ // The {@link FopFactoryConfig} doesn't need to be exposed in the "public" API, this method
+ // should remain package private.
+ FopFactoryConfig buildConfiguration() {
fopFactoryConfigBuilder = CompletedFopFactoryConfigBuilder.INSTANCE;
return config;
}
@@ -107,7 +118,7 @@ public final class FopFactoryBuilder {
* @return the FopFactory instance
*/
public FopFactory build() {
- return FopFactory.newInstance(buildConfig());
+ return FopFactory.newInstance(buildConfiguration());
}
/**
@@ -150,13 +161,12 @@ public final class FopFactoryBuilder {
/**
* Sets the {@link LayoutManagerMaker} so that users can configure how FOP creates
- * {@link LayoutManager}s.
+ * {@link org.apache.fop.layoutmgr.LayoutManager}s.
*
* @param lmMaker he layout manager maker
* @return <code>this</code>
*/
- public FopFactoryBuilder setLayoutManagerMakerOverride(
- LayoutManagerMaker lmMaker) {
+ public FopFactoryBuilder setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
fopFactoryConfigBuilder.setLayoutManagerMakerOverride(lmMaker);
return this;
}
@@ -285,11 +295,10 @@ public final class FopFactoryBuilder {
}
/**
- * Sets whether to chose a {@link Renderer} in preference to an
+ * Sets whether to chose a {@link org.apache.fop.render.Renderer} in preference to an
* {@link org.apache.fop.render.intermediate.IFDocumentHandler}.
*
- * @see {@link RendererFactory}
- * @param preferRenderer true to prefer {@link Renderer}
+ * @param preferRenderer true to prefer {@link org.apache.fop.render.Renderer}
* @return <code>this</code>
*/
public FopFactoryBuilder setPreferRenderer(boolean preferRenderer) {
diff --git a/src/java/org/apache/fop/apps/FopFactoryConfig.java b/src/java/org/apache/fop/apps/FopFactoryConfig.java
index 2545eea5e..60e8d98e7 100644
--- a/src/java/org/apache/fop/apps/FopFactoryConfig.java
+++ b/src/java/org/apache/fop/apps/FopFactoryConfig.java
@@ -34,6 +34,9 @@ import org.apache.fop.layoutmgr.LayoutManagerMaker;
/**
* The configuration data for a {@link FopFactory} instance.
*/
+// TODO: Make this interface and any implementations of this interface package private. Though
+// they are used by classes that are considered the public API, this object doesn't need to be a
+// part of the API. Why would a user care how the internal objects are passed around? They shouldn't.
public interface FopFactoryConfig {
/** Defines if FOP should use an alternative rule to determine text indents */
@@ -64,7 +67,10 @@ public interface FopFactoryConfig {
*/
boolean isAccessibilityEnabled();
- /** @see {@link FopFactory#getLayoutManagerMakerOverride()} */
+ /**
+ * Returns the overriding LayoutManagerMaker instance, if any.
+ * @return the overriding LayoutManagerMaker or null
+ */
LayoutManagerMaker getLayoutManagerMakerOverride();
/**
@@ -81,31 +87,54 @@ public interface FopFactoryConfig {
*/
URI getBaseURI();
- /** @see {@link FopFactory#validateStrictly()} */
+ /**
+ * Returns whether FOP is strictly validating input XSL
+ * @return true of strict validation turned on, false otherwise
+ */
boolean validateStrictly();
- /** @see {@link FopFactory#validateUserConfigStrictly()} */
+ /**
+ * Is the user configuration to be validated?
+ * @return if the user configuration should be validated
+ */
boolean validateUserConfigStrictly();
- /** @see {@link FopFactory#isBreakIndentInheritanceOnReferenceAreaBoundary()} */
+ /**
+ * @return true if the indent inheritance should be broken when crossing reference area
+ * boundaries (for more info, see the javadoc for the relative member variable)
+ */
boolean isBreakIndentInheritanceOnReferenceAreaBoundary();
- /** @see {@link FopFactory#getSourceResolution()} */
+ /** @return the resolution for resolution-dependent input */
float getSourceResolution();
- /** @see {@link FopFactory#getTargetResolution()} */
+ /** @return the resolution for resolution-dependent output */
float getTargetResolution();
- /** @see {@link FopFactory#getPageHeight()} */
+ /**
+ * Gets the default page-height to use as fallback,
+ * in case page-height="auto"
+ *
+ * @return the page-height, as a String
+ */
String getPageHeight();
- /** @see {@link FopFactory#getPageWidth()} */
+ /**
+ * Gets the default page-width to use as fallback,
+ * in case page-width="auto"
+ *
+ * @return the page-width, as a String
+ */
String getPageWidth();
- /** @see {@link FopFactory#getIgnoredNamespace()} */
+ /** @return the set of namespaces that are ignored by FOP */
Set<String> getIgnoredNamespaces();
- /** @see {@link FopFactory#isNamespaceIgnored(String)} */
+ /**
+ * Indicates whether a namespace URI is on the ignored list.
+ * @param namespace the namespace URI
+ * @return true if the namespace is ignored by FOP
+ */
boolean isNamespaceIgnored(String namespace);
/**
@@ -115,17 +144,23 @@ public interface FopFactoryConfig {
*/
Configuration getUserConfig();
- /** @see {@link org.apache.fop.render.RendererFactory#isRendererPreferred()} */
+ /** @see org.apache.fop.render.RendererFactory#isRendererPreferred() */
boolean preferRenderer();
- /** @see {@link FopFactory#getFontManager()} */
+ /**
+ * Returns the font manager.
+ * @return the font manager
+ */
FontManager getFontManager();
- /** @see {@link FopFactory#getImageManager()} */
+ /**
+ * Returns the image manager.
+ * @return the image manager
+ */
ImageManager getImageManager();
boolean isComplexScriptFeaturesEnabled();
- /** @see {@link FopFactory#getHyphenationPatternNames()} */
+ /** @return the hyphenation pattern names */
Map<String, String> getHyphenationPatternNames();
}
diff --git a/src/java/org/apache/fop/apps/io/ResourceResolverFactory.java b/src/java/org/apache/fop/apps/io/ResourceResolverFactory.java
index 2c8300fb9..72eac456d 100644
--- a/src/java/org/apache/fop/apps/io/ResourceResolverFactory.java
+++ b/src/java/org/apache/fop/apps/io/ResourceResolverFactory.java
@@ -83,6 +83,15 @@ public final class ResourceResolverFactory {
return new TempAwareResourceResolver(tempResourceResolver, defaultResourceResolver);
}
+ /**
+ * This creates the builder class for binding URI schemas to implementations of
+ * {@link ResourceResolver}. This allows users to define their own URI schemas such that they
+ * have finer control over the acquisition of resources.
+ *
+ * @param defaultResolver the default resource resolver that should be used in the event that
+ * none of the other registered resolvers match the schema
+ * @return the schema aware {@link ResourceResolver} builder
+ */
public static SchemaAwareResourceResolverBuilder createSchemaAwareResourceResolverBuilder(
ResourceResolver defaultResolver) {
return new SchemaAwareResourceResolverBuilderImpl(defaultResolver);
@@ -99,10 +108,12 @@ public final class ResourceResolverFactory {
new NormalResourceResolver());
}
+ /** {@inheritDoc} */
public Resource getResource(URI uri) throws IOException {
return delegate.getResource(uri);
}
+ /** {@inheritDoc} */
public OutputStream getOutputStream(URI uri) throws IOException {
return delegate.getOutputStream(uri);
}
@@ -125,6 +136,7 @@ public final class ResourceResolverFactory {
return TempResourceURIGenerator.isTempUri(uri);
}
+ /** {@inheritDoc} */
public Resource getResource(URI uri) throws IOException {
if (isTempUri(uri)) {
return tempResourceResolver.getResource(uri.getPath());
@@ -133,6 +145,7 @@ public final class ResourceResolverFactory {
}
}
+ /** {@inheritDoc} */
public OutputStream getOutputStream(URI uri) throws IOException {
if (isTempUri(uri)) {
return tempResourceResolver.getOutputStream(uri.getPath());
@@ -140,7 +153,6 @@ public final class ResourceResolverFactory {
return defaultResourceResolver.getOutputStream(uri);
}
}
-
}
private static class DefaultTempResourceResolver implements TempResourceResolver {
@@ -150,10 +162,12 @@ public final class ResourceResolverFactory {
return file;
}
+ /** {@inheritDoc} */
public Resource getResource(String id) throws IOException {
return new Resource(getTempFile(id).toURI().toURL().openStream());
}
+ /** {@inheritDoc} */
public OutputStream getOutputStream(String id) throws IOException {
File file = getTempFile(id);
if (file.createNewFile()) {
@@ -196,19 +210,52 @@ public final class ResourceResolverFactory {
}
}
+ /** {@inheritDoc} */
public Resource getResource(URI uri) throws IOException {
return getResourceResolverForSchema(uri).getResource(uri);
}
+ /** {@inheritDoc} */
public OutputStream getOutputStream(URI uri) throws IOException {
return getResourceResolverForSchema(uri).getOutputStream(uri);
}
}
+ /**
+ * Implementations of this interface will be builders for {@link ResourceResolver}, they bind
+ * URI schemas to their respective resolver. This gives users more control over the mechanisms
+ * by which URIs are resolved.
+ * <p>
+ * Here is an example of how this could be used:
+ * </p>
+ * <p><code>
+ * SchemaAwareResourceResolverBuilder builder
+ * = ResourceResolverFactory.createSchemaAwareResourceResolverBuilder(defaultResolver);
+ * builder.registerResourceResolverForSchema("test", testResolver);
+ * builder.registerResourceResolverForSchema("anotherTest", test2Resolver);
+ * ResourceResolver resolver = builder.build();
+ * </code></p>
+ * This will result in all URIs for the form "test:///..." will be resolved using the
+ * <code>testResolver</code> object; URIs of the form "anotherTest:///..." will be resolved
+ * using <code>test2Resolver</code>; all other URIs will be resolved from the defaultResolver.
+ */
public interface SchemaAwareResourceResolverBuilder {
+ /**
+ * Register a schema with its respective {@link ResourceResolver}. This resolver will be
+ * used as the only resolver for the specified schema.
+ *
+ * @param schema the schema to be used with the given resolver
+ * @param resourceResolver the resource resolver
+ */
void registerResourceResolverForSchema(String schema, ResourceResolver resourceResolver);
+ /**
+ * Builds a {@link ResourceResolver} that will delegate to the respective resource resolver
+ * when a registered URI schema is given
+ *
+ * @return a resolver that delegates to the appropriate schema resolver
+ */
ResourceResolver build();
}
@@ -218,10 +265,12 @@ public final class ResourceResolverFactory {
private static final SchemaAwareResourceResolverBuilder INSTANCE
= new CompletedSchemaAwareResourceResolverBuilder();
+ /** {@inheritDoc} */
public ResourceResolver build() {
throw new IllegalStateException("Resource resolver already built");
}
+ /** {@inheritDoc} */
public void registerResourceResolverForSchema(String schema,
ResourceResolver resourceResolver) {
throw new IllegalStateException("Resource resolver already built");
@@ -240,11 +289,13 @@ public final class ResourceResolverFactory {
this.defaultResolver = defaultResolver;
}
+ /** {@inheritDoc} */
public void registerResourceResolverForSchema(String schema,
ResourceResolver resourceResolver) {
schemaHandlingResourceResolvers.put(schema, resourceResolver);
}
+ /** {@inheritDoc} */
public ResourceResolver build() {
return new SchemaAwareResourceResolver(
Collections.unmodifiableMap(schemaHandlingResourceResolvers), defaultResolver);
@@ -261,11 +312,13 @@ public final class ResourceResolverFactory {
this.delegate = new ActiveSchemaAwareResourceResolverBuilder(defaultResolver);
}
+ /** {@inheritDoc} */
public void registerResourceResolverForSchema(String schema,
ResourceResolver resourceResolver) {
delegate.registerResourceResolverForSchema(schema, resourceResolver);
}
+ /** {@inheritDoc} */
public ResourceResolver build() {
ResourceResolver resourceResolver = delegate.build();
delegate = CompletedSchemaAwareResourceResolverBuilder.INSTANCE;
diff --git a/src/java/org/apache/fop/apps/io/TempResourceResolver.java b/src/java/org/apache/fop/apps/io/TempResourceResolver.java
index b17630a1d..cf307fab6 100644
--- a/src/java/org/apache/fop/apps/io/TempResourceResolver.java
+++ b/src/java/org/apache/fop/apps/io/TempResourceResolver.java
@@ -35,7 +35,7 @@ public interface TempResourceResolver {
* @return the resource
* @throws IOException if an I/O error occured during resource acquisition
*/
- Resource getResource(String id) throws IOException;
+ Resource getResource(String uri) throws IOException;
/**
* Gets an temporary-output stream of a given URI.
@@ -44,5 +44,5 @@ public interface TempResourceResolver {
* @return the output stream
* @throws IOException if an I/O error occured while creating an output stream
*/
- OutputStream getOutputStream(String id) throws IOException;
+ OutputStream getOutputStream(String uri) throws IOException;
}
diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java
index aa402aa6a..886e27527 100644
--- a/src/java/org/apache/fop/cli/CommandLineOptions.java
+++ b/src/java/org/apache/fop/cli/CommandLineOptions.java
@@ -24,6 +24,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
+import java.net.URI;
import java.util.Locale;
import java.util.Map;
import java.util.Vector;
@@ -42,6 +43,7 @@ import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FopConfParser;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.FopFactoryBuilder;
+import org.apache.fop.apps.FopFactoryConfig;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.pdf.PDFAMode;
import org.apache.fop.pdf.PDFEncryptionManager;
@@ -116,7 +118,7 @@ public class CommandLineOptions {
/* rendering options (for the user agent) */
private Map renderingOptions = new java.util.HashMap();
/* target resolution (for the user agent) */
- private int targetResolution = 0;
+ private float targetResolution = FopFactoryConfig.DEFAULT_TARGET_RESOLUTION;
private boolean strictValidation = true;
/* control memory-conservation policy */
@@ -137,6 +139,8 @@ public class CommandLineOptions {
private boolean flushCache = false;
+ private URI baseURI = new File(".").getAbsoluteFile().toURI();
+
/**
* Construct a command line option object.
*/
@@ -465,6 +469,7 @@ public class CommandLineOptions {
this.useStdIn = true;
} else {
fofile = new File(filename);
+ baseURI = getBaseURI(fofile);
}
return 1;
}
@@ -494,11 +499,16 @@ public class CommandLineOptions {
this.useStdIn = true;
} else {
xmlfile = new File(filename);
+ baseURI = getBaseURI(xmlfile);
}
return 1;
}
}
+ private URI getBaseURI(File file) {
+ return file.getAbsoluteFile().getParentFile().toURI();
+ }
+
private int parseAWTOutputOption(String[] args, int i) throws FOPException {
setOutputMode(MimeConstants.MIME_FOP_AWT_PREVIEW);
return 0;
@@ -725,6 +735,7 @@ public class CommandLineOptions {
this.useStdIn = true;
} else {
fofile = new File(filename);
+ baseURI = getBaseURI(fofile);
}
} else if (outputmode == null) {
outputmode = MimeConstants.MIME_PDF;
@@ -783,6 +794,7 @@ public class CommandLineOptions {
this.useStdIn = true;
} else {
areatreefile = new File(filename);
+ baseURI = getBaseURI(areatreefile);
}
return 1;
}
@@ -799,6 +811,7 @@ public class CommandLineOptions {
this.useStdIn = true;
} else {
iffile = new File(filename);
+ baseURI = getBaseURI(iffile);
}
return 1;
}
@@ -815,6 +828,7 @@ public class CommandLineOptions {
this.useStdIn = true;
} else {
imagefile = new File(filename);
+ baseURI = getBaseURI(imagefile);
}
return 1;
}
@@ -1030,15 +1044,22 @@ public class CommandLineOptions {
private void setUserConfig() throws FOPException, IOException {
FopFactoryBuilder fopFactoryBuilder;
if (userConfigFile == null) {
- fopFactoryBuilder = new FopFactoryBuilder(new File(".").toURI());
+ fopFactoryBuilder = new FopFactoryBuilder(baseURI);
+ fopFactoryBuilder.setStrictFOValidation(strictValidation);
+ fopFactoryBuilder.setTargetResolution(targetResolution);
+ fopFactoryBuilder.setComplexScriptFeatures(useComplexScriptFeatures);
} else {
try {
fopFactoryBuilder = new FopConfParser(userConfigFile).getFopFactoryBuilder();
} catch (SAXException e) {
throw new FOPException(e);
}
- fopFactoryBuilder.setStrictFOValidation(strictValidation);
- fopFactoryBuilder.setComplexScriptFeatures(useComplexScriptFeatures);
+ if (!strictValidation) {
+ fopFactoryBuilder.setStrictFOValidation(strictValidation);
+ }
+ if (useComplexScriptFeatures) {
+ fopFactoryBuilder.setComplexScriptFeatures(useComplexScriptFeatures);
+ }
}
factory = fopFactoryBuilder.build();
}
diff --git a/src/java/org/apache/fop/fonts/DefaultFontConfig.java b/src/java/org/apache/fop/fonts/DefaultFontConfig.java
index 6c5cebb42..375db34df 100644
--- a/src/java/org/apache/fop/fonts/DefaultFontConfig.java
+++ b/src/java/org/apache/fop/fonts/DefaultFontConfig.java
@@ -89,7 +89,7 @@ public final class DefaultFontConfig implements FontConfig {
} else {
this.strict = strict;
this.fontInfoCfg = cfg.getChild("fonts", false);
- instance = new DefaultFontConfig(cfg.getChild("auto-detect", false) != null);
+ instance = new DefaultFontConfig(fontInfoCfg.getChild("auto-detect", false) != null);
parse();
}
}
diff --git a/src/java/org/apache/fop/fonts/DefaultFontConfigurator.java b/src/java/org/apache/fop/fonts/DefaultFontConfigurator.java
index 2c60cf4bf..9534ef8ad 100644
--- a/src/java/org/apache/fop/fonts/DefaultFontConfigurator.java
+++ b/src/java/org/apache/fop/fonts/DefaultFontConfigurator.java
@@ -52,7 +52,6 @@ public class DefaultFontConfigurator implements FontConfigurator<EmbedFontInfo>
/**
* Main constructor
- * @param fontInfoConfig the configuration object
* @param fontManager the font manager
* @param listener the font event listener
* @param strict true if an Exception should be thrown if an error is found.
diff --git a/src/java/org/apache/fop/fonts/FontCache.java b/src/java/org/apache/fop/fonts/FontCache.java
index 35997f3d7..52db98ff3 100644
--- a/src/java/org/apache/fop/fonts/FontCache.java
+++ b/src/java/org/apache/fop/fonts/FontCache.java
@@ -53,7 +53,7 @@ public final class FontCache implements Serializable {
* Serialization Version UID. Change this value if you want to make sure the
* user's cache file is purged after an update.
*/
- private static final long serialVersionUID = 605232520271754719L;
+ private static final long serialVersionUID = 9129238336422194339L;
/** logging instance */
private static Log log = LogFactory.getLog(FontCache.class);
@@ -65,7 +65,7 @@ public final class FontCache implements Serializable {
private static final String DEFAULT_CACHE_FILENAME = "fop-fonts.cache";
/** has this cache been changed since it was last read? */
- private transient boolean changed = false;
+ private transient boolean changed;
/** change lock */
private final boolean[] changeLock = new boolean[1];
@@ -73,12 +73,14 @@ public final class FontCache implements Serializable {
/**
* master mapping of font url -> font info. This needs to be a list, since a
* TTC file may contain more than 1 font.
+ * @serial
*/
private Map<String, CachedFontFile> fontfileMap = null;
/**
* mapping of font url -> file modified date (for all fonts that have failed
* to load)
+ * @serial
*/
private Map<String, Long> failedFontMap = null;
@@ -139,6 +141,7 @@ public final class FontCache implements Serializable {
*
* @return the font cache deserialized from the file (or null if no cache
* file exists or if it could not be read)
+ * @deprecated use {@link #loadFrom(File)} instead
*/
public static FontCache load() {
return loadFrom(getDefaultCacheFile(false));
@@ -190,8 +193,8 @@ public final class FontCache implements Serializable {
/**
* Writes the font cache to disk.
*
- * @throws FOPException
- * fop exception
+ * @throws FOPException fop exception
+ * @deprecated use {@link #saveTo(File)} instead
*/
public void save() throws FOPException {
saveTo(getDefaultCacheFile(true));
@@ -462,10 +465,9 @@ public final class FontCache implements Serializable {
}
/**
- * Retrieve the last modified date/time of a URL.
+ * Retrieve the last modified date/time of a URI.
*
- * @param url
- * the URL
+ * @param uri the URI
* @return the last modified date/time
*/
public static long getLastModified(URI uri) {
diff --git a/src/java/org/apache/fop/fonts/FontManager.java b/src/java/org/apache/fop/fonts/FontManager.java
index e9b021978..bff001f73 100644
--- a/src/java/org/apache/fop/fonts/FontManager.java
+++ b/src/java/org/apache/fop/fonts/FontManager.java
@@ -138,7 +138,6 @@ public class FontManager {
/**
* Whether or not to cache results of font triplet detection/auto-config
- * @param useCache use cache or not
*/
public void disableFontCache() {
fontCacheManager = FontCacheManagerFactory.createDisabled();
@@ -163,8 +162,7 @@ public class FontManager {
/**
* Deletes the current FontCache file
- * @return Returns true if the font cache file was successfully deleted.
- * @throws FOPException -
+ * @throws FOPException if an error was thrown while deleting the cache
*/
public void deleteCache() throws FOPException {
fontCacheManager.delete(getCacheFile(true));
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
index 5fa411101..9f94b4f49 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
@@ -329,7 +329,7 @@ public abstract class AbstractBreaker {
* @return the top-level LayoutContext
*/
protected LayoutContext createLayoutContext() {
- return new LayoutContext(0);
+ return LayoutContext.newInstance();
}
/**
@@ -481,6 +481,11 @@ public abstract class AbstractBreaker {
addAreas(alg, 0, partCount, originalList, effectiveList);
}
+ protected void addAreas(PageBreakingAlgorithm alg, int startPart, int partCount,
+ BlockSequence originalList, BlockSequence effectiveList) {
+ addAreas(alg, startPart, partCount, originalList, effectiveList, LayoutContext.newInstance());
+ }
+
/**
* Phase 3 of Knuth algorithm: Adds the areas
* @param alg PageBreakingAlgorithm instance which determined the breaks
@@ -490,9 +495,7 @@ public abstract class AbstractBreaker {
* @param effectiveList effective Knuth element list (after adjustments)
*/
protected void addAreas(PageBreakingAlgorithm alg, int startPart, int partCount,
- BlockSequence originalList, BlockSequence effectiveList) {
- LayoutContext childLC;
- // add areas
+ BlockSequence originalList, BlockSequence effectiveList, final LayoutContext childLC) {
int startElementIndex = 0;
int endElementIndex = 0;
int lastBreak = -1;
@@ -507,7 +510,17 @@ public abstract class AbstractBreaker {
ListElement lastBreakElement = effectiveList.getElement(endElementIndex);
if (lastBreakElement.isPenalty()) {
KnuthPenalty pen = (KnuthPenalty)lastBreakElement;
- lastBreakClass = pen.getBreakClass();
+ if (pen.getPenalty() == KnuthPenalty.INFINITE) {
+ /**
+ * That means that there was a keep.within-page="always", but that
+ * it's OK to break at a column. TODO The break class is being
+ * abused to implement keep.within-column and keep.within-page.
+ * This is very misleading and must be revised.
+ */
+ lastBreakClass = Constants.EN_COLUMN;
+ } else {
+ lastBreakClass = pen.getBreakClass();
+ }
} else {
lastBreakClass = Constants.EN_COLUMN;
}
@@ -550,19 +563,13 @@ public abstract class AbstractBreaker {
// ignore KnuthGlue and KnuthPenalty objects
// at the beginning of the line
- ListIterator<KnuthElement> effectiveListIterator
- = effectiveList.listIterator(startElementIndex);
- while (effectiveListIterator.hasNext()
- && !(effectiveListIterator.next()).isBox()) {
- startElementIndex++;
- }
+ startElementIndex = alg.par.getFirstBoxIndex(startElementIndex);
if (startElementIndex <= endElementIndex) {
if (log.isDebugEnabled()) {
log.debug(" addAreas from " + startElementIndex
+ " to " + endElementIndex);
}
- childLC = new LayoutContext(0);
// set the space adjustment ratio
childLC.setSpaceAdjust(pbp.bpdAdjust);
// add space before if display-align is center or bottom
@@ -576,7 +583,9 @@ public abstract class AbstractBreaker {
&& p < (partCount - 1)) {
// count the boxes whose width is not 0
int boxCount = 0;
- effectiveListIterator = effectiveList.listIterator(startElementIndex);
+ @SuppressWarnings("unchecked")
+ ListIterator<KnuthElement> effectiveListIterator = effectiveList
+ .listIterator(startElementIndex);
while (effectiveListIterator.nextIndex() <= endElementIndex) {
KnuthElement tempEl = effectiveListIterator.next();
if (tempEl.isBox() && tempEl.getWidth() > 0) {
diff --git a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
index 97484aaab..c80982cce 100644
--- a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
+++ b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
@@ -40,7 +40,7 @@ public final class AreaAdditionUtil {
public static void addAreas(BlockStackingLayoutManager bslm,
PositionIterator parentIter, LayoutContext layoutContext) {
LayoutManager childLM;
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.offspringOf(layoutContext);
LayoutManager firstLM = null;
LayoutManager lastLM = null;
Position firstPos = null;
diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
index adce89ac0..920589657 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
@@ -193,7 +193,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
*/
@Override
protected LayoutContext makeChildLayoutContext(LayoutContext context) {
- LayoutContext childLC = new LayoutContext(0);
+ LayoutContext childLC = LayoutContext.newInstance();
childLC.setStackLimitBP(
context.getStackLimitBP().minus(MinOptMax.getInstance(relDims.bpd)));
childLC.setRefIPD(relDims.ipd);
@@ -707,7 +707,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
return curChildLM;
}
- public void addContainedAreas() {
+ public void addContainedAreas(LayoutContext layoutContext) {
if (isEmpty()) {
return;
}
@@ -715,8 +715,10 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
//overflow should be visible.
this.deferredAlg.removeAllPageBreaks();
this.addAreas(this.deferredAlg,
+ 0,
this.deferredAlg.getPageBreaks().size(),
- this.deferredOriginalList, this.deferredEffectiveList);
+ this.deferredOriginalList, this.deferredEffectiveList,
+ LayoutContext.offspringOf(layoutContext));
}
}
@@ -754,7 +756,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
LayoutManager childLM;
LayoutManager lastLM = null;
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.offspringOf(layoutContext);
lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
// set space after in the LayoutContext for children
if (layoutContext.getSpaceAfter() > 0) {
@@ -821,7 +823,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
}
} else {
//Add child areas inside the reference area
- bcpos.getBreaker().addContainedAreas();
+ bcpos.getBreaker().addContainedAreas(layoutContext);
}
addMarkersToPage(false, isFirst(firstPos), isLast(lastPos));
@@ -1044,10 +1046,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
return true;
}
- public int getBreakBefore() {
- return BreakOpportunityHelper.getBreakBefore(this);
- }
-
}
diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
index 03b2d380c..a99b45620 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
@@ -272,7 +272,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co
LayoutManager childLM;
LayoutManager lastLM = null;
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.offspringOf(layoutContext);
lc.setSpaceAdjust(layoutContext.getSpaceAdjust());
// set space after in the LayoutContext for children
if (layoutContext.getSpaceAfter() > 0) {
@@ -504,8 +504,4 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co
return true;
}
- public int getBreakBefore() {
- return BreakOpportunityHelper.getBreakBefore(this);
- }
-
}
diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
index 78ab6711a..d11f062cb 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
@@ -383,7 +383,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
* @return a new child layout context
*/
protected LayoutContext makeChildLayoutContext(LayoutContext context) {
- LayoutContext childLC = new LayoutContext(0);
+ LayoutContext childLC = LayoutContext.newInstance();
childLC.copyPendingMarksFrom(context);
childLC.setStackLimitBP(context.getStackLimitBP());
childLC.setRefIPD(referenceIPD);
@@ -1035,7 +1035,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
* @return true if an element has been added due to a break-before.
*/
protected boolean addKnuthElementsForBreakBefore(List returnList, LayoutContext context) {
- int breakBefore = BreakOpportunityHelper.getBreakBefore(this);
+ int breakBefore = getBreakBefore();
if (breakBefore == EN_PAGE
|| breakBefore == EN_COLUMN
|| breakBefore == EN_EVEN_PAGE
@@ -1050,6 +1050,17 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
}
/**
+ * Returns the highest priority break-before value on this layout manager or its
+ * relevant descendants.
+ *
+ * @return the break-before value (Constants.EN_*)
+ * @see BreakOpportunity#getBreakBefore()
+ */
+ public int getBreakBefore() {
+ return BreakOpportunityHelper.getBreakBefore(this);
+ }
+
+ /**
* Creates Knuth elements for break-after and adds them to the return list.
* @param returnList return list to add the additional elements to
* @param context the layout context
diff --git a/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
index 7e55c31f6..3830878fe 100644
--- a/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
+++ b/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
@@ -532,14 +532,15 @@ public abstract class BreakingAlgorithm {
// index of the first KnuthBox in the sequence, in case of non-centered
// alignment. For centered alignment, we need to take into account preceding
// penalties+glues used for the filler spaces
- int firstBoxIndex = startIndex;
+ int previousPosition = startIndex;
if (alignment != Constants.EN_CENTER) {
- firstBoxIndex = par.getFirstBoxIndex(startIndex);
+ int firstBoxIndex = par.getFirstBoxIndex(startIndex);
+ previousPosition = (firstBoxIndex >= par.size()) ? startIndex : firstBoxIndex - 1;
}
- firstBoxIndex = (firstBoxIndex < 0) ? 0 : firstBoxIndex;
+ previousPosition = (previousPosition < 0) ? 0 : previousPosition;
// create an active node representing the starting point
- addNode(0, createNode(firstBoxIndex, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, null));
+ addNode(0, createNode(previousPosition, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, null));
KnuthNode lastForced = getNode(0);
if (log.isTraceEnabled()) {
diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
index 1ea3c84d4..0260046e1 100644
--- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
@@ -200,7 +200,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager
*/
@Override
protected LayoutContext makeChildLayoutContext(LayoutContext context) {
- LayoutContext childLC = new LayoutContext(0);
+ LayoutContext childLC = LayoutContext.newInstance();
childLC.setStackLimitBP(context.getStackLimitBP());
childLC.setRefIPD(context.getRefIPD());
childLC.setWritingMode(getCurrentPage().getSimplePageMaster().getWritingMode());
diff --git a/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java
index 078b7c451..432493a71 100644
--- a/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java
@@ -42,7 +42,7 @@ public class FootnoteBodyLayoutManager extends BlockStackingLayoutManager {
public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) {
LayoutManager childLM;
LayoutManager lastLM = null;
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.newInstance();
// "unwrap" the NonLeafPositions stored in parentIter
// and put them in a new list;
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthSequence.java b/src/java/org/apache/fop/layoutmgr/KnuthSequence.java
index d568da45e..8d5e77ae0 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthSequence.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthSequence.java
@@ -20,6 +20,7 @@
package org.apache.fop.layoutmgr;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
@@ -159,46 +160,26 @@ public abstract class KnuthSequence extends ArrayList {
: (ListElement) get(index);
}
- /** @return the position index of the first box in this sequence */
- protected int getFirstBoxIndex() {
- if (isEmpty()) {
- return -1;
- } else {
- return getFirstBoxIndex(0);
- }
- }
-
/**
- * Get the position index of the first box in this sequence,
- * starting at the given index. If there is no box after the
- * passed {@code startIndex}, the starting index itself is returned.
- * @param startIndex the starting index for the lookup
- * @return the absolute position index of the next box element
+ * Returns the position index of the first box in this sequence, starting at the given
+ * index. If {@code startIndex} is outside the bounds of this sequence, it is
+ * returned.
+ *
+ * @param startIndex the index from which to start the lookup
+ * @return the index of the next box element, {@link #size()} if there is no such
+ * element, {@code startIndex} if {@code (startIndex < 0 || startIndex >= size())}
*/
protected int getFirstBoxIndex(int startIndex) {
- if (isEmpty() || startIndex < 0 || startIndex >= size()) {
- return -1;
+ if (startIndex < 0 || startIndex >= size()) {
+ return startIndex;
} else {
- ListElement element = null;
- int posIndex = startIndex;
- int lastIndex = size();
- while ( posIndex < lastIndex ) {
- element = getElement(posIndex);
- if ( !element.isBox() ) {
- posIndex++;
- } else {
- break;
- }
- }
- if ( posIndex != startIndex ) {
- if ( ( element != null ) && element.isBox() ) {
- return posIndex - 1;
- } else {
- return startIndex;
- }
- } else {
- return startIndex;
+ int boxIndex = startIndex;
+ @SuppressWarnings("unchecked")
+ Iterator<ListElement> iter = listIterator(startIndex);
+ while (iter.hasNext() && !iter.next().isBox()) {
+ boxIndex++;
}
+ return boxIndex;
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/LayoutContext.java b/src/java/org/apache/fop/layoutmgr/LayoutContext.java
index a2512c50b..21983c20f 100644
--- a/src/java/org/apache/fop/layoutmgr/LayoutContext.java
+++ b/src/java/org/apache/fop/layoutmgr/LayoutContext.java
@@ -33,47 +33,27 @@ import org.apache.fop.traits.WritingMode;
* This class is used to pass information to the getNextKnuthElements()
* method. It is set up by higher level LM and used by lower level LM.
*/
-public class LayoutContext {
+public final class LayoutContext {
- /** linebreak at line feed only flag */
- public static final int LINEBREAK_AT_LF_ONLY = 0x01;
/** Generated break possibility is first in a new area */
- public static final int NEW_AREA = 0x02;
- /** ipd unknown flag */
- public static final int IPD_UNKNOWN = 0x04;
- /** Signal to a Line LM that a higher level LM may provoke a change
- * in the reference area, thus ref area IPD. The LineLM should return
- * without looking for a line break.
- */
- public static final int CHECK_REF_AREA = 0x08;
+ public static final int NEW_AREA = 0x01;
/**
* 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_BREAK_BEFORE = 0x10;
- /** first area flag */
- public static final int FIRST_AREA = 0x20;
- /** try hypenate flag */
- public static final int TRY_HYPHENATE = 0x40;
- /** last area flag */
- public static final int LAST_AREA = 0x80;
- /** resolve leading space flag */
- public static final int RESOLVE_LEADING_SPACE = 0x100;
+ public static final int SUPPRESS_BREAK_BEFORE = 0x02;
- /**
- * This flag indicates that there's a keep-with-next that hasn't
- * been processed, yet.
- */
- //public static final int KEEP_WITH_NEXT_PENDING = 0x200;
- /**
- * This flag indicates that there's a keep-with-previous that hasn't
- * been processed, yet.
- */
- //public static final int KEEP_WITH_PREVIOUS_PENDING = 0x400;
+ public static final int FIRST_AREA = 0x04;
+
+ public static final int LAST_AREA = 0x08;
+ public static final int RESOLVE_LEADING_SPACE = 0x10;
+
+ private static final int TREAT_AS_ARTIFACT = 0x20;
private int flags; // Contains some set of flags defined above
+
/**
* Total available stacking dimension for a "galley-level" layout
* manager in block-progression-direction. It is passed by the
@@ -145,11 +125,27 @@ public class LayoutContext {
private int disableColumnBalancing;
+ public static LayoutContext newInstance() {
+ return new LayoutContext(0);
+ }
+
+ public static LayoutContext copyOf(LayoutContext copy) {
+ return new LayoutContext(copy);
+ }
+
/**
- * Copy constructor for creating child layout contexts.
- * @param parentLC the parent layout context to copy from
+ * Returns a descendant of the given layout context. The new context is the same as
+ * what would have been created by {@link #newInstance()}, except for inheritable
+ * properties that are passed on by the parent. At the moment, the only inheritable
+ * property is the value returned by {@link #treatAsArtifact()}.
*/
- public LayoutContext(LayoutContext parentLC) {
+ public static LayoutContext offspringOf(LayoutContext parent) {
+ LayoutContext offspring = new LayoutContext(0);
+ offspring.setTreatAsArtifact(parent.treatAsArtifact());
+ return offspring;
+ }
+
+ private LayoutContext(LayoutContext parentLC) {
this.flags = parentLC.flags;
this.refIPD = parentLC.refIPD;
this.writingMode = parentLC.writingMode;
@@ -170,11 +166,7 @@ public class LayoutContext {
this.disableColumnBalancing = parentLC.disableColumnBalancing;
}
- /**
- * Main constructor.
- * @param flags the initial flags
- */
- public LayoutContext(int flags) {
+ private LayoutContext(int flags) {
this.flags = flags;
this.refIPD = 0;
stackLimitBP = MinOptMax.ZERO;
@@ -435,11 +427,6 @@ public class LayoutContext {
return hyphContext;
}
- /** @return true if try hyphenate is set */
- public boolean tryHyphenate() {
- return ((this.flags & TRY_HYPHENATE) != 0);
- }
-
/**
* Sets the currently applicable alignment in BP direction.
* @param alignment one of EN_START, EN_JUSTIFY etc.
@@ -673,7 +660,6 @@ public class LayoutContext {
+ "\nIs First Area: \t" + isFirstArea()
+ "\nStarts New Area: \t" + startsNewArea()
+ "\nIs Last Area: \t" + isLastArea()
- + "\nTry Hyphenate: \t" + tryHyphenate()
+ "\nKeeps: \t[keep-with-next=" + getKeepWithNextPending()
+ "][keep-with-previous=" + getKeepWithPreviousPending() + "] pending"
+ "\nBreaks: \tforced [" + (breakBefore != Constants.EN_AUTO ? "break-before" : "") + "]["
@@ -698,5 +684,13 @@ public class LayoutContext {
public void setDisableColumnBalancing(int disableColumnBalancing) {
this.disableColumnBalancing = disableColumnBalancing;
}
+
+ public boolean treatAsArtifact() {
+ return (flags & TREAT_AS_ARTIFACT) != 0;
+ }
+
+ public void setTreatAsArtifact(boolean treatAsArtifact) {
+ setFlags(TREAT_AS_ARTIFACT, treatAsArtifact);
+ }
}
diff --git a/src/java/org/apache/fop/layoutmgr/PageBreaker.java b/src/java/org/apache/fop/layoutmgr/PageBreaker.java
index 8fd131a73..309f4e32f 100644
--- a/src/java/org/apache/fop/layoutmgr/PageBreaker.java
+++ b/src/java/org/apache/fop/layoutmgr/PageBreaker.java
@@ -95,8 +95,7 @@ public class PageBreaker extends AbstractBreaker {
return new PageBreakingLayoutListener() {
public void notifyOverflow(int part, int amount, FObj obj) {
- Page p = pageProvider.getPage(
- false, part, PageProvider.RELTO_CURRENT_ELEMENT_LIST);
+ Page p = pageProvider.getPageFromColumnIndex(part);
RegionBody body = (RegionBody)p.getSimplePageMaster().getRegion(
Region.FO_REGION_BODY);
BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
@@ -167,7 +166,7 @@ public class PageBreaker extends AbstractBreaker {
&& ((KnuthBlockBox) element).hasAnchors()) {
// element represents a line with footnote citations
containsFootnotes = true;
- LayoutContext footnoteContext = new LayoutContext(context);
+ LayoutContext footnoteContext = LayoutContext.copyOf(context);
footnoteContext.setStackLimitBP(context.getStackLimitBP());
footnoteContext.setRefIPD(pslm.getCurrentPV()
.getRegionReference(Constants.FO_REGION_BODY).getIPD());
@@ -330,7 +329,7 @@ public class PageBreaker extends AbstractBreaker {
//Get page break from which we restart
PageBreakPosition pbp = (PageBreakPosition)
alg.getPageBreaks().get(restartPoint - 1);
- newStartPos = pbp.getLeafPos() + 1;
+ newStartPos = alg.par.getFirstBoxIndex(pbp.getLeafPos() + 1);
//Handle page break right here to avoid any side-effects
if (newStartPos > 0) {
handleBreakTrait(Constants.EN_PAGE);
@@ -473,7 +472,7 @@ public class PageBreaker extends AbstractBreaker {
SpaceResolver.performConditionalsNotification(elementList,
firstIndex, lastIndex, -1);
- LayoutContext childLC = new LayoutContext(0);
+ LayoutContext childLC = LayoutContext.newInstance();
AreaAdditionUtil.addAreas(null,
new KnuthPossPosIter(elementList, firstIndex, lastIndex + 1),
childLC);
@@ -521,7 +520,6 @@ public class PageBreaker extends AbstractBreaker {
return;
case Constants.EN_COLUMN:
case Constants.EN_AUTO:
- case Constants.EN_PAGE:
case -1:
PageViewport pv = curPage.getPageViewport();
@@ -545,6 +543,7 @@ public class PageBreaker extends AbstractBreaker {
/*curPage = */pslm.makeNewPage(false);
}
return;
+ case Constants.EN_PAGE:
default:
log.debug("handling break-before after page " + pslm.getCurrentPageNum()
+ " breakVal=" + getBreakClassName(breakVal));
@@ -560,7 +559,7 @@ public class PageBreaker extends AbstractBreaker {
}
/**
- * Check if a blank page is needed to accomodate
+ * Check if a blank page is needed to accommodate
* desired even or odd page number.
* @param breakVal - value of break-before or break-after trait.
*/
diff --git a/src/java/org/apache/fop/layoutmgr/PageProvider.java b/src/java/org/apache/fop/layoutmgr/PageProvider.java
index 0ad990899..8117d547d 100644
--- a/src/java/org/apache/fop/layoutmgr/PageProvider.java
+++ b/src/java/org/apache/fop/layoutmgr/PageProvider.java
@@ -151,18 +151,37 @@ public class PageProvider implements Constants {
return this.lastReportedBPD;
}
- // Wish there were a more elegant way to do this in Java
- private int[] getColIndexAndColCount(int index) {
+ private static class Column {
+
+ final Page page;
+
+ final int pageIndex;
+
+ final int colIndex;
+
+ final int columnCount;
+
+ Column(Page page, int pageIndex, int colIndex, int columnCount) {
+ this.page = page;
+ this.pageIndex = pageIndex;
+ this.colIndex = colIndex;
+ this.columnCount = columnCount;
+ }
+
+ }
+
+ private Column getColumn(int index) {
int columnCount = 0;
int colIndex = startColumnOfCurrentElementList + index;
int pageIndex = -1;
+ Page page;
do {
colIndex -= columnCount;
pageIndex++;
- Page page = getPage(false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
+ page = getPage(false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
columnCount = page.getPageViewport().getCurrentSpan().getColumnCount();
} while (colIndex >= columnCount);
- return new int[] {colIndex, columnCount};
+ return new Column(page, pageIndex, colIndex, columnCount);
}
/**
@@ -173,22 +192,13 @@ public class PageProvider implements Constants {
* than, equal to or greater than the IPD of the following part
*/
public int compareIPDs(int index) {
- int columnCount = 0;
- int colIndex = startColumnOfCurrentElementList + index;
- int pageIndex = -1;
- Page page;
- do {
- colIndex -= columnCount;
- pageIndex++;
- page = getPage(false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
- columnCount = page.getPageViewport().getCurrentSpan().getColumnCount();
- } while (colIndex >= columnCount);
- if (colIndex + 1 < columnCount) {
+ Column column = getColumn(index);
+ if (column.colIndex + 1 < column.columnCount) {
// Next part is a column on same page => same IPD
return 0;
} else {
- Page nextPage = getPage(false, pageIndex + 1, RELTO_CURRENT_ELEMENT_LIST);
- return page.getPageViewport().getBodyRegion().getIPD()
+ Page nextPage = getPage(false, column.pageIndex + 1, RELTO_CURRENT_ELEMENT_LIST);
+ return column.page.getPageViewport().getBodyRegion().getIPD()
- nextPage.getPageViewport().getBodyRegion().getIPD();
}
}
@@ -199,7 +209,7 @@ public class PageProvider implements Constants {
* @return {@code true} if the break starts a new page
*/
boolean startPage(int index) {
- return getColIndexAndColCount(index)[0] == 0;
+ return getColumn(index).colIndex == 0;
}
/**
@@ -208,8 +218,8 @@ public class PageProvider implements Constants {
* @return {@code true} if the break ends a page
*/
boolean endPage(int index) {
- int[] colIndexAndColCount = getColIndexAndColCount(index);
- return colIndexAndColCount[0] == colIndexAndColCount[1] - 1;
+ Column column = getColumn(index);
+ return column.colIndex == column.columnCount - 1;
}
/**
@@ -219,7 +229,7 @@ public class PageProvider implements Constants {
* @return the number of columns
*/
int getColumnCount(int index) {
- return getColIndexAndColCount(index)[1];
+ return getColumn(index).columnCount;
}
/**
@@ -229,24 +239,12 @@ public class PageProvider implements Constants {
* @return the requested part index
*/
public int getStartingPartIndexForLastPage(int partCount) {
- int result = 0;
- int idx = 0;
- int pageIndex = 0;
- int colIndex = startColumnOfCurrentElementList;
- Page page = getPage(
- false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
- while (idx < partCount) {
- if ((colIndex >= page.getPageViewport().getCurrentSpan().getColumnCount())) {
- colIndex = 0;
- pageIndex++;
- page = getPage(
- false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
- result = idx;
- }
- colIndex++;
- idx++;
- }
- return result;
+ int lastPartIndex = partCount - 1;
+ return lastPartIndex - getColumn(lastPartIndex).colIndex;
+ }
+
+ Page getPageFromColumnIndex(int columnIndex) {
+ return getColumn(columnIndex).page;
}
/**
@@ -291,7 +289,9 @@ public class PageProvider implements Constants {
log.trace("last page requested: " + index);
}
}
- while (intIndex >= cachedPages.size()) {
+ if (intIndex > cachedPages.size()) {
+ throw new UnsupportedOperationException("Cannot handle holes in page cache");
+ } else if (intIndex == cachedPages.size()) {
if (log.isTraceEnabled()) {
log.trace("Caching " + index);
}
diff --git a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
index d5949f4a2..403daceb3 100644
--- a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
@@ -232,7 +232,7 @@ public class StaticContentLayoutManager extends BlockStackingLayoutManager {
List returnList = new LinkedList();
while ((curLM = getChildLM()) != null) {
- LayoutContext childLC = new LayoutContext(0);
+ LayoutContext childLC = LayoutContext.newInstance();
childLC.setStackLimitBP(context.getStackLimitBP());
childLC.setRefIPD(context.getRefIPD());
childLC.setWritingMode(context.getWritingMode());
diff --git a/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java
index a7bc78be8..c3026e5e7 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java
@@ -24,6 +24,7 @@ import java.awt.Rectangle;
import java.util.List;
import org.apache.fop.area.Area;
+import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.InlineViewport;
import org.apache.fop.datatypes.LengthBase;
import org.apache.fop.fo.FObj;
@@ -92,7 +93,6 @@ public abstract class AbstractGraphicsLayoutManager extends LeafNodeLayoutManage
transferForeignAttributes(viewportArea);
InlineViewport vp = new InlineViewport(viewportArea, bidiLevel);
- TraitSetter.addStructureTreeElement(vp, fobj.getStructureTreeElement());
TraitSetter.setProducerID(vp, fobj.getId());
vp.setIPD(imageLayout.getViewportSize().width);
vp.setBPD(imageLayout.getViewportSize().height);
@@ -118,6 +118,21 @@ public abstract class AbstractGraphicsLayoutManager extends LeafNodeLayoutManage
return super.getNextKnuthElements(context, alignment);
}
+ @Override
+ protected InlineArea getEffectiveArea(LayoutContext layoutContext) {
+ /*
+ * If an image is in a repeated table heading, then it must be treated as real
+ * content the first time and then as artifact. Therefore we cannot re-use the
+ * area, as we have to account for the likely different values of treatAsArtifact.
+ */
+ InlineArea area = curArea != null ? curArea : getInlineArea();
+ curArea = null;
+ if (!layoutContext.treatAsArtifact()) {
+ TraitSetter.addStructureTreeElement(area, ((AbstractGraphics) fobj).getStructureTreeElement());
+ }
+ return area;
+ }
+
/** {@inheritDoc} */
protected AlignmentContext makeAlignmentContext(LayoutContext context) {
final AbstractGraphics fobj = (AbstractGraphics)this.fobj;
diff --git a/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java
index b9110de9e..cad6fd3cf 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java
@@ -19,17 +19,18 @@
package org.apache.fop.layoutmgr.inline;
-import org.apache.fop.area.Resolvable;
+import org.apache.fop.area.PageViewport;
import org.apache.fop.area.Trait;
import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.TextArea;
+import org.apache.fop.area.inline.UnresolvedPageNumber;
import org.apache.fop.fo.flow.AbstractPageNumberCitation;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.layoutmgr.LayoutContext;
-import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.TraitSetter;
+import org.apache.fop.traits.MinOptMax;
/**
* LayoutManager for the fo:page-number-citation(-last) formatting object
@@ -42,7 +43,9 @@ public abstract class AbstractPageNumberCitationLayoutManager extends LeafNodeLa
protected Font font;
/** Indicates whether the page referred to by the citation has been resolved yet */
- protected boolean resolved = false;
+ private boolean resolved;
+
+ private String citationString;
/**
* Constructor
@@ -78,47 +81,79 @@ public abstract class AbstractPageNumberCitationLayoutManager extends LeafNodeLa
);
}
- /** {@inheritDoc} */
- public abstract InlineArea get(LayoutContext context);
+ @Override
+ protected MinOptMax getAllocationIPD(int refIPD) {
+ determineCitationString();
+ int ipd = getStringWidth(citationString);
+ return MinOptMax.getInstance(ipd);
+ }
- /**
- * {@inheritDoc}
- * , LayoutContext)
- */
- public void addAreas(PositionIterator posIter, LayoutContext context) {
- super.addAreas(posIter, context);
- if (!resolved) {
- getPSLM().addUnresolvedArea(fobj.getRefId(), (Resolvable) curArea);
+ private void determineCitationString() {
+ assert citationString == null;
+ PageViewport page = getCitedPage();
+ if (page != null) {
+ resolved = true;
+ citationString = page.getPageNumberString();
+ } else {
+ resolved = false;
+ citationString = "MMM"; // Use a place holder
+ }
+ }
+
+ private int getStringWidth(String str) {
+ int width = 0;
+ for (int count = 0; count < str.length(); count++) {
+ width += font.getCharWidth(str.charAt(count));
+ }
+ return width;
+ }
+
+ protected abstract PageViewport getCitedPage();
+
+ @Override
+ protected InlineArea getEffectiveArea(LayoutContext layoutContext) {
+ InlineArea area = getPageNumberCitationArea();
+ if (!layoutContext.treatAsArtifact()) {
+ TraitSetter.addStructureTreeElement(area, fobj.getStructureTreeElement());
+ }
+ return area;
+ }
+
+ private InlineArea getPageNumberCitationArea() {
+ TextArea text;
+ if (resolved) {
+ text = new TextArea();
+ text.addWord(citationString, 0);
+ } else {
+ UnresolvedPageNumber unresolved = new UnresolvedPageNumber(fobj.getRefId(), font,
+ getReferenceType());
+ getPSLM().addUnresolvedArea(fobj.getRefId(), unresolved);
+ text = unresolved;
}
+ setTraits(text);
+ return text;
}
/**
- * Updates the traits for the generated text area.
- * @param text the text area
+ * @return {@link org.apache.fop.area.inline.UnresolvedPageNumber#FIRST} or
+ * {@link org.apache.fop.area.inline.UnresolvedPageNumber#LAST}
*/
- protected void updateTextAreaTraits(TextArea text) {
+ protected abstract boolean getReferenceType();
+
+ private void setTraits(TextArea text) {
TraitSetter.setProducerID(text, fobj.getId());
+ int bidiLevel = getBidiLevel();
+ text.setBidiLevel(bidiLevel);
+ int width = getStringWidth(citationString); // TODO: [GA] !I18N!
+ text.setIPD(width); // TODO: [GA] !I18N!
text.setBPD(font.getAscender() - font.getDescender());
text.setBaselineOffset(font.getAscender());
TraitSetter.addFontTraits(text, font);
text.addTrait(Trait.COLOR, fobj.getColor());
- TraitSetter.addStructureTreeElement(text, fobj.getStructureTreeElement());
TraitSetter.addTextDecoration(text, fobj.getTextDecoration());
}
/**
- * @param str string to be measured
- * @return width (in millipoints ??) of the string
- */
- protected int getStringWidth(String str) {
- int width = 0;
- for (int count = 0; count < str.length(); count++) {
- width += font.getCharWidth(str.charAt(count));
- }
- return width;
- }
-
- /**
* @return bidi level governing abstract page number citation
*/
protected int getBidiLevel() {
diff --git a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
index 32d4d1004..212170eae 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
@@ -23,6 +23,7 @@ import java.util.LinkedList;
import java.util.List;
import org.apache.fop.area.Trait;
+import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.fo.flow.Character;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
@@ -69,17 +70,15 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
hyphIPD = fobj.getCommonHyphenation().getHyphIPD(font);
borderProps = fobj.getCommonBorderPaddingBackground();
setCommonBorderPaddingBackground(borderProps);
- TextArea chArea = getCharacterInlineArea(fobj);
- chArea.setBaselineOffset(font.getAscender());
- setCurrentArea(chArea);
}
- private TextArea getCharacterInlineArea(Character node) {
+ private TextArea createCharacterArea() {
+ Character fobj = (Character) this.fobj;
TextArea text = new TextArea();
- char ch = node.getCharacter();
+ char ch = fobj.getCharacter();
int ipd = font.getCharWidth(ch);
int blockProgressionOffset = 0;
- int level = node.getBidiLevel();
+ int level = fobj.getBidiLevel();
if (CharUtilities.isAnySpace(ch)) {
// add space unless it's zero-width:
if (!CharUtilities.isZeroWidthSpace(ch)) {
@@ -90,32 +89,29 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
int[] levels = ( level >= 0 ) ? new int[] {level} : null;
text.addWord(String.valueOf(ch), ipd, null, levels, null, blockProgressionOffset);
}
- TraitSetter.setProducerID(text, node.getId());
- TraitSetter.addTextDecoration(text, node.getTextDecoration());
- TraitSetter.addStructureTreeElement(text, node.getStructureTreeElement());
+
+ TraitSetter.setProducerID(text, fobj.getId());
+ TraitSetter.addTextDecoration(text, fobj.getTextDecoration());
+ text.setIPD(font.getCharWidth(fobj.getCharacter()));
+ text.setBPD(font.getAscender() - font.getDescender());
+ text.setBaselineOffset(font.getAscender());
+ TraitSetter.addFontTraits(text, font);
+ text.addTrait(Trait.COLOR, fobj.getColor());
return text;
}
- /** {@inheritDoc} */
@Override
- public List getNextKnuthElements(LayoutContext context, int alignment) {
- MinOptMax ipd;
- curArea = get(context);
- KnuthSequence seq = new InlineKnuthSequence();
-
- if (curArea == null) {
- setFinished(true);
- return null;
+ protected InlineArea getEffectiveArea(LayoutContext layoutContext) {
+ InlineArea area = createCharacterArea();
+ if (!layoutContext.treatAsArtifact()) {
+ TraitSetter.addStructureTreeElement(area, ((Character) fobj).getStructureTreeElement());
}
+ return area;
+ }
- Character fobj = (Character)this.fobj;
-
- ipd = MinOptMax.getInstance(curArea.getIPD());
-
- curArea.setBPD(font.getAscender() - font.getDescender());
-
- TraitSetter.addFontTraits(curArea, font);
- curArea.addTrait(Trait.COLOR, fobj.getColor());
+ /** {@inheritDoc} */
+ public List getNextKnuthElements(LayoutContext context, int alignment) {
+ Character fobj = (Character) this.fobj;
// TODO: may need some special handling for fo:character
alignmentContext = new AlignmentContext(font
@@ -126,9 +122,11 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
, fobj.getDominantBaseline()
, context.getAlignmentContext());
+ KnuthSequence seq = new InlineKnuthSequence();
addKnuthElementsForBorderPaddingStart(seq);
// create the AreaInfo object to store the computed values
+ MinOptMax ipd = MinOptMax.getInstance(font.getCharWidth(fobj.getCharacter()));
areaInfo = new AreaInfo((short) 0, ipd, false, alignmentContext);
// node is a fo:Character
@@ -162,7 +160,7 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
/** {@inheritDoc} */
@Override
public String getWordChars(Position pos) {
- return ((TextArea) curArea).getText();
+ return String.valueOf(((Character) fobj).getCharacter());
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
index c7eaa1820..b3c768987 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
@@ -110,7 +110,8 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager
int ipd = 1000000;
- LayoutContext childLC = new LayoutContext(LayoutContext.NEW_AREA);
+ LayoutContext childLC = LayoutContext.newInstance();
+ childLC.setFlags(LayoutContext.NEW_AREA);
childLC.setLeadingSpace(new SpaceSpecifier(false));
childLC.setTrailingSpace(new SpaceSpecifier(false));
childLC.setRefIPD(ipd);
@@ -143,7 +144,7 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager
middlefollow = maxtb - lineLead;
}
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.newInstance();
lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
lc.setLeadingSpace(new SpaceSpecifier(false));
@@ -160,7 +161,7 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager
int savedIPD = ((InlineArea)holder).getIPD();
// set to zero the ipd adjustment ratio, to avoid spaces in the pattern
// to be modified
- LayoutContext childContext = new LayoutContext(context);
+ LayoutContext childContext = LayoutContext.copyOf(context);
childContext.setIPDAdjust(0.0);
childLM.addAreas(posIter, childContext);
((InlineArea)holder).setIPD(savedIPD);
diff --git a/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java
index 68a240ff1..50b88b5b9 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java
@@ -151,7 +151,7 @@ public class FootnoteLayoutManager extends InlineStackingLayoutManager {
citationLM.setParent(getParent());
// make the citationLM add its areas
- LayoutContext childContext = new LayoutContext(context);
+ LayoutContext childContext = LayoutContext.copyOf(context);
PositionIterator childPosIter = new PositionIterator(positionList.listIterator());
LayoutManager childLM;
while ((childLM = childPosIter.getNextChildLM()) != null) {
diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
index e87b29b2d..77ac8c4d6 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
@@ -283,7 +283,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
, context.getAlignmentContext());
}
- childLC = new LayoutContext(context);
+ childLC = LayoutContext.copyOf(context);
childLC.setAlignmentContext(alignmentContext);
if (context.startsNewArea()) {
@@ -439,7 +439,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
addId();
- setChildContext(new LayoutContext(context)); // Store current value
+ setChildContext(LayoutContext.copyOf(context)); // Store current value
// "Unwrap" the NonLeafPositions stored in parentIter and put
// them in a new list. Set lastLM to be the LayoutManager
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
index b3d3218ab..aa2f79759 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
@@ -191,7 +191,7 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager {
clm.addChildLM(lm);
lm.initialize();
- LayoutContext childContext = new LayoutContext(0);
+ LayoutContext childContext = LayoutContext.newInstance();
childContext.setAlignmentContext(context.getAlignmentContext());
contentList = clm.getNextKnuthElements(childContext, 0);
int width = clm.getStackingSize();
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java
index 203c7a7fc..001fde817 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java
@@ -188,7 +188,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
public void addAreas(PositionIterator posIter, LayoutContext context) {
addId();
- InlineArea area = getEffectiveArea();
+ InlineArea area = getEffectiveArea(context);
if (area.getAllocIPD() > 0 || area.getAllocBPD() > 0) {
offsetArea(area, context);
widthAdjustArea(area, context);
@@ -211,7 +211,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
* @return the effective area to be added to the area tree. Normally, this is simply "curArea"
* but in the case of page-number(-citation) curArea is cloned, updated and returned.
*/
- protected InlineArea getEffectiveArea() {
+ protected InlineArea getEffectiveArea(LayoutContext layoutContext) {
return curArea;
}
@@ -264,11 +264,6 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
public List getNextKnuthElements(LayoutContext context, int alignment) {
curArea = get(context);
- if (curArea == null) {
- setFinished(true);
- return null;
- }
-
alignmentContext = makeAlignmentContext(context);
MinOptMax ipd = getAllocationIPD(context.getRefIPD());
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
index 5b8145432..00cd427d9 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
@@ -674,7 +674,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
* @param context the LayoutContext
*/
private void collectInlineKnuthElements(LayoutContext context) {
- LayoutContext inlineLC = new LayoutContext(context);
+ LayoutContext inlineLC = LayoutContext.copyOf(context);
// convert all the text in a sequence of paragraphs made
// of KnuthBox, KnuthGlue and KnuthPenalty objects
@@ -1522,7 +1522,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
PositionIterator inlinePosIter = new KnuthPossPosIter(seq, startElementIndex,
endElementIndex + 1);
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.offspringOf(context);
lc.setAlignmentContext(alignmentContext);
lc.setSpaceAdjust(lbp.dAdjust);
lc.setIPDAdjust(lbp.ipdAdjust);
@@ -1577,12 +1577,12 @@ public class LineLayoutManager extends InlineStackingLayoutManager
LineArea lineArea = new LineArea();
setCurrentArea(lineArea);
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.newInstance();
lc.setAlignmentContext(alignmentContext);
setChildContext(lc);
PositionIterator childPosIter = new PositionIterator(positionList.listIterator());
- LayoutContext blocklc = new LayoutContext(0);
+ LayoutContext blocklc = LayoutContext.offspringOf(context);
blocklc.setLeadingSpace(new SpaceSpecifier(true));
blocklc.setTrailingSpace(new SpaceSpecifier(false));
blocklc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
diff --git a/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java
index b1ba38565..81846615f 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java
@@ -20,65 +20,36 @@
package org.apache.fop.layoutmgr.inline;
import org.apache.fop.area.PageViewport;
-import org.apache.fop.area.Resolvable;
-import org.apache.fop.area.inline.InlineArea;
-import org.apache.fop.area.inline.TextArea;
import org.apache.fop.area.inline.UnresolvedPageNumber;
import org.apache.fop.fo.flow.PageNumberCitationLast;
-import org.apache.fop.layoutmgr.LayoutContext;
-import org.apache.fop.layoutmgr.LayoutManager;
/**
- * LayoutManager for the fo:page-number-citation-last formatting object
+ * LayoutManager for the fo:page-number-citation-last formatting object.
*/
public class PageNumberCitationLastLayoutManager extends AbstractPageNumberCitationLayoutManager {
/**
- * Constructor
+ * Constructor.
*
* @param node the formatting object that creates this area
* TODO better retrieval of font info
*/
public PageNumberCitationLastLayoutManager(PageNumberCitationLast node) {
super(node);
- fobj = node;
}
- /** {@inheritDoc} */
- public InlineArea get(LayoutContext context) {
- curArea = getPageNumberCitationLastInlineArea(parentLayoutManager);
- return curArea;
- }
-
- /**
- * if id can be resolved then simply return a word, otherwise
- * return a resolvable area
- */
- private InlineArea getPageNumberCitationLastInlineArea(LayoutManager parentLM) {
- TextArea text = null;
- int level = getBidiLevel();
- if (!getPSLM().associateLayoutManagerID(fobj.getRefId())) {
- text = new UnresolvedPageNumber(fobj.getRefId(), font, UnresolvedPageNumber.LAST);
- getPSLM().addUnresolvedArea(fobj.getRefId(), (Resolvable)text);
- String str = "MMM"; // reserve three spaces for page number
- int width = getStringWidth(str);
- text.setBidiLevel(level);
- text.setIPD(width);
- resolved = false;
+ @Override
+ protected PageViewport getCitedPage() {
+ if (getPSLM().associateLayoutManagerID(fobj.getRefId())) {
+ return getPSLM().getLastPVWithID(fobj.getRefId());
} else {
- PageViewport page = getPSLM().getLastPVWithID(fobj.getRefId());
- String str = page.getPageNumberString();
- // get page string from parent, build area
- text = new TextArea();
- int width = getStringWidth(str);
- text.setBidiLevel(level);
- text.addWord(str, 0, level);
- text.setIPD(width);
- resolved = true;
+ return null;
}
+ }
- updateTextAreaTraits(text);
-
- return text;
+ @Override
+ protected boolean getReferenceType() {
+ return UnresolvedPageNumber.LAST;
}
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java
index 16ce09ec5..a4976f833 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java
@@ -20,19 +20,16 @@
package org.apache.fop.layoutmgr.inline;
import org.apache.fop.area.PageViewport;
-import org.apache.fop.area.inline.InlineArea;
-import org.apache.fop.area.inline.TextArea;
import org.apache.fop.area.inline.UnresolvedPageNumber;
import org.apache.fop.fo.flow.PageNumberCitation;
-import org.apache.fop.layoutmgr.LayoutContext;
/**
- * LayoutManager for the fo:page-number-citation formatting object
+ * LayoutManager for the fo:page-number-citation formatting object.
*/
public class PageNumberCitationLayoutManager extends AbstractPageNumberCitationLayoutManager {
/**
- * Constructor
+ * Constructor.
*
* @param node the formatting object that creates this area
* TODO better retrieval of font info
@@ -41,42 +38,14 @@ public class PageNumberCitationLayoutManager extends AbstractPageNumberCitationL
super(node);
}
- /** {@inheritDoc} */
- public InlineArea get(LayoutContext context) {
- curArea = getPageNumberCitationInlineArea();
- return curArea;
+ @Override
+ protected PageViewport getCitedPage() {
+ return getPSLM().getFirstPVWithID(fobj.getRefId());
}
- /**
- * if id can be resolved then simply return a word, otherwise
- * return a resolvable area
- *
- * TODO: [GA] May need to run bidi algorithm and script processor
- * on resolved page number.
- */
- private InlineArea getPageNumberCitationInlineArea() {
- PageViewport page = getPSLM().getFirstPVWithID(fobj.getRefId());
- TextArea text = null;
- int level = getBidiLevel();
- if (page != null) {
- String str = page.getPageNumberString();
- // get page string from parent, build area
- text = new TextArea();
- int width = getStringWidth(str); // TODO: [GA] !I18N!
- text.setBidiLevel(level);
- text.addWord(str, 0, level);
- text.setIPD(width); // TODO: [GA] !I18N!
- resolved = true;
- } else {
- text = new UnresolvedPageNumber(fobj.getRefId(), font);
- String str = "MMM"; // reserve three spaces for page number
- int width = getStringWidth(str); // TODO: [GA] !I18N!
- text.setBidiLevel(level);
- text.setIPD(width); // TODO: [GA] !I18N!
- resolved = false;
- }
- updateTextAreaTraits(text);
- return text;
+ @Override
+ protected boolean getReferenceType() {
+ return UnresolvedPageNumber.FIRST;
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java
index c3ee5af32..82e53666c 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java
@@ -85,14 +85,13 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager {
text.setBaselineOffset(font.getAscender());
TraitSetter.addFontTraits(text, font);
text.addTrait(Trait.COLOR, fobj.getColor());
- TraitSetter.addStructureTreeElement(text, fobj.getStructureTreeElement());
TraitSetter.addTextDecoration(text, fobj.getTextDecoration());
return text;
}
/** {@inheritDoc} */
- protected InlineArea getEffectiveArea() {
+ protected InlineArea getEffectiveArea(LayoutContext layoutContext) {
TextArea baseArea = (TextArea)curArea;
//TODO Maybe replace that with a clone() call or better, a copy constructor
//TODO or even better: delay area creation until addAreas() stage
@@ -105,6 +104,9 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager {
ta.setBaselineOffset(baseArea.getBaselineOffset());
ta.addTrait(Trait.COLOR, fobj.getColor()); //only to initialize the trait map
ta.getTraits().putAll(baseArea.getTraits());
+ if (!layoutContext.treatAsArtifact()) {
+ TraitSetter.addStructureTreeElement(ta, fobj.getStructureTreeElement());
+ }
updateContent(ta);
return ta;
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
index 645a78527..c2f69cf98 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
@@ -469,7 +469,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
TraitSetter.addFontTraits(textArea, font);
textArea.addTrait(Trait.COLOR, foText.getColor());
TraitSetter.addTextDecoration(textArea, foText.getTextDecoration());
- TraitSetter.addStructureTreeElement(textArea, foText.getStructureTreeElement());
+ if (!context.treatAsArtifact()) {
+ TraitSetter.addStructureTreeElement(textArea, foText.getStructureTreeElement());
+ }
return textArea;
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
index ca5179399..9b37e2405 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
@@ -71,7 +71,7 @@ public class WrapperLayoutManager extends LeafNodeLayoutManager {
TraitSetter.setProducerID(helperBlock, fobj.getId());
parentLayoutManager.addChildArea(helperBlock);
} else {
- InlineArea area = getEffectiveArea();
+ InlineArea area = getEffectiveArea(context);
parentLayoutManager.addChildArea(area);
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
index 5bd451ffb..480934bf3 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
@@ -141,7 +141,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager
// the list block contains areas stacked from each list item
LayoutManager childLM;
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.offspringOf(layoutContext);
LayoutManager firstLM = null;
LayoutManager lastLM = null;
Position firstPos = null;
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
index a84069082..3204a867e 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
@@ -20,6 +20,7 @@
package org.apache.fop.layoutmgr.list;
import java.util.LinkedList;
+import java.util.List;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
@@ -28,9 +29,11 @@ import org.apache.fop.fo.flow.ListItemBody;
import org.apache.fop.fo.flow.ListItemLabel;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
+import org.apache.fop.layoutmgr.BreakOpportunity;
import org.apache.fop.layoutmgr.Keep;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.LayoutManager;
+import org.apache.fop.layoutmgr.ListElement;
import org.apache.fop.layoutmgr.NonLeafPosition;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.layoutmgr.PositionIterator;
@@ -40,7 +43,7 @@ import org.apache.fop.layoutmgr.TraitSetter;
/**
* LayoutManager for a list-item-label or list-item-body FO.
*/
-public class ListItemContentLayoutManager extends BlockStackingLayoutManager {
+public class ListItemContentLayoutManager extends BlockStackingLayoutManager implements BreakOpportunity {
private Block curBlockArea;
@@ -98,7 +101,7 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager {
addId();
LayoutManager childLM;
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.offspringOf(layoutContext);
LayoutManager firstLM = null;
LayoutManager lastLM = null;
Position firstPos = null;
@@ -220,5 +223,16 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager {
public Keep getKeepWithPrevious() {
return Keep.KEEP_AUTO;
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<ListElement> getNextKnuthElements(LayoutContext context, int alignment) {
+ List<ListElement> elements = new LinkedList<ListElement>();
+ do {
+ elements.addAll(super.getNextKnuthElements(context, alignment));
+ } while (!isFinished());
+ return elements;
+ }
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
index bc7daa24f..32aa4c674 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
@@ -35,6 +35,8 @@ import org.apache.fop.fo.flow.ListItemLabel;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.BreakElement;
+import org.apache.fop.layoutmgr.BreakOpportunity;
+import org.apache.fop.layoutmgr.BreakOpportunityHelper;
import org.apache.fop.layoutmgr.ConditionalElementListener;
import org.apache.fop.layoutmgr.ElementListObserver;
import org.apache.fop.layoutmgr.ElementListUtils;
@@ -56,13 +58,14 @@ import org.apache.fop.layoutmgr.SpaceResolver;
import org.apache.fop.layoutmgr.TraitSetter;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.traits.SpaceVal;
+import org.apache.fop.util.BreakUtil;
/**
* LayoutManager for a list-item FO.
* The list item contains a list item label and a list item body.
*/
-public class ListItemLayoutManager extends BlockStackingLayoutManager
- implements ConditionalElementListener {
+public class ListItemLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener,
+ BreakOpportunity {
/** logging instance */
private static Log log = LogFactory.getLog(ListItemLayoutManager.class);
@@ -204,6 +207,7 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager
// label
childLC = makeChildLayoutContext(context);
+ childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
label.initialize();
labelList = label.getNextKnuthElements(childLC, alignment);
@@ -217,6 +221,7 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager
// body
childLC = makeChildLayoutContext(context);
+ childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
body.initialize();
bodyList = body.getNextKnuthElements(childLC, alignment);
@@ -296,16 +301,23 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager
//Additional penalty height from penalties in the source lists
int additionalPenaltyHeight = 0;
int stepPenalty = 0;
+ int breakClass = EN_AUTO;
KnuthElement endEl = (KnuthElement)elementLists[0].get(end[0]);
if (endEl instanceof KnuthPenalty) {
additionalPenaltyHeight = endEl.getWidth();
- stepPenalty = Math.max(stepPenalty, endEl.getPenalty());
+ stepPenalty = endEl.getPenalty() == -KnuthElement.INFINITE ? -KnuthElement.INFINITE : Math
+ .max(stepPenalty, endEl.getPenalty());
+ breakClass = BreakUtil.compareBreakClasses(breakClass,
+ ((KnuthPenalty) endEl).getBreakClass());
}
endEl = (KnuthElement)elementLists[1].get(end[1]);
if (endEl instanceof KnuthPenalty) {
additionalPenaltyHeight = Math.max(
additionalPenaltyHeight, endEl.getWidth());
- stepPenalty = Math.max(stepPenalty, endEl.getPenalty());
+ stepPenalty = endEl.getPenalty() == -KnuthElement.INFINITE ? -KnuthElement.INFINITE : Math
+ .max(stepPenalty, endEl.getPenalty());
+ breakClass = BreakUtil.compareBreakClasses(breakClass,
+ ((KnuthPenalty) endEl).getBreakClass());
}
int boxHeight = step - addedBoxHeight - penaltyHeight;
@@ -343,9 +355,9 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager
int p = stepPenalty;
if (p > -KnuthElement.INFINITE) {
p = Math.max(p, keep.getPenalty());
+ breakClass = keep.getContext();
}
- returnList.add(new BreakElement(stepPosition, penaltyHeight, p, keep.getContext(),
- context));
+ returnList.add(new BreakElement(stepPosition, penaltyHeight, p, breakClass, context));
}
}
@@ -476,7 +488,7 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager
addId();
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.offspringOf(layoutContext);
Position firstPos = null;
Position lastPos = null;
@@ -693,6 +705,13 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager
body.reset();
}
+ @Override
+ public int getBreakBefore() {
+ int breakBefore = BreakOpportunityHelper.getBreakBefore(this);
+ breakBefore = BreakUtil.compareBreakClasses(breakBefore, label.getBreakBefore());
+ breakBefore = BreakUtil.compareBreakClasses(breakBefore, body.getBreakBefore());
+ return breakBefore;
+ }
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
index f41f77ea4..ed46d2199 100644
--- a/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
@@ -112,7 +112,7 @@ class RowGroupLayoutManager {
spanWidth += ((TableColumn) colIter.next()).getColumnWidth().getValue(
tableLM);
}
- LayoutContext childLC = new LayoutContext(0);
+ LayoutContext childLC = LayoutContext.newInstance();
childLC.setStackLimitBP(context.getStackLimitBP()); //necessary?
childLC.setRefIPD(spanWidth);
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
index fc35a8069..0582a0283 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
@@ -81,7 +81,7 @@ public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager {
int ipd = context.getRefIPD();
BreakPoss bp;
- LayoutContext childLC = new LayoutContext(0);
+ LayoutContext childLC = LayoutContext.newInstance();
// if line layout manager then set stack limit to ipd
// line LM actually generates a LineArea which is a block
childLC.setStackLimit(
@@ -145,7 +145,7 @@ public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager {
/* TODO: Reimplement using Knuth approach
LayoutManager childLM;
int iStartPos = 0;
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.newInstance();
while (parentIter.hasNext()) {
LeafPosition lfp = (LeafPosition) parentIter.next();
// Add the block areas to Area
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
index 7ba0b5970..66f7ad9f2 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
@@ -76,7 +76,7 @@ public class TableCaptionLayoutManager extends BlockStackingLayoutManager {
int ipd = context.getRefIPD();
BreakPoss bp;
- LayoutContext childLC = new LayoutContext(0);
+ LayoutContext childLC = LayoutContext.newInstance();
// if line layout manager then set stack limit to ipd
// line LM actually generates a LineArea which is a block
childLC.setStackLimit(
@@ -141,7 +141,7 @@ public class TableCaptionLayoutManager extends BlockStackingLayoutManager {
/* TODO: Reimplement using Knuth approach
LayoutManager childLM;
int iStartPos = 0;
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.newInstance();
while (parentIter.hasNext()) {
LeafPosition lfp = (LeafPosition) parentIter.next();
// Add the block areas to Area
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
index d5f259b38..2ca5a26d1 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
@@ -144,7 +144,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
LayoutManager curLM; // currently active LM
LayoutManager prevLM = null; // previously active LM
while ((curLM = getChildLM()) != null) {
- LayoutContext childLC = new LayoutContext(0);
+ LayoutContext childLC = LayoutContext.newInstance();
// curLM is a ?
childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit));
childLC.setRefIPD(cellIPD);
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
index f5e7500e2..ea8774716 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
@@ -71,6 +71,8 @@ public class TableContentLayoutManager implements PercentBaseContext {
private TableStepper stepper;
+ private boolean headerIsBeingRepeated;
+
/**
* Main constructor
* @param parent Parent layout manager
@@ -383,6 +385,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
}
}
}
+ boolean treatFooterAsArtifact = layoutContext.treatAsArtifact();
if (lastPos instanceof TableHFPenaltyPosition) {
TableHFPenaltyPosition penaltyPos = (TableHFPenaltyPosition)lastPos;
LOG.debug("Break at penalty!");
@@ -393,6 +396,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
}
if (penaltyPos.footerElements != null) {
footerElements = penaltyPos.footerElements;
+ treatFooterAsArtifact = true;
}
}
@@ -403,10 +407,18 @@ public class TableContentLayoutManager implements PercentBaseContext {
}
if (headerElements != null) {
+ boolean ancestorTreatAsArtifact = layoutContext.treatAsArtifact();
+ if (headerIsBeingRepeated) {
+ layoutContext.setTreatAsArtifact(true);
+ }
//header positions for the last part are the second-to-last element and need to
//be handled first before all other TableContentPositions
addHeaderFooterAreas(headerElements, tableLM.getTable().getTableHeader(), painter,
false);
+ if (!ancestorTreatAsArtifact) {
+ headerIsBeingRepeated = true;
+ }
+ layoutContext.setTreatAsArtifact(ancestorTreatAsArtifact);
}
if (tablePositions.isEmpty()) {
@@ -419,9 +431,12 @@ public class TableContentLayoutManager implements PercentBaseContext {
}
if (footerElements != null) {
+ boolean ancestorTreatAsArtifact = layoutContext.treatAsArtifact();
+ layoutContext.setTreatAsArtifact(treatFooterAsArtifact);
//Positions for footers are simply added at the end
addHeaderFooterAreas(footerElements, tableLM.getTable().getTableFooter(), painter,
true);
+ layoutContext.setTreatAsArtifact(ancestorTreatAsArtifact);
}
this.usedBPD += painter.getAccumulatedBPD();
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
index 7e343697a..5a4152c69 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
@@ -242,7 +242,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager
// Elements for the table-header/footer/body
List contentKnuthElements;
contentLM = new TableContentLayoutManager(this);
- LayoutContext childLC = new LayoutContext(0);
+ LayoutContext childLC = LayoutContext.newInstance();
/*
childLC.setStackLimit(
MinOptMax.subtract(context.getStackLimit(),
@@ -355,7 +355,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager
// BPD of the table, i.e., height of its content; table's borders and paddings not counted
int tableHeight = 0;
//Body childLM;
- LayoutContext lc = new LayoutContext(0);
+ LayoutContext lc = LayoutContext.offspringOf(layoutContext);
lc.setRefIPD(getContentAreaIPD());
diff --git a/src/java/org/apache/fop/pdf/PDFArray.java b/src/java/org/apache/fop/pdf/PDFArray.java
index 131830328..78f5d080b 100644
--- a/src/java/org/apache/fop/pdf/PDFArray.java
+++ b/src/java/org/apache/fop/pdf/PDFArray.java
@@ -100,6 +100,15 @@ public class PDFArray extends PDFObject {
}
/**
+ * Creates an array object made of the given elements.
+ *
+ * @param elements the array content
+ */
+ public PDFArray(List<?> elements) {
+ this(null, elements);
+ }
+
+ /**
* Create the array object
* @param parent the array's parent if any
* @param values the actual array wrapped by this object
diff --git a/src/java/org/apache/fop/pdf/PDFDocument.java b/src/java/org/apache/fop/pdf/PDFDocument.java
index dad404d11..e46a22c4a 100644
--- a/src/java/org/apache/fop/pdf/PDFDocument.java
+++ b/src/java/org/apache/fop/pdf/PDFDocument.java
@@ -37,6 +37,7 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.pdf.StandardStructureAttributes.Table.Scope;
import org.apache.fop.pdf.xref.CrossReferenceStream;
import org.apache.fop.pdf.xref.CrossReferenceTable;
import org.apache.fop.pdf.xref.TrailerDictionary;
@@ -362,7 +363,7 @@ public class PDFDocument {
* hierarchy
* @return a dictionary of type StructElem
*/
- public PDFStructElem makeStructureElement(PDFName structureType, PDFObject parent) {
+ public PDFStructElem makeStructureElement(StructureType structureType, PDFObject parent) {
PDFStructElem structElem = new PDFStructElem(parent, structureType);
assignObjectNumber(structElem);
structureTreeElements.add(structElem);
@@ -370,6 +371,23 @@ public class PDFDocument {
}
/**
+ * Creates and returns a structure element.
+ *
+ * @param structureType the structure type of the new element (value for the
+ * S entry)
+ * @param parent the parent of the new structure element in the structure
+ * hierarchy
+ * @param scope the scope of the given table header element
+ * @return a dictionary of type StructElem
+ */
+ public PDFStructElem makeStructureElement(StructureType structureType, PDFObject parent,
+ Scope scope) {
+ PDFStructElem structElem = makeStructureElement(structureType, parent);
+ versionController.addTableHeaderScopeAttribute(structElem, scope);
+ return structElem;
+ }
+
+ /**
* Get the {@link PDFInfo} object for this document.
*
* @return the {@link PDFInfo} object
diff --git a/src/java/org/apache/fop/pdf/PDFProfile.java b/src/java/org/apache/fop/pdf/PDFProfile.java
index 580a9a791..98005e469 100644
--- a/src/java/org/apache/fop/pdf/PDFProfile.java
+++ b/src/java/org/apache/fop/pdf/PDFProfile.java
@@ -202,7 +202,8 @@ public class PDFProfile {
PDFDictionary markInfo = getDocument().getRoot().getMarkInfo();
if (markInfo == null) {
throw new PDFConformanceException(format(
- "{0} requires the MarkInfo dictionary to be present", getPDFAMode()));
+ "{0} requires that the accessibility option in the configuration file be enabled",
+ getPDFAMode()));
}
if (!Boolean.TRUE.equals(markInfo.get("Marked"))) {
throw new PDFConformanceException(format(err,
diff --git a/src/java/org/apache/fop/pdf/PDFStructElem.java b/src/java/org/apache/fop/pdf/PDFStructElem.java
index a77111170..28cebb3ee 100644
--- a/src/java/org/apache/fop/pdf/PDFStructElem.java
+++ b/src/java/org/apache/fop/pdf/PDFStructElem.java
@@ -26,6 +26,7 @@ import java.util.List;
import java.util.Locale;
import org.apache.fop.accessibility.StructureTreeElement;
+import org.apache.fop.pdf.StandardStructureAttributes.Table;
import org.apache.fop.util.LanguageTags;
/**
@@ -33,6 +34,8 @@ import org.apache.fop.util.LanguageTags;
*/
public class PDFStructElem extends PDFDictionary implements StructureTreeElement, CompressedObject {
+ private StructureType structureType;
+
private PDFStructElem parentElement;
/**
@@ -40,18 +43,25 @@ public class PDFStructElem extends PDFDictionary implements StructureTreeElement
*/
protected List<PDFObject> kids;
+ private List<PDFDictionary> attributes;
+
/**
* Creates a new structure element.
*
* @param parent parent of this element
* @param structureType the structure type of this element
*/
- PDFStructElem(PDFObject parent, PDFName structureType) {
+ PDFStructElem(PDFObject parent, StructureType structureType) {
+ this(parent);
+ this.structureType = structureType;
+ put("S", structureType.getName());
+ setParent(parent);
+ }
+
+ private PDFStructElem(PDFObject parent) {
if (parent instanceof PDFStructElem) {
parentElement = (PDFStructElem) parent;
}
- put("S", structureType);
- setParent(parent);
}
/**
@@ -72,9 +82,7 @@ public class PDFStructElem extends PDFDictionary implements StructureTreeElement
}
/**
- * Add a kid to this structure element. This element will then add itself to
- * its parent structure element if it has not already, and so will the
- * parent, and so on.
+ * Adds a kid to this structure element.
*
* @param kid element to be added
*/
@@ -111,8 +119,8 @@ public class PDFStructElem extends PDFDictionary implements StructureTreeElement
*
* @return the value of the S entry
*/
- public PDFName getStructureType() {
- return (PDFName) get("S");
+ public StructureType getStructureType() {
+ return structureType;
}
/**
@@ -145,9 +153,21 @@ public class PDFStructElem extends PDFDictionary implements StructureTreeElement
@Override
protected void writeDictionary(OutputStream out, StringBuilder textBuffer) throws IOException {
attachKids();
+ attachAttributes();
super.writeDictionary(out, textBuffer);
}
+ private void attachAttributes() {
+ if (attributes != null) {
+ if (attributes.size() == 1) {
+ put("A", attributes.get(0));
+ } else {
+ PDFArray array = new PDFArray(attributes);
+ put("A", array);
+ }
+ }
+ }
+
/**
* Attaches all valid kids to the kids array.
*
@@ -177,6 +197,24 @@ public class PDFStructElem extends PDFDictionary implements StructureTreeElement
return kidsAttached;
}
+ public void setTableAttributeColSpan(int colSpan) {
+ setTableAttributeRowColumnSpan("ColSpan", colSpan);
+ }
+
+ public void setTableAttributeRowSpan(int rowSpan) {
+ setTableAttributeRowColumnSpan("RowSpan", rowSpan);
+ }
+
+ private void setTableAttributeRowColumnSpan(String typeSpan, int span) {
+ PDFDictionary attribute = new PDFDictionary();
+ attribute.put("O", Table.NAME);
+ attribute.put(typeSpan, span);
+ if (attributes == null) {
+ attributes = new ArrayList<PDFDictionary>(2);
+ }
+ attributes.add(attribute);
+ }
+
/**
* Class representing a placeholder for a PDF Structure Element.
*/
@@ -196,13 +234,8 @@ public class PDFStructElem extends PDFDictionary implements StructureTreeElement
}
}
- /**
- * Constructor
- * @param parent -
- * @param name -
- */
- public Placeholder(PDFObject parent, String name) {
- super(parent, new PDFName(name));
+ public Placeholder(PDFObject parent) {
+ super(parent);
}
}
diff --git a/src/java/org/apache/fop/pdf/StandardStructureAttributes.java b/src/java/org/apache/fop/pdf/StandardStructureAttributes.java
new file mode 100644
index 000000000..0a93d46bb
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/StandardStructureAttributes.java
@@ -0,0 +1,69 @@
+/*
+ * 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.pdf;
+
+/**
+ * Standard attributes, as defined in section 10.7.5 of the PDF Reference, Fourth edition (PDF 1.5).
+ */
+public final class StandardStructureAttributes {
+
+ public static final class Table {
+
+ /**
+ * The name to use as an attribute owner. This is the value of the 'O' entry in
+ * the attribute's dictionary.
+ */
+ public static final PDFName NAME = new PDFName("Table");
+
+ public static enum Scope {
+ ROW("Row"),
+ COLUMN("Column"),
+ BOTH("Both");
+
+ private final PDFName name;
+
+ private Scope(String name) {
+ this.name = new PDFName(name);
+ }
+
+ /**
+ * Returns the name of this attribute.
+ *
+ * @return a name suitable for use as a value in the attribute's dictionary
+ */
+ public PDFName getName() {
+ return name;
+ }
+
+ /**
+ * Sets the given scope on the given table header element.
+ */
+ static void addScopeAttribute(PDFStructElem th, Scope scope) {
+ PDFDictionary scopeAttribute = new PDFDictionary();
+ scopeAttribute.put("O", Table.NAME);
+ scopeAttribute.put("Scope", scope.getName());
+ th.put("A", scopeAttribute);
+ }
+ }
+ }
+
+ private StandardStructureAttributes() { }
+
+}
diff --git a/src/java/org/apache/fop/pdf/StandardStructureTypes.java b/src/java/org/apache/fop/pdf/StandardStructureTypes.java
new file mode 100644
index 000000000..dc045e180
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/StandardStructureTypes.java
@@ -0,0 +1,132 @@
+/*
+ * 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.pdf;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Standard structure types, as defined in section 10.7.4 of the PDF Reference, Fourth Edition (PDF 1.5).
+ */
+public final class StandardStructureTypes {
+
+ public static final class Grouping {
+
+ public static final StructureType DOCUMENT = new StructureTypeImpl("Document");
+ public static final StructureType PART = new StructureTypeImpl("Part");
+ public static final StructureType ART = new StructureTypeImpl("Art");
+ public static final StructureType SECT = new StructureTypeImpl("Sect");
+ public static final StructureType DIV = new StructureTypeImpl("Div");
+ public static final StructureType BLOCK_QUOTE = new StructureTypeImpl("BlockQuote");
+ public static final StructureType CAPTION = new StructureTypeImpl("Caption");
+ public static final StructureType TOC = new StructureTypeImpl("TOC");
+ public static final StructureType TOCI = new StructureTypeImpl("TOCI");
+ public static final StructureType INDEX = new StructureTypeImpl("Index");
+ public static final StructureType NON_STRUCT = new StructureTypeImpl("NonStruct");
+ public static final StructureType PRIVATE = new StructureTypeImpl("Private");
+ }
+
+ public static final class Paragraphlike {
+ public static final StructureType H = new StructureTypeImpl("H");
+ public static final StructureType H1 = new StructureTypeImpl("H1");
+ public static final StructureType H2 = new StructureTypeImpl("H2");
+ public static final StructureType H3 = new StructureTypeImpl("H3");
+ public static final StructureType H4 = new StructureTypeImpl("H4");
+ public static final StructureType H5 = new StructureTypeImpl("H5");
+ public static final StructureType H6 = new StructureTypeImpl("H6");
+ public static final StructureType P = new StructureTypeImpl("P");
+ }
+
+ public static final class List {
+ public static final StructureType L = new StructureTypeImpl("L");
+ public static final StructureType LI = new StructureTypeImpl("LI");
+ public static final StructureType LBL = new StructureTypeImpl("Lbl");
+ public static final StructureType LBODY = new StructureTypeImpl("LBody");
+ }
+
+ public static final class Table {
+ public static final StructureType TABLE = new StructureTypeImpl("Table");
+ public static final StructureType TR = new StructureTypeImpl("TR");
+ public static final StructureType TH = new StructureTypeImpl("TH");
+ public static final StructureType TD = new StructureTypeImpl("TD");
+ public static final StructureType THEAD = new StructureTypeImpl("THead");
+ public static final StructureType TBODY = new StructureTypeImpl("TBody");
+ public static final StructureType TFOOT = new StructureTypeImpl("TFoot");
+ }
+
+ public static final class InlineLevelStructure {
+ public static final StructureType SPAN = new StructureTypeImpl("Span");
+ public static final StructureType QUOTE = new StructureTypeImpl("Quote");
+ public static final StructureType NOTE = new StructureTypeImpl("Note");
+ public static final StructureType REFERENCE = new StructureTypeImpl("Reference");
+ public static final StructureType BIB_ENTRY = new StructureTypeImpl("BibEntry");
+ public static final StructureType CODE = new StructureTypeImpl("Code");
+ public static final StructureType LINK = new StructureTypeImpl("Link");
+ public static final StructureType ANNOT = new StructureTypeImpl("Annot");
+ }
+
+ public static final class RubyOrWarichu {
+ public static final StructureType RUBY = new StructureTypeImpl("Ruby");
+ public static final StructureType RB = new StructureTypeImpl("RB");
+ public static final StructureType RT = new StructureTypeImpl("RT");
+ public static final StructureType RP = new StructureTypeImpl("RP");
+ public static final StructureType WARICHU = new StructureTypeImpl("Warichu");
+ public static final StructureType WT = new StructureTypeImpl("WT");
+ public static final StructureType WP = new StructureTypeImpl("WP");
+ }
+
+ public static final class Illustration {
+ public static final StructureType FIGURE = new StructureTypeImpl("Figure");
+ public static final StructureType FORMULA = new StructureTypeImpl("Formula");
+ public static final StructureType FORM = new StructureTypeImpl("Form");
+ }
+
+ private static class StructureTypeImpl implements StructureType {
+
+ private final PDFName name;
+
+ protected StructureTypeImpl(String name) {
+ this.name = new PDFName(name);
+ StandardStructureTypes.STRUCTURE_TYPES.put(name, this);
+ }
+
+ public PDFName getName() {
+ return name;
+ }
+
+ }
+
+ private static final Map<String, StructureType> STRUCTURE_TYPES = new HashMap<String, StructureType>();
+
+ private StandardStructureTypes() { }
+
+ /**
+ * Returns the standard structure type of the given name.
+ *
+ * @param name the name of a structure type, case sensitive. For example, Document,
+ * Sect, H1, etc.
+ * @return the corresponding {@code StructureType} instance, or {@code null} if the given
+ * name does not correspond to a standard structure type
+ */
+ public static StructureType get(String name) {
+ return STRUCTURE_TYPES.get(name);
+ }
+
+}
diff --git a/src/java/org/apache/fop/pdf/StreamCacheFactory.java b/src/java/org/apache/fop/pdf/StreamCacheFactory.java
index aa4d665da..e81edf62a 100644
--- a/src/java/org/apache/fop/pdf/StreamCacheFactory.java
+++ b/src/java/org/apache/fop/pdf/StreamCacheFactory.java
@@ -30,7 +30,6 @@ public final class StreamCacheFactory {
/**
* Returns an instance of a StreamCacheFactory with the requested features.
- * @param cacheToFile True if file shall be cached using a temporary file
* @return StreamCacheFactory the requested factory
*/
public static StreamCacheFactory getInstance() {
diff --git a/src/java/org/apache/fop/pdf/StructureType.java b/src/java/org/apache/fop/pdf/StructureType.java
new file mode 100644
index 000000000..7b9b4c169
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/StructureType.java
@@ -0,0 +1,34 @@
+/*
+ * 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.pdf;
+
+/**
+ * A structure type, as defined in Section 10.6.2 of the PDF Reference, fourth edition (PDF 1.5).
+ */
+public interface StructureType {
+
+ /**
+ * Returns the name of this structure type.
+ *
+ * @return the name object identifying this structure type
+ */
+ PDFName getName();
+
+}
diff --git a/src/java/org/apache/fop/pdf/VersionController.java b/src/java/org/apache/fop/pdf/VersionController.java
index 4a92f4994..bd5e4d20f 100644
--- a/src/java/org/apache/fop/pdf/VersionController.java
+++ b/src/java/org/apache/fop/pdf/VersionController.java
@@ -19,6 +19,8 @@
package org.apache.fop.pdf;
+import org.apache.fop.pdf.StandardStructureAttributes.Table.Scope;
+
/**
* An abstraction that controls the mutability of the PDF version for a document.
*/
@@ -47,6 +49,8 @@ public abstract class VersionController {
*/
public abstract void setPDFVersion(Version version);
+ abstract void addTableHeaderScopeAttribute(PDFStructElem th, Scope scope);
+
@Override
public String toString() {
return version.toString();
@@ -67,6 +71,13 @@ public abstract class VersionController {
public void setPDFVersion(Version version) {
throw new IllegalStateException("Cannot change the version of this PDF document.");
}
+
+ @Override
+ void addTableHeaderScopeAttribute(PDFStructElem th, Scope scope) {
+ if (super.version.compareTo(Version.V1_4) > 0) {
+ Scope.addScopeAttribute(th, scope);
+ }
+ }
}
/**
@@ -91,6 +102,12 @@ public abstract class VersionController {
doc.getRoot().setVersion(version);
}
}
+
+ @Override
+ void addTableHeaderScopeAttribute(PDFStructElem th, Scope scope) {
+ setPDFVersion(Version.V1_5);
+ Scope.addScopeAttribute(th, scope);
+ }
}
/**
diff --git a/src/java/org/apache/fop/render/AbstractRendererMaker.java b/src/java/org/apache/fop/render/AbstractRendererMaker.java
index b4a281efa..505a60a1c 100644
--- a/src/java/org/apache/fop/render/AbstractRendererMaker.java
+++ b/src/java/org/apache/fop/render/AbstractRendererMaker.java
@@ -46,10 +46,10 @@ public abstract class AbstractRendererMaker {
public abstract String[] getSupportedMimeTypes();
/**
- * Returns a renderer config object that can be used to
- * configure the renderer.
+ * Configures a given renderer using the appropriate configurator.
+ *
* @param userAgent user agent
- * @return a config object that can be used to configure the renderer
+ * @param renderer the renderer that is to be configured
*/
public abstract void configureRenderer(FOUserAgent userAgent, Renderer renderer)
throws FOPException;
diff --git a/src/java/org/apache/fop/render/PrintRendererConfigurator.java b/src/java/org/apache/fop/render/PrintRendererConfigurator.java
index 8de2d1a92..96da591c1 100644
--- a/src/java/org/apache/fop/render/PrintRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/PrintRendererConfigurator.java
@@ -36,6 +36,7 @@ import org.apache.fop.fonts.FontManager;
import org.apache.fop.render.RendererConfig.RendererConfigParser;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+import org.apache.fop.render.pdf.PDFRendererConfig.PDFRendererConfigParser;
/**
* Base Print renderer configurator (mostly handles font configuration)
@@ -166,7 +167,9 @@ public abstract class PrintRendererConfigurator extends AbstractRendererConfigur
}
public static PrintRendererConfigurator createDefaultInstance(FOUserAgent userAgent) {
- return new PrintRendererConfigurator(userAgent, null) {
+ // Since PDF is the default output is PDF, it makes sense for the default config parser
+ // to also be the PDF flavour
+ return new PrintRendererConfigurator(userAgent, new PDFRendererConfigParser()) {
@Override
protected List<FontCollection> getDefaultFontCollection() {
throw new UnsupportedOperationException();
diff --git a/src/java/org/apache/fop/render/afp/AFPFontConfig.java b/src/java/org/apache/fop/render/afp/AFPFontConfig.java
index eca76078f..aef0b666c 100644
--- a/src/java/org/apache/fop/render/afp/AFPFontConfig.java
+++ b/src/java/org/apache/fop/render/afp/AFPFontConfig.java
@@ -329,8 +329,8 @@ public final class AFPFontConfig implements FontConfig {
AFPResourceAccessor accessor = getAccessor(resourceResolver);
CharacterSet characterSet = CharacterSetBuilder.getDoubleByteInstance().buildDBCS(
characterset, super.codePage, super.encoding, charsetType, accessor, eventProducer);
- return getFontInfo(new DoubleByteFont(super.codePage, super.embeddable, characterSet),
- this);
+ return getFontInfo(new DoubleByteFont(super.codePage, super.embeddable, characterSet,
+ eventProducer), this);
}
}
@@ -365,7 +365,8 @@ public final class AFPFontConfig implements FontConfig {
characterSet = CharacterSetBuilder.getSingleByteInstance().buildSBCS(
characterset, super.codePage, super.encoding, accessor, eventProducer);
}
- return getFontInfo(new OutlineFont(super.name, super.embeddable, characterSet), this);
+ return getFontInfo(new OutlineFont(super.name, super.embeddable, characterSet,
+ eventProducer), this);
}
}
diff --git a/src/java/org/apache/fop/render/intermediate/IFDocumentHandlerConfigurator.java b/src/java/org/apache/fop/render/intermediate/IFDocumentHandlerConfigurator.java
index c00ebe29e..a55f42e9d 100644
--- a/src/java/org/apache/fop/render/intermediate/IFDocumentHandlerConfigurator.java
+++ b/src/java/org/apache/fop/render/intermediate/IFDocumentHandlerConfigurator.java
@@ -29,6 +29,7 @@ public interface IFDocumentHandlerConfigurator {
/**
* Configures a intermediate format document handler.
+ *
* @param documentHandler the document handler instance
* @throws FOPException if an error occurs while configuring the object
*/
@@ -36,10 +37,10 @@ public interface IFDocumentHandlerConfigurator {
/**
* Sets up the {@link FontInfo} object for the IFDocumentHandler.
- * @param documentHandler the document handler instance
+ *
+ * @param mimeType the MIME type of the document handler
* @param fontInfo the font info object to set up
* @throws FOPException if an error occurs while configuring the object
*/
void setupFontInfo(String mimeType, FontInfo fontInfo) throws FOPException;
-
}
diff --git a/src/java/org/apache/fop/render/pcl/PCLGraphics2D.java b/src/java/org/apache/fop/render/pcl/PCLGraphics2D.java
index 3fc988110..0fbf86c2c 100644
--- a/src/java/org/apache/fop/render/pcl/PCLGraphics2D.java
+++ b/src/java/org/apache/fop/render/pcl/PCLGraphics2D.java
@@ -25,7 +25,6 @@ import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Shape;
@@ -44,6 +43,7 @@ import java.text.AttributedCharacterIterator;
import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
import org.apache.xmlgraphics.java2d.GraphicContext;
+import org.apache.xmlgraphics.java2d.GraphicsConfigurationWithTransparency;
import org.apache.xmlgraphics.util.UnitConv;
/**
@@ -127,8 +127,7 @@ public class PCLGraphics2D extends AbstractGraphics2D {
/** {@inheritDoc} */
public GraphicsConfiguration getDeviceConfiguration() {
- return GraphicsEnvironment.getLocalGraphicsEnvironment()
- .getDefaultScreenDevice().getDefaultConfiguration();
+ return new GraphicsConfigurationWithTransparency();
}
/**
diff --git a/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java b/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java
index 0f752e886..68bfd8686 100644
--- a/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java
+++ b/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java
@@ -19,145 +19,66 @@
package org.apache.fop.render.pdf;
-import java.util.HashMap;
import java.util.Map;
import org.apache.fop.events.EventBroadcaster;
-import org.apache.fop.pdf.PDFName;
import org.apache.fop.pdf.PDFObject;
import org.apache.fop.pdf.PDFStructElem;
+import org.apache.fop.pdf.StandardStructureTypes;
+import org.apache.fop.pdf.StructureType;
/**
* This class provides the standard mappings from Formatting Objects to PDF structure types.
*/
final class FOToPDFRoleMap {
- /**
- * Standard structure types defined by the PDF Reference, Fourth Edition (PDF 1.5).
- */
- private static final Map<String, PDFName> STANDARD_STRUCTURE_TYPES
- = new HashMap<String, PDFName>();
-
- private static final Map<String, Mapper> DEFAULT_MAPPINGS
- = new java.util.HashMap<String, Mapper>();
-
- private static final PDFName THEAD;
- private static final PDFName NON_STRUCT;
+ private static final Map<String, Mapper> DEFAULT_MAPPINGS = new java.util.HashMap<String, Mapper>();
static {
- // Create PDFNames for the standard structure types
- // Table 10.18: Grouping elements
- addStructureType("Document");
- addStructureType("Part");
- addStructureType("Art");
- addStructureType("Sect");
- addStructureType("Div");
- addStructureType("BlockQuote");
- addStructureType("Caption");
- addStructureType("TOC");
- addStructureType("TOCI");
- addStructureType("Index");
- addStructureType("NonStruct");
- addStructureType("Private");
- // Table 10.20: Paragraphlike elements
- addStructureType("H");
- addStructureType("H1");
- addStructureType("H2");
- addStructureType("H3");
- addStructureType("H4");
- addStructureType("H5");
- addStructureType("H6");
- addStructureType("P");
- // Table 10.21: List elements
- addStructureType("L");
- addStructureType("LI");
- addStructureType("Lbl");
- addStructureType("LBody");
- // Table 10.22: Table elements
- addStructureType("Table");
- addStructureType("TR");
- addStructureType("TH");
- addStructureType("TD");
- addStructureType("THead");
- addStructureType("TBody");
- addStructureType("TFoot");
- // Table 10.23: Inline-level structure elements
- addStructureType("Span");
- addStructureType("Quote");
- addStructureType("Note");
- addStructureType("Reference");
- addStructureType("BibEntry");
- addStructureType("Code");
- addStructureType("Link");
- addStructureType("Annot");
- // Table 10.24: Ruby and Warichu elements
- addStructureType("Ruby");
- addStructureType("RB");
- addStructureType("RT");
- addStructureType("RP");
- addStructureType("Warichu");
- addStructureType("WT");
- addStructureType("WP");
- // Table 10.25: Illustration elements
- addStructureType("Figure");
- addStructureType("Formula");
- addStructureType("Form");
-
- NON_STRUCT = STANDARD_STRUCTURE_TYPES.get("NonStruct");
- assert NON_STRUCT != null;
- THEAD = STANDARD_STRUCTURE_TYPES.get("THead");
- assert THEAD != null;
-
// Create the standard mappings
// Declarations and Pagination and Layout Formatting Objects
- addMapping("root", "Document");
- addMapping("page-sequence", "Part");
- addMapping("flow", "Sect");
- addMapping("static-content", "Sect");
+ addMapping("root", StandardStructureTypes.Grouping.DOCUMENT);
+ addMapping("page-sequence", StandardStructureTypes.Grouping.PART);
+ addMapping("flow", StandardStructureTypes.Grouping.SECT);
+ addMapping("static-content", StandardStructureTypes.Grouping.SECT);
// Block-level Formatting Objects
- addMapping("block", "P");
- addMapping("block-container", "Div");
+ addMapping("block", StandardStructureTypes.Paragraphlike.P);
+ addMapping("block-container", StandardStructureTypes.Grouping.DIV);
// Inline-level Formatting Objects
- addMapping("character", "Span");
- addMapping("external-graphic", "Figure");
- addMapping("instream-foreign-object", "Figure");
- addMapping("inline", "Span");
- addMapping("inline-container", "Div");
- addMapping("page-number", "Quote");
- addMapping("page-number-citation", "Quote");
- addMapping("page-number-citation-last", "Quote");
+ addMapping("character", StandardStructureTypes.InlineLevelStructure.SPAN);
+ addMapping("external-graphic", StandardStructureTypes.Illustration.FIGURE);
+ addMapping("instream-foreign-object", StandardStructureTypes.Illustration.FIGURE);
+ addMapping("inline", StandardStructureTypes.InlineLevelStructure.SPAN);
+ addMapping("inline-container", StandardStructureTypes.Grouping.DIV);
+ addMapping("page-number", StandardStructureTypes.InlineLevelStructure.QUOTE);
+ addMapping("page-number-citation", StandardStructureTypes.InlineLevelStructure.QUOTE);
+ addMapping("page-number-citation-last", StandardStructureTypes.InlineLevelStructure.QUOTE);
// Formatting Objects for Tables
- addMapping("table-and-caption", "Div");
- addMapping("table", "Table");
- addMapping("table-caption", "Caption");
- addMapping("table-header", "THead");
- addMapping("table-footer", "TFoot");
- addMapping("table-body", "TBody");
- addMapping("table-row", "TR");
+ addMapping("table-and-caption", StandardStructureTypes.Grouping.DIV);
+ addMapping("table", StandardStructureTypes.Table.TABLE);
+ addMapping("table-caption", StandardStructureTypes.Grouping.CAPTION);
+ addMapping("table-header", StandardStructureTypes.Table.THEAD);
+ addMapping("table-footer", StandardStructureTypes.Table.TFOOT);
+ addMapping("table-body", StandardStructureTypes.Table.TBODY);
+ addMapping("table-row", StandardStructureTypes.Table.TR);
addMapping("table-cell", new TableCellMapper());
// Formatting Objects for Lists
- addMapping("list-block", "L");
- addMapping("list-item", "LI");
- addMapping("list-item-body", "LBody");
- addMapping("list-item-label", "Lbl");
+ addMapping("list-block", StandardStructureTypes.List.L);
+ addMapping("list-item", StandardStructureTypes.List.LI);
+ addMapping("list-item-body", StandardStructureTypes.List.LBODY);
+ addMapping("list-item-label", StandardStructureTypes.List.LBL);
// Dynamic Effects: Link and Multi Formatting Objects
- addMapping("basic-link", "Link");
+ addMapping("basic-link", StandardStructureTypes.InlineLevelStructure.LINK);
// Out-of-Line Formatting Objects
- addMapping("float", "Div");
- addMapping("footnote", "Note");
- addMapping("footnote-body", "Sect");
- addMapping("wrapper", "Span");
- addMapping("marker", "Private");
- }
-
- private static void addStructureType(String structureType) {
- STANDARD_STRUCTURE_TYPES.put(structureType, new PDFName(structureType));
+ addMapping("float", StandardStructureTypes.Grouping.DIV);
+ addMapping("footnote", StandardStructureTypes.InlineLevelStructure.NOTE);
+ addMapping("footnote-body", StandardStructureTypes.Grouping.SECT);
+ addMapping("wrapper", StandardStructureTypes.InlineLevelStructure.SPAN);
+ addMapping("marker", StandardStructureTypes.Grouping.PRIVATE);
}
- private static void addMapping(String fo, String structureType) {
- PDFName type = STANDARD_STRUCTURE_TYPES.get(structureType);
- assert type != null;
- addMapping(fo, new SimpleMapper(type));
+ private static void addMapping(String fo, StructureType structureType) {
+ addMapping(fo, new SimpleMapper(structureType));
}
private static void addMapping(String fo, Mapper mapper) {
@@ -173,13 +94,13 @@ final class FOToPDFRoleMap {
* @param eventBroadcaster the event broadcaster
* @return the structure type or null if no match could be found
*/
- public static PDFName mapFormattingObject(String fo, String role,
+ public static StructureType mapFormattingObject(String fo, String role,
PDFObject parent, EventBroadcaster eventBroadcaster) {
- PDFName type = null;
+ StructureType type = null;
if (role == null) {
type = getDefaultMappingFor(fo, parent);
} else {
- type = STANDARD_STRUCTURE_TYPES.get(role);
+ type = StandardStructureTypes.get(role);
if (type == null) {
type = getDefaultMappingFor(fo, parent);
PDFEventProducer.Provider.get(eventBroadcaster).nonStandardStructureType(fo,
@@ -196,28 +117,28 @@ final class FOToPDFRoleMap {
* @param parent the parent of the structure element to be mapped
* @return the structure type or NonStruct if no match could be found
*/
- private static PDFName getDefaultMappingFor(String fo, PDFObject parent) {
+ private static StructureType getDefaultMappingFor(String fo, PDFObject parent) {
Mapper mapper = DEFAULT_MAPPINGS.get(fo);
if (mapper != null) {
return mapper.getStructureType(parent);
} else {
- return NON_STRUCT;
+ return StandardStructureTypes.Grouping.NON_STRUCT;
}
}
private interface Mapper {
- PDFName getStructureType(PDFObject parent);
+ StructureType getStructureType(PDFObject parent);
}
private static class SimpleMapper implements Mapper {
- private PDFName structureType;
+ private StructureType structureType;
- public SimpleMapper(PDFName structureType) {
+ public SimpleMapper(StructureType structureType) {
this.structureType = structureType;
}
- public PDFName getStructureType(PDFObject parent) {
+ public StructureType getStructureType(PDFObject parent) {
return structureType;
}
@@ -225,17 +146,14 @@ final class FOToPDFRoleMap {
private static class TableCellMapper implements Mapper {
- public PDFName getStructureType(PDFObject parent) {
+ public StructureType getStructureType(PDFObject parent) {
PDFStructElem grandParent = ((PDFStructElem) parent).getParentStructElem();
//TODO What to do with cells from table-footer? Currently they are mapped on TD.
- PDFName type;
- if (THEAD.equals(grandParent.getStructureType())) {
- type = STANDARD_STRUCTURE_TYPES.get("TH");
+ if (grandParent.getStructureType() == StandardStructureTypes.Table.THEAD) {
+ return StandardStructureTypes.Table.TH;
} else {
- type = STANDARD_STRUCTURE_TYPES.get("TD");
+ return StandardStructureTypes.Table.TD;
}
- assert type != null;
- return type;
}
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java b/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
index 6559e8d56..ee00d2401 100644
--- a/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
+++ b/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
@@ -132,7 +132,7 @@ class PDFLogicalStructureHandler {
? structureTreeElement.getParentStructElem()
: structureTreeElement;
pageParentTreeArray.add(parent);
- String type = parent.getStructureType().toString();
+ String type = parent.getStructureType().getName().toString();
int mcid = pageParentTreeArray.length() - 1;
return new MarkedContentInfo(type, mcid, structureTreeElement);
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java b/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
index 049345609..0de7443bf 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
@@ -185,7 +185,7 @@ public final class PDFRendererConfig implements RendererConfig {
}
debug.append(filterList.get(j));
}
- LogUtil.handleError(LOG, debug.toString(), true);
+ LOG.debug(debug.toString());
}
if (filterMap.get(type) != null) {
diff --git a/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java b/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
index 3839d47bc..1377bbfce 100644
--- a/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
+++ b/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
@@ -29,18 +29,18 @@ import org.apache.fop.accessibility.StructureTreeEventHandler;
import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.pdf.PDFFactory;
-import org.apache.fop.pdf.PDFName;
import org.apache.fop.pdf.PDFObject;
import org.apache.fop.pdf.PDFParentTree;
import org.apache.fop.pdf.PDFStructElem;
import org.apache.fop.pdf.PDFStructTreeRoot;
+import org.apache.fop.pdf.StandardStructureAttributes.Table.Scope;
+import org.apache.fop.pdf.StandardStructureTypes.Table;
+import org.apache.fop.pdf.StructureType;
class PDFStructureTreeBuilder implements StructureTreeEventHandler {
private PDFFactory pdfFactory;
- private PDFLogicalStructureHandler logicalStructureHandler;
-
private EventBroadcaster eventBroadcaster;
private LinkedList<PDFStructElem> ancestors = new LinkedList<PDFStructElem>();
@@ -52,11 +52,10 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
}
void setLogicalStructureHandler(PDFLogicalStructureHandler logicalStructureHandler) {
- this.logicalStructureHandler = logicalStructureHandler;
- createRootStructureElement();
+ createRootStructureElement(logicalStructureHandler);
}
- private void createRootStructureElement() {
+ private void createRootStructureElement(PDFLogicalStructureHandler logicalStructureHandler) {
assert rootStructureElement == null;
PDFParentTree parentTree = logicalStructureHandler.getParentTree();
PDFStructTreeRoot structTreeRoot = pdfFactory.getDocument().makeStructTreeRoot(parentTree);
@@ -79,8 +78,13 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
}
private PDFStructElem createStructureElement(String name, PDFObject parent, String role) {
- PDFName structureType = FOToPDFRoleMap.mapFormattingObject(name, role, parent, eventBroadcaster);
- return pdfFactory.getDocument().makeStructureElement(structureType, parent);
+ StructureType structureType = FOToPDFRoleMap.mapFormattingObject(name, role, parent,
+ eventBroadcaster);
+ if (structureType == Table.TH) {
+ return pdfFactory.getDocument().makeStructureElement(structureType, parent, Scope.COLUMN);
+ } else {
+ return pdfFactory.getDocument().makeStructureElement(structureType, parent);
+ }
}
public void endPageSequence() {
@@ -90,11 +94,23 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
PDFStructElem parent = ancestors.getFirst();
String role = attributes.getValue("role");
PDFStructElem structElem = createStructureElement(name, parent, role);
+ setSpanAttributes(structElem, attributes);
parent.addKid(structElem);
ancestors.addFirst(structElem);
return structElem;
}
+ private void setSpanAttributes(PDFStructElem structElem, Attributes attributes) {
+ String columnSpan = attributes.getValue("number-columns-spanned");
+ if (columnSpan != null) {
+ structElem.setTableAttributeColSpan(Integer.parseInt(columnSpan));
+ }
+ String rowSpan = attributes.getValue("number-rows-spanned");
+ if (rowSpan != null) {
+ structElem.setTableAttributeRowSpan(Integer.parseInt(rowSpan));
+ }
+ }
+
public void endNode(String name) {
removeFirstAncestor();
}
@@ -123,7 +139,7 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
String role = attributes.getValue("role");
PDFStructElem structElem;
if ("#PCDATA".equals(name)) {
- structElem = new PDFStructElem.Placeholder(parent, name);
+ structElem = new PDFStructElem.Placeholder(parent);
} else {
structElem = createStructureElement(name, parent, role);
}
diff --git a/src/java/org/apache/fop/render/ps/PSRendererOption.java b/src/java/org/apache/fop/render/ps/PSRendererOption.java
index 4c3396921..992ca1959 100644
--- a/src/java/org/apache/fop/render/ps/PSRendererOption.java
+++ b/src/java/org/apache/fop/render/ps/PSRendererOption.java
@@ -29,7 +29,7 @@ import org.apache.fop.render.RendererConfigOption;
public enum PSRendererOption implements RendererConfigOption {
/** Indicates whether landscape pages should be rotated, default: false */
AUTO_ROTATE_LANDSCAPE("auto-rotate-landscape", false),
- /** Sets the PostScript language leven, default: {@see PSGenerator#DEFAULT_LANGUAGE_LEVEL}*/
+ /** Sets the PostScript language level, default: {@link PSGenerator#DEFAULT_LANGUAGE_LEVEL} */
LANGUAGE_LEVEL("language-level", PSGenerator.DEFAULT_LANGUAGE_LEVEL),
/** Whether resources should be optimized in a post-processing run, default: false */
OPTIMIZE_RESOURCES("optimize-resources", false),
diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java
index 87c12d869..7517babf2 100644
--- a/src/java/org/apache/fop/svg/PDFGraphics2D.java
+++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java
@@ -68,6 +68,7 @@ import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
import org.apache.xmlgraphics.java2d.GraphicContext;
+import org.apache.xmlgraphics.java2d.GraphicsConfigurationWithTransparency;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
@@ -1765,7 +1766,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
*/
@Override
public GraphicsConfiguration getDeviceConfiguration() {
- return new PDFGraphicsConfiguration();
+ return new GraphicsConfigurationWithTransparency();
}
/**
diff --git a/src/java/org/apache/fop/util/ColorSpaceCache.java b/src/java/org/apache/fop/util/ColorSpaceCache.java
index a249fe47b..acb83cdef 100644
--- a/src/java/org/apache/fop/util/ColorSpaceCache.java
+++ b/src/java/org/apache/fop/util/ColorSpaceCache.java
@@ -62,13 +62,11 @@ public class ColorSpaceCache {
* If that fails null is returned.
*
* @param profileName the profile name
- * @param base a base URI to resolve relative URIs
- * @param iccProfileSrc ICC Profile source to return a ColorSpace for
+ * @param iccProfileSrc ICC Profile source to return a ColorSpace
* @param renderingIntent overriding rendering intent
* @return ICC ColorSpace object or null if ColorSpace could not be created
*/
- public ColorSpace get(String profileName, String iccProfileSrc,
- RenderingIntent renderingIntent) {
+ public ColorSpace get(String profileName, String iccProfileSrc, RenderingIntent renderingIntent) {
String key = profileName + ":" + iccProfileSrc;
// TODO: This stuff needs some TLC, fix it!!
ColorSpace colorSpace = null;