<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>
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;
/**
// 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;
- }
}
/**
* <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 {
"(#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);
}
/** {@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");
+ }
}
}
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);
+ }
}
}
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.
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;
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;
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();
<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.
is probably not expressing the indended outcome according to the spec. The test
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>