diff options
-rw-r--r-- | src/java/org/apache/fop/events/EventFormatter.xml | 3 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/flow/Wrapper.java | 56 | ||||
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java | 16 | ||||
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java | 4 | ||||
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java | 19 | ||||
-rw-r--r-- | status.xml | 9 | ||||
-rw-r--r-- | test/layoutengine/disabled-testcases.xml | 6 |
7 files changed, 75 insertions, 38 deletions
diff --git a/src/java/org/apache/fop/events/EventFormatter.xml b/src/java/org/apache/fop/events/EventFormatter.xml index 74e120407..4bff75f85 100644 --- a/src/java/org/apache/fop/events/EventFormatter.xml +++ b/src/java/org/apache/fop/events/EventFormatter.xml @@ -26,9 +26,10 @@ <message key="rule.childOfSPM">The element must be a child of fo:simple-page-master.</message> <message key="rule.childOfDeclarations">The element must be a child of fo:declarations.</message> <message key="rule.childOfSPMorDeclarations">The element must be a child of fo:declarations or fo:simple-page-master.</message> + <message key="rule.wrapperInvalidChildForParent">An fo:wrapper is only permitted to have children that would be permitted for its parent.</message> <message key="org.apache.fop.fo.FOValidationEventProducer.tooManyNodes">For "{elementName}", only one "{offendingNode}" may be declared.{{locator}}</message> <message key="org.apache.fop.fo.FOValidationEventProducer.nodeOutOfOrder">For "{elementName}", "{tooLateNode}" must be declared before "{tooEarlyNode}"!{{locator}}</message> - <message key="org.apache.fop.fo.FOValidationEventProducer.invalidChild">"{offendingNode}" is not a valid child element of "{elementName}"![ {ruleViolated,lookup}]{{locator}}</message> + <message key="org.apache.fop.fo.FOValidationEventProducer.invalidChild">"{offendingNode}" is not a valid child of "{elementName}"![ {ruleViolated,lookup}]{{locator}}</message> <message key="org.apache.fop.fo.FOValidationEventProducer.missingChildElement">"{elementName}" is missing child elements.[ Required content model: {contentModel}]{{locator}}</message> <message key="org.apache.fop.fo.FOValidationEventProducer.missingProperty">Element "{elementName}" is missing required property "{propertyName}"!{{locator}}</message> diff --git a/src/java/org/apache/fop/fo/flow/Wrapper.java b/src/java/org/apache/fop/fo/flow/Wrapper.java index 4b1cfeeac..dfe837315 100644 --- a/src/java/org/apache/fop/fo/flow/Wrapper.java +++ b/src/java/org/apache/fop/fo/flow/Wrapper.java @@ -22,9 +22,10 @@ package org.apache.fop.fo.flow; import org.xml.sax.Locator; import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FOText; import org.apache.fop.fo.FObjMixed; -import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; /** @@ -39,25 +40,15 @@ public class Wrapper extends FObjMixed { // used for FO validation private boolean blockOrInlineItemFound = false; - private boolean inlineChildrenAllowed = false; /** - * Base constructor + * Create a Wrapper instance that is a child of the + * given {@link FONode} * * @param parent {@link FONode} that is the parent of this object */ public Wrapper(FONode parent) { super(parent); - /* Check if the fo:wrapper is a child of a FO that allows mixed content - * (or a descendant in nested fo:wrapper sequence, the first of which - * is a child of a FO that allows mixed content) */ - FONode ancestor = this.parent; - while (ancestor instanceof Wrapper) { - ancestor = ancestor.getParent(); - } - if (ancestor instanceof FObjMixed ) { - inlineChildrenAllowed = true; - } } /** @@ -66,7 +57,6 @@ public class Wrapper extends FObjMixed { * <br><i>Additionally (unimplemented): "An fo:wrapper that is a child of an * fo:multi-properties is only permitted to have children that would * be permitted in place of the fo:multi-properties."</i> - * */ protected void validateChildNode(Locator loc, String nsURI, String localName) throws ValidationException { @@ -77,8 +67,12 @@ public class Wrapper extends FObjMixed { "(#PCDATA|%inline;|%block;)"); } } else if (isBlockOrInlineItem(nsURI, localName)) { - //delegate validation to parent - FONode.validateChildNode(this.parent, loc, nsURI, localName); + try { + //delegate validation to parent + FONode.validateChildNode(this.parent, loc, nsURI, localName); + } catch (ValidationException vex) { + invalidChildError(loc, getName(), FO_URI, localName, "rule.wrapperInvalidChildForParent"); + } blockOrInlineItemFound = true; } else { invalidChildError(loc, nsURI, localName); @@ -87,15 +81,27 @@ public class Wrapper extends FObjMixed { } /** {@inheritDoc} */ - protected void addCharacters( - char[] data, - int start, - int end, - PropertyList pList, - Locator locator) throws FOPException { - /* Only add text if the fo:wrapper's parent allows inline children */ - if (this.inlineChildrenAllowed) { - super.addCharacters(data, start, end, pList, locator); + protected void addChildNode(FONode child) throws FOPException { + super.addChildNode(child); + /* If the child is a text node, and it generates areas + * (i.e. contains either non-white-space or preserved + * white-space), then check whether the nearest non-wrapper + * ancestor allows this. + */ + if (child instanceof FOText + && ((FOText)child).willCreateArea()) { + FONode ancestor = parent; + while (ancestor.getNameId() == Constants.FO_WRAPPER) { + ancestor = ancestor.getParent(); + } + if (!(ancestor instanceof FObjMixed)) { + invalidChildError( + getLocator(), + getLocalName(), + FONode.FO_URI, + "#PCDATA", + "rule.wrapperInvalidChildForParent"); + } } } diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index e9d529ebe..b208e4e9b 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -1527,10 +1527,20 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager protected void wrapPositionElements(List sourceList, List targetList, boolean force) { ListIterator listIter = sourceList.listIterator(); + Object tempElement; while (listIter.hasNext()) { - ListElement tempElement; - tempElement = (ListElement) listIter.next(); - wrapPositionElement(tempElement, targetList, force); + tempElement = listIter.next(); + if (tempElement instanceof ListElement) { + wrapPositionElement( + (ListElement) tempElement, + targetList, + force); + } else if (tempElement instanceof List) { + wrapPositionElements( + (List) tempElement, + targetList, + force); + } } } diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java index c54f0ce12..9cd5c622d 100644 --- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java @@ -30,6 +30,7 @@ import org.apache.fop.area.Area; import org.apache.fop.area.BlockParent; import org.apache.fop.fo.pagination.Flow; import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager; +import org.apache.fop.layoutmgr.inline.WrapperLayoutManager; /** * LayoutManager for an fo:flow object. @@ -75,7 +76,8 @@ public class FlowLayoutManager extends BlockStackingLayoutManager LinkedList returnList = new LinkedList(); while ((curLM = getChildLM()) != null) { - if (curLM instanceof InlineLevelLayoutManager) { + if (!(curLM instanceof WrapperLayoutManager) + && curLM instanceof InlineLevelLayoutManager) { log.error("inline area not allowed under flow - ignoring"); curLM.setFinished(true); continue; diff --git a/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java index 09e22d481..8108bbf40 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java @@ -20,7 +20,12 @@ package org.apache.fop.layoutmgr.inline; import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.area.Block; +import org.apache.fop.area.LineArea; import org.apache.fop.fo.flow.Wrapper; +import org.apache.fop.layoutmgr.BlockLayoutManager; +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.PositionIterator; import org.apache.fop.layoutmgr.TraitSetter; @@ -66,7 +71,19 @@ public class WrapperLayoutManager extends LeafNodeLayoutManager { if (fobj.hasId()) { addId(); InlineArea area = getEffectiveArea(); - parentLM.addChildArea(area); + if (parentLM instanceof BlockStackingLayoutManager + && !(parentLM instanceof BlockLayoutManager)) { + Block helperBlock = new Block(); + LineArea helperLine = new LineArea(); + InlineParent helperInline = new InlineParent(); + helperInline.addChildArea(area); + helperLine.addInlineArea(helperInline); + helperLine.updateExtentsFromChildren(); + helperBlock.addLineArea(helperLine); + parentLM.addChildArea(helperBlock); + } else { + parentLM.addChildArea(area); + } } while (posIter.hasNext()) { posIter.next(); diff --git a/status.xml b/status.xml index 90992bb56..a48920e36 100644 --- a/status.xml +++ b/status.xml @@ -57,10 +57,17 @@ <action context="Renderers" dev="AC" importance="high" type="add"> Added SVG support for AFP (GOCA). </action --> + <action context="Code" dev="AD" type="fix" fixes-bug="42423"> + Added support for the "id" attribute on fo:wrappers when used + as a child of the fo:flow. + </action> + <action context="Code" dev="AD" type="fix" fixes-bug="41500"> + Fixed a ClassCastException when using an fo:wrapper as a child + of an fo:block-container. + </action> <action context="Fonts" dev="AC" type="add"> Add support for font substitution. </action> - <action context="Code" dev="AD" type="fix" fixed-bug="44203"> <action context="Renderers" dev="JM" type="fix" fixes-bug="43650"> PCL Renderer: Improved page format selection so it doesn't interfere with duplex printing. diff --git a/test/layoutengine/disabled-testcases.xml b/test/layoutengine/disabled-testcases.xml index 12d7ed1aa..c17457a3d 100644 --- a/test/layoutengine/disabled-testcases.xml +++ b/test/layoutengine/disabled-testcases.xml @@ -234,12 +234,6 @@ case should be revisited.</description> </testcase> <testcase> - <name>fo:wrapper around block-level content (with id)</name> - <file>wrapper_block_id.xml</file> - <description>"id" attributes on fo:wrapper around block-level content don't get - added to the area tree.</description> - </testcase> - <testcase> <name>Soft hyphen with normal hyphenation enabled</name> <file>block_shy_linebreaking_hyph.xml</file> <description>A soft hyphen should be a preferred as break compared to a |