diff options
31 files changed, 1472 insertions, 1984 deletions
diff --git a/src/java/org/apache/fop/fo/FOEventHandler.java b/src/java/org/apache/fop/fo/FOEventHandler.java index 69cb7d06b..28dd32ba0 100644 --- a/src/java/org/apache/fop/fo/FOEventHandler.java +++ b/src/java/org/apache/fop/fo/FOEventHandler.java @@ -40,9 +40,9 @@ import org.apache.fop.fo.flow.ListBlock; import org.apache.fop.fo.flow.ListItem; import org.apache.fop.fo.flow.PageNumber; import org.apache.fop.fo.flow.Table; -import org.apache.fop.fo.flow.TableColumn; import org.apache.fop.fo.flow.TableBody; import org.apache.fop.fo.flow.TableCell; +import org.apache.fop.fo.flow.TableColumn; import org.apache.fop.fo.flow.TableRow; import org.apache.fop.fo.pagination.Flow; import org.apache.fop.fo.pagination.PageSequence; @@ -78,7 +78,7 @@ public abstract class FOEventHandler { */ private Set idReferences = new HashSet(); - /* + /** * The property list maker. */ protected PropertyListMaker propertyListMaker; @@ -89,6 +89,11 @@ public abstract class FOEventHandler { protected XMLWhiteSpaceHandler whiteSpaceHandler = new XMLWhiteSpaceHandler(); /** + * Indicates whether processing descendants of a marker + */ + private boolean inMarker = false; + + /** * Main constructor * @param foUserAgent the apps.FOUserAgent instance for this process */ @@ -144,6 +149,23 @@ public abstract class FOEventHandler { } /** + * Switch to or from marker context + * (used by FOTreeBuilder when processing + * a marker) + * + */ + protected void switchMarkerContext(boolean inMarker) { + this.inMarker = inMarker; + } + + /** + * Check whether in marker context + */ + protected boolean inMarker() { + return this.inMarker; + } + + /** * This method is called to indicate the start of a new document run. * @throws SAXException In case of a problem */ @@ -185,9 +207,10 @@ public abstract class FOEventHandler { } /** - * This method is called to indicate the start of a new fo:flow or fo:static-content. - * This method also handles fo:static-content tags, because the StaticContent class - * is derived from the Flow class. + * This method is called to indicate the start of a new fo:flow + * or fo:static-content. + * This method also handles fo:static-content tags, because the + * StaticContent class is derived from the Flow class. * * @param fl Flow that is starting. */ @@ -219,15 +242,15 @@ public abstract class FOEventHandler { * * @param blc BlockContainer that is starting. */ - public void startBlockContainer(BlockContainer blc) { - } + public void startBlockContainer(BlockContainer blc) { + } - /** + /** * * @param blc BlockContainer that is ending. */ - public void endBlockContainer(BlockContainer blc) { - } + public void endBlockContainer(BlockContainer blc) { + } /** * diff --git a/src/java/org/apache/fop/fo/FONode.java b/src/java/org/apache/fop/fo/FONode.java index 2fa53902e..91817b87f 100644 --- a/src/java/org/apache/fop/fo/FONode.java +++ b/src/java/org/apache/fop/fo/FONode.java @@ -81,7 +81,6 @@ public abstract class FONode implements Cloneable { throws FOPException { FONode foNode = (FONode) clone(); foNode.parent = cloneparent; - cloneparent.addChildNode(foNode); return foNode; } @@ -124,6 +123,10 @@ public abstract class FONode implements Cloneable { public FOEventHandler getFOEventHandler() { return parent.getFOEventHandler(); } + + protected boolean inMarker() { + return getFOEventHandler().inMarker(); + } /** * Returns the user agent for the node. @@ -257,7 +260,7 @@ public abstract class FONode implements Cloneable { /** * Return an iterator over the object's child nodes starting - * at the pased node. + * at the passed node. * @param childNode First node in the iterator * @return A ListIterator or null if child node isn't a child of * this FObj. @@ -580,5 +583,35 @@ public abstract class FONode implements Cloneable { return null; } + /** + * @return true if markers are valid children + */ + protected boolean canHaveMarkers() { + int foId = getNameId(); + switch (foId) { + case Constants.FO_BASIC_LINK: + case Constants.FO_BIDI_OVERRIDE: + case Constants.FO_BLOCK: + case Constants.FO_BLOCK_CONTAINER: + case Constants.FO_FLOW: + case Constants.FO_INLINE: + case Constants.FO_INLINE_CONTAINER: + case Constants.FO_LIST_BLOCK: + case Constants.FO_LIST_ITEM: + case Constants.FO_LIST_ITEM_BODY: + case Constants.FO_LIST_ITEM_LABEL: + case Constants.FO_TABLE: + case Constants.FO_TABLE_BODY: + case Constants.FO_TABLE_HEADER: + case Constants.FO_TABLE_FOOTER: + case Constants.FO_TABLE_CELL: + case Constants.FO_TABLE_AND_CAPTION: + case Constants.FO_TABLE_CAPTION: + case Constants.FO_WRAPPER: + return true; + default: + return false; + } + } } diff --git a/src/java/org/apache/fop/fo/FOPropertyMapping.java b/src/java/org/apache/fop/fo/FOPropertyMapping.java index 7c1bbc773..bf23e4d97 100644 --- a/src/java/org/apache/fop/fo/FOPropertyMapping.java +++ b/src/java/org/apache/fop/fo/FOPropertyMapping.java @@ -30,7 +30,7 @@ import org.apache.fop.fo.properties.BorderWidthPropertyMaker; import org.apache.fop.fo.properties.BoxPropShorthandParser; import org.apache.fop.fo.properties.CharacterProperty; import org.apache.fop.fo.properties.ColorProperty; -import org.apache.fop.fo.properties.ColumnNumberPropertyMaker; +import org.apache.fop.fo.flow.TableFObj.ColumnNumberPropertyMaker; import org.apache.fop.fo.properties.CondLengthProperty; import org.apache.fop.fo.properties.CorrespondingPropertyMaker; import org.apache.fop.fo.properties.DimensionPropertyMaker; @@ -326,11 +326,13 @@ public final class FOPropertyMapping implements Constants { * @return a propId that matches the property name. */ public static int getPropertyId(String name) { - Integer i = (Integer) s_htPropNames.get(name); - if (i == null) { - return -1; + if (name != null) { + Integer i = (Integer) s_htPropNames.get(name); + if (i != null) { + return i.intValue(); + } } - return i.intValue(); + return -1; } /** @@ -339,11 +341,13 @@ public final class FOPropertyMapping implements Constants { * @return a subpropId that matches the subproperty name. */ public static int getSubPropertyId(String name) { - Integer i = (Integer) s_htSubPropNames.get(name); - if (i == null) { - return -1; + if (name != null) { + Integer i = (Integer) s_htSubPropNames.get(name); + if (i != null) { + return i.intValue(); + } } - return i.intValue(); + return -1; } // returns a property, compound, or property.compound name @@ -2263,8 +2267,8 @@ public final class FOPropertyMapping implements Constants { sub = new LengthProperty.Maker(CP_INLINE_PROGRESSION_DIRECTION); sub.setDefault("0pt"); - m.addSubpropMaker(sub); sub.setByShorthand(true); + m.addSubpropMaker(sub); addPropertyMaker("border-separation", m); // border-start-precedence diff --git a/src/java/org/apache/fop/fo/FOText.java b/src/java/org/apache/fop/fo/FOText.java index 8b578b146..ec8fcfb7e 100644 --- a/src/java/org/apache/fop/fo/FOText.java +++ b/src/java/org/apache/fop/fo/FOText.java @@ -151,6 +151,23 @@ public class FOText extends FONode { } /** + * @see org.apache.fop.fo.FONode#clone(FONode, boolean) + */ + public FONode clone(FONode parent, boolean removeChildren) + throws FOPException { + FOText ft = (FOText) super.clone(parent, removeChildren); + if (removeChildren) { + //not really removing, but just make sure the char array + //pointed to is really a different one + if (ca != null) { + ft.ca = new char[ca.length]; + System.arraycopy(ca, 0, ft.ca, 0, ca.length); + } + } + return ft; + } + + /** * @see org.apache.fop.fo.FObj#bind(PropertyList) */ public void bind(PropertyList pList) throws FOPException { @@ -171,8 +188,8 @@ public class FOText extends FONode { /** @see org.apache.fop.fo.FONode#endOfNode() */ protected void endOfNode() throws FOPException { - createBlockPointers(); textTransform(); + getFOEventHandler().characters(ca, startIndex, endIndex); } /** @@ -210,28 +227,11 @@ public class FOText extends FONode { } /** - * This method is run as part of the Constructor, to create xref pointers to + * This method is run as part of the ancestor Block's flushText(), to create xref pointers to * the previous FOText objects within the same Block */ - private void createBlockPointers() { - // build pointers between the FOText objects withing the same Block - // - // find the ancestorBlock of the current node - FONode ancestorFONode = this; - while (this.ancestorBlock == null) { - ancestorFONode = ancestorFONode.parent; - if (ancestorFONode instanceof org.apache.fop.fo.pagination.Title) { - return; - } else if (ancestorFONode instanceof org.apache.fop.fo.flow.Marker) { - return; - } else if (ancestorFONode instanceof Root) { - getLogger().warn("Unexpected: fo:text with no fo:block ancestor. The text is: " - + new String(ca)); - return; - } else if (ancestorFONode instanceof Block) { - this.ancestorBlock = (Block)ancestorFONode; - } - } + protected void createBlockPointers(Block ancestorBlock) { + this.ancestorBlock = ancestorBlock; // if the last FOText is a sibling, point to it, and have it point here if (lastFOTextProcessed != null) { if (lastFOTextProcessed.ancestorBlock == this.ancestorBlock) { @@ -252,7 +252,8 @@ public class FOText extends FONode { * text-transform property. */ private void textTransform() { - if (textTransform == Constants.EN_NONE) { + if (getFOEventHandler().inMarker() + || textTransform == Constants.EN_NONE) { return; } for (int i = 0; i < endIndex; i++) { diff --git a/src/java/org/apache/fop/fo/FOTreeBuilder.java b/src/java/org/apache/fop/fo/FOTreeBuilder.java index 0f2874b4b..4c754520d 100644 --- a/src/java/org/apache/fop/fo/FOTreeBuilder.java +++ b/src/java/org/apache/fop/fo/FOTreeBuilder.java @@ -246,7 +246,7 @@ public class FOTreeBuilder extends DefaultHandler { */ public FormattingResults getResults() { if (getEventHandler() instanceof AreaTreeHandler) { - return ((AreaTreeHandler)getEventHandler()).getResults(); + return ((AreaTreeHandler) getEventHandler()).getResults(); } else { //No formatting results available for output formats no //involving the layout engine. @@ -268,6 +268,11 @@ public class FOTreeBuilder extends DefaultHandler { * Current propertyList for the node being handled. */ protected PropertyList currentPropertyList; + + /** + * Current marker nesting-depth + */ + private int nestedMarkerDepth = 0; /** * SAX Handler for the start of an element @@ -278,16 +283,17 @@ public class FOTreeBuilder extends DefaultHandler { /* the node found in the FO document */ FONode foNode; - PropertyList propertyList; + PropertyList propertyList = null; // Check to ensure first node encountered is an fo:root if (rootFObj == null) { if (!namespaceURI.equals(FOElementMapping.URI) || !localName.equals("root")) { - throw new SAXException(new ValidationException( - "Error: First element must be the fo:root formatting object. Found " - + FONode.getNodeString(namespaceURI, localName) + " instead." - + " Please make sure you're producing a valid XSL-FO document.")); + throw new ValidationException( + "Error: First element must be the fo:root formatting object. " + + "Found " + FONode.getNodeString(namespaceURI, localName) + + " instead." + + " Please make sure you're producing a valid XSL-FO document."); } } else { // check that incoming node is valid for currentFObj if (namespaceURI.equals(FOElementMapping.URI)) { @@ -301,7 +307,8 @@ public class FOTreeBuilder extends DefaultHandler { } } - ElementMapping.Maker fobjMaker = findFOMaker(namespaceURI, localName); + ElementMapping.Maker fobjMaker = + findFOMaker(namespaceURI, localName); try { foNode = fobjMaker.make(currentFObj); @@ -309,8 +316,17 @@ public class FOTreeBuilder extends DefaultHandler { rootFObj = (Root) foNode; rootFObj.setFOEventHandler(foEventHandler); } - propertyList = foNode.createPropertyList(currentPropertyList, foEventHandler); - foNode.processNode(localName, getEffectiveLocator(), attlist, propertyList); + propertyList = foNode.createPropertyList( + currentPropertyList, foEventHandler); + foNode.processNode(localName, getEffectiveLocator(), + attlist, propertyList); + if (foNode.getNameId() == Constants.FO_MARKER) { + if (foEventHandler.inMarker()) { + nestedMarkerDepth++; + } else { + foEventHandler.switchMarkerContext(true); + } + } foNode.startOfNode(); } catch (IllegalArgumentException e) { throw new SAXException(e); @@ -321,11 +337,13 @@ public class FOTreeBuilder extends DefaultHandler { ContentHandler subHandler = chFactory.createContentHandler(); if (subHandler instanceof ObjectSource && foNode instanceof ObjectBuiltListener) { - ((ObjectSource)subHandler).setObjectBuiltListener((ObjectBuiltListener)foNode); + ((ObjectSource) subHandler).setObjectBuiltListener( + (ObjectBuiltListener) foNode); } subHandler.startDocument(); - subHandler.startElement(namespaceURI, localName, rawName, attlist); + subHandler.startElement(namespaceURI, localName, + rawName, attlist); depth = 1; delegate = subHandler; } @@ -335,7 +353,7 @@ public class FOTreeBuilder extends DefaultHandler { } currentFObj = foNode; - if (propertyList != null) { + if (propertyList != null && !foEventHandler.inMarker()) { currentPropertyList = propertyList; } } @@ -356,11 +374,24 @@ public class FOTreeBuilder extends DefaultHandler { + " (" + currentFObj.getNamespaceURI() + ") vs. " + localName + " (" + uri + ")"); } + currentFObj.endOfNode(); - - if (currentPropertyList.getFObj() == currentFObj) { - currentPropertyList = currentPropertyList.getParentPropertyList(); + + if (currentPropertyList != null + && currentPropertyList.getFObj() == currentFObj + && !foEventHandler.inMarker()) { + currentPropertyList = + currentPropertyList.getParentPropertyList(); + } + + if (currentFObj.getNameId() == Constants.FO_MARKER) { + if (nestedMarkerDepth == 0) { + foEventHandler.switchMarkerContext(false); + } else { + nestedMarkerDepth--; + } } + if (currentFObj.getParent() == null) { log.debug("endElement for top-level " + currentFObj.getName()); } @@ -373,19 +404,15 @@ public class FOTreeBuilder extends DefaultHandler { */ public void characters(char[] data, int start, int length) throws FOPException { - if (currentFObj != null) { - currentFObj.addCharacters(data, start, start + length, - currentPropertyList, getEffectiveLocator()); - } + if (currentFObj != null) { + currentFObj.addCharacters(data, start, start + length, + currentPropertyList, getEffectiveLocator()); + } } public void endDocument() throws SAXException { currentFObj = null; - } - - - + } } - } diff --git a/src/java/org/apache/fop/fo/FObj.java b/src/java/org/apache/fop/fo/FObj.java index 29278b1b8..1372b65c4 100644 --- a/src/java/org/apache/fop/fo/FObj.java +++ b/src/java/org/apache/fop/fo/FObj.java @@ -20,7 +20,6 @@ package org.apache.fop.fo; import java.util.Collections; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ListIterator; @@ -119,11 +118,15 @@ public abstract class FObj extends FONode implements Constants { * @see org.apache.fop.fo.FONode#processNode */ public void processNode(String elementName, Locator locator, - Attributes attlist, PropertyList pList) throws FOPException { + Attributes attlist, PropertyList pList) + throws FOPException { setLocator(locator); pList.addAttributesToList(attlist); - pList.setWritingMode(); - bind(pList); + if (!inMarker() + || "marker".equals(elementName)) { + pList.setWritingMode(); + bind(pList); + } } /** @@ -154,7 +157,7 @@ public abstract class FObj extends FONode implements Constants { * @throws ValidationException if the ID is already defined elsewhere */ protected void checkId(String id) throws ValidationException { - if (!id.equals("")) { + if (!inMarker() && !id.equals("")) { Set idrefs = getFOEventHandler().getIDReferences(); if (!idrefs.contains(id)) { idrefs.add(id); @@ -178,13 +181,15 @@ public abstract class FObj extends FONode implements Constants { * @see org.apache.fop.fo.FONode#addChildNode(FONode) */ protected void addChildNode(FONode child) throws FOPException { - if (PropertySets.canHaveMarkers(getNameId()) && child.getNameId() == FO_MARKER) { - addMarker((Marker)child); + if (canHaveMarkers() && child.getNameId() == FO_MARKER) { + addMarker((Marker) child); } else { ExtensionAttachment attachment = child.getExtensionAttachment(); if (attachment != null) { - //This removes the element from the normal children, so no layout manager - //is being created for them as they are only additional information. + /* This removes the element from the normal children, + * so no layout manager is being created for them + * as they are only additional information. + */ addExtensionAttachment(attachment); } else { if (childNodes == null) { @@ -195,6 +200,10 @@ public abstract class FObj extends FONode implements Constants { } } + protected static void addChildTo(FONode child, FObj parent) throws FOPException { + parent.addChildNode(child); + } + /** @see org.apache.fop.fo.FONode#removeChild(org.apache.fop.fo.FONode) */ public void removeChild(FONode child) { if (childNodes != null) { @@ -251,6 +260,20 @@ public abstract class FObj extends FONode implements Constants { } /** + * Return a FONode based on the index in the list of childNodes. + * @param nodeIndex index of the node to return + * @return the node or null if the index is invalid + */ + public FONode getChildNodeAt(int nodeIndex) { + if (childNodes != null) { + if (nodeIndex >= 0 && nodeIndex < childNodes.size()) { + return (FONode) childNodes.get(nodeIndex); + } + } + return null; + } + + /** * Notifies a FObj that one of it's children is removed. * This method is subclassed by Block to clear the firstInlineChild variable. * @param node the node that was removed diff --git a/src/java/org/apache/fop/fo/FObjMixed.java b/src/java/org/apache/fop/fo/FObjMixed.java index 7efcbf59f..84f27fbb9 100644 --- a/src/java/org/apache/fop/fo/FObjMixed.java +++ b/src/java/org/apache/fop/fo/FObjMixed.java @@ -42,7 +42,7 @@ public abstract class FObjMixed extends FObj { protected FObjMixed(FONode parent) { super(parent); } - + /** @see org.apache.fop.fo.FONode */ protected void addCharacters(char[] data, int start, int end, PropertyList pList, @@ -50,7 +50,9 @@ public abstract class FObjMixed extends FObj { if (ft == null) { ft = new FOText(this); ft.setLocator(locator); - ft.bind(pList); + if (!inMarker()) { + ft.bind(pList); + } } ft.addCharacters(data, start, end, null, null); } @@ -58,12 +60,27 @@ public abstract class FObjMixed extends FObj { /** @see org.apache.fop.fo.FONode#endOfNode() */ protected void endOfNode() throws FOPException { flushText(); - getFOEventHandler().whiteSpaceHandler - .handleWhiteSpace(this, currentTextNode); + if (!inMarker() + || getNameId() == FO_MARKER) { + getFOEventHandler().whiteSpaceHandler + .handleWhiteSpace(this, currentTextNode); + } super.endOfNode(); } /** + * Handles white-space for the node that is passed in, + * starting at its current text-node + * (used by RetrieveMarker to trigger 'end-of-node' white-space + * handling) + * @param fobj the node for which to handle white-space + */ + protected static void handleWhiteSpaceFor(FObjMixed fobj) { + fobj.getFOEventHandler().getXMLWhiteSpaceHandler() + .handleWhiteSpace(fobj, fobj.currentTextNode); + } + + /** * Adds accumulated text as one FOText instance. * Makes sure that nested calls to itself do nothing. * @throws FOPException if there is a problem during processing @@ -72,8 +89,29 @@ public abstract class FObjMixed extends FObj { if (ft != null) { FOText lft = ft; ft = null; + if (getNameId() == FO_BLOCK) { + lft.createBlockPointers((org.apache.fop.fo.flow.Block) this); + } else if (getNameId() != FO_MARKER + && getNameId() != FO_TITLE + && getNameId() != FO_BOOKMARK_TITLE) { + FONode fo = parent; + int foNameId = fo.getNameId(); + while (foNameId != FO_BLOCK + && foNameId != FO_MARKER + && foNameId != FO_TITLE + && foNameId != FO_BOOKMARK_TITLE + && foNameId != FO_PAGE_SEQUENCE) { + fo = fo.getParent(); + foNameId = fo.getNameId(); + } + if (foNameId == FO_BLOCK) { + lft.createBlockPointers((org.apache.fop.fo.flow.Block) fo); + } else if (foNameId == FO_PAGE_SEQUENCE) { + log.error("Could not create block pointers." + + " FOText w/o Block ancestor."); + } + } lft.endOfNode(); - getFOEventHandler().characters(lft.ca, lft.startIndex, lft.endIndex); addChildNode(lft); } } @@ -83,15 +121,18 @@ public abstract class FObjMixed extends FObj { */ protected void addChildNode(FONode child) throws FOPException { flushText(); - if (child instanceof FOText || child.getNameId() == FO_CHARACTER) { - if (currentTextNode == null) { - currentTextNode = child; + if (!inMarker() + || getNameId() == FO_MARKER) { + if (child instanceof FOText || child.getNameId() == FO_CHARACTER) { + if (currentTextNode == null) { + currentTextNode = child; + } + } else { + // handle white-space for all text up to here + getFOEventHandler().whiteSpaceHandler + .handleWhiteSpace(this, currentTextNode, child); + currentTextNode = null; } - } else { - // handle white-space for all text up to here - getFOEventHandler().whiteSpaceHandler - .handleWhiteSpace(this, currentTextNode, child); - currentTextNode = null; } super.addChildNode(child); } diff --git a/src/java/org/apache/fop/fo/PropertyList.java b/src/java/org/apache/fop/fo/PropertyList.java index 6fdd1bf21..0600601c7 100644 --- a/src/java/org/apache/fop/fo/PropertyList.java +++ b/src/java/org/apache/fop/fo/PropertyList.java @@ -169,8 +169,11 @@ public abstract class PropertyList { boolean bTryDefault) throws PropertyException { PropertyMaker propertyMaker = findMaker(propId & Constants.PROPERTY_MASK); - return propertyMaker.get(propId & Constants.COMPOUND_MASK, this, - bTryInherit, bTryDefault); + if (propertyMaker != null) { + return propertyMaker.get(propId & Constants.COMPOUND_MASK, this, + bTryInherit, bTryDefault); + } + return null; } /** @@ -260,8 +263,11 @@ public abstract class PropertyList { * Adds the attributes, passed in by the parser to the PropertyList * * @param attributes Collection of attributes passed to us from the parser. + * @throws ValidationException if there is an attribute that does not + * map to a property id (strict validation only) */ - public void addAttributesToList(Attributes attributes) { + public void addAttributesToList(Attributes attributes) + throws ValidationException { /* * If column-number/number-columns-spanned are specified, then we * need them before all others (possible from-table-column() on any @@ -308,69 +314,104 @@ public abstract class PropertyList { if (factory.getElementMappingRegistry().isKnownNamespace(attributeNS)) { getFObj().addForeignAttribute(attributeNS, attributeName, attributeValue); } else { - handleInvalidProperty(attributeName); + handleInvalidProperty( + "Error processing foreign attribute: " + + attributeNS + "/@" + attributeName, attributeName); } } } } + + /** + * Validates a property name. + * @param propertyName the property name to check + * @return true if the base property name and the subproperty name (if any) + * can be correctly mapped to an id + * @throws ValidationException in case the property name + * is invalid for the FO namespace + */ + protected boolean isValidPropertyName(String propertyName) + throws ValidationException { + + int propId = FOPropertyMapping.getPropertyId( + findBasePropertyName(propertyName)); + int subpropId = FOPropertyMapping.getSubPropertyId( + findSubPropertyName(propertyName)); + + if (propId == -1 + || (subpropId == -1 + && findSubPropertyName(propertyName) != null)) { + StringBuffer errorMessage = new StringBuffer().append( + "Invalid property name \'").append(propertyName); + handleInvalidProperty(errorMessage.toString(), propertyName); + return false; + } + return true; + } /** * * @param attributes Collection of attributes * @param attributeName Attribute name to convert * @param attributeValue Attribute value to assign to property + * @throws ValidationException in case the property name is invalid + * for the FO namespace */ private void convertAttributeToProperty(Attributes attributes, String attributeName, - String attributeValue) { - - PropertyMaker propertyMaker = null; - FObj parentFO = fobj.findNearestAncestorFObj(); + String attributeValue) + throws ValidationException { - /* Handle "compound" properties, ex. space-before.minimum */ - String basePropertyName = findBasePropertyName(attributeName); - String subPropertyName = findSubPropertyName(attributeName); + if (attributeValue != null) { + + if (!isValidPropertyName(attributeName)) { + //will log an error or throw an exception + return; + } + FObj parentFO = fobj.findNearestAncestorFObj(); + + + /* Handle "compound" properties, ex. space-before.minimum */ + String basePropertyName = findBasePropertyName(attributeName); + String subPropertyName = findSubPropertyName(attributeName); - int propId = FOPropertyMapping.getPropertyId(basePropertyName); + int propId = FOPropertyMapping.getPropertyId(basePropertyName); + int subpropId = FOPropertyMapping.getSubPropertyId(subPropertyName); + + PropertyMaker propertyMaker = findMaker(propId); + if (propertyMaker == null) { + log.warn("No PropertyMaker registered for " + attributeName + + ". Ignoring property."); + return; + } - propertyMaker = findMaker(propId); - if (propertyMaker == null) { - handleInvalidProperty(attributeName); - return; - } - if (attributeValue == null) { - return; - } - try { - Property prop = null; - if (subPropertyName == null) { // base attribute only found - /* Do nothing if the base property has already been created. - * This is e.g. the case when a compound attribute was - * specified before the base attribute; in these cases - * the base attribute was already created in - * findBaseProperty() - */ - if (getExplicit(propId) != null) { - return; + try { + Property prop = null; + if (subPropertyName == null) { // base attribute only found + /* Do nothing if the base property has already been created. + * This is e.g. the case when a compound attribute was + * specified before the base attribute; in these cases + * the base attribute was already created in + * findBaseProperty() + */ + if (getExplicit(propId) != null) { + return; + } + prop = propertyMaker.make(this, attributeValue, parentFO); + } else { // e.g. "leader-length.maximum" + Property baseProperty = + findBaseProperty(attributes, parentFO, propId, + basePropertyName, propertyMaker); + prop = propertyMaker.make(baseProperty, subpropId, + this, attributeValue, parentFO); } - prop = propertyMaker.make(this, attributeValue, parentFO); - } else { // e.g. "leader-length.maximum" - Property baseProperty = findBaseProperty(attributes, - parentFO, propId, basePropertyName, propertyMaker); - int subpropertyId = FOPropertyMapping.getSubPropertyId(subPropertyName); - if (subpropertyId == -1) { - handleInvalidProperty(attributeName); - return; + if (prop != null) { + putExplicit(propId, prop); } - prop = propertyMaker.make(baseProperty, subpropertyId, - this, attributeValue, parentFO); - } - if (prop != null) { - putExplicit(propId, prop); + } catch (PropertyException e) { + log.error("Ignoring property: " + + attributeName + "=\"" + attributeValue + "\""); } - } catch (PropertyException e) { - // TODO: Add strict validation. - log.error(e.getMessage()); } } @@ -405,9 +446,19 @@ public abstract class PropertyList { return null; // could not find base property } - private void handleInvalidProperty(String attributeName) { - if (!attributeName.startsWith("xmlns")) { - log.error("property '" + attributeName + "' ignored"); + /** + * @param message ... + * @param propName ... + * @throws ValidationException ... + */ + protected void handleInvalidProperty(String message, String propName) + throws ValidationException { + if (!propName.startsWith("xmlns")) { + if (fobj.getUserAgent().validateStrictly()) { + fobj.attributeError(message); + } else { + log.error(message + " Property ignored."); + } } } @@ -418,7 +469,7 @@ public abstract class PropertyList { * @param attributeName String to be atomized * @return the base portion of the attribute */ - private static String findBasePropertyName(String attributeName) { + protected static String findBasePropertyName(String attributeName) { int separatorCharIndex = attributeName.indexOf('.'); String basePropertyName = attributeName; if (separatorCharIndex > -1) { @@ -434,7 +485,7 @@ public abstract class PropertyList { * @param attributeName String to be atomized * @return the sub portion of the attribute */ - private static String findSubPropertyName(String attributeName) { + protected static String findSubPropertyName(String attributeName) { int separatorCharIndex = attributeName.indexOf('.'); String subpropertyName = null; if (separatorCharIndex > -1) { diff --git a/src/java/org/apache/fop/fo/PropertySets.java b/src/java/org/apache/fop/fo/PropertySets.java deleted file mode 100644 index 29455add1..000000000 --- a/src/java/org/apache/fop/fo/PropertySets.java +++ /dev/null @@ -1,1192 +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.fo; - -import org.apache.fop.fo.Constants; -import java.util.BitSet; -import java.util.ArrayList; - -public class PropertySets { - private static short[][] mapping = null; - private static BitSet can_have_markers = null; - private static BitSet no_inline_areas = null; - - private Element[] elements = new Element[Constants.FRM_OBJ_COUNT + 1]; - private BitSet block_elems = new BitSet(); - private BitSet inline_elems = new BitSet(); - - BitSet CommonAccessibilityProperties = new BitSet(); - BitSet CommonAbsolutePositionProperties = new BitSet(); - BitSet CommonAuralProperties = new BitSet(); - BitSet CommonBorderPaddingBackgroundProperties = new BitSet(); - BitSet CommonFontProperties = new BitSet(); - BitSet CommonHyphenationProperties = new BitSet(); - BitSet CommonMarginPropertiesBlock = new BitSet(); - BitSet CommonMarginPropertiesInline = new BitSet(); - BitSet CommonRelativePositionProperties = new BitSet(); - - public void initializeElements() { - block_elems.set(Constants.FO_BLOCK); - block_elems.set(Constants.FO_BLOCK_CONTAINER); - block_elems.set(Constants.FO_TABLE_AND_CAPTION); - block_elems.set(Constants.FO_TABLE); - block_elems.set(Constants.FO_LIST_BLOCK); - - inline_elems.set(Constants.FO_BIDI_OVERRIDE); - inline_elems.set(Constants.FO_CHARACTER); - inline_elems.set(Constants.FO_EXTERNAL_GRAPHIC); - inline_elems.set(Constants.FO_INSTREAM_FOREIGN_OBJECT); - inline_elems.set(Constants.FO_INLINE); - inline_elems.set(Constants.FO_INLINE_CONTAINER); - inline_elems.set(Constants.FO_LEADER); - inline_elems.set(Constants.FO_PAGE_NUMBER); - inline_elems.set(Constants.FO_PAGE_NUMBER_CITATION); - inline_elems.set(Constants.FO_PAGE_NUMBER_CITATION_LAST); - inline_elems.set(Constants.FO_BASIC_LINK); - inline_elems.set(Constants.FO_MULTI_TOGGLE); - } - - public void initializeCommon() { - CommonAccessibilityProperties.set(Constants.PR_SOURCE_DOCUMENT); - CommonAccessibilityProperties.set(Constants.PR_ROLE); - - CommonAbsolutePositionProperties.set(Constants.PR_ABSOLUTE_POSITION); - CommonAbsolutePositionProperties.set(Constants.PR_POSITION); - CommonAbsolutePositionProperties.set(Constants.PR_TOP); - CommonAbsolutePositionProperties.set(Constants.PR_RIGHT); - CommonAbsolutePositionProperties.set(Constants.PR_BOTTOM); - CommonAbsolutePositionProperties.set(Constants.PR_LEFT); - - CommonAuralProperties.set(Constants.PR_AZIMUTH); - CommonAuralProperties.set(Constants.PR_CUE_AFTER); - CommonAuralProperties.set(Constants.PR_CUE_BEFORE); - CommonAuralProperties.set(Constants.PR_CUE); - CommonAuralProperties.set(Constants.PR_ELEVATION); - CommonAuralProperties.set(Constants.PR_PAUSE_AFTER); - CommonAuralProperties.set(Constants.PR_PAUSE_BEFORE); - CommonAuralProperties.set(Constants.PR_PAUSE); - CommonAuralProperties.set(Constants.PR_PITCH); - CommonAuralProperties.set(Constants.PR_PITCH_RANGE); - CommonAuralProperties.set(Constants.PR_PLAY_DURING); - CommonAuralProperties.set(Constants.PR_RICHNESS); - CommonAuralProperties.set(Constants.PR_SPEAK); - CommonAuralProperties.set(Constants.PR_SPEAK_HEADER); - CommonAuralProperties.set(Constants.PR_SPEAK_NUMERAL); - CommonAuralProperties.set(Constants.PR_SPEAK_PUNCTUATION); - CommonAuralProperties.set(Constants.PR_SPEECH_RATE); - CommonAuralProperties.set(Constants.PR_STRESS); - CommonAuralProperties.set(Constants.PR_VOICE_FAMILY); - CommonAuralProperties.set(Constants.PR_VOLUME); - - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BACKGROUND_ATTACHMENT); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BACKGROUND_COLOR); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BACKGROUND_IMAGE); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BACKGROUND_REPEAT); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BACKGROUND_POSITION_HORIZONTAL); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BACKGROUND_POSITION_VERTICAL); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_BEFORE_COLOR); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_BEFORE_STYLE); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_BEFORE_WIDTH); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_AFTER_COLOR); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_AFTER_STYLE); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_AFTER_WIDTH); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_START_COLOR); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_START_STYLE); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_START_WIDTH); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_END_COLOR); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_END_STYLE); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_END_WIDTH); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_TOP_COLOR); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_TOP_STYLE); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_TOP_WIDTH); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_BOTTOM_COLOR); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_BOTTOM_STYLE); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_BOTTOM_WIDTH); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_LEFT_COLOR); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_LEFT_STYLE); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_LEFT_WIDTH); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_RIGHT_COLOR); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_RIGHT_STYLE); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_RIGHT_WIDTH); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_PADDING_BEFORE); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_PADDING_AFTER); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_PADDING_START); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_PADDING_END); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_PADDING_TOP); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_PADDING_BOTTOM); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_PADDING_LEFT); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_PADDING_RIGHT); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_STYLE); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_WIDTH); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_COLOR); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_TOP); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_BOTTOM); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_LEFT); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_BORDER_RIGHT); - CommonBorderPaddingBackgroundProperties.set(Constants.PR_PADDING); - - CommonFontProperties.set(Constants.PR_FONT); - CommonFontProperties.set(Constants.PR_FONT_FAMILY); - CommonFontProperties.set(Constants.PR_FONT_SELECTION_STRATEGY); - CommonFontProperties.set(Constants.PR_FONT_SIZE); - CommonFontProperties.set(Constants.PR_FONT_STRETCH); - CommonFontProperties.set(Constants.PR_FONT_SIZE_ADJUST); - CommonFontProperties.set(Constants.PR_FONT_STYLE); - CommonFontProperties.set(Constants.PR_FONT_VARIANT); - CommonFontProperties.set(Constants.PR_FONT_WEIGHT); - - CommonHyphenationProperties.set(Constants.PR_COUNTRY); - CommonHyphenationProperties.set(Constants.PR_LANGUAGE); - CommonHyphenationProperties.set(Constants.PR_SCRIPT); - CommonHyphenationProperties.set(Constants.PR_HYPHENATE); - CommonHyphenationProperties.set(Constants.PR_HYPHENATION_CHARACTER); - CommonHyphenationProperties.set(Constants.PR_HYPHENATION_PUSH_CHARACTER_COUNT); - CommonHyphenationProperties.set(Constants.PR_HYPHENATION_REMAIN_CHARACTER_COUNT); - - CommonMarginPropertiesBlock.set(Constants.PR_MARGIN); - CommonMarginPropertiesBlock.set(Constants.PR_MARGIN_TOP); - CommonMarginPropertiesBlock.set(Constants.PR_MARGIN_BOTTOM); - CommonMarginPropertiesBlock.set(Constants.PR_MARGIN_LEFT); - CommonMarginPropertiesBlock.set(Constants.PR_MARGIN_RIGHT); - CommonMarginPropertiesBlock.set(Constants.PR_SPACE_BEFORE); - CommonMarginPropertiesBlock.set(Constants.PR_SPACE_AFTER); - CommonMarginPropertiesBlock.set(Constants.PR_START_INDENT); - CommonMarginPropertiesBlock.set(Constants.PR_END_INDENT); - - CommonMarginPropertiesInline.set(Constants.PR_SPACE_END); - CommonMarginPropertiesInline.set(Constants.PR_SPACE_START); - - CommonRelativePositionProperties.set(Constants.PR_RELATIVE_POSITION); - - - } - - public void initialize() { - // define the fo: elements - for (int i = 1; i < elements.length; i++) { - elements[i] = new Element(i); - } - - // populate the elements with properties and content elements. - Element elem; - elem = elements[Constants.FO_ROOT]; - elem.addProperty(Constants.PR_MEDIA_USAGE); - elem.addContent(Constants.FO_LAYOUT_MASTER_SET); - elem.addContent(Constants.FO_DECLARATIONS); - elem.addContent(Constants.FO_PAGE_SEQUENCE); - - elem = elements[Constants.FO_DECLARATIONS]; - elem.addContent(Constants.FO_COLOR_PROFILE); - - elem = elements[Constants.FO_COLOR_PROFILE]; - elem.addProperty(Constants.PR_SRC); - elem.addProperty(Constants.PR_COLOR_PROFILE_NAME); - elem.addProperty(Constants.PR_RENDERING_INTENT); - - elem = elements[Constants.FO_BOOKMARK_TREE]; - elem.addContent(Constants.FO_BOOKMARK); - - elem = elements[Constants.FO_BOOKMARK]; - elem.addContent(Constants.FO_BOOKMARK_TITLE); - elem.addContent(Constants.FO_BOOKMARK); - elem.addProperties(CommonAccessibilityProperties); - elem.addProperty(Constants.PR_EXTERNAL_DESTINATION); - elem.addProperty(Constants.PR_INTERNAL_DESTINATION); - elem.addProperty(Constants.PR_STARTING_STATE); - - elem = elements[Constants.FO_BOOKMARK_TITLE]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperty(Constants.PR_FONT_STYLE); - elem.addProperty(Constants.PR_FONT_WEIGHT); - - elem = elements[Constants.FO_PAGE_SEQUENCE_WRAPPER]; - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_INDEX_CLASS); - elem.addProperty(Constants.PR_INDEX_KEY); - - elem = elements[Constants.FO_PAGE_SEQUENCE]; - elem.addProperty(Constants.PR_COUNTRY); - elem.addProperty(Constants.PR_FORMAT); - elem.addProperty(Constants.PR_LANGUAGE); - elem.addProperty(Constants.PR_LETTER_VALUE); - elem.addProperty(Constants.PR_GROUPING_SEPARATOR); - elem.addProperty(Constants.PR_GROUPING_SIZE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_INITIAL_PAGE_NUMBER); - elem.addProperty(Constants.PR_FORCE_PAGE_COUNT); - elem.addProperty(Constants.PR_MASTER_REFERENCE); - elem.addContent(Constants.FO_TITLE); - elem.addContent(Constants.FO_STATIC_CONTENT); - elem.addContent(Constants.FO_FLOW); - - elem = elements[Constants.FO_LAYOUT_MASTER_SET]; - elem.addProperty(Constants.PR_MASTER_NAME); - elem.addContent(Constants.FO_SIMPLE_PAGE_MASTER); - elem.addContent(Constants.FO_PAGE_SEQUENCE_MASTER); - - elem = elements[Constants.FO_PAGE_SEQUENCE_MASTER]; - elem.addProperty(Constants.PR_MASTER_NAME); - elem.addContent(Constants.FO_SINGLE_PAGE_MASTER_REFERENCE); - elem.addContent(Constants.FO_REPEATABLE_PAGE_MASTER_REFERENCE); - elem.addContent(Constants.FO_REPEATABLE_PAGE_MASTER_ALTERNATIVES); - - elem = elements[Constants.FO_SINGLE_PAGE_MASTER_REFERENCE]; - elem.addProperty(Constants.PR_MASTER_REFERENCE); - - elem = elements[Constants.FO_REPEATABLE_PAGE_MASTER_REFERENCE]; - elem.addProperty(Constants.PR_MASTER_REFERENCE); - elem.addProperty(Constants.PR_MAXIMUM_REPEATS); - - elem = elements[Constants.FO_REPEATABLE_PAGE_MASTER_ALTERNATIVES]; - elem.addProperty(Constants.PR_MAXIMUM_REPEATS); - elem.addContent(Constants.FO_CONDITIONAL_PAGE_MASTER_REFERENCE); - - elem = elements[Constants.FO_CONDITIONAL_PAGE_MASTER_REFERENCE]; - elem.addProperty(Constants.PR_MASTER_REFERENCE); - elem.addProperty(Constants.PR_PAGE_POSITION); - elem.addProperty(Constants.PR_ODD_OR_EVEN); - elem.addProperty(Constants.PR_BLANK_OR_NOT_BLANK); - - elem = elements[Constants.FO_SIMPLE_PAGE_MASTER]; - elem.addProperties(CommonMarginPropertiesBlock); - elem.addProperty(Constants.PR_MASTER_NAME); - elem.addProperty(Constants.PR_PAGE_HEIGHT); - elem.addProperty(Constants.PR_PAGE_WIDTH); - elem.addProperty(Constants.PR_REFERENCE_ORIENTATION); - elem.addProperty(Constants.PR_WRITING_MODE); - elem.addContent(Constants.FO_REGION_BODY); - elem.addContent(Constants.FO_REGION_BEFORE); - elem.addContent(Constants.FO_REGION_AFTER); - elem.addContent(Constants.FO_REGION_START); - elem.addContent(Constants.FO_REGION_END); - - elem = elements[Constants.FO_REGION_BODY]; - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonMarginPropertiesBlock); - elem.addProperty(Constants.PR_CLIP); - elem.addProperty(Constants.PR_COLUMN_COUNT); - elem.addProperty(Constants.PR_COLUMN_GAP); - elem.addProperty(Constants.PR_DISPLAY_ALIGN); - elem.addProperty(Constants.PR_OVERFLOW); - elem.addProperty(Constants.PR_REGION_NAME); - elem.addProperty(Constants.PR_REFERENCE_ORIENTATION); - elem.addProperty(Constants.PR_WRITING_MODE); - - elem = elements[Constants.FO_REGION_BEFORE]; - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperty(Constants.PR_CLIP); - elem.addProperty(Constants.PR_DISPLAY_ALIGN); - elem.addProperty(Constants.PR_EXTENT); - elem.addProperty(Constants.PR_OVERFLOW); - elem.addProperty(Constants.PR_PRECEDENCE); - elem.addProperty(Constants.PR_REGION_NAME); - elem.addProperty(Constants.PR_REFERENCE_ORIENTATION); - elem.addProperty(Constants.PR_WRITING_MODE); - - elem = elements[Constants.FO_REGION_AFTER]; - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperty(Constants.PR_CLIP); - elem.addProperty(Constants.PR_DISPLAY_ALIGN); - elem.addProperty(Constants.PR_EXTENT); - elem.addProperty(Constants.PR_OVERFLOW); - elem.addProperty(Constants.PR_PRECEDENCE); - elem.addProperty(Constants.PR_REGION_NAME); - elem.addProperty(Constants.PR_REFERENCE_ORIENTATION); - elem.addProperty(Constants.PR_WRITING_MODE); - - elem = elements[Constants.FO_REGION_START]; - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperty(Constants.PR_CLIP); - elem.addProperty(Constants.PR_DISPLAY_ALIGN); - elem.addProperty(Constants.PR_EXTENT); - elem.addProperty(Constants.PR_OVERFLOW); - elem.addProperty(Constants.PR_REGION_NAME); - elem.addProperty(Constants.PR_REFERENCE_ORIENTATION); - elem.addProperty(Constants.PR_WRITING_MODE); - - elem = elements[Constants.FO_REGION_END]; - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperty(Constants.PR_CLIP); - elem.addProperty(Constants.PR_DISPLAY_ALIGN); - elem.addProperty(Constants.PR_EXTENT); - elem.addProperty(Constants.PR_OVERFLOW); - elem.addProperty(Constants.PR_REGION_NAME); - elem.addProperty(Constants.PR_REFERENCE_ORIENTATION); - elem.addProperty(Constants.PR_WRITING_MODE); - - elem = elements[Constants.FO_FLOW]; - elem.addProperty(Constants.PR_FLOW_NAME); - elem.addContent(block_elems); - - elem = elements[Constants.FO_STATIC_CONTENT]; - elem.addProperty(Constants.PR_FLOW_NAME); - elem.addContent(block_elems); - - elem = elements[Constants.FO_TITLE]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonFontProperties); - elem.addProperties(CommonMarginPropertiesInline); - elem.addProperty(Constants.PR_COLOR); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addContent(inline_elems); - - elem = elements[Constants.FO_BLOCK]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonFontProperties); - elem.addProperties(CommonHyphenationProperties); - elem.addProperties(CommonMarginPropertiesBlock); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_PAGE_BREAK_AFTER); - elem.addProperty(Constants.PR_PAGE_BREAK_BEFORE); - elem.addProperty(Constants.PR_BREAK_AFTER); - elem.addProperty(Constants.PR_BREAK_BEFORE); - elem.addProperty(Constants.PR_COLOR); - elem.addProperty(Constants.PR_TEXT_DEPTH); - elem.addProperty(Constants.PR_TEXT_ALTITUDE); - elem.addProperty(Constants.PR_HYPHENATION_KEEP); - elem.addProperty(Constants.PR_HYPHENATION_LADDER_COUNT); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_LAST_LINE_END_INDENT); - elem.addProperty(Constants.PR_LINEFEED_TREATMENT); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_LINE_HEIGHT_SHIFT_ADJUSTMENT); - elem.addProperty(Constants.PR_LINE_STACKING_STRATEGY); - elem.addProperty(Constants.PR_ORPHANS); - elem.addProperty(Constants.PR_WHITE_SPACE_TREATMENT); - elem.addProperty(Constants.PR_SPAN); - elem.addProperty(Constants.PR_TEXT_ALIGN); - elem.addProperty(Constants.PR_TEXT_ALIGN_LAST); - elem.addProperty(Constants.PR_TEXT_INDENT); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addProperty(Constants.PR_WHITE_SPACE_COLLAPSE); - elem.addProperty(Constants.PR_WIDOWS); - elem.addProperty(Constants.PR_WRAP_OPTION); - elem.addContent(inline_elems); - elem.addContent(block_elems); - - elem = elements[Constants.FO_BLOCK_CONTAINER]; - elem.addProperties(CommonAbsolutePositionProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonMarginPropertiesBlock); - elem.addProperty(Constants.PR_BLOCK_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_X_BLOCK_PROGRESSION_UNIT); - elem.addProperty(Constants.PR_PAGE_BREAK_AFTER); - elem.addProperty(Constants.PR_PAGE_BREAK_BEFORE); - elem.addProperty(Constants.PR_BREAK_AFTER); - elem.addProperty(Constants.PR_BREAK_BEFORE); - elem.addProperty(Constants.PR_CLIP); - elem.addProperty(Constants.PR_DISPLAY_ALIGN); - elem.addProperty(Constants.PR_HEIGHT); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_INLINE_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_OVERFLOW); - elem.addProperty(Constants.PR_REFERENCE_ORIENTATION); - elem.addProperty(Constants.PR_SPAN); - elem.addProperty(Constants.PR_WIDTH); - elem.addProperty(Constants.PR_WRITING_MODE); - elem.addProperty(Constants.PR_Z_INDEX); - elem.addContent(block_elems); - - elem = elements[Constants.FO_BIDI_OVERRIDE]; - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonFontProperties); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_COLOR); - elem.addProperty(Constants.PR_DIRECTION); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_LETTER_SPACING); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_SCORE_SPACES); - elem.addProperty(Constants.PR_UNICODE_BIDI); - elem.addProperty(Constants.PR_WORD_SPACING); - elem.addContent(inline_elems); - elem.addContent(block_elems); - - elem = elements[Constants.FO_CHARACTER]; - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonFontProperties); - elem.addProperties(CommonHyphenationProperties); - elem.addProperties(CommonMarginPropertiesInline); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_VERTICAL_ALIGN); - elem.addProperty(Constants.PR_ALIGNMENT_ADJUST); - elem.addProperty(Constants.PR_TREAT_AS_WORD_SPACE); - elem.addProperty(Constants.PR_ALIGNMENT_BASELINE); - elem.addProperty(Constants.PR_BASELINE_SHIFT); - elem.addProperty(Constants.PR_CHARACTER); - elem.addProperty(Constants.PR_COLOR); - elem.addProperty(Constants.PR_DOMINANT_BASELINE); - elem.addProperty(Constants.PR_TEXT_DEPTH); - elem.addProperty(Constants.PR_TEXT_ALTITUDE); - elem.addProperty(Constants.PR_GLYPH_ORIENTATION_HORIZONTAL); - elem.addProperty(Constants.PR_GLYPH_ORIENTATION_VERTICAL); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_LETTER_SPACING); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_SCORE_SPACES); - elem.addProperty(Constants.PR_SUPPRESS_AT_LINE_BREAK); - elem.addProperty(Constants.PR_TEXT_DECORATION); - elem.addProperty(Constants.PR_TEXT_SHADOW); - elem.addProperty(Constants.PR_TEXT_TRANSFORM); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addProperty(Constants.PR_WORD_SPACING); - - elem = elements[Constants.FO_INITIAL_PROPERTY_SET]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonFontProperties); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_COLOR); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_LETTER_SPACING); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_SCORE_SPACES); - elem.addProperty(Constants.PR_TEXT_DECORATION); - elem.addProperty(Constants.PR_TEXT_SHADOW); - elem.addProperty(Constants.PR_TEXT_TRANSFORM); - elem.addProperty(Constants.PR_WORD_SPACING); - - elem = elements[Constants.FO_EXTERNAL_GRAPHIC]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonMarginPropertiesInline); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_VERTICAL_ALIGN); - elem.addProperty(Constants.PR_ALIGNMENT_ADJUST); - elem.addProperty(Constants.PR_ALIGNMENT_BASELINE); - elem.addProperty(Constants.PR_BASELINE_SHIFT); - elem.addProperty(Constants.PR_BLOCK_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_CLIP); - elem.addProperty(Constants.PR_CONTENT_HEIGHT); - elem.addProperty(Constants.PR_CONTENT_TYPE); - elem.addProperty(Constants.PR_CONTENT_WIDTH); - elem.addProperty(Constants.PR_DISPLAY_ALIGN); - elem.addProperty(Constants.PR_DOMINANT_BASELINE); - elem.addProperty(Constants.PR_HEIGHT); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_INLINE_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_OVERFLOW); - elem.addProperty(Constants.PR_SCALING); - elem.addProperty(Constants.PR_SCALING_METHOD); - elem.addProperty(Constants.PR_SRC); - elem.addProperty(Constants.PR_TEXT_ALIGN); - elem.addProperty(Constants.PR_WIDTH); - - elem = elements[Constants.FO_INSTREAM_FOREIGN_OBJECT]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonMarginPropertiesInline); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_VERTICAL_ALIGN); - elem.addProperty(Constants.PR_ALIGNMENT_ADJUST); - elem.addProperty(Constants.PR_ALIGNMENT_BASELINE); - elem.addProperty(Constants.PR_BASELINE_SHIFT); - elem.addProperty(Constants.PR_BLOCK_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_CLIP); - elem.addProperty(Constants.PR_CONTENT_HEIGHT); - elem.addProperty(Constants.PR_CONTENT_TYPE); - elem.addProperty(Constants.PR_CONTENT_WIDTH); - elem.addProperty(Constants.PR_DISPLAY_ALIGN); - elem.addProperty(Constants.PR_DOMINANT_BASELINE); - elem.addProperty(Constants.PR_HEIGHT); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_INLINE_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_OVERFLOW); - elem.addProperty(Constants.PR_SCALING); - elem.addProperty(Constants.PR_SCALING_METHOD); - elem.addProperty(Constants.PR_TEXT_ALIGN); - elem.addProperty(Constants.PR_WIDTH); - - elem = elements[Constants.FO_INLINE]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonFontProperties); - elem.addProperties(CommonMarginPropertiesInline); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_VERTICAL_ALIGN); - elem.addProperty(Constants.PR_ALIGNMENT_ADJUST); - elem.addProperty(Constants.PR_ALIGNMENT_BASELINE); - elem.addProperty(Constants.PR_BASELINE_SHIFT); - elem.addProperty(Constants.PR_BLOCK_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_COLOR); - elem.addProperty(Constants.PR_DOMINANT_BASELINE); - elem.addProperty(Constants.PR_HEIGHT); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_INLINE_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_TEXT_DECORATION); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addProperty(Constants.PR_WIDTH); - elem.addProperty(Constants.PR_WRAP_OPTION); - elem.addContent(inline_elems); - elem.addContent(block_elems); - - elem = elements[Constants.FO_INLINE_CONTAINER]; - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonMarginPropertiesInline); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_VERTICAL_ALIGN); - elem.addProperty(Constants.PR_ALIGNMENT_ADJUST); - elem.addProperty(Constants.PR_ALIGNMENT_BASELINE); - elem.addProperty(Constants.PR_BASELINE_SHIFT); - elem.addProperty(Constants.PR_BLOCK_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_CLIP); - elem.addProperty(Constants.PR_DISPLAY_ALIGN); - elem.addProperty(Constants.PR_DOMINANT_BASELINE); - elem.addProperty(Constants.PR_HEIGHT); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_INLINE_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_OVERFLOW); - elem.addProperty(Constants.PR_REFERENCE_ORIENTATION); - elem.addProperty(Constants.PR_WIDTH); - elem.addProperty(Constants.PR_WRITING_MODE); - elem.addContent(block_elems); - - elem = elements[Constants.FO_LEADER]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonFontProperties); - elem.addProperties(CommonMarginPropertiesInline); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_VERTICAL_ALIGN); - elem.addProperty(Constants.PR_ALIGNMENT_ADJUST); - elem.addProperty(Constants.PR_ALIGNMENT_BASELINE); - elem.addProperty(Constants.PR_BASELINE_SHIFT); - elem.addProperty(Constants.PR_COLOR); - elem.addProperty(Constants.PR_DOMINANT_BASELINE); - elem.addProperty(Constants.PR_TEXT_DEPTH); - elem.addProperty(Constants.PR_TEXT_ALTITUDE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_LEADER_ALIGNMENT); - elem.addProperty(Constants.PR_LEADER_LENGTH); - elem.addProperty(Constants.PR_LEADER_PATTERN); - elem.addProperty(Constants.PR_LEADER_PATTERN_WIDTH); - elem.addProperty(Constants.PR_RULE_STYLE); - elem.addProperty(Constants.PR_RULE_THICKNESS); - elem.addProperty(Constants.PR_LETTER_SPACING); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_TEXT_SHADOW); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addProperty(Constants.PR_WORD_SPACING); - elem.addContent(inline_elems); - - elem = elements[Constants.FO_PAGE_NUMBER]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonFontProperties); - elem.addProperties(CommonMarginPropertiesInline); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_VERTICAL_ALIGN); - elem.addProperty(Constants.PR_ALIGNMENT_ADJUST); - elem.addProperty(Constants.PR_ALIGNMENT_BASELINE); - elem.addProperty(Constants.PR_BASELINE_SHIFT); - elem.addProperty(Constants.PR_DOMINANT_BASELINE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_LETTER_SPACING); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_SCORE_SPACES); - elem.addProperty(Constants.PR_TEXT_ALTITUDE); - elem.addProperty(Constants.PR_TEXT_DECORATION); - elem.addProperty(Constants.PR_TEXT_DEPTH); - elem.addProperty(Constants.PR_TEXT_SHADOW); - elem.addProperty(Constants.PR_TEXT_TRANSFORM); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addProperty(Constants.PR_WORD_SPACING); - elem.addProperty(Constants.PR_WRAP_OPTION); - - elem = elements[Constants.FO_PAGE_NUMBER_CITATION]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonFontProperties); - elem.addProperties(CommonMarginPropertiesInline); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_VERTICAL_ALIGN); - elem.addProperty(Constants.PR_ALIGNMENT_ADJUST); - elem.addProperty(Constants.PR_ALIGNMENT_BASELINE); - elem.addProperty(Constants.PR_BASELINE_SHIFT); - elem.addProperty(Constants.PR_DOMINANT_BASELINE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_LETTER_SPACING); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_REF_ID); - elem.addProperty(Constants.PR_SCORE_SPACES); - elem.addProperty(Constants.PR_TEXT_ALTITUDE); - elem.addProperty(Constants.PR_TEXT_DECORATION); - elem.addProperty(Constants.PR_TEXT_DEPTH); - elem.addProperty(Constants.PR_TEXT_SHADOW); - elem.addProperty(Constants.PR_TEXT_TRANSFORM); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addProperty(Constants.PR_WORD_SPACING); - elem.addProperty(Constants.PR_WRAP_OPTION); - - elem = elements[Constants.FO_PAGE_NUMBER_CITATION_LAST]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonFontProperties); - elem.addProperties(CommonMarginPropertiesInline); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_VERTICAL_ALIGN); - elem.addProperty(Constants.PR_ALIGNMENT_ADJUST); - elem.addProperty(Constants.PR_ALIGNMENT_BASELINE); - elem.addProperty(Constants.PR_BASELINE_SHIFT); - elem.addProperty(Constants.PR_DOMINANT_BASELINE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_LETTER_SPACING); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_REF_ID); - elem.addProperty(Constants.PR_SCORE_SPACES); - elem.addProperty(Constants.PR_TEXT_ALTITUDE); - elem.addProperty(Constants.PR_TEXT_DECORATION); - elem.addProperty(Constants.PR_TEXT_DEPTH); - elem.addProperty(Constants.PR_TEXT_SHADOW); - elem.addProperty(Constants.PR_TEXT_TRANSFORM); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addProperty(Constants.PR_WORD_SPACING); - elem.addProperty(Constants.PR_WRAP_OPTION); - - elem = elements[Constants.FO_TABLE_AND_CAPTION]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonMarginPropertiesBlock); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_PAGE_BREAK_AFTER); - elem.addProperty(Constants.PR_PAGE_BREAK_BEFORE); - elem.addProperty(Constants.PR_BREAK_AFTER); - elem.addProperty(Constants.PR_BREAK_BEFORE); - elem.addProperty(Constants.PR_CAPTION_SIDE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_TEXT_ALIGN); - elem.addContent(Constants.FO_TABLE_CAPTION); - elem.addContent(Constants.FO_TABLE); - - elem = elements[Constants.FO_TABLE]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonMarginPropertiesBlock); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_BLOCK_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_BORDER_AFTER_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_BEFORE_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_SPACING); - elem.addProperty(Constants.PR_BORDER_COLLAPSE); - elem.addProperty(Constants.PR_BORDER_END_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_SEPARATION); - elem.addProperty(Constants.PR_BORDER_START_PRECEDENCE); - elem.addProperty(Constants.PR_PAGE_BREAK_AFTER); - elem.addProperty(Constants.PR_PAGE_BREAK_BEFORE); - elem.addProperty(Constants.PR_BREAK_AFTER); - elem.addProperty(Constants.PR_BREAK_BEFORE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_INLINE_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_HEIGHT); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_TABLE_LAYOUT); - elem.addProperty(Constants.PR_TABLE_OMIT_FOOTER_AT_BREAK); - elem.addProperty(Constants.PR_TABLE_OMIT_HEADER_AT_BREAK); - elem.addProperty(Constants.PR_WIDTH); - elem.addProperty(Constants.PR_WRITING_MODE); - elem.addContent(Constants.FO_TABLE_COLUMN); - elem.addContent(Constants.FO_TABLE_HEADER); - elem.addContent(Constants.FO_TABLE_FOOTER); - elem.addContent(Constants.FO_TABLE_BODY); - - elem = elements[Constants.FO_TABLE_COLUMN]; - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperty(Constants.PR_BORDER_AFTER_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_BEFORE_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_END_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_START_PRECEDENCE); - elem.addProperty(Constants.PR_COLUMN_NUMBER); - elem.addProperty(Constants.PR_COLUMN_WIDTH); - elem.addProperty(Constants.PR_NUMBER_COLUMNS_REPEATED); - elem.addProperty(Constants.PR_NUMBER_COLUMNS_SPANNED); - elem.addProperty(Constants.PR_VISIBILITY); - - elem = elements[Constants.FO_TABLE_CAPTION]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_BLOCK_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_HEIGHT); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_INLINE_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addProperty(Constants.PR_WIDTH); - elem.addContent(block_elems); - - elem = elements[Constants.FO_TABLE_HEADER]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_BORDER_AFTER_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_BEFORE_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_END_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_START_PRECEDENCE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addContent(Constants.FO_TABLE_ROW); - elem.addContent(Constants.FO_TABLE_CELL); - - elem = elements[Constants.FO_TABLE_FOOTER]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_BORDER_AFTER_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_BEFORE_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_END_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_START_PRECEDENCE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addContent(Constants.FO_TABLE_ROW); - elem.addContent(Constants.FO_TABLE_CELL); - - elem = elements[Constants.FO_TABLE_BODY]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_BORDER_AFTER_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_BEFORE_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_END_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_START_PRECEDENCE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addContent(Constants.FO_TABLE_ROW); - elem.addContent(Constants.FO_TABLE_CELL); - - elem = elements[Constants.FO_TABLE_ROW]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperty(Constants.PR_BLOCK_PROGRESSION_DIMENSION); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_BORDER_AFTER_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_BEFORE_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_END_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_START_PRECEDENCE); - elem.addProperty(Constants.PR_PAGE_BREAK_AFTER); - elem.addProperty(Constants.PR_PAGE_BREAK_BEFORE); - elem.addProperty(Constants.PR_BREAK_AFTER); - elem.addProperty(Constants.PR_BREAK_BEFORE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_HEIGHT); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_VISIBILITY); - elem.addContent(Constants.FO_TABLE_CELL); - - elem = elements[Constants.FO_TABLE_CELL]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_BORDER_AFTER_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_BEFORE_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_END_PRECEDENCE); - elem.addProperty(Constants.PR_BORDER_START_PRECEDENCE); - elem.addProperty(Constants.PR_BLOCK_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_COLUMN_NUMBER); - elem.addProperty(Constants.PR_DISPLAY_ALIGN); - elem.addProperty(Constants.PR_RELATIVE_ALIGN); - elem.addProperty(Constants.PR_EMPTY_CELLS); - elem.addProperty(Constants.PR_ENDS_ROW); - elem.addProperty(Constants.PR_HEIGHT); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_INLINE_PROGRESSION_DIMENSION); - elem.addProperty(Constants.PR_NUMBER_COLUMNS_SPANNED); - elem.addProperty(Constants.PR_NUMBER_ROWS_SPANNED); - elem.addProperty(Constants.PR_STARTS_ROW); - elem.addProperty(Constants.PR_WIDTH); - elem.addContent(block_elems); - - elem = elements[Constants.FO_LIST_BLOCK]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonMarginPropertiesBlock); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_PAGE_BREAK_AFTER); - elem.addProperty(Constants.PR_PAGE_BREAK_BEFORE); - elem.addProperty(Constants.PR_BREAK_AFTER); - elem.addProperty(Constants.PR_BREAK_BEFORE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_PROVISIONAL_DISTANCE_BETWEEN_STARTS); - elem.addProperty(Constants.PR_PROVISIONAL_LABEL_SEPARATION); - elem.addContent(Constants.FO_LIST_ITEM); - - elem = elements[Constants.FO_LIST_ITEM]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonMarginPropertiesBlock); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_PAGE_BREAK_AFTER); - elem.addProperty(Constants.PR_PAGE_BREAK_BEFORE); - elem.addProperty(Constants.PR_BREAK_AFTER); - elem.addProperty(Constants.PR_BREAK_BEFORE); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_RELATIVE_ALIGN); - elem.addContent(Constants.FO_LIST_ITEM_LABEL); - elem.addContent(Constants.FO_LIST_ITEM_BODY); - - elem = elements[Constants.FO_LIST_ITEM_BODY]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addContent(block_elems); - - elem = elements[Constants.FO_LIST_ITEM_LABEL]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addContent(block_elems); - - elem = elements[Constants.FO_BASIC_LINK]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperties(CommonAuralProperties); - elem.addProperties(CommonBorderPaddingBackgroundProperties); - elem.addProperties(CommonMarginPropertiesInline); - elem.addProperties(CommonRelativePositionProperties); - elem.addProperty(Constants.PR_VERTICAL_ALIGN); - elem.addProperty(Constants.PR_ALIGNMENT_ADJUST); - elem.addProperty(Constants.PR_ALIGNMENT_BASELINE); - elem.addProperty(Constants.PR_BASELINE_SHIFT); - elem.addProperty(Constants.PR_DESTINATION_PLACEMENT_OFFSET); - elem.addProperty(Constants.PR_DOMINANT_BASELINE); - elem.addProperty(Constants.PR_EXTERNAL_DESTINATION); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_INDICATE_DESTINATION); - elem.addProperty(Constants.PR_INTERNAL_DESTINATION); - elem.addProperty(Constants.PR_PAGE_BREAK_INSIDE); - elem.addProperty(Constants.PR_KEEP_TOGETHER); - elem.addProperty(Constants.PR_KEEP_WITH_NEXT); - elem.addProperty(Constants.PR_KEEP_WITH_PREVIOUS); - elem.addProperty(Constants.PR_LINE_HEIGHT); - elem.addProperty(Constants.PR_SHOW_DESTINATION); - elem.addProperty(Constants.PR_TARGET_PROCESSING_CONTEXT); - elem.addProperty(Constants.PR_TARGET_PRESENTATION_CONTEXT); - elem.addProperty(Constants.PR_TARGET_STYLESHEET); - elem.addContent(inline_elems); - elem.addContent(block_elems); - - elem = elements[Constants.FO_MULTI_SWITCH]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperty(Constants.PR_AUTO_RESTORE); - elem.addProperty(Constants.PR_ID); - elem.addContent(Constants.FO_MULTI_CASE); - - elem = elements[Constants.FO_MULTI_CASE]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_STARTING_STATE); - elem.addProperty(Constants.PR_CASE_NAME); - elem.addProperty(Constants.PR_CASE_TITLE); - elem.addContent(inline_elems); - elem.addContent(block_elems); - - elem = elements[Constants.FO_MULTI_TOGGLE]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_SWITCH_TO); - elem.addContent(inline_elems); - elem.addContent(block_elems); - - elem = elements[Constants.FO_MULTI_PROPERTIES]; - elem.addProperties(CommonAccessibilityProperties); - elem.addProperty(Constants.PR_ID); - elem.addContent(Constants.FO_MULTI_PROPERTY_SET); - elem.addContent(Constants.FO_WRAPPER); - - elem = elements[Constants.FO_MULTI_PROPERTY_SET]; - elem.addProperty(Constants.PR_ID); - elem.addProperty(Constants.PR_ACTIVE_STATE); - - elem = elements[Constants.FO_FLOAT]; - elem.addProperty(Constants.PR_FLOAT); - elem.addProperty(Constants.PR_CLEAR); - elem.addContent(block_elems); - - elem = elements[Constants.FO_FOOTNOTE]; - elem.addProperties(CommonAccessibilityProperties); - elem.addContent(Constants.FO_INLINE); - elem.addContent(Constants.FO_FOOTNOTE_BODY); - - elem = elements[Constants.FO_FOOTNOTE_BODY]; - elem.addProperties(CommonAccessibilityProperties); - elem.addContent(block_elems); - - elem = elements[Constants.FO_WRAPPER]; - elem.addProperty(Constants.PR_ID); - elem.addContent(inline_elems); - elem.addContent(block_elems); - - elem = elements[Constants.FO_MARKER]; - elem.addProperty(Constants.PR_MARKER_CLASS_NAME); - elem.addContent(inline_elems); - elem.addContent(block_elems); - - elem = elements[Constants.FO_RETRIEVE_MARKER]; - elem.addProperty(Constants.PR_RETRIEVE_CLASS_NAME); - elem.addProperty(Constants.PR_RETRIEVE_POSITION); - elem.addProperty(Constants.PR_RETRIEVE_BOUNDARY); - - // Merge the attributes from the children into the parent. - for (boolean dirty = true; dirty;) { - dirty = false; - for (int i = 1; i < elements.length; i++) { - dirty = dirty || elements[i].merge(); - } - } - // Calculate the sparse indices for each element. - for (int i = 1; i < elements.length; i++) { - mapping[i] = makeSparseIndices(elements[i].valid); - } - } - - /** - * Turn a BitSet into an array of shorts with the first element - * on the array the number of set bits in the BitSet. - */ - private static short[] makeSparseIndices(BitSet set) { - short[] indices = new short[Constants.PROPERTY_COUNT + 1]; - int j = 1; - for (int i = 0; i < Constants.PROPERTY_COUNT + 1; i++) { - if (set.get(i)) { - indices[i] = (short) j++; - } - } - indices[0] = (short)j; - return indices; - } - - public static short[] getPropertySet(int elementId) { - if (mapping == null) { - mapping = new short[Constants.FRM_OBJ_COUNT + 1][]; - PropertySets ps = new PropertySets(); - ps.initializeElements(); - ps.initializeCommon(); - ps.initialize(); - } - return mapping[elementId]; - } - - /** - * Determines if fo:markers are allowed as children for the given FO - * @param elementId Constants enumeration ID of the FO (e.g., FO_ROOT) - * @return true if fo:markers allowed, false otherwise - * @todo check if still needed after validateChildNode() fully implemented - */ - public static boolean canHaveMarkers(int elementId) { - if (can_have_markers == null) { - can_have_markers = new BitSet(); - can_have_markers.set(Constants.FO_BASIC_LINK); - can_have_markers.set(Constants.FO_BIDI_OVERRIDE); - can_have_markers.set(Constants.FO_BLOCK); - can_have_markers.set(Constants.FO_BLOCK_CONTAINER); - can_have_markers.set(Constants.FO_FLOW); - can_have_markers.set(Constants.FO_INLINE); - can_have_markers.set(Constants.FO_INLINE_CONTAINER); - can_have_markers.set(Constants.FO_LIST_BLOCK); - can_have_markers.set(Constants.FO_LIST_ITEM); - can_have_markers.set(Constants.FO_LIST_ITEM_BODY); - can_have_markers.set(Constants.FO_LIST_ITEM_LABEL); - can_have_markers.set(Constants.FO_TABLE); - can_have_markers.set(Constants.FO_TABLE_BODY); - can_have_markers.set(Constants.FO_TABLE_HEADER); - can_have_markers.set(Constants.FO_TABLE_FOOTER); - can_have_markers.set(Constants.FO_TABLE_CELL); - can_have_markers.set(Constants.FO_TABLE_AND_CAPTION); - can_have_markers.set(Constants.FO_TABLE_CAPTION); - can_have_markers.set(Constants.FO_WRAPPER); - } - return can_have_markers.get(elementId); - } - - /** - * Determines if the FO generates inline areas. Used only within flow.Block - * for whitespace handling - * @param elementId Constants enumeration ID of the FO (e.g., FO_ROOT) - * @return true if id property is applicable, false otherwise - * @todo see if more values need to be entered here (copied values over - * from legacy code, list of FO's below probably incomplete) - * @todo see if still needed (LM has a similar generatesInlineAreas() - * method) - */ - public static boolean generatesInlineAreas(int elementId) { - if (no_inline_areas == null) { - no_inline_areas = new BitSet(); - no_inline_areas.set(Constants.FO_UNKNOWN_NODE); - no_inline_areas.set(Constants.FO_BLOCK); - no_inline_areas.set(Constants.FO_BLOCK_CONTAINER); - no_inline_areas.set(Constants.FO_LIST_BLOCK); - no_inline_areas.set(Constants.FO_LIST_ITEM); - no_inline_areas.set(Constants.FO_TABLE); - no_inline_areas.set(Constants.FO_TABLE_AND_CAPTION); - } - return !(no_inline_areas.get(elementId)); - } - - /** - * An object that represent the properties and contents of a fo element - */ - class Element { - BitSet relevant = new BitSet(); - BitSet valid = new BitSet(); - int elementId; - ArrayList childFOs; - - Element(int elementId) { - this.elementId = elementId; - } - - /** - * Add a single property to the element. - */ - public void addProperty(int propId) { - relevant.set(propId); - valid.set(propId); - } - - /** - * Add a set of properties to the element. - */ - public void addProperties(BitSet properties) { - relevant.or(properties); - valid.or(properties); - } - - /** - * Add a single fo element as a content child. - */ - public void addContent(int elementId) { - if (childFOs == null) { - childFOs = new ArrayList(); - } - childFOs.add(elements[elementId]); - } - - /** - * Add a set of fo elements as content childFOs. - */ - public void addContent(BitSet elements) { - for (int i = 0; i < elements.size(); i++) { - if (elements.get(i)) { - addContent(i); - } - } - } - - /** - * Merge the properties from the child FO's into the set of valid - * properties. Return true if at least one property could be added. - */ - public boolean merge() { - if (childFOs == null) { - return false; - } - boolean dirty = false; - for (int i = 0; i < childFOs.size(); i++) { - Element child = (Element) childFOs.get(i); - BitSet childValid = child.valid; - int n = childValid.length(); - for (int j = 0; j < n; j++) { - if (childValid.get(j) && !valid.get(j)) { - dirty = true; - valid.set(j); - } - } - } - return dirty; - } - } -} diff --git a/src/java/org/apache/fop/fo/StaticPropertyList.java b/src/java/org/apache/fop/fo/StaticPropertyList.java index f4b8f7ad6..1ef3abd73 100755 --- a/src/java/org/apache/fop/fo/StaticPropertyList.java +++ b/src/java/org/apache/fop/fo/StaticPropertyList.java @@ -21,7 +21,7 @@ import org.apache.fop.fo.properties.Property; /** * A very fast implementation of PropertyList that uses arrays to store - * the explit set properties and another array to store cached values. + * the explicit set properties and another array to store cached values. */ public class StaticPropertyList extends PropertyList { private Property[] explicit; diff --git a/src/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java b/src/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java index 9055057a9..183224ce1 100644 --- a/src/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java +++ b/src/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java @@ -72,11 +72,34 @@ public class XMLWhiteSpaceHandler { * @param firstTextNode the node at which to start */ public void handleWhiteSpace(FObjMixed fo, FONode firstTextNode) { - if (fo.getNameId() == Constants.FO_BLOCK) { - this.currentBlock = (Block) fo; - this.linefeedTreatment = currentBlock.getLinefeedTreatment(); - this.whiteSpaceCollapse = currentBlock.getWhitespaceCollapse(); - this.whiteSpaceTreatment = currentBlock.getWhitespaceTreatment(); + if (fo.getNameId() == Constants.FO_BLOCK + || fo.getNameId() == Constants.FO_RETRIEVE_MARKER) { + if (fo.getNameId() == Constants.FO_BLOCK) { + this.currentBlock = (Block) fo; + } else { + FONode ancestor = fo.parent; + while (ancestor.getNameId() != Constants.FO_BLOCK + && ancestor.getNameId() != Constants.FO_STATIC_CONTENT) { + ancestor = ancestor.getParent(); + } + if (ancestor.getNameId() == Constants.FO_BLOCK) { + this.currentBlock = (Block) ancestor; + } + } + if (currentBlock != null) { + this.linefeedTreatment = currentBlock.getLinefeedTreatment(); + this.whiteSpaceCollapse = currentBlock.getWhitespaceCollapse(); + this.whiteSpaceTreatment = + currentBlock.getWhitespaceTreatment(); + } else { + /* fo:retrieve-marker as direct child of static-content + * set properties to their initial values + */ + this.linefeedTreatment = Constants.EN_TREAT_AS_SPACE; + this.whiteSpaceCollapse = Constants.EN_TRUE; + this.whiteSpaceTreatment = + Constants.EN_IGNORE_IF_SURROUNDING_LINEFEED; + } } else if (fo.getNameId() == Constants.FO_TITLE || fo.getNameId() == Constants.FO_BOOKMARK_TITLE) { /* Two special types of FO that can contain #PCDATA @@ -84,7 +107,8 @@ public class XMLWhiteSpaceHandler { */ this.linefeedTreatment = Constants.EN_TREAT_AS_SPACE; this.whiteSpaceCollapse = Constants.EN_TRUE; - this.whiteSpaceTreatment = Constants.EN_IGNORE_IF_SURROUNDING_LINEFEED; + this.whiteSpaceTreatment = + Constants.EN_IGNORE_IF_SURROUNDING_LINEFEED; } currentFO = fo; if (firstTextNode == null) { @@ -94,7 +118,10 @@ public class XMLWhiteSpaceHandler { charIter = new RecursiveCharIterator(fo, firstTextNode); inWhiteSpace = false; int textNodeIndex = -1; - if (currentFO == currentBlock) { + if (currentFO == currentBlock + || currentBlock == null + || (currentFO.getNameId() == Constants.FO_RETRIEVE_MARKER + && currentFO.getParent() == currentBlock)) { textNodeIndex = fo.childNodes.indexOf(firstTextNode); afterLinefeed = ((textNodeIndex == 0) || (textNodeIndex > 0 @@ -104,7 +131,8 @@ public class XMLWhiteSpaceHandler { endOfBlock = (nextChild == null && currentFO == currentBlock); if (nextChild != null) { int nextChildId = nextChild.getNameId(); - nextChildIsBlockLevel = (nextChildId == Constants.FO_BLOCK + nextChildIsBlockLevel = ( + nextChildId == Constants.FO_BLOCK || nextChildId == Constants.FO_TABLE_AND_CAPTION || nextChildId == Constants.FO_TABLE || nextChildId == Constants.FO_LIST_BLOCK @@ -149,6 +177,11 @@ public class XMLWhiteSpaceHandler { addPendingInline(fo); } } + + if (currentFO == currentBlock && nextChild == null) { + /* end of block: clear the reference */ + currentBlock = null; + } } /** diff --git a/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java b/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java index 731b403f1..8b14a0c64 100644 --- a/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java +++ b/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java @@ -24,9 +24,9 @@ import org.apache.fop.fo.Constants; import org.apache.fop.fo.FObj; import org.apache.fop.fo.FOPropertyMapping; import org.apache.fop.fo.flow.Table; -import org.apache.fop.fo.flow.TableFObj; import org.apache.fop.fo.flow.TableCell; import org.apache.fop.fo.flow.TableColumn; +import org.apache.fop.fo.flow.TableFObj; import org.apache.fop.fo.properties.Property; /** diff --git a/src/java/org/apache/fop/fo/flow/Block.java b/src/java/org/apache/fop/fo/flow/Block.java index 6e9e5d662..b5dd2626f 100644 --- a/src/java/org/apache/fop/fo/flow/Block.java +++ b/src/java/org/apache/fop/fo/flow/Block.java @@ -42,20 +42,6 @@ import org.apache.fop.fo.properties.CommonRelativePosition; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.SpaceProperty; -/* - Modified by Mark Lillywhite mark-fop@inomial.com. The changes - here are based on memory profiling and do not change functionality. - Essentially, the Block object had a pointer to a BlockArea object - that it created. The BlockArea was not referenced after the Block - was finished except to determine the size of the BlockArea, however - a reference to the BlockArea was maintained and this caused a lot of - GC problems, and was a major reason for FOP memory leaks. So, - the reference to BlockArea was made local, the required information - is now stored (instead of a reference to the complex BlockArea object) - and it appears that there are a lot of changes in this file, in fact - there are only a few sematic changes; mostly I just got rid of - "this." from blockArea since BlockArea is now local. - */ /** * Class modelling the fo:block object. */ @@ -361,6 +347,48 @@ public class Block extends FObjMixed { return whiteSpaceCollapse; } + /** + * @return Returns the commonAccessibility. + */ + public CommonAccessibility getCommonAccessibility() { + return this.commonAccessibility; + } + + /** + * @return Returns the commonAural. + */ + public CommonAural getCommonAural() { + return this.commonAural; + } + + /** + * @return Returns the commonRelativePosition. + */ + public CommonRelativePosition getCommonRelativePosition() { + return this.commonRelativePosition; + } + + /** + * @return Returns the hyphenationKeep. + */ + public int getHyphenationKeep() { + return this.hyphenationKeep; + } + + /** + * @return Returns the intrusionDisplace. + */ + public int getIntrusionDisplace() { + return this.intrusionDisplace; + } + + /** + * @return Returns the lineHeightShiftAdjustment. + */ + public int getLineHeightShiftAdjustment() { + return this.lineHeightShiftAdjustment; + } + /** @see org.apache.fop.fo.FONode#charIterator() */ public CharIterator charIterator() { return NullCharIterator.getInstance(); @@ -377,4 +405,5 @@ public class Block extends FObjMixed { public int getNameId() { return FO_BLOCK; } + } diff --git a/src/java/org/apache/fop/fo/flow/Marker.java b/src/java/org/apache/fop/fo/flow/Marker.java index d848e281d..f9c61d90f 100644 --- a/src/java/org/apache/fop/fo/flow/Marker.java +++ b/src/java/org/apache/fop/fo/flow/Marker.java @@ -20,9 +20,8 @@ package org.apache.fop.fo.flow; import java.util.HashMap; -import java.util.Iterator; - +import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.apache.fop.apps.FOPException; @@ -30,6 +29,7 @@ import org.apache.fop.fo.FOEventHandler; import org.apache.fop.fo.FONode; import org.apache.fop.fo.FObj; import org.apache.fop.fo.FObjMixed; +import org.apache.fop.fo.FOPropertyMapping; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.PropertyListMaker; import org.apache.fop.fo.ValidationException; @@ -44,7 +44,7 @@ public class Marker extends FObjMixed { // End of property values private PropertyListMaker savePropertyListMaker; - private HashMap descPLists = new HashMap(); + private HashMap descendantPropertyLists = new HashMap(); /** * Create a marker fo. @@ -76,14 +76,11 @@ public class Marker extends FObjMixed { * @param foNode the FO node whose property list is requested * @return the MarkerPropertyList of foNode */ - protected MarkerPropertyList getPList(FONode foNode) { - return (MarkerPropertyList) descPLists.get(foNode); - } - - protected PropertyList createPropertyList(PropertyList parent, FOEventHandler foEventHandler) throws FOPException { - return new MarkerPropertyList(this, parent); + protected MarkerPropertyList getPropertyListFor(FONode foNode) { + return (MarkerPropertyList) + descendantPropertyLists.get(foNode); } - + /** @see org.apache.fop.fo.FONode#startOfNode() */ protected void startOfNode() { FOEventHandler foEventHandler = getFOEventHandler(); @@ -92,30 +89,18 @@ public class Marker extends FObjMixed { foEventHandler.setPropertyListMaker(new PropertyListMaker() { public PropertyList make(FObj fobj, PropertyList parentPropertyList) { PropertyList pList = new MarkerPropertyList(fobj, parentPropertyList); - descPLists.put(fobj, pList); + descendantPropertyLists.put(fobj, pList); return pList; } }); } - + /** @see org.apache.fop.fo.FONode#endOfNode() */ protected void endOfNode() throws FOPException { super.endOfNode(); // Pop the MarkerPropertyList maker. getFOEventHandler().setPropertyListMaker(savePropertyListMaker); savePropertyListMaker = null; - // unparent the child property lists - Iterator iter = getChildNodes(); - if (iter != null) { - while (iter.hasNext()) { - FONode child = (FONode) iter.next(); - MarkerPropertyList pList - = (MarkerPropertyList) descPLists.get(child); - if (pList != null) { - pList.setParentPropertyList(null); - } - } - } } /** @@ -132,7 +117,11 @@ public class Marker extends FObjMixed { invalidChildError(loc, nsURI, localName); } } - + + protected boolean inMarker() { + return true; + } + /** * Return the "marker-class-name" property. */ @@ -160,30 +149,252 @@ public class Marker extends FObjMixed { } /** - * An implementation of PropertyList which only stores the explicit - * assigned properties. It is memory efficient but slow. + * An implementation of PropertyList which only stores the explicitly + * specified properties/attributes as bundles of name-value-namespace + * strings */ - public class MarkerPropertyList extends PropertyList { - HashMap explicit = new HashMap(); - public MarkerPropertyList(FObj fobj, PropertyList parentPropertyList) { - super(fobj, parentPropertyList); + protected class MarkerPropertyList extends PropertyList + implements Attributes { + + protected class MarkerAttribute { + + protected String namespace; + protected String qname; + protected String name; + protected String value; + + /** + * Main constructor + * @param namespace the namespace URI + * @param qname the qualified name + * @param name the name + * @param value the value + */ + public MarkerAttribute(String namespace, String qname, + String name, String value) { + this.namespace = namespace; + this.qname = qname; + this.name = (name == null ? qname : name); + this.value = value; + } + + /** + * Convenience constructor for FO attributes + * @param name the attribute name + * @param value the attribute value + */ + public MarkerAttribute(String name, String value) { + this.namespace = null; + this.qname = name; + this.name = name; + this.value = value; + } } + /** the array of attributes **/ + private MarkerAttribute[] attribs; + /** - * Set the parent property list. Used to assign a new parent - * before re-binding all the child elements. + * Overriding default constructor + * + * @param fobj the FObj to attach + * @param parentPropertyList ignored */ - public void setParentPropertyList(PropertyList parentPropertyList) { - this.parentPropertyList = parentPropertyList; + public MarkerPropertyList(FObj fobj, PropertyList parentPropertyList) { + /* ignore parentPropertyList + * won't be used because the attributes will be stored + * without resolving + */ + super(fobj, null); } + + /** + * Override that doesn't convert the attributes to Property instances, + * but simply stores the attributes for later processing; + * + * @see org.apache.fop.fo.PropertyList#addAttributesToList(Attributes) + */ + public void addAttributesToList(Attributes attributes) + throws ValidationException { + + this.attribs = new MarkerAttribute[attributes.getLength()]; + String name; + String value; + String namespace; + String qname; + + for (int i = attributes.getLength(); --i >= 0;) { + namespace = attributes.getURI(i); + qname = attributes.getQName(i); + name = attributes.getLocalName(i); + value = attributes.getValue(i); + + this.attribs[i] = + new MarkerAttribute(namespace, qname, name, value); + } + } + + /** + * Null implementation; not used by this type of PropertyList + * @see org.apache.fop.fo.PropertyList#putExplicit(int, Property) + */ public void putExplicit(int propId, Property value) { - explicit.put(new Integer(propId), value); + //nop } + /** + * Null implementation; not used by this type of PropertyList + * @see org.apache.fop.fo.PropertyList#getExplicit(int) + */ public Property getExplicit(int propId) { - return (Property) explicit.get(new Integer(propId)); + return null; + } + + /** + * @see org.xml.sax.Attributes#getLength() + */ + public int getLength() { + if (attribs == null) { + return 0; + } else { + return attribs.length; + } + } + + /** + * @see org.xml.sax.Attributes#getURI() + */ + public String getURI(int index) { + if (attribs != null + && index < attribs.length + && index >= 0 + && attribs[index] != null) { + return attribs[index].namespace; + } else { + return null; + } + } + + /** + * @see org.xml.sax.Attributes#getLocalName() + */ + public String getLocalName(int index) { + if (attribs != null + && index < attribs.length + && index >= 0 + && attribs[index] != null) { + return attribs[index].name; + } else { + return null; + } + } + + /** + * @see org.xml.sax.Attributes#getQName() + */ + public String getQName(int index) { + if (attribs != null + && index < attribs.length + && index >= 0 + && attribs[index] != null) { + return attribs[index].qname; + } else { + return null; + } } - } -} + /** + * Default implementation; not used + * @see org.xml.sax.Attributes#getType() + */ + public String getType(int index) { + return "CDATA"; + } + + /** + * @see org.xml.sax.Attributes#getValue() + */ + public String getValue(int index) { + if (attribs != null + && index < attribs.length + && index >= 0 + && attribs[index] != null) { + return attribs[index].value; + } else { + return null; + } + } + + /** + * @see org.xml.sax.Attributes#getIndex() + */ + public int getIndex(String name, String namespace) { + int index = -1; + if (attribs != null && name != null && namespace != null) { + for (int i = attribs.length; --i >= 0;) { + if (attribs[i] != null + && namespace.equals(attribs[i].namespace) + && name.equals(attribs[i].name)) { + break; + } + } + } + return index; + } + + /** + * @see org.xml.sax.Attributes#getIndex() + */ + public int getIndex(String qname) { + int index = -1; + if (attribs != null && qname != null) { + for (int i = attribs.length; --i >= 0;) { + if (attribs[i] != null + && qname.equals(attribs[i].qname)) { + break; + } + } + } + return index; + } + + /** + * Default implementation; not used + * @see org.xml.sax.Attributes#getType() + */ + public String getType(String name, String namespace) { + return "CDATA"; + } + + /** + * Default implementation; not used + * @see org.xml.sax.Attributes#getType() + */ + public String getType(String qname) { + return "CDATA"; + } + + /** + * @see org.xml.sax.Attributes#getValue() + */ + public String getValue(String name, String namespace) { + int index = getIndex(name, namespace); + if (index > 0) { + return getValue(index); + } + return null; + } + + /** + * @see org.xml.sax.Attributes#getValue() + */ + public String getValue(String qname) { + int index = getIndex(qname); + if (index > 0) { + return getValue(index); + } + return null; + } + } +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/fo/flow/RetrieveMarker.java b/src/java/org/apache/fop/fo/flow/RetrieveMarker.java index bbdaa24a7..8665ed810 100644 --- a/src/java/org/apache/fop/fo/flow/RetrieveMarker.java +++ b/src/java/org/apache/fop/fo/flow/RetrieveMarker.java @@ -19,24 +19,24 @@ package org.apache.fop.fo.flow; -import java.util.Map; import java.util.HashMap; import java.util.Iterator; -import java.util.ArrayList; - -import org.xml.sax.Locator; - -import org.apache.commons.logging.Log; import org.apache.fop.apps.FOPException; -import org.apache.fop.fo.FOEventHandler; import org.apache.fop.fo.FONode; -import org.apache.fop.fo.FOText; +import org.apache.fop.fo.FOPropertyMapping; import org.apache.fop.fo.FObj; import org.apache.fop.fo.FObjMixed; +import org.apache.fop.fo.FOText; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.StaticPropertyList; import org.apache.fop.fo.ValidationException; +import org.apache.fop.fo.expr.PropertyException; +import org.apache.fop.fo.properties.Property; +import org.apache.fop.fo.properties.PropertyMaker; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; + /** @@ -44,7 +44,7 @@ import org.apache.fop.fo.ValidationException; * This will create a layout manager that will retrieve * a marker based on the information. */ -public class RetrieveMarker extends FObj { +public class RetrieveMarker extends FObjMixed { // The value of properties relevant for fo:retrieve-marker. private String retrieveClassName; private int retrievePosition; @@ -78,7 +78,9 @@ public class RetrieveMarker extends FObj { if (retrieveClassName == null || retrieveClassName.equals("")) { missingPropertyError("retrieve-class-name"); - } + } + + propertyList = pList.getParentPropertyList(); } /** @@ -90,40 +92,70 @@ public class RetrieveMarker extends FObj { invalidChildError(loc, nsURI, localName); } - protected PropertyList createPropertyList(PropertyList parent, - FOEventHandler foEventHandler) throws FOPException { - // TODO: A special RetrieveMarkerPropertyList would be more memory - // efficient. Storing a StaticPropertyList like this will keep all - // the parent PropertyLists alive. - propertyList = new StaticPropertyList(this, parent); - return propertyList; - } - - public PropertyList getPropertyList() { - return propertyList; - } - /** - * Return the "retrieve-class-name" property. + * @return the "retrieve-class-name" property. */ public String getRetrieveClassName() { return retrieveClassName; } /** - * Return the "retrieve-position" property. + * @return the "retrieve-position" property (enum value). */ public int getRetrievePosition() { return retrievePosition; } /** - * Return the "retrieve-boundry" property. + * @return the "retrieve-boundary" property (enum value). */ public int getRetrieveBoundary() { return retrieveBoundary; } + + private PropertyList createPropertyListFor(FObj fo, PropertyList parent) { + return getFOEventHandler().getPropertyListMaker().make(fo, parent); + } + + private void cloneSingleNode(FONode child, FONode newParent, + Marker marker, PropertyList parentPropertyList) + throws FOPException { + if (child != null) { + FONode newChild = child.clone(newParent, true); + if (child instanceof FObj) { + Marker.MarkerPropertyList pList; + PropertyList newPropertyList = createPropertyListFor( + (FObj) newChild, parentPropertyList); + + pList = marker.getPropertyListFor(child); + newChild.processNode( + child.getLocalName(), + getLocator(), + pList, + newPropertyList); + if (newChild.getNameId() == FO_TABLE) { + Table t = (Table) child; + cloneSubtree(t.getColumns().listIterator(), + newChild, marker, newPropertyList); + cloneSingleNode(t.getTableHeader(), + newChild, marker, newPropertyList); + cloneSingleNode(t.getTableFooter(), + newChild, marker, newPropertyList); + } + cloneSubtree(child.getChildNodes(), newChild, + marker, newPropertyList); + if (newChild instanceof FObjMixed) { + handleWhiteSpaceFor((FObjMixed) newChild); + } + } else if (child instanceof FOText) { + FOText ft = (FOText) newChild; + ft.bind(parentPropertyList); + } + addChildTo(newChild, (FObj) newParent); + } + } + /** * Clone the FO nodes in the parent iterator, * attach the new nodes to the new parent, @@ -136,94 +168,48 @@ public class RetrieveMarker extends FObj { * @param descPLists the map of the new nodes to property lists */ private void cloneSubtree(Iterator parentIter, FONode newParent, - Marker marker, Map descPLists) - throws FOPException { - if (parentIter == null) return; - while (parentIter.hasNext()) { - FONode child = (FONode) parentIter.next(); - FONode newChild = child.clone(newParent, true); - descPLists.put(newChild, marker.getPList(child)); - cloneSubtree(child.getChildNodes(), newChild, marker, descPLists); - } - } - - /** - * Clone the subtree of marker, - * and attach the new subtree to this node. - * The property lists are not cloned; - * the existing property lists of the direct children - * are reparented to the property list of this node. - * @param marker the marker that is to be cloned - * @param descPLists the map of the new nodes to property lists - */ - private void cloneFromMarker(Marker marker, Map descPLists) + Marker marker, PropertyList parentPropertyList) throws FOPException { - // release child nodes from a possible earlier layout - childNodes = new ArrayList(); - Iterator markerIter = marker.getChildNodes(); - cloneSubtree(markerIter, this, marker, descPLists); - // reparent the property lists of the direct children - for (Iterator iter = getChildNodes(); iter.hasNext(); ) { - FONode child = (FONode) iter.next(); - Marker.MarkerPropertyList pList - = (Marker.MarkerPropertyList) descPLists.get(child); - if (pList != null) { - pList.setParentPropertyList(propertyList); + if (parentIter != null) { + FONode child; + while (parentIter.hasNext()) { + child = (FONode) parentIter.next(); + cloneSingleNode(child, newParent, + marker, parentPropertyList); } } } - /** - * Bind the new nodes to the property values in this context - * @param descPLists the map of the new nodes to property lists - */ - private void bindChildren(Map descPLists) throws FOPException { - for (Iterator i = descPLists.keySet().iterator(); i.hasNext(); ) { - FONode desc = (FONode) i.next(); - PropertyList descPList; - if (desc instanceof FObj) { - descPList = (PropertyList) descPLists.get(desc); - ((FObj) desc).bind(descPList); - } else if (desc instanceof FOText) { - descPList = (PropertyList) descPLists.get(desc.getParent()); - if (descPList == null) { - descPList = propertyList; - } - ((FOText) desc).bind(descPList); - } + private void cloneFromMarker(Marker marker) + throws FOPException { + // clean up remnants from a possible earlier layout + if (childNodes != null) { + currentTextNode = null; + childNodes.removeAll(childNodes); } + cloneSubtree(marker.getChildNodes(), this, + marker, propertyList); } /** - * Clone the subtree of marker - * and bind the nodes to the property values in this context. - * The property lists are not cloned, - * but the subtree is attached to the property list of this node. - * This is only needed for the binding of the FO nodes. - * After that a subsequent retrieve-marker - * may reparent the property lists. + * Clone the subtree of the given marker + * * @param marker the marker that is to be cloned */ public void bindMarker(Marker marker) { - // assert(marker != null); - // catch empty marker - if (marker.getChildNodes() == null) { - return; - } - HashMap descPLists = new HashMap(); - try { - cloneFromMarker(marker, descPLists); - } catch (FOPException exc) { - Log log = getLogger(); - log.error("fo:retrieve-marker unable to clone subtree of fo:marker", exc); - return; - } - try { - bindChildren(descPLists); - } catch (FOPException exc) { - Log log = getLogger(); - log.error("fo:retrieve-marker unable to rebind property values", exc); + if (marker.getChildNodes() != null) { + try { + cloneFromMarker(marker); + } catch (FOPException exc) { + log.error("fo:retrieve-marker unable to clone " + + "subtree of fo:marker (marker-class-name=" + + marker.getMarkerClassName() + ")", exc); + return; + } + } else if (log.isInfoEnabled()) { + log.info("Empty marker retrieved..."); } + return; } /** @see org.apache.fop.fo.FONode#getLocalName() */ @@ -236,5 +222,5 @@ public class RetrieveMarker extends FObj { */ public int getNameId() { return FO_RETRIEVE_MARKER; - } -} + } +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/fo/flow/Table.java b/src/java/org/apache/fop/fo/flow/Table.java index 954c3ba0b..9a4724ed4 100644 --- a/src/java/org/apache/fop/fo/flow/Table.java +++ b/src/java/org/apache/fop/fo/flow/Table.java @@ -27,6 +27,7 @@ import org.xml.sax.Locator; import org.apache.fop.apps.FOPException; import org.apache.fop.datatypes.ValidationPercentBaseContext; import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.StaticPropertyList; import org.apache.fop.fo.ValidationException; @@ -209,15 +210,19 @@ public class Table extends TableFObj { * @see org.apache.fop.fo.FONode#endOfNode */ protected void endOfNode() throws FOPException { + if (!tableBodyFound) { missingChildElementError( "(marker*,table-column*,table-header?,table-footer?" + ",table-body+)"); } - if (columns != null && !columns.isEmpty()) { - for (int i = columns.size(); --i >= 0;) { - if (isColumnNumberUsed(i + 1)) { - ((TableColumn) columns.get(i)).releasePropertyList(); + if (!inMarker()) { + if (columns != null && !columns.isEmpty()) { + for (int i = columns.size(); --i >= 0;) { + TableColumn col = (TableColumn) columns.get(i); + if (col != null) { + col.releasePropertyList(); + } } } } @@ -229,7 +234,14 @@ public class Table extends TableFObj { */ protected void addChildNode(FONode child) throws FOPException { if ("fo:table-column".equals(child.getName())) { - addColumnNode((TableColumn) child); + if (columns == null) { + columns = new java.util.ArrayList(); + } + if (!inMarker()) { + addColumnNode((TableColumn) child); + } else { + columns.add((TableColumn) child); + } } else { if ("fo:table-footer".equals(child.getName())) { tableFooter = (TableBody) child; @@ -252,9 +264,6 @@ public class Table extends TableFObj { private void addColumnNode(TableColumn col) { int colNumber = col.getColumnNumber(); int colRepeat = col.getNumberColumnsRepeated(); - if (columns == null) { - columns = new java.util.ArrayList(); - } if (columns.size() < colNumber) { //add nulls for non-occupied indices between //the last column up to and including the current one @@ -273,6 +282,10 @@ public class Table extends TableFObj { columns.add(col); } } + //flag column indices used by this column + int startIndex = columnIndex - 1; + int endIndex = startIndex + colRepeat; + flagColumnIndices(startIndex, endIndex); } /** @return true of table-layout="auto" */ @@ -458,9 +471,17 @@ public class Table extends TableFObj { } /** - * @see org.apache.fop.fo.flow.TableFObj#existsUsedColumnIndices() + * @see org.apache.fop.fo.FONode#clone(FONode, boolean) */ - protected boolean existsUsedColumnIndices() { - return (usedColumnIndices != null); + public FONode clone(FONode parent, boolean removeChildren) + throws FOPException { + FObj fobj = (FObj) super.clone(parent, removeChildren); + if (removeChildren) { + Table t = (Table) fobj; + t.columns = null; + t.tableHeader = null; + t.tableFooter = null; + } + return fobj; } } diff --git a/src/java/org/apache/fop/fo/flow/TableBody.java b/src/java/org/apache/fop/fo/flow/TableBody.java index 655279ee8..0a50b946d 100644 --- a/src/java/org/apache/fop/fo/flow/TableBody.java +++ b/src/java/org/apache/fop/fo/flow/TableBody.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.List; import java.util.ListIterator; +import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.apache.fop.apps.FOPException; @@ -33,6 +34,7 @@ import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.StaticPropertyList; import org.apache.fop.fo.ValidationException; +import org.apache.fop.fo.flow.TableFObj.PendingSpan; import org.apache.fop.fo.properties.CommonAccessibility; import org.apache.fop.fo.properties.CommonAural; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; @@ -62,7 +64,7 @@ public class TableBody extends TableFObj { * used for initial values of column-number property */ protected List pendingSpans; - protected BitSet usedColumnIndices = new BitSet(); + protected BitSet usedColumnIndices; private int columnIndex = 1; protected boolean firstRow = true; @@ -88,10 +90,29 @@ public class TableBody extends TableFObj { } /** + * @see org.apache.fop.fo.FONode#processNode() + */ + public void processNode(String elementName, Locator locator, + Attributes attlist, PropertyList pList) + throws FOPException { + if (!inMarker()) { + if (getTable().columns != null) { + int cap = getTable().columns.size(); + pendingSpans = new java.util.ArrayList(cap); + usedColumnIndices = new java.util.BitSet(cap); + } else { + pendingSpans = new java.util.ArrayList(); + usedColumnIndices = new java.util.BitSet(); + } + setNextColumnIndex(); + } + super.processNode(elementName, locator, attlist, pList); + } + + /** * @see org.apache.fop.fo.FONode#startOfNode */ protected void startOfNode() throws FOPException { - initPendingSpans(); getFOEventHandler().startBody(this); } @@ -99,7 +120,16 @@ public class TableBody extends TableFObj { * @see org.apache.fop.fo.FONode#endOfNode */ protected void endOfNode() throws FOPException { + + if (!inMarker()) { + // clean up + savedPropertyList = null; + pendingSpans = null; + usedColumnIndices = null; + } + getFOEventHandler().endBody(this); + if (!(tableRowsFound || tableCellsFound)) { if (getUserAgent().validateStrictly()) { missingChildElementError("marker* (table-row+|table-cell+)"); @@ -110,18 +140,11 @@ public class TableBody extends TableFObj { } } + /* if (tableCellsFound) { convertCellsToRows(); } - - //reset column index (so that it would be - //correct if the table is cloned during - //marker retrieval) - resetColumnIndex(); - //release references - savedPropertyList = null; - pendingSpans = null; - usedColumnIndices = null; + */ } /** @@ -159,6 +182,18 @@ public class TableBody extends TableFObj { } /** + * @see org.apache.fop.fo.FONode#addChildNode(FONode) + */ + protected void addChildNode(FONode child) throws FOPException { + if (!inMarker()) { + if (firstRow && child.getNameId() == FO_TABLE_ROW) { + firstRow = false; + } + } + super.addChildNode(child); + } + + /** * If table-cells are used as direct children of a table-body|header|footer * they are replaced in this method by proper table-rows. * @throws FOPException if there's a problem binding the TableRow's @@ -243,15 +278,17 @@ public class TableBody extends TableFObj { * column-number of 2, since the first column is already * occupied...) */ - protected void initPendingSpans() { - if (getTable().columns != null) { - List tableCols = getTable().columns; - pendingSpans = new java.util.ArrayList(tableCols.size()); - for (int i = tableCols.size(); --i >= 0;) { - pendingSpans.add(null); - } - } else { - if (firstRow && pendingSpans == null) { + protected void initPendingSpans(FONode child) { + if (child.getNameId() == FO_TABLE_ROW) { + pendingSpans = ((TableRow) child).pendingSpans; + } else if (pendingSpans == null) { + if (getTable().columns != null) { + List tableCols = getTable().columns; + pendingSpans = new java.util.ArrayList(tableCols.size()); + for (int i = tableCols.size(); --i >= 0;) { + pendingSpans.add(null); + } + } else { pendingSpans = new java.util.ArrayList(); } } @@ -262,7 +299,7 @@ public class TableBody extends TableFObj { * * @return the next column number to use */ - public int getCurrentColumnIndex() { + protected int getCurrentColumnIndex() { return columnIndex; } @@ -273,7 +310,7 @@ public class TableBody extends TableFObj { * * @param newIndex the new column index */ - public void setCurrentColumnIndex(int newIndex) { + protected void setCurrentColumnIndex(int newIndex) { columnIndex = newIndex; } @@ -281,11 +318,12 @@ public class TableBody extends TableFObj { * Resets the current column index for the TableBody * */ - public void resetColumnIndex() { + protected void resetColumnIndex() { columnIndex = 1; - for (int i = 0; i < usedColumnIndices.size(); i++) { + for (int i = usedColumnIndices.length(); --i >= 0;) { usedColumnIndices.clear(i); } + PendingSpan pSpan; for (int i = pendingSpans.size(); --i >= 0;) { pSpan = (PendingSpan) pendingSpans.get(i); @@ -293,13 +331,10 @@ public class TableBody extends TableFObj { pSpan.rowsLeft--; if (pSpan.rowsLeft == 0) { pendingSpans.set(i, null); + } else { + usedColumnIndices.set(i); } } - if (pendingSpans.get(i) != null) { - usedColumnIndices.set(i); - } else { - usedColumnIndices.clear(i); - } } if (!firstRow) { setNextColumnIndex(); @@ -310,19 +345,19 @@ public class TableBody extends TableFObj { * Increases columnIndex to the next available value * */ - private void setNextColumnIndex() { + protected void setNextColumnIndex() { while (usedColumnIndices.get(columnIndex - 1)) { //increment columnIndex columnIndex++; - //if the table has explicit columns, and - //the updated index is not assigned to any - //column, increment further until the next - //index occupied by a column... - if (getTable().columns != null) { - while (columnIndex <= getTable().columns.size() - && !getTable().isColumnNumberUsed(columnIndex) ) { - columnIndex++; - } + } + //if the table has explicit columns, and + //the index is not assigned to any + //column, increment further until the next + //index occupied by a column... + if (getTable().columns != null) { + while (columnIndex <= getTable().columns.size() + && !getTable().isColumnNumberUsed(columnIndex) ) { + columnIndex++; } } } @@ -337,11 +372,10 @@ public class TableBody extends TableFObj { * b) there is no previous cell (implicit * start of row) */ - protected boolean lastCellEndedRow(TableCell currentCell) { - if (childNodes != null && childNodes.indexOf(currentCell) > 0) { - FONode prevNode = (FONode) childNodes.get( - childNodes.indexOf(currentCell) - 1); - if (prevNode != null && prevNode.getNameId() == FO_TABLE_CELL) { + protected boolean previousCellEndedRow() { + if (childNodes != null) { + FONode prevNode = (FONode) childNodes.get(childNodes.size() - 1); + if (prevNode.getNameId() == FO_TABLE_CELL) { return ((TableCell) prevNode).endsRow(); } } @@ -368,11 +402,4 @@ public class TableBody extends TableFObj { } setNextColumnIndex(); } - - /** - * @see org.apache.fop.fo.flow.TableFObj#existsUsedColumnIndices() - */ - protected boolean existsUsedColumnIndices() { - return (usedColumnIndices != null); - } } diff --git a/src/java/org/apache/fop/fo/flow/TableCell.java b/src/java/org/apache/fop/fo/flow/TableCell.java index 15cbac391..467a2a856 100644 --- a/src/java/org/apache/fop/fo/flow/TableCell.java +++ b/src/java/org/apache/fop/fo/flow/TableCell.java @@ -22,6 +22,7 @@ package org.apache.fop.fo.flow; import java.util.BitSet; import java.util.List; +import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.apache.fop.apps.FOPException; @@ -30,10 +31,12 @@ import org.apache.fop.datatypes.Numeric; import org.apache.fop.fo.FONode; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; +import org.apache.fop.fo.expr.PropertyException; import org.apache.fop.fo.properties.CommonAccessibility; import org.apache.fop.fo.properties.CommonAural; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.CommonRelativePosition; +import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.LengthRangeProperty; /** @@ -59,6 +62,9 @@ public class TableCell extends TableFObj { private Numeric numberRowsSpanned; private int startsRow; private Length width; + private KeepProperty keepTogether; + private KeepProperty keepWithNext; + private KeepProperty keepWithPrevious; // End of property values /** used for FO validation */ @@ -95,11 +101,6 @@ public class TableCell extends TableFObj { protected int top; /** - * Set to true if all content completely laid out. - */ - private boolean bDone = false; - - /** * @param parent FONode that is the parent of this object */ public TableCell(FONode parent) { @@ -122,16 +123,14 @@ public class TableCell extends TableFObj { height = pList.get(PR_HEIGHT).getLength(); id = pList.get(PR_ID).getString(); inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange(); + columnNumber = pList.get(PR_COLUMN_NUMBER).getNumeric(); numberColumnsSpanned = pList.get(PR_NUMBER_COLUMNS_SPANNED).getNumeric(); numberRowsSpanned = pList.get(PR_NUMBER_ROWS_SPANNED).getNumeric(); startsRow = pList.get(PR_STARTS_ROW).getEnum(); width = pList.get(PR_WIDTH).getLength(); - - //Check to make sure we're not in retrieve-marker context - //TODO: Can this be generalized/extended to other FOs/Properties? - if (((TableFObj) parent).existsUsedColumnIndices()) { - columnNumber = pList.get(PR_COLUMN_NUMBER).getNumeric(); - } + keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep(); + keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep(); + keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep(); super.bind(pList); } @@ -163,112 +162,9 @@ public class TableCell extends TableFObj { getLogger().warn("starts-row/ends-row for fo:table-cells " + "non-applicable for children of an fo:table-row."); } - updateParentColumnIndex(); getFOEventHandler().endCell(this); } - private void updateParentColumnIndex() { - - int rowSpan = getNumberRowsSpanned(); - int colSpan = getNumberColumnsSpanned(); - int columnIndex = ((TableFObj) parent).getCurrentColumnIndex(); - - int i = -1; - while (++i < colSpan) { - //if table has explicit columns and the column-number isn't - //assigned to any column, increment further until the next - //column is encountered - if (getTable().getColumns() != null) { - while (columnIndex <= getTable().getColumns().size() - && !getTable().isColumnNumberUsed(columnIndex)) { - columnIndex++; - } - } - //if column-number is already in use by another cell - //in the current row => error! - if (((TableFObj) parent).isColumnNumberUsed(columnIndex + i)) { - log.error("fo:table-cell overlaps in column " - + (columnIndex + i)); - } - } - - if (parent.getNameId() == FO_TABLE_ROW) { - /* parent is a fo:table-row */ - TableRow row = (TableRow) parent; - TableBody body = (TableBody) parent.getParent(); - - if (body.isFirst(row) && getTable().columns == null ) { - row.pendingSpans.add(null); - if (row.usedColumnIndices == null) { - row.usedColumnIndices = new BitSet(); - } - } - //if the current cell spans more than one row, - //update pending span list for the next row - if (rowSpan > 1) { - for (i = colSpan; --i >= 0;) { - row.pendingSpans.set(columnIndex - 1 + i, - new PendingSpan(rowSpan)); - } - } - } else { - /* parent is (should be) a fo:table-body/-header/-footer */ - TableBody body = (TableBody) parent; - - /* if body.firstRow is still true, and : - * a) the cell starts a row, - * b) there was a previous cell - * c) that previous cell didn't explicitly end the previous row - * => set firstRow flag to false - */ - if (startsRow() && body.firstRow) { - if (!body.lastCellEndedRow(this)) { - body.firstRow = false; - } - } - - /* if there were no explicit columns, pendingSpans - * will not be properly initialized for the first row... - */ - if (body.firstRow && getTable().columns == null) { - for (i = colSpan; --i >= 0;) { - body.pendingSpans.add(null); - } - } - - /* if the current cell spans more than one row, - * update pending span list for the next row - */ - if (rowSpan > 1) { - for (i = colSpan; --i >= 0;) { - body.pendingSpans.set(columnIndex - 1 + i, - new PendingSpan(rowSpan)); - } - } - } - //flag column indices used by this cell, - //take into account that possibly not all column-numbers - //are used by columns in the parent table (if any), - //so a cell spanning three columns, might actually - //take up more than three columnIndices... - int startIndex = columnIndex - 1; - int endIndex = startIndex + colSpan; - if (getTable().columns != null) { - List cols = getTable().columns; - int tmpIndex = endIndex; - for (i = startIndex; i <= tmpIndex; ++i) { - if (i < cols.size() && cols.get(i) == null) { - endIndex++; - } - } - } - ((TableFObj) parent).flagColumnIndices(startIndex, endIndex); - if (endsRow() && parent.getNameId() != FO_TABLE_ROW) { - ((TableBody) parent).firstRow = false; - ((TableBody) parent).resetColumnIndex(); - } - } - /** * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String) * XSL Content Model: marker* (%block;)+ @@ -304,7 +200,7 @@ public class TableCell extends TableFObj { * @return the Common Border, Padding, and Background Properties. */ public CommonBorderPaddingBackground getCommonBorderPaddingBackground() { - return commonBorderPaddingBackground; + return this.commonBorderPaddingBackground; } /** diff --git a/src/java/org/apache/fop/fo/flow/TableColumn.java b/src/java/org/apache/fop/fo/flow/TableColumn.java index 9fbce1849..c82eb474a 100644 --- a/src/java/org/apache/fop/fo/flow/TableColumn.java +++ b/src/java/org/apache/fop/fo/flow/TableColumn.java @@ -78,10 +78,6 @@ public class TableColumn extends TableFObj { visibility = pList.get(PR_VISIBILITY).getEnum(); super.bind(pList); - if (getTable().isColumnNumberUsed(columnNumber.getValue())) { - throw new PropertyException("column-number \"" + columnNumber - + "\" has already been assigned to a previous column"); - } if (numberColumnsRepeated.getValue() <= 0) { throw new PropertyException("number-columns-repeated must be 1 or bigger, " + "but got " + numberColumnsRepeated.getValue()); @@ -104,10 +100,6 @@ public class TableColumn extends TableFObj { * @see org.apache.fop.fo.FONode#endOfNode */ protected void endOfNode() throws FOPException { - //flag column indices used by this column - int startIndex = getColumnNumber() - 1; - int endIndex = startIndex + getNumberColumnsRepeated(); - getTable().flagColumnIndices(startIndex, endIndex); getFOEventHandler().endColumn(this); } @@ -211,6 +203,4 @@ public class TableColumn extends TableFObj { protected void releasePropertyList() { this.pList = null; } - -} - +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/fo/flow/TableFObj.java b/src/java/org/apache/fop/fo/flow/TableFObj.java index 1497f2c6e..d2ea03d35 100644 --- a/src/java/org/apache/fop/fo/flow/TableFObj.java +++ b/src/java/org/apache/fop/fo/flow/TableFObj.java @@ -19,13 +19,23 @@ package org.apache.fop.fo.flow; +import java.util.BitSet; +import java.util.Iterator; +import java.util.List; + import org.apache.fop.apps.FOPException; import org.apache.fop.datatypes.Numeric; import org.apache.fop.datatypes.ValidationPercentBaseContext; +import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.ValidationException; +import org.apache.fop.fo.expr.PropertyException; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.fo.properties.NumberProperty; +import org.apache.fop.fo.properties.Property; +import org.apache.fop.fo.properties.PropertyMaker; /** * Superclass for table-related FOs @@ -89,13 +99,129 @@ public abstract class TableFObj extends FObj { if (getNameId() != FO_TABLE //Separate check for fo:table in Table.java && getNameId() != FO_TABLE_CELL && getCommonBorderPaddingBackground().hasPadding( - ValidationPercentBaseContext.getPseudoContextForValidationPurposes())) { - attributeWarning("padding-* properties are not applicable to " + getName() + ValidationPercentBaseContext + .getPseudoContextForValidationPurposes())) { + attributeWarning( + "padding-* properties are not applicable to " + getName() + ", but a non-zero value for padding was found."); } } /** + * @see org.apache.fop.fo.FONode#addChildNode(FONode) + */ + protected void addChildNode(FONode child) throws FOPException { + if (!inMarker() + && child.getNameId() == FO_TABLE_CELL) { + /* update current column index for the table-body/table-row */ + updateColumnIndex((TableCell) child); + } + super.addChildNode(child); + } + + private void updateColumnIndex(TableCell cell) + throws ValidationException { + + int rowSpan = cell.getNumberRowsSpanned(); + int colSpan = cell.getNumberColumnsSpanned(); + int columnIndex = getCurrentColumnIndex(); + + int i = -1; + while (++i < colSpan) { + if (isColumnNumberUsed(columnIndex + i)) { + /* if column-number is already in use by another cell + * in the current row => error! + */ + StringBuffer errorMessage = new StringBuffer(); + errorMessage.append("fo:table-cell overlaps in column ") + .append(columnIndex + i); + if (locator.getLineNumber() != -1) { + errorMessage.append(" (line #") + .append(locator.getLineNumber()).append(", column #") + .append(locator.getColumnNumber()).append(")"); + } + throw new ValidationException(errorMessage.toString()); + } + } + + if (getNameId() == FO_TABLE_ROW) { + + TableRow row = (TableRow) this; + TableBody body = (TableBody) parent; + + for (i = colSpan; --i >= 0;) { + row.pendingSpans.add(null); + } + + /* if the current cell spans more than one row, + * update pending span list for the next row + */ + if (rowSpan > 1) { + for (i = colSpan; --i >= 0;) { + row.pendingSpans.set(columnIndex - 1 + i, + new PendingSpan(rowSpan)); + } + } + } else { + + TableBody body = (TableBody) this; + + /* if body.firstRow is still true, and : + * a) the cell starts a row, + * b) there was a previous cell + * c) that previous cell didn't explicitly end the previous row + * => set firstRow flag to false + */ + if (body.firstRow && cell.startsRow()) { + if (!body.previousCellEndedRow()) { + body.firstRow = false; + } + } + + /* pendingSpans not initialized for the first row... + */ + if (body.firstRow) { + for (i = colSpan; --i >= 0;) { + body.pendingSpans.add(null); + } + } + + /* if the current cell spans more than one row, + * update pending span list for the next row + */ + if (rowSpan > 1) { + for (i = colSpan; --i >= 0;) { + body.pendingSpans.set(columnIndex - 1 + i, + new PendingSpan(rowSpan)); + } + } + } + + /* flag column indices used by this cell, + * take into account that possibly not all column-numbers + * are used by columns in the parent table (if any), + * so a cell spanning three columns, might actually + * take up more than three columnIndices... + */ + int startIndex = columnIndex - 1; + int endIndex = startIndex + colSpan; + if (getTable().columns != null) { + List cols = getTable().columns; + int tmpIndex = endIndex; + for (i = startIndex; i <= tmpIndex; ++i) { + if (i < cols.size() && cols.get(i) == null) { + endIndex++; + } + } + } + flagColumnIndices(startIndex, endIndex); + if (getNameId() != FO_TABLE_ROW && cell.endsRow()) { + ((TableBody) this).firstRow = false; + ((TableBody) this).resetColumnIndex(); + } + } + + /** * * @param side the side for which to return the border precedence * @return the "border-precedence" value for the given side @@ -121,7 +247,7 @@ public abstract class TableFObj extends FObj { * * @return the next column number to use */ - public int getCurrentColumnIndex() { + protected int getCurrentColumnIndex() { return 0; } @@ -133,10 +259,10 @@ public abstract class TableFObj extends FObj { * * @param newIndex new value for column index */ - public void setCurrentColumnIndex(int newIndex) { + protected void setCurrentColumnIndex(int newIndex) { //do nothing by default } - + /** * Checks if a certain column-number is already occupied * (overridden for Table, TableBody, TableRow) @@ -184,10 +310,83 @@ public abstract class TableFObj extends FObj { } /** - * Overridden for Table, TableBody, TableRow - * @return true if the usedColumnIndices BitSet exists, and is initialized + * PropertyMaker subclass for the column-number property + * */ - protected boolean existsUsedColumnIndices() { - return false; + public static class ColumnNumberPropertyMaker extends NumberProperty.Maker { + + /** + * Constructor + * @param propId the id of the property for which the maker should + * be created + */ + public ColumnNumberPropertyMaker(int propId) { + super(propId); + } + + /** + * @see PropertyMaker#make(PropertyList) + */ + public Property make(PropertyList propertyList) + throws PropertyException { + FObj fo = propertyList.getFObj(); + + if (fo.getNameId() == Constants.FO_TABLE_CELL + || fo.getNameId() == Constants.FO_TABLE_COLUMN) { + if (fo.getNameId() == Constants.FO_TABLE_CELL + && fo.getParent().getNameId() != Constants.FO_TABLE_ROW + && (propertyList.get(Constants.PR_STARTS_ROW).getEnum() + == Constants.EN_TRUE)) { + TableBody parent = (TableBody) fo.getParent(); + if (!parent.previousCellEndedRow()) { + parent.resetColumnIndex(); + } + } + return new NumberProperty(((TableFObj) fo.getParent()) + .getCurrentColumnIndex()); + } else { + throw new PropertyException( + "column-number property is only allowed" + + " on fo:table-cell or fo:table-column, not on " + + fo.getName()); + } + } + + /** + * Check the value of the column-number property. + * Return the parent's column index (initial value) in case + * of a negative or zero value + * + * @see org.apache.fop.fo.properties.PropertyMaker#get( + * int, PropertyList, boolean, boolean) + */ + public Property get(int subpropId, PropertyList propertyList, + boolean tryInherit, boolean tryDefault) + throws PropertyException { + + Property p = super.get(0, propertyList, tryInherit, tryDefault); + TableFObj fo = (TableFObj) propertyList.getFObj(); + TableFObj parent = (TableFObj) propertyList.getParentFObj(); + int columnIndex = p.getNumeric().getValue(); + + if (columnIndex <= 0) { + fo.getLogger().warn("Specified negative or zero value for " + + "column-number on " + fo.getName() + ": " + + columnIndex + " forced to " + + parent.getCurrentColumnIndex()); + return new NumberProperty(parent.getCurrentColumnIndex()); + } + //TODO: check for non-integer value and round + + /* if column-number was explicitly specified, force the + * parent's current column index to the specified value, + * so that the updated index will be the correct initial + * value for the next cell/column (see Rec 7.26.8) + */ + if (propertyList.getExplicit(Constants.PR_COLUMN_NUMBER) != null) { + parent.setCurrentColumnIndex(p.getNumeric().getValue()); + } + return p; + } } } diff --git a/src/java/org/apache/fop/fo/flow/TableFooter.java b/src/java/org/apache/fop/fo/flow/TableFooter.java index e698b1d55..82c698c0f 100644 --- a/src/java/org/apache/fop/fo/flow/TableFooter.java +++ b/src/java/org/apache/fop/fo/flow/TableFooter.java @@ -40,7 +40,6 @@ public class TableFooter extends TableBody { * @see org.apache.fop.fo.FONode#startOfNode */ protected void startOfNode() throws FOPException { - initPendingSpans(); //getFOEventHandler().startBody(this); } diff --git a/src/java/org/apache/fop/fo/flow/TableHeader.java b/src/java/org/apache/fop/fo/flow/TableHeader.java index ac6e96871..a487dd072 100644 --- a/src/java/org/apache/fop/fo/flow/TableHeader.java +++ b/src/java/org/apache/fop/fo/flow/TableHeader.java @@ -40,7 +40,6 @@ public class TableHeader extends TableBody { * @see org.apache.fop.fo.FONode#startOfNode */ protected void startOfNode() throws FOPException { - initPendingSpans(); //getFOEventHandler().startHeader(this); } diff --git a/src/java/org/apache/fop/fo/flow/TableRow.java b/src/java/org/apache/fop/fo/flow/TableRow.java index f93720545..1f0cb14ae 100644 --- a/src/java/org/apache/fop/fo/flow/TableRow.java +++ b/src/java/org/apache/fop/fo/flow/TableRow.java @@ -22,6 +22,7 @@ package org.apache.fop.fo.flow; import java.util.BitSet; import java.util.List; +import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.apache.fop.apps.FOPException; @@ -105,23 +106,29 @@ public class TableRow extends TableFObj { } /** + * @see org.apache.fop.fo.FONode#processNode(String, Locator, + * Attributes, PropertyList) + */ + public void processNode(String elementName, Locator locator, + Attributes attlist, PropertyList pList) throws FOPException { + if (!inMarker()) { + TableBody body = (TableBody) parent; + body.resetColumnIndex(); + pendingSpans = body.pendingSpans; + usedColumnIndices = body.usedColumnIndices; + while (usedColumnIndices.get(columnIndex - 1)) { + columnIndex++; + } + } + super.processNode(elementName, locator, attlist, pList); + } + + /** * @see org.apache.fop.fo.FONode#startOfNode */ protected void startOfNode() throws FOPException { - pendingSpans = ((TableBody) parent).pendingSpans; - usedColumnIndices = ((TableBody) parent).usedColumnIndices; - while (usedColumnIndices.get(columnIndex - 1)) { - columnIndex++; - } - checkId(id); getFOEventHandler().startRow(this); - if (((TableBody) parent).isFirst(this) - && getTable().columns == null ) { - if (pendingSpans == null) { - pendingSpans = new java.util.ArrayList(); - } - } } /** @@ -131,17 +138,10 @@ public class TableRow extends TableFObj { if (childNodes == null) { missingChildElementError("(table-cell+)"); } - if (((TableBody) parent).isFirst(this) - && getTable().columns == null ) { - //force parent body's pendingSpans - //to the one accumulated after processing this row - ((TableBody) parent).pendingSpans = pendingSpans; + if (!inMarker()) { + pendingSpans = null; + usedColumnIndices = null; } - ((TableBody) parent).resetColumnIndex(); - columnIndex = 1; - //release references - pendingSpans = null; - usedColumnIndices = null; getFOEventHandler().endRow(this); } @@ -155,7 +155,7 @@ public class TableRow extends TableFObj { if (!(FO_URI.equals(nsURI) && localName.equals("table-cell"))) { invalidChildError(loc, nsURI, localName); } - } + } /** * @return the "id" property. @@ -292,12 +292,5 @@ public class TableRow extends TableFObj { while (usedColumnIndices.get(columnIndex - 1)) { columnIndex++; } - } - - /** - * @see org.apache.fop.fo.flow.TableFObj#existsUsedColumnIndices() - */ - protected boolean existsUsedColumnIndices() { - return (usedColumnIndices != null); - } + } } diff --git a/src/java/org/apache/fop/fo/properties/ColumnNumberPropertyMaker.java b/src/java/org/apache/fop/fo/properties/ColumnNumberPropertyMaker.java deleted file mode 100644 index e1f6928cc..000000000 --- a/src/java/org/apache/fop/fo/properties/ColumnNumberPropertyMaker.java +++ /dev/null @@ -1,112 +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.fo.properties; - -import java.util.Iterator; - -import org.apache.fop.fo.Constants; -import org.apache.fop.fo.FObj; -import org.apache.fop.fo.PropertyList; -import org.apache.fop.fo.expr.PropertyException; -import org.apache.fop.fo.flow.TableBody; -import org.apache.fop.fo.flow.TableCell; -import org.apache.fop.fo.flow.TableFObj; - -/** - * Maker class for the column-number property on table-cells and - * table-columns - * - */ -public class ColumnNumberPropertyMaker extends NumberProperty.Maker { - - /** - * Constructor - * @param propId the id of the property for which the maker should be created - */ - public ColumnNumberPropertyMaker(int propId) { - super(propId); - } - - /** - * @see PropertyMaker#make(PropertyList) - */ - public Property make(PropertyList propertyList) throws PropertyException { - FObj fo = propertyList.getFObj(); - - if (fo.getNameId() == Constants.FO_TABLE_CELL - || fo.getNameId() == Constants.FO_TABLE_COLUMN) { - if (fo.getNameId() == Constants.FO_TABLE_CELL - && fo.getParent().getNameId() != Constants.FO_TABLE_ROW - && (propertyList.get(Constants.PR_STARTS_ROW).getEnum() - == Constants.EN_TRUE)) { - TableBody parent = (TableBody) fo.getParent(); - TableCell prevCell = null; - for (Iterator i = parent.getChildNodes(); - (i != null && i.hasNext());) { - prevCell = (TableCell) i.next(); - } - if (prevCell != null && !prevCell.endsRow()) { - parent.resetColumnIndex(); - } - } - return new NumberProperty(((TableFObj) fo.getParent()) - .getCurrentColumnIndex()); - } else { - throw new PropertyException("column-number property is only allowed" - + " on fo:table-cell or fo:table-column, not on " - + fo.getName()); - } - } - - /** - * Check the value of the column-number property. - * Return the parent's column index (initial value) in case - * of a negative or zero value - * - * @see org.apache.fop.fo.properties.PropertyMaker#get( - * int, PropertyList, boolean, boolean) - */ - public Property get(int subpropId, PropertyList propertyList, - boolean tryInherit, boolean tryDefault) - throws PropertyException { - - Property p = super.get(0, propertyList, tryInherit, tryDefault); - TableFObj fo = (TableFObj) propertyList.getFObj(); - TableFObj parent = (TableFObj) propertyList.getParentFObj(); - int columnIndex = p.getNumeric().getValue(); - - if (columnIndex <= 0) { - fo.getLogger().warn("Specified negative or zero value for " - + "column-number on " + fo.getName() + ": " - + columnIndex + " forced to " - + parent.getCurrentColumnIndex()); - return new NumberProperty(parent.getCurrentColumnIndex()); - } - //TODO: check for non-integer value and round - - //if column-number was explicitly specified, force the parent's current - //column index to the specified value, so that the updated index will - //be the correct initial value for the next cell/column (see Rec 7.26.8) - if (propertyList.getExplicit(Constants.PR_COLUMN_NUMBER) != null) { - parent.setCurrentColumnIndex(p.getNumeric().getValue()); - } - return p; - } -} diff --git a/src/java/org/apache/fop/fo/properties/FontShorthandProperty.java b/src/java/org/apache/fop/fo/properties/FontShorthandProperty.java index e652d153d..69177ad29 100644 --- a/src/java/org/apache/fop/fo/properties/FontShorthandProperty.java +++ b/src/java/org/apache/fop/fo/properties/FontShorthandProperty.java @@ -53,136 +53,142 @@ public class FontShorthandProperty extends ListProperty { public Property make(PropertyList propertyList, String value, FObj fo) throws PropertyException { - FontShorthandProperty newProp = new FontShorthandProperty(); - newProp.setSpecifiedValue(value); - - String specVal = value; - Property prop = null; - if ("inherit".equals(specVal)) { - for (int i = PROP_IDS.length; --i >= 0;) { - prop = propertyList.getFromParent(PROP_IDS[i]); - newProp.addProperty(prop, i); - } - } else { - /* initialize list with nulls */ - for (int pos = 6; --pos >= 0;) { - newProp.addProperty(null, pos); - } - prop = checkEnumValues(specVal); - if (prop == null) { - /* not an enum: - * value should consist at least of font-size and font-family - * separated by a space - * mind the possible spaces from quoted font-family names - */ - int spaceIndex = value.indexOf(' '); - int quoteIndex = (value.indexOf('\'') == -1) - ? value.indexOf('\"') : value.indexOf('\''); - if (spaceIndex == -1 - || (quoteIndex != -1 && spaceIndex > quoteIndex)) { - /* no spaces or first space appears after the first - * single/double quote, so malformed value string + try { + FontShorthandProperty newProp = new FontShorthandProperty(); + newProp.setSpecifiedValue(value); + + String specVal = value; + Property prop = null; + if ("inherit".equals(specVal)) { + /* fill the list with the individual properties from the parent */ + for (int i = PROP_IDS.length; --i >= 0;) { + prop = propertyList.getFromParent(PROP_IDS[i]); + newProp.addProperty(prop, i); + } + } else { + /* initialize list with nulls */ + for (int pos = PROP_IDS.length; --pos >= 0;) { + newProp.addProperty(null, pos); + } + prop = checkEnumValues(specVal); + if (prop == null) { + /* not an enum: + * value should consist at least of font-size and font-family + * separated by a space + * mind the possible spaces from quoted font-family names */ - throw new PropertyException("Invalid property value: " - + "font=\"" + value + "\""); - } - PropertyMaker m = null; - int fromIndex = spaceIndex + 1; - int toIndex = specVal.length(); - /* at least one space that appears before the first - * single/double quote, so extract the individual properties - */ - boolean fontFamilyParsed = false; - int commaIndex = value.indexOf(','); - while (!fontFamilyParsed) { - /* value contains a (list of) possibly quoted - * font-family name(s) + int spaceIndex = value.indexOf(' '); + int quoteIndex = (value.indexOf('\'') == -1) + ? value.indexOf('\"') : value.indexOf('\''); + if (spaceIndex == -1 + || (quoteIndex != -1 && spaceIndex > quoteIndex)) { + /* no spaces or first space appears after the first + * single/double quote, so malformed value string + */ + throw new PropertyException("Invalid property value: " + + "font=\"" + value + "\""); + } + PropertyMaker m = null; + int fromIndex = spaceIndex + 1; + int toIndex = specVal.length(); + /* at least one space that appears before the first + * single/double quote, so extract the individual properties */ - if (commaIndex == -1) { - /* no list, just a single name - * (or first name in the list) + boolean fontFamilyParsed = false; + int commaIndex = value.indexOf(','); + while (!fontFamilyParsed) { + /* value contains a (list of) possibly quoted + * font-family name(s) */ - if (quoteIndex != -1) { - /* a single name, quoted + if (commaIndex == -1) { + /* no list, just a single name + * (or first name in the list) */ - fromIndex = quoteIndex; - } - m = FObj.getPropertyMakerFor(PROP_IDS[1]); - prop = m.make(propertyList, specVal.substring(fromIndex), fo); - newProp.addProperty(prop, 1); - fontFamilyParsed = true; - } else { - if (quoteIndex != -1 && quoteIndex < commaIndex) { - /* a quoted font-family name as first name - * in the comma-separated list - * fromIndex = index of the first quote - */ - fromIndex = quoteIndex; - quoteIndex = -1; + if (quoteIndex != -1) { + /* a single name, quoted + */ + fromIndex = quoteIndex; + } + m = FObj.getPropertyMakerFor(PROP_IDS[1]); + prop = m.make(propertyList, specVal.substring(fromIndex), fo); + newProp.addProperty(prop, 1); + fontFamilyParsed = true; } else { - fromIndex = value.lastIndexOf(' ', commaIndex) + 1; + if (quoteIndex != -1 && quoteIndex < commaIndex) { + /* a quoted font-family name as first name + * in the comma-separated list + * fromIndex = index of the first quote + */ + fromIndex = quoteIndex; + quoteIndex = -1; + } else { + fromIndex = value.lastIndexOf(' ', commaIndex) + 1; + } + commaIndex = -1; } - commaIndex = -1; } - } - toIndex = fromIndex - 1; - fromIndex = value.lastIndexOf(' ', toIndex - 1) + 1; - value = specVal.substring(fromIndex, toIndex); - int slashIndex = value.indexOf('/'); - String fontSize = value.substring(0, - (slashIndex == -1) ? value.length() : slashIndex); - m = FObj.getPropertyMakerFor(PROP_IDS[0]); - prop = m.make(propertyList, fontSize, fo); - /* need to make sure subsequent call to LineHeightPropertyMaker.make() - * doesn't generate the default font-size property... - */ - propertyList.putExplicit(PROP_IDS[0], prop); - newProp.addProperty(prop, 0); - if (slashIndex != -1) { - /* line-height */ - String lineHeight = value.substring(slashIndex + 1); - m = FObj.getPropertyMakerFor(PROP_IDS[2]); - prop = m.make(propertyList, lineHeight, fo); - newProp.addProperty(prop, 2); - } - if (fromIndex != 0) { toIndex = fromIndex - 1; - value = specVal.substring(0, toIndex); - fromIndex = 0; - spaceIndex = value.indexOf(' '); - do { - toIndex = (spaceIndex == -1) ? value.length() : spaceIndex; - String val = value.substring(fromIndex, toIndex); - for (int i = 6; --i >= 3;) { - if (newProp.list.get(i) == null) { - /* not set */ - m = FObj.getPropertyMakerFor(PROP_IDS[i]); - val = m.checkValueKeywords(val); - prop = m.checkEnumValues(val); - if (prop != null) { - newProp.addProperty(prop, i); + fromIndex = value.lastIndexOf(' ', toIndex - 1) + 1; + value = specVal.substring(fromIndex, toIndex); + int slashIndex = value.indexOf('/'); + String fontSize = value.substring(0, + (slashIndex == -1) ? value.length() : slashIndex); + m = FObj.getPropertyMakerFor(PROP_IDS[0]); + prop = m.make(propertyList, fontSize, fo); + /* need to make sure subsequent call to LineHeightPropertyMaker.make() + * doesn't generate the default font-size property... + */ + propertyList.putExplicit(PROP_IDS[0], prop); + newProp.addProperty(prop, 0); + if (slashIndex != -1) { + /* line-height */ + String lineHeight = value.substring(slashIndex + 1); + m = FObj.getPropertyMakerFor(PROP_IDS[2]); + prop = m.make(propertyList, lineHeight, fo); + newProp.addProperty(prop, 2); + } + if (fromIndex != 0) { + toIndex = fromIndex - 1; + value = specVal.substring(0, toIndex); + fromIndex = 0; + spaceIndex = value.indexOf(' '); + do { + toIndex = (spaceIndex == -1) ? value.length() : spaceIndex; + String val = value.substring(fromIndex, toIndex); + for (int i = 6; --i >= 3;) { + if (newProp.list.get(i) == null) { + /* not set */ + m = FObj.getPropertyMakerFor(PROP_IDS[i]); + val = m.checkValueKeywords(val); + prop = m.checkEnumValues(val); + if (prop != null) { + newProp.addProperty(prop, i); + } } } - } - fromIndex = toIndex + 1; - spaceIndex = value.indexOf(' ', fromIndex); - } while (toIndex != value.length()); + fromIndex = toIndex + 1; + spaceIndex = value.indexOf(' ', fromIndex); + } while (toIndex != value.length()); + } + } else { + //TODO: implement enum values + log.warn("Enum values other than \"inherit\"" + + " not yet supported for the font shorthand."); + return null; } - } else { - //TODO: implement enum values - log.warn("Enum values other than \"inherit\"" - + " not yet supported for the font shorthand."); - return null; } - } - if (newProp.list.get(0) == null || newProp.list.get(1) == null) { - throw new PropertyException("Invalid property value: " - + "font-size and font-family are required for the font shorthand" - + "\nfont=" + value); - } - return newProp; + if (newProp.list.get(0) == null || newProp.list.get(1) == null) { + throw new PropertyException("Invalid property value: " + + "font-size and font-family are required for the font shorthand" + + "\nfont=\"" + value + "\""); + } + return newProp; + } catch (PropertyException pe) { + pe.setLocator(propertyList.getFObj().getLocator()); + pe.setPropertyName(getName()); + throw pe; + } } - } private void addProperty(Property prop, int pos) { diff --git a/status.xml b/status.xml index b71af09d4..55fc7a73b 100644 --- a/status.xml +++ b/status.xml @@ -28,6 +28,11 @@ <changes> <release version="FOP Trunk"> + <action context="Code" dev="AD" type="fix"> + Deferred property resolution for markers until they are actually retrieved, + which leads to percentages and relative font-sizes now getting the correct + values. Also deferred white-space-handling for markers. + </action> <action context="Code" dev="JM" type="update"> Changed the way overflowing pages are handled. The overflow property on region-body is now used to define the behaviour. diff --git a/test/fotree/testcases/table-cell_column-number_rowspan_bug38397.fo b/test/fotree/testcases/table-cell_column-number_rowspan_bug38397.fo new file mode 100644 index 000000000..0cf275217 --- /dev/null +++ b/test/fotree/testcases/table-cell_column-number_rowspan_bug38397.fo @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" + xmlns:test="http://xmlgraphics.apache.org/fop/test"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="normal" white-space-collapse="true"> + <fo:flow flow-name="xsl-region-body"> + <fo:table table-layout="fixed" width="100%" border-collapse="separate"> + <fo:table-column column-width="proportional-column-width(1)"/> + <fo:table-column column-width="proportional-column-width(1)"/> + <fo:table-column column-width="proportional-column-width(2)"/> + <fo:table-column column-width="proportional-column-width(2)"/> + <fo:table-body> + <fo:table-row> + <fo:table-cell number-rows-spanned="3" number-columns-spanned="2" display-align="center" border="solid 0.5pt"> + <test:assert property="column-number" expected="1" /> + <fo:block>cell1</fo:block> + </fo:table-cell> + <fo:table-cell number-rows-spanned="2" display-align="center" border="solid 0.5pt"> + <test:assert property="column-number" expected="3" /> + <fo:block>cell2</fo:block> + </fo:table-cell> + <fo:table-cell border="solid 0.5pt"> + <test:assert property="column-number" expected="4" /> + <fo:block>cell3</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row background-color="yellow"> + <fo:table-cell border="solid 0.5pt"> + <test:assert property="column-number" expected="4" /> + <fo:block>cell4</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell number-rows-spanned="2" display-align="center" border="solid 0.5pt"> + <test:assert property="column-number" expected="3" /> + <fo:block>cell5</fo:block> + </fo:table-cell> + <fo:table-cell border="solid 0.5pt"> + <test:assert property="column-number" expected="4" /> + <fo:block>cell6</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row background-color="yellow"> + <fo:table-cell number-rows-spanned="3" display-align="center" border="solid 0.5pt"> + <test:assert property="column-number" expected="1" /> + <fo:block>cell7</fo:block> + </fo:table-cell> + <fo:table-cell number-rows-spanned="3" display-align="center" border="solid 0.5pt"> + <test:assert property="column-number" expected="2" /> + <fo:block>cell8</fo:block> + </fo:table-cell> + <fo:table-cell border="solid 0.5pt"> + <test:assert property="column-number" expected="4" /> + <fo:block>cell9</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell number-rows-spanned="2" display-align="center" border="solid 0.5pt"> + <test:assert property="column-number" expected="3" /> + <fo:block>cell10</fo:block> + </fo:table-cell> + <fo:table-cell border="solid 0.5pt"> + <test:assert property="column-number" expected="4" /> + <fo:block>cell11</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row background-color="yellow"> + <fo:table-cell border="solid 0.5pt"> + <test:assert property="column-number" expected="4" /> + <fo:block>cell12</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + </fo:flow> + </fo:page-sequence> +</fo:root> diff --git a/test/layoutengine/disabled-testcases.xml b/test/layoutengine/disabled-testcases.xml index f920caea4..85d129643 100644 --- a/test/layoutengine/disabled-testcases.xml +++ b/test/layoutengine/disabled-testcases.xml @@ -195,20 +195,6 @@ lists, yet.</description> </testcase> <testcase> - <name>Whitespace around markers is not handled correctly</name> - <file>marker_white-space-collapse.xml</file> - <description>Whitespace within markers is handled according to the value of - the white-space-collapse property in the context of the fo:marker and not according to - the value of the property in the fo:retrieve-marker context.</description> - </testcase> - <testcase> - <name>Relative font sizes within markers are not handled correctly</name> - <file>marker_font-size.xml</file> - <description>Relative font sizes within markers are evaluated according to the - font size in the fo:marker context and not the font size in the fo:retrieve-marker - context.</description> - </testcase> - <testcase> <name>Page breaking doesn't deal with IPD changes</name> <file>page-breaking_4.xml</file> <description>Page breaking currently doesn't support changing available IPD @@ -334,7 +320,8 @@ <testcase> <name>table-cell empty area with marker.xml</name> <file>table-cell_empty_area_with_marker.xml</file> - <description>A table-cell producing an empty area does currently not add any markers to a page. See TODO entry in AreaAdditionUtil.</description> + <description>A table-cell producing an empty area does currently not add any markers to a page. + See TODO entry in AreaAdditionUtil.</description> </testcase> <testcase> <name>Border conditionality on table</name> diff --git a/test/layoutengine/standard-testcases/marker_font-size.xml b/test/layoutengine/standard-testcases/marker_font-size.xml index 26a0a172c..c4a7baba1 100644 --- a/test/layoutengine/standard-testcases/marker_font-size.xml +++ b/test/layoutengine/standard-testcases/marker_font-size.xml @@ -37,7 +37,9 @@ <fo:page-sequence master-reference="normal"> <fo:static-content flow-name="xsl-region-before"> <fo:block background-color="yellow" font-size="16pt"> - 1. Marker <fo:retrieve-marker retrieve-class-name="m1" /> + 1. Marker <fo:retrieve-marker retrieve-class-name="m1" + retrieve-boundary="page" + retrieve-position="first-starting-within-page" /> </fo:block> </fo:static-content> <fo:static-content flow-name="xsl-region-after"> @@ -46,7 +48,7 @@ </fo:block> </fo:static-content> <fo:flow flow-name="xsl-region-body"> - <fo:block background-color="red" white-space-collapse="false"> + <fo:block background-color="red"> <fo:marker marker-class-name="m1"> <fo:block font-size=".5em"> First marker with small font @@ -65,8 +67,9 @@ </fo:root> </fo> <checks> + <!-- font-size relative to the retrieve-marker context? --> <eval expected="8000" xpath="//regionBefore/block[1]/block/lineArea/text/@font-size"/> - - <eval expected="20000" xpath="//regionBefore/block[1]/block/lineArea/text/@font-size"/> + <eval expected="20000" xpath="//regionAfter/block[1]/block/lineArea/text/@font-size"/> + </checks> </testcase> diff --git a/test/layoutengine/standard-testcases/marker_percentage-resolution.xml b/test/layoutengine/standard-testcases/marker_percentage-resolution.xml new file mode 100644 index 000000000..6bb9343ad --- /dev/null +++ b/test/layoutengine/standard-testcases/marker_percentage-resolution.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<testcase> + <info> + <p> + This test checks markers and percentage resolution: + Percentages should be evaluated in the context in which the marker is + retrieved. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="2in"> + <fo:region-body margin="0.5in 0"/> + <fo:region-after extent="0.5in"/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="normal"> + <fo:static-content flow-name="xsl-region-after"> + <fo:block text-align="end" background-color="yellow"> + <fo:retrieve-marker retrieve-class-name="test" + retrieve-boundary="page" + retrieve-position="last-ending-within-page"/> + </fo:block> + </fo:static-content> + <fo:flow flow-name="xsl-region-body"> + <fo:table table-layout="fixed" width="100%"> + <fo:table-column number-columns-repeated="2"/> + <fo:table-body> + <fo:table-row> + <fo:table-cell> + <fo:marker marker-class-name="test"> + <fo:table table-layout="fixed" width="100%"> + <fo:table-column number-columns-repeated="2"/> + <fo:table-body> + <fo:table-row> + <fo:table-cell> + <fo:block>Subtotal</fo:block> + </fo:table-cell> + <fo:table-cell text-align="end"> + <fo:block>29.95</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + </fo:marker> + <fo:block>MemoryStick 32MB</fo:block> + </fo:table-cell> + <fo:table-cell text-align="end"> + <fo:block>29.95</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell> + <fo:marker marker-class-name="test"> + <fo:block-container inline-progression-dimension="75%"> + <fo:block>Test</fo:block> + </fo:block-container> + <fo:table table-layout="fixed" width="100%"> + <fo:table-column number-columns-repeated="2"/> + <fo:table-body> + <fo:table-row> + <fo:table-cell> + <fo:block>Subtotal</fo:block> + </fo:table-cell> + <fo:table-cell text-align="end"> + <fo:block>49.95</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + </fo:marker> + <fo:block>Geek-Tool</fo:block> + </fo:table-cell> + <fo:table-cell text-align="end"> + <fo:block>20.00</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <eval expected="270000" xpath="//regionAfter/block[1]/block[1]/@ipd"/> + <eval expected="360000" xpath="//regionAfter/block[1]/block[2]/@ipd"/> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/marker_white-space-collapse.xml b/test/layoutengine/standard-testcases/marker_white-space-collapse.xml index 645d34f4e..ddb9d23a2 100644 --- a/test/layoutengine/standard-testcases/marker_white-space-collapse.xml +++ b/test/layoutengine/standard-testcases/marker_white-space-collapse.xml @@ -52,7 +52,7 @@ </fo:block> </fo:static-content> <fo:flow flow-name="xsl-region-body"> - <fo:block background-color="red" white-space-collapse="false"> + <fo:block background-color="red"> <fo:marker marker-class-name="m1"> <fo:block> First marker with whitespace around @@ -71,11 +71,12 @@ </fo:root> </fo> <checks> - <!-- These checks do not have the correct values --> - <eval expected="1" xpath="count(//regionBefore/block[1]/block/lineArea/text/space)"/> - <eval expected="4" xpath="count(//regionBefore/block[2]/block/lineArea/text/space)"/> + <!-- preserve inter-word whitespace in the first block, + collapse them in the second --> + <eval expected="9" xpath="count(//regionBefore/block[1]/block[1]/lineArea[1]/text/space)"/> + <eval expected="4" xpath="count(//regionBefore/block[2]/block[1]/lineArea[1]/text/space)"/> - <eval expected="1" xpath="count(//regionAfter/block[1]/block/lineArea/text/space)"/> - <eval expected="4" xpath="count(//regionAfter/block[2]/block/lineArea/text/space)"/> + <eval expected="8" xpath="count(//regionAfter/block[1]/block[1]/lineArea[1]/text/space)"/> + <eval expected="4" xpath="count(//regionAfter/block[2]/block[1]/lineArea[1]/text/space)"/> </checks> </testcase> |