From: Simon Steiner
Date: Fri, 13 Jul 2018 10:29:57 +0000 (+0000)
Subject: FOP-1760: Add change bar generation
X-Git-Tag: fop-2_4~49
X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e6748b4ed1522214915b2e3cd4df2db9f2b7b3b2;p=xmlgraphics-fop.git
FOP-1760: Add change bar generation
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1835810 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/fop-core/src/main/java/org/apache/fop/area/Area.java b/fop-core/src/main/java/org/apache/fop/area/Area.java
index 895367c19..87f645dd2 100644
--- a/fop-core/src/main/java/org/apache/fop/area/Area.java
+++ b/fop-core/src/main/java/org/apache/fop/area/Area.java
@@ -20,12 +20,14 @@
package org.apache.fop.area;
import java.io.Serializable;
+import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.fo.flow.ChangeBar;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.WritingModeTraitsGetter;
@@ -128,6 +130,29 @@ public class Area extends AreaTreeObject implements Serializable {
*/
protected static final Log log = LogFactory.getLog(Area.class);
+ /**
+ * The active change bar list
+ */
+ private List changeBarList;
+
+ /**
+ * Returns the active change bar list.
+ *
+ * @return The active change bar list
+ */
+ public List getChangeBarList() {
+ return changeBarList;
+ }
+
+ /**
+ * Sets the active change bar list.
+ *
+ * @param changeBarList The active change bar list
+ */
+ public void setChangeBarList(List changeBarList) {
+ this.changeBarList = changeBarList;
+ }
+
/**
* Get the area class of this area.
*
diff --git a/fop-core/src/main/java/org/apache/fop/area/AreaTreeParser.java b/fop-core/src/main/java/org/apache/fop/area/AreaTreeParser.java
index 41563a85e..587e8e449 100644
--- a/fop-core/src/main/java/org/apache/fop/area/AreaTreeParser.java
+++ b/fop-core/src/main/java/org/apache/fop/area/AreaTreeParser.java
@@ -66,6 +66,7 @@ import org.apache.fop.area.inline.Container;
import org.apache.fop.area.inline.ForeignObject;
import org.apache.fop.area.inline.Image;
import org.apache.fop.area.inline.InlineArea;
+import org.apache.fop.area.inline.InlineBlock;
import org.apache.fop.area.inline.InlineBlockParent;
import org.apache.fop.area.inline.InlineParent;
import org.apache.fop.area.inline.InlineViewport;
@@ -80,6 +81,7 @@ import org.apache.fop.fo.extensions.ExtensionAttachment;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.traits.BorderProps;
+import org.apache.fop.traits.Direction;
import org.apache.fop.traits.Visibility;
import org.apache.fop.util.ColorUtil;
import org.apache.fop.util.ContentHandlerFactory;
@@ -190,6 +192,7 @@ public class AreaTreeParser {
makers.put("block", new BlockMaker());
makers.put("lineArea", new LineAreaMaker());
makers.put("inline", new InlineMaker());
+ makers.put("inlineblock", new InlineBlockMaker());
makers.put("inlineparent", new InlineParentMaker());
makers.put("inlineblockparent", new InlineBlockParentMaker());
makers.put("text", new TextMaker());
@@ -594,6 +597,17 @@ public class AreaTreeParser {
BodyRegion body = getCurrentBodyRegion();
Span span = new Span(columnCount,
body.getColumnGap(), ipd);
+
+ String blockDirection = attributes.getValue("block-progression-direction");
+ if (blockDirection != null) {
+ span.addTrait(Trait.BLOCK_PROGRESSION_DIRECTION, Direction.valueOf(blockDirection));
+ }
+
+ String inlineDirection = attributes.getValue("inline-progression-direction");
+ if (inlineDirection != null) {
+ span.addTrait(Trait.INLINE_PROGRESSION_DIRECTION, Direction.valueOf(inlineDirection));
+ }
+
transferForeignObjects(attributes, span);
setAreaAttributes(attributes, span);
body.getMainReference().getSpans().add(span);
@@ -723,6 +737,34 @@ public class AreaTreeParser {
}
}
+ private class InlineBlockMaker extends AbstractMaker {
+
+ public void startElement(Attributes attributes) {
+
+ Block block = new Block();
+
+ if (attributes.getValue("left-offset") != null) {
+ block.setXOffset(XMLUtil.getAttributeAsInt(attributes, "left-offset", 0));
+ }
+ if (attributes.getValue("top-offset") != null) {
+ block.setYOffset(XMLUtil.getAttributeAsInt(attributes, "top-offset", 0));
+ }
+ transferForeignObjects(attributes, block);
+ setAreaAttributes(attributes, block);
+ setTraits(attributes, block, SUBSET_COMMON);
+ setTraits(attributes, block, SUBSET_BOX);
+ setTraits(attributes, block, SUBSET_COLOR);
+ Area parent = (Area)areaStack.peek();
+ InlineBlock inlineBlock = new InlineBlock(block);
+ parent.addChildArea(inlineBlock);
+ areaStack.push(inlineBlock);
+ }
+
+ public void endElement() {
+ assertObjectOfClass(areaStack.pop(), InlineBlock.class);
+ }
+ }
+
private class InlineParentMaker extends AbstractMaker {
public void startElement(Attributes attributes) {
diff --git a/fop-core/src/main/java/org/apache/fop/area/Span.java b/fop-core/src/main/java/org/apache/fop/area/Span.java
index 41610f355..9fa22c6fd 100644
--- a/fop-core/src/main/java/org/apache/fop/area/Span.java
+++ b/fop-core/src/main/java/org/apache/fop/area/Span.java
@@ -81,6 +81,15 @@ public class Span extends Area {
return colCount;
}
+ /**
+ * Get the column gap for this span area.
+ *
+ * @return the column gap for this span area
+ */
+ public int getColumnGap() {
+ return colGap;
+ }
+
/**
* Get the width of a single column within this Span
*
@@ -206,6 +215,8 @@ public class Span extends Area {
}
break;
}
+ addTrait(Trait.INLINE_PROGRESSION_DIRECTION, wmtg.getInlineProgressionDirection());
+ addTrait(Trait.BLOCK_PROGRESSION_DIRECTION, wmtg.getBlockProgressionDirection());
}
/** {@inheritDoc} */
diff --git a/fop-core/src/main/java/org/apache/fop/area/inline/InlineBlock.java b/fop-core/src/main/java/org/apache/fop/area/inline/InlineBlock.java
new file mode 100644
index 000000000..9b5f96708
--- /dev/null
+++ b/fop-core/src/main/java/org/apache/fop/area/inline/InlineBlock.java
@@ -0,0 +1,43 @@
+/*
+ * 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.area.inline;
+
+import org.apache.fop.area.Block;
+
+/**
+ * This is the inline block area class.
+ * It wraps the child block when it has to be placed into inline parent.
+ */
+public class InlineBlock extends InlineParent {
+
+ private static final long serialVersionUID = -3725062353292109517L;
+ private final Block block;
+
+ public InlineBlock(Block block) {
+ this.block = block;
+ }
+
+ /**
+ * @return the wrapped block
+ */
+ public Block getBlock() {
+ return block;
+ }
+}
diff --git a/fop-core/src/main/java/org/apache/fop/area/inline/TextArea.java b/fop-core/src/main/java/org/apache/fop/area/inline/TextArea.java
index 3081a38eb..a03e536ce 100644
--- a/fop-core/src/main/java/org/apache/fop/area/inline/TextArea.java
+++ b/fop-core/src/main/java/org/apache/fop/area/inline/TextArea.java
@@ -95,6 +95,7 @@ public class TextArea extends AbstractTextArea {
WordArea wordArea = new WordArea(
blockProgressionOffset, minWordLevel, word, letterAdjust, levels, gposAdjustments);
wordArea.setIPD(ipd);
+ wordArea.setChangeBarList(getChangeBarList());
addChildArea(wordArea);
wordArea.setParentArea(this);
updateLevel(minWordLevel);
@@ -113,6 +114,7 @@ public class TextArea extends AbstractTextArea {
char space, int ipd, boolean adjustable, int blockProgressionOffset, int level) {
SpaceArea spaceArea = new SpaceArea(blockProgressionOffset, level, space, adjustable);
spaceArea.setIPD(ipd);
+ spaceArea.setChangeBarList(getChangeBarList());
addChildArea(spaceArea);
spaceArea.setParentArea(this);
updateLevel(level);
diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOElementMapping.java b/fop-core/src/main/java/org/apache/fop/fo/FOElementMapping.java
index b087e1d9c..8bf92c2b3 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/FOElementMapping.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/FOElementMapping.java
@@ -141,6 +141,10 @@ public class FOElementMapping extends ElementMapping {
foObjs.put("marker", new MarkerMaker());
foObjs.put("retrieve-marker", new RetrieveMarkerMaker());
foObjs.put("retrieve-table-marker", new RetrieveTableMarkerMaker());
+
+ // change bars
+ foObjs.put("change-bar-begin", new ChangeBarBeginMaker());
+ foObjs.put("change-bar-end", new ChangeBarEndMaker());
}
}
@@ -527,4 +531,16 @@ public class FOElementMapping extends ElementMapping {
return new org.apache.fop.fo.flow.RetrieveTableMarker(parent);
}
}
+
+ static class ChangeBarBeginMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new org.apache.fop.fo.flow.ChangeBarBegin(parent);
+ }
+ }
+
+ static class ChangeBarEndMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new org.apache.fop.fo.flow.ChangeBarEnd(parent);
+ }
+ }
}
diff --git a/fop-core/src/main/java/org/apache/fop/fo/FONode.java b/fop-core/src/main/java/org/apache/fop/fo/FONode.java
index b4e0ec0fe..f3c582dd5 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/FONode.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/FONode.java
@@ -20,6 +20,7 @@
package org.apache.fop.fo;
// Java
+import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Stack;
@@ -42,6 +43,7 @@ import org.apache.fop.fo.extensions.ExtensionAttachment;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.fo.extensions.InternalElementMapping;
import org.apache.fop.fo.extensions.svg.SVGElementMapping;
+import org.apache.fop.fo.flow.ChangeBar;
import org.apache.fop.fo.pagination.Root;
import org.apache.fop.util.CharUtilities;
import org.apache.fop.util.ContentHandlerFactory;
@@ -63,6 +65,12 @@ public abstract class FONode implements Cloneable {
/** pointer to the sibling nodes */
protected FONode[] siblings;
+ /** The list of active change bars for the given node */
+ protected List nodeChangeBarList;
+
+ /** The list of active change bars for the start of the given node */
+ protected List startOfNodeChangeBarList;
+
/**
* Marks the location of this object from the input FO
*
Call locator.getSystemId()
,
@@ -173,6 +181,18 @@ public abstract class FONode implements Cloneable {
return getBuilderContext().inMarker();
}
+ /**
+ * Tests if the given element is a change bar element.
+ *
+ * @param namespaceURI The name space of the element
+ * @param localName The local name of the element
+ * @return A boolean value true if the given element is a change bar element
+ */
+ public boolean isChangeBarElement(String namespaceURI, String localName) {
+ return FO_URI.equals(namespaceURI)
+ && (localName.equals("change-bar-begin") || localName.equals("change-bar-end"));
+ }
+
/**
* Returns the user agent that is associated with the
* tree's FOEventHandler
.
@@ -1082,6 +1102,15 @@ public abstract class FONode implements Cloneable {
}
+ /**
+ * Returns the list of active change bars.
+ *
+ * @return The list of active change bars
+ */
+ public List getChangeBarList() {
+ return nodeChangeBarList;
+ }
+
/**
* Sets the structure tree element.
*
diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java b/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java
index da92cc834..0b8da47cc 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java
@@ -322,6 +322,7 @@ public final class FOPropertyMapping implements Constants {
gp.createTableProperties();
gp.createWritingModeProperties();
gp.createMiscProperties();
+ gp.createChangeBarProperties();
// Hardcode the subproperties.
addSubpropMakerName("length", CP_LENGTH);
@@ -2588,6 +2589,56 @@ public final class FOPropertyMapping implements Constants {
addPropertyMaker("writing-mode", m);
}
+ private void createChangeBarProperties() {
+ PropertyMaker m;
+
+ // change-bar-class
+ m = new StringProperty.Maker(PR_CHANGE_BAR_CLASS);
+ m.setInherited(false);
+ m.setDefault("");
+ addPropertyMaker("change-bar-class", m);
+
+ // change-bar-color
+ m = new ColorProperty.Maker(PR_CHANGE_BAR_COLOR);
+
+ m.setInherited(true);
+ // TODO: fall back to "color" property
+ m.setDefault("black");
+ addPropertyMaker("change-bar-color", m);
+
+ // change-bar-placement
+ m = new EnumProperty.Maker(PR_CHANGE_BAR_PLACEMENT);
+ m.setInherited(true);
+ m.setDefault("start");
+ m.addEnum("start", getEnumProperty(EN_START, "START"));
+ m.addEnum("end", getEnumProperty(EN_END, "END"));
+ m.addEnum("left", getEnumProperty(EN_LEFT, "LEFT"));
+ m.addEnum("right", getEnumProperty(EN_RIGHT, "RIGHT"));
+ m.addEnum("inside", getEnumProperty(EN_INSIDE, "INSIDE"));
+ m.addEnum("outside", getEnumProperty(EN_OUTSIDE, "OUTSIDE"));
+ m.addEnum("alternate", getEnumProperty(EN_ALTERNATE, "ALTERNATE"));
+ addPropertyMaker("change-bar-placement", m);
+
+ // change-bar-style
+ m = new EnumProperty.Maker(PR_CHANGE_BAR_STYLE);
+ m.useGeneric(genericBorderStyle);
+ m.setInherited(true);
+ m.setDefault("solid");
+ addPropertyMaker("change-bar-style", m);
+
+ // change-bar-width
+ m = new LengthProperty.Maker(PR_CHANGE_BAR_WIDTH);
+ m.setInherited(true);
+ m.setDefault("6pt");
+ addPropertyMaker("change-bar-width", m);
+
+ // change-bar-offset
+ m = new LengthProperty.Maker(PR_CHANGE_BAR_OFFSET);
+ m.setInherited(true);
+ m.setDefault("6pt");
+ addPropertyMaker("change-bar-offset", m);
+ }
+
private void createMiscProperties() {
PropertyMaker m;
diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOText.java b/fop-core/src/main/java/org/apache/fop/fo/FOText.java
index 563d96993..207c3184c 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/FOText.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/FOText.java
@@ -33,6 +33,7 @@ import org.apache.fop.apps.FOPException;
import org.apache.fop.complexscripts.bidi.DelimitedTextRange;
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.flow.Block;
+import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.properties.CommonFont;
import org.apache.fop.fo.properties.CommonHyphenation;
import org.apache.fop.fo.properties.CommonTextDecoration;
@@ -109,6 +110,11 @@ public class FOText extends FONode implements CharSequence, TextFragment {
*/
public FOText(FONode parent) {
super(parent);
+
+ PageSequence pageSequence = getRoot().getLastPageSequence();
+ if (pageSequence != null && pageSequence.hasChangeBars()) {
+ nodeChangeBarList = getRoot().getLastPageSequence().getClonedChangeBarList();
+ }
}
/** {@inheritDoc} */
diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOTreeBuilder.java b/fop-core/src/main/java/org/apache/fop/fo/FOTreeBuilder.java
index e3afbbb75..249f0e0fe 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/FOTreeBuilder.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/FOTreeBuilder.java
@@ -273,7 +273,9 @@ public class FOTreeBuilder extends DefaultHandler {
if (currentFObj.getNamespaceURI().equals(FOElementMapping.URI)
|| currentFObj.getNamespaceURI().equals(ExtensionElementMapping.URI)
|| currentFObj.getNamespaceURI().equals(PDFElementMapping.NAMESPACE)) {
- currentFObj.validateChildNode(locator, namespaceURI, localName);
+ if (!currentFObj.isChangeBarElement(namespaceURI, localName)) {
+ currentFObj.validateChildNode(locator, namespaceURI, localName);
+ }
}
}
diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOValidationEventProducer.java b/fop-core/src/main/java/org/apache/fop/fo/FOValidationEventProducer.java
index a96cb3fe3..452a9f563 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/FOValidationEventProducer.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/FOValidationEventProducer.java
@@ -381,6 +381,47 @@ public interface FOValidationEventProducer extends EventProducer {
void unknownFormattingObject(Object source, String elementName,
QName offendingNode, Locator loc);
+ /**
+ * A class for change bars is not unique.
+ * @param source the event source
+ * @param elementName the name of the context node
+ * @param name the class name
+ * @param loc the location of the error or null
+ * @event.severity FATAL
+ */
+ void changeBarClassNotUnique(Object source, String elementName, String name,
+ Locator loc);
+
+ /**
+ * Change bars were not stacked correctly
+ * @param source the event source
+ * @param elementName the name of the context node
+ * @param beginName the class name of the beginning change bar
+ * @param endName the class name of the ending change bar
+ * @param loc the location of the error or null
+ * @event.severity FATAL
+ */
+ void changeBarWrongStacking(Object source, String elementName, String beginName,
+ String endName, Locator loc);
+
+ /**
+ * Change bar ended without a start of bar occurred
+ * @param source the event source
+ * @param elementName the name of the context node
+ * @param loc the location of the error or null
+ * @event.severity FATAL
+ */
+ void changeBarNoBegin(Object source, String elementName, Locator loc);
+
+ /**
+ * Change bar not descendant of fo:flow or fo:static-content
+ * @param source the event source
+ * @param elementName the name of the context node
+ * @param loc the location of the error or null
+ * @event.severity FATAL
+ */
+ void changeBarWrongAncestor(Object source, String elementName, Locator loc);
+
/**
* Alternate text is missing for a graphic element.
*
diff --git a/fop-core/src/main/java/org/apache/fop/fo/FObj.java b/fop-core/src/main/java/org/apache/fop/fo/FObj.java
index fc105e7e6..f57e59bd1 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/FObj.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/FObj.java
@@ -21,6 +21,7 @@ package org.apache.fop.fo;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -34,7 +35,9 @@ import org.apache.xmlgraphics.util.QName;
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.extensions.ExtensionAttachment;
+import org.apache.fop.fo.flow.ChangeBar;
import org.apache.fop.fo.flow.Marker;
+import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.properties.Property;
import org.apache.fop.fo.properties.PropertyMaker;
@@ -182,6 +185,39 @@ public abstract class FObj extends FONode implements Constants {
if (id != null) {
checkId(id);
}
+
+ PageSequence pageSequence = getRoot().getLastPageSequence();
+ if (pageSequence != null && pageSequence.hasChangeBars()) {
+ startOfNodeChangeBarList = pageSequence.getClonedChangeBarList();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws FOPException FOP Exception
+ */
+ public void endOfNode() throws FOPException {
+
+ List endOfNodeChangeBarList = null;
+
+ PageSequence pageSequence = getRoot().getLastPageSequence();
+ if (pageSequence != null) {
+ endOfNodeChangeBarList = pageSequence.getClonedChangeBarList();
+ }
+
+ if (startOfNodeChangeBarList != null && endOfNodeChangeBarList != null) {
+
+ nodeChangeBarList = new LinkedList(endOfNodeChangeBarList);
+ nodeChangeBarList.retainAll(startOfNodeChangeBarList);
+
+ if (nodeChangeBarList.isEmpty()) {
+ nodeChangeBarList = null;
+ }
+
+ startOfNodeChangeBarList = null;
+ }
+
+ super.endOfNode();
}
/**
@@ -492,6 +528,8 @@ public abstract class FObj extends FONode implements Constants {
protected boolean isInlineItem(String nsURI, String lName) {
return (FO_URI.equals(nsURI)
&& ("bidi-override".equals(lName)
+ || "change-bar-begin".equals(lName)
+ || "change-bar-end".equals(lName)
|| "character".equals(lName)
|| "external-graphic".equals(lName)
|| "instream-foreign-object".equals(lName)
diff --git a/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBar.java b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBar.java
new file mode 100644
index 000000000..5fa12346b
--- /dev/null
+++ b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBar.java
@@ -0,0 +1,214 @@
+/*
+ * 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.flow;
+
+import java.awt.Color;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.datatypes.Length;
+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;
+import org.apache.fop.fo.properties.SpaceProperty;
+
+/**
+ * Common change bar base class. Handles change bar properties and validates child nodes.
+ */
+public abstract class ChangeBar extends FObj {
+
+ /**
+ * Constructs a ChangeBar element with common parts for both begin and end change bars.
+ *
+ * @param parent The parent node
+ */
+ public ChangeBar(FONode parent) {
+ super(parent);
+ }
+
+ /**
+ * The change bar class (required).
+ */
+ protected String changeBarClass;
+
+ /**
+ * The change bar color.
+ */
+ protected Color color;
+
+ /**
+ * The change bar offset.
+ */
+ protected Length offset;
+
+ /**
+ * The change bar placement.
+ */
+ protected int placement = -1;
+
+ /**
+ * The change bar style.
+ */
+ protected int style = -1;
+
+ /**
+ * The change bar width.
+ */
+ protected Length width;
+
+ /**
+ * The actual line height.
+ */
+ protected SpaceProperty lineHeight;
+
+ /** {@inheritDoc} */
+ public void bind(PropertyList pList) throws FOPException {
+ super.bind(pList);
+
+ changeBarClass = pList.get(PR_CHANGE_BAR_CLASS).getString();
+ color = pList.get(PR_CHANGE_BAR_COLOR).getColor(getUserAgent());
+ offset = pList.get(PR_CHANGE_BAR_OFFSET).getLength();
+ placement = pList.get(PR_CHANGE_BAR_PLACEMENT).getEnum();
+ style = pList.get(PR_CHANGE_BAR_STYLE).getEnum();
+ width = pList.get(PR_CHANGE_BAR_WIDTH).getLength();
+ lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
+ }
+
+ /** {@inheritDoc} */
+ protected void validateChildNode(
+ Locator loc,
+ String namespaceURI,
+ String localName) throws ValidationException {
+ // no children allowed
+ invalidChildError(loc, namespaceURI, localName);
+ }
+
+ /** {@inheritDoc} */
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList pList) throws FOPException {
+ super.processNode(elementName, locator, attlist, pList);
+
+ if (inMarker()) {
+ PropertyList newPList = new StaticPropertyList(this, null);
+ newPList.addAttributesToList(attlist);
+ bind(newPList);
+ }
+
+ if (changeBarClass == null || changeBarClass.isEmpty()) {
+ missingPropertyError("change-bar-class");
+ }
+
+ if (findAncestor(FO_FLOW) == -1
+ && findAncestor(FO_STATIC_CONTENT) == -1) {
+ getFOValidationEventProducer().changeBarWrongAncestor(this, getName(), locator);
+ }
+ }
+
+ /**
+ * Adds the current change bar to the active change bar list.
+ */
+ protected void push() {
+ getRoot().getLastPageSequence().pushChangeBar(this);
+ }
+
+ /**
+ * Removes the starting counterpart of the current change bar from the active change bar list.
+ */
+ protected void pop() {
+ getRoot().getLastPageSequence().popChangeBar(this);
+ }
+
+ /**
+ * Returns the starting counterpart of the current (ending) change bar.
+ *
+ * @return The starting counterpart of the current (ending) change bar
+ */
+ protected ChangeBar getChangeBarBegin() {
+ return getRoot().getLastPageSequence().getChangeBarBegin(this);
+ }
+
+ /**
+ * Returns the change bar class.
+ *
+ * @return The change bar class
+ */
+ public String getChangeBarClass() {
+ return changeBarClass;
+ }
+
+ /**
+ * Returns the change bar color.
+ *
+ * @return The change bar color
+ */
+ public Color getColor() {
+ return color;
+ }
+
+ /**
+ * Returns the change bar offset.
+ *
+ * @return The change bar offset
+ */
+ public Length getOffset() {
+ return offset;
+ }
+
+ /**
+ * Returns the change bar placement.
+ *
+ * @return The change bar placement
+ */
+ public int getPlacement() {
+ return placement;
+ }
+
+ /**
+ * Returns the change bar style.
+ *
+ * @return The change bar style
+ */
+ public int getStyle() {
+ return style;
+ }
+
+ /**
+ * Returns the change bar width.
+ *
+ * @return The change bar width
+ */
+ public Length getWidth() {
+ return width;
+ }
+
+ /**
+ * Returns the line height.
+ *
+ * @return The line height
+ */
+ public SpaceProperty getLineHeight() {
+ return lineHeight;
+ }
+
+}
diff --git a/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarBegin.java b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarBegin.java
new file mode 100644
index 000000000..961a0e37f
--- /dev/null
+++ b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarBegin.java
@@ -0,0 +1,60 @@
+/*
+ * 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.flow;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.PropertyList;
+
+public class ChangeBarBegin extends ChangeBar {
+
+ /**
+ * Constructs a new ChangeBarBegin element.
+ *
+ * @param parent The parent node
+ */
+ public ChangeBarBegin(FONode parent) {
+ super(parent);
+ }
+
+ /** {@inheritDoc} */
+ public String getLocalName() {
+ return "change-bar-begin";
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return {@link org.apache.fop.fo.Constants#FO_CHANGE_BAR_BEGIN}
+ */
+ public int getNameId() {
+ return FO_CHANGE_BAR_BEGIN;
+ }
+
+ /** {@inheritDoc} */
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList pList) throws FOPException {
+ super.processNode(elementName, locator, attlist, pList);
+
+ push();
+ }
+}
diff --git a/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarEnd.java b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarEnd.java
new file mode 100644
index 000000000..4feca13a6
--- /dev/null
+++ b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarEnd.java
@@ -0,0 +1,67 @@
+/*
+ * 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.flow;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.PropertyList;
+
+public class ChangeBarEnd extends ChangeBar {
+
+ /**
+ * Constructs a new ChangeBarEnd element.
+ *
+ * @param parent The parent node
+ */
+ public ChangeBarEnd(FONode parent) {
+ super(parent);
+ }
+
+ /** {@inheritDoc} */
+ public String getLocalName() {
+ return "change-bar-end";
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return {@link org.apache.fop.fo.Constants#FO_CHANGE_BAR_END}
+ */
+ public int getNameId() {
+ return FO_CHANGE_BAR_END;
+ }
+
+ /** {@inheritDoc} */
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList pList) throws FOPException {
+ super.processNode(elementName, locator, attlist, pList);
+
+ // check if we have an element on the stack at all
+ ChangeBar changeBarStart = getChangeBarBegin();
+
+ if (changeBarStart == null) {
+ getFOValidationEventProducer().changeBarNoBegin(this, getName(), locator);
+ } else {
+ pop();
+ }
+ }
+}
diff --git a/fop-core/src/main/java/org/apache/fop/fo/flow/table/TableRow.java b/fop-core/src/main/java/org/apache/fop/fo/flow/table/TableRow.java
index 2beaf2f99..024b77905 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/flow/table/TableRow.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/flow/table/TableRow.java
@@ -90,9 +90,11 @@ public class TableRow extends TableCellContainer implements BreakPropertySet {
/** {@inheritDoc} */
protected void addChildNode(FONode child) throws FOPException {
if (!inMarker()) {
- TableCell cell = (TableCell) child;
- TablePart part = (TablePart) getParent();
- addTableCellChild(cell, part.isFirst(this));
+ if (child instanceof TableCell) {
+ TableCell cell = (TableCell) child;
+ TablePart part = (TablePart) getParent();
+ addTableCellChild(cell, part.isFirst(this));
+ }
}
super.addChildNode(child);
}
diff --git a/fop-core/src/main/java/org/apache/fop/fo/pagination/PageSequence.java b/fop-core/src/main/java/org/apache/fop/fo/pagination/PageSequence.java
index a1a966e90..3f82e6822 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/pagination/PageSequence.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/pagination/PageSequence.java
@@ -19,6 +19,8 @@
package org.apache.fop.fo.pagination;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Stack;
@@ -31,6 +33,7 @@ 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.flow.ChangeBar;
import org.apache.fop.fo.properties.CommonHyphenation;
import org.apache.fop.traits.Direction;
import org.apache.fop.traits.WritingMode;
@@ -77,6 +80,11 @@ public class PageSequence extends AbstractPageSequence implements WritingModeTra
*/
private Flow mainFlow;
+ /**
+ * Active change bars
+ */
+ private final List changeBarList = new LinkedList();
+
/**
* Create a PageSequence instance that is a child of the
* given {@link FONode}.
@@ -118,6 +126,7 @@ public class PageSequence extends AbstractPageSequence implements WritingModeTra
masterReference, getLocator());
}
}
+ getRoot().addPageSequence(this);
getFOEventHandler().startPageSequence(this);
}
@@ -464,4 +473,73 @@ public class PageSequence extends AbstractPageSequence implements WritingModeTra
return pageSequenceMaster.getLastSimplePageMaster(isOddPage, isFirstPage, isBlank, getMainFlow()
.getFlowName());
}
+
+ /**
+ * Adds the specified change bar to the active change bar list.
+ *
+ * @param changeBarBegin The starting change bar element
+ */
+ public void pushChangeBar(ChangeBar changeBarBegin) {
+ changeBarList.add(changeBarBegin);
+ }
+
+ /**
+ * Removes the couple of the specified change bar from the active change bar list.
+ *
+ * @param changeBarEnd The ending change bar element
+ */
+ public void popChangeBar(ChangeBar changeBarEnd) {
+ ChangeBar changeBarBegin = getChangeBarBegin(changeBarEnd);
+ if (changeBarBegin != null) {
+ changeBarList.remove(changeBarBegin);
+ }
+ }
+
+ /**
+ * Returns the starting counterpart of the specified ending change bar.
+ *
+ * @param changeBarEnd The ending change bar element
+ * @return The starting counterpart of the specified ending change bar
+ */
+ public ChangeBar getChangeBarBegin(ChangeBar changeBarEnd) {
+ if (changeBarList.isEmpty()) {
+ return null;
+ } else {
+ String changeBarClass = changeBarEnd.getChangeBarClass();
+ for (int i = changeBarList.size() - 1; i >= 0; i--) {
+ ChangeBar changeBar = changeBarList.get(i);
+ if (changeBar.getChangeBarClass().equals(changeBarClass)) {
+ return changeBar;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Tests if there are any active change bars.
+ *
+ * @return A boolean value true if there are any active change bars
+ */
+ public boolean hasChangeBars() {
+ return !changeBarList.isEmpty();
+ }
+
+ /**
+ * Returns the list of active change bars.
+ *
+ * @return The list of active change bars
+ */
+ public List getChangeBarList() {
+ return changeBarList;
+ }
+
+ /**
+ * Returns the copy of active change bars list.
+ *
+ * @return The list containing a copy of the active change bars
+ */
+ public List getClonedChangeBarList() {
+ return new LinkedList(changeBarList);
+ }
}
diff --git a/fop-core/src/main/java/org/apache/fop/fo/pagination/Root.java b/fop-core/src/main/java/org/apache/fop/fo/pagination/Root.java
index 51309a65d..3b895b372 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/pagination/Root.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/pagination/Root.java
@@ -281,6 +281,28 @@ public class Root extends FObj implements CommonAccessibilityHolder {
}
}
+ /**
+ * Adds the specified page sequence.
+ *
+ * @param pageSequence The page sequence to add
+ */
+ public void addPageSequence(PageSequence pageSequence) {
+ pageSequences.add(pageSequence);
+ }
+
+ /**
+ * Returns the last page sequence (current while parsing).
+ *
+ * @return The last page sequence or null
+ */
+ public PageSequence getLastPageSequence() {
+ if (getPageSequenceCount() > 0) {
+ return pageSequences.get(getPageSequenceCount() - 1);
+ } else {
+ return null;
+ }
+ }
+
/**
* Returns the associated LayoutMasterSet.
* @return the LayoutMasterSet instance
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java
index b687689bc..ca5d1c507 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java
@@ -28,6 +28,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.datatypes.LengthBase;
import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.flow.ChangeBar;
/**
* The base class for nearly all LayoutManagers.
@@ -257,6 +258,19 @@ public abstract class AbstractBaseLayoutManager
return fobj;
}
+ /**
+ * Returns the active change bar list.
+ *
+ * @return The active change bar list
+ */
+ public List getChangeBarList() {
+ if (fobj == null) {
+ return null;
+ } else {
+ return fobj.getChangeBarList();
+ }
+ }
+
/** {@inheritDoc} */
public void reset() {
throw new UnsupportedOperationException("Not implemented");
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
index 9ce113d11..f0fc77577 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
@@ -854,6 +854,7 @@ public class BlockContainerLayoutManager extends SpacedBorderedPaddedBlockLayout
int level = getBlockContainerFO().getBidiLevel();
viewportBlockArea = new BlockViewport(allowBPDUpdate);
+ viewportBlockArea.setChangeBarList(getChangeBarList());
viewportBlockArea.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE);
if (level >= 0) {
viewportBlockArea.setBidiLevel(level);
@@ -892,6 +893,7 @@ public class BlockContainerLayoutManager extends SpacedBorderedPaddedBlockLayout
}
referenceArea = new Block();
+ referenceArea.setChangeBarList(getChangeBarList());
referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
if (level >= 0) {
referenceArea.setBidiLevel(level);
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
index 722a011ae..ac0da5f6a 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
@@ -357,6 +357,7 @@ public class BlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
curBlockArea.setIPD(super.getContentAreaIPD());
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
index b8714a570..6069dbcc3 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
@@ -124,6 +124,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
int sp = TraitSetter.getEffectiveSpace(adjust, minoptmax);
if (sp != 0) {
Block spacer = new Block();
+ spacer.setChangeBarList(getChangeBarList());
spacer.setBPD(sp);
parentLayoutManager.addChildArea(spacer);
}
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
index aae5a6b30..06ad4eeba 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
@@ -178,6 +178,7 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan
Dimension imageSize = this.imageLayout.getViewportSize();
Block blockArea = new Block();
+ blockArea.setChangeBarList(getChangeBarList());
blockArea.setIPD(imageSize.width);
LineArea lineArea = new LineArea();
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
index e95cd18ec..3a706a325 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
@@ -39,6 +39,8 @@ import org.apache.fop.fo.flow.BasicLink;
import org.apache.fop.fo.flow.BidiOverride;
import org.apache.fop.fo.flow.Block;
import org.apache.fop.fo.flow.BlockContainer;
+import org.apache.fop.fo.flow.ChangeBarBegin;
+import org.apache.fop.fo.flow.ChangeBarEnd;
import org.apache.fop.fo.flow.Character;
import org.apache.fop.fo.flow.ExternalGraphic;
import org.apache.fop.fo.flow.Float;
@@ -146,6 +148,8 @@ public class LayoutManagerMapping implements LayoutManagerMaker {
registerMaker(TableHeader.class, new Maker());
registerMaker(Wrapper.class, new WrapperLayoutManagerMaker());
registerMaker(Title.class, new InlineLayoutManagerMaker());
+ registerMaker(ChangeBarBegin.class, new Maker());
+ registerMaker(ChangeBarEnd.class, new Maker());
registerMaker(MultiCase.class, new MultiCaseLayoutManagerMaker());
registerMaker(MultiSwitch.class, new MultiSwitchLayoutManagerMaker());
registerMaker(Float.class, new FloatLayoutManagerMaker());
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java
index 2e1b7f2ae..c06ec522a 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java
@@ -133,6 +133,7 @@ public abstract class AbstractPageNumberCitationLayoutManager extends LeafNodeLa
getPSLM().addUnresolvedArea(citation.getRefId(), unresolved);
text = unresolved;
}
+ text.setChangeBarList(getChangeBarList());
setTraits(text);
return text;
}
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
index c959ee7be..3f68df0e2 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
@@ -75,6 +75,7 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
private TextArea createCharacterArea() {
Character fobj = (Character) this.fobj;
TextArea text = new TextArea();
+ text.setChangeBarList(getChangeBarList());
char ch = fobj.getCharacter();
int ipd = font.getCharWidth(ch);
int blockProgressionOffset = 0;
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
index af1664981..a5f128f85 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
@@ -84,6 +84,7 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager
// get breaks then add areas to title
this.parentLM = pslm;
holder = new LineArea();
+ holder.setChangeBarList(getChangeBarList());
// setUserAgent(foTitle.getUserAgent());
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java
index 2719d5c96..8a204607e 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java
@@ -42,7 +42,9 @@ public class ExternalGraphicLayoutManager extends AbstractGraphicsLayoutManager
/** {@inheritDoc} */
protected Area getChildArea() {
- return new Image(((ExternalGraphic) fobj).getSrc());
+ Image im = new Image(((ExternalGraphic) fobj).getSrc());
+ im.setChangeBarList(getChangeBarList());
+ return im;
}
}
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
index df37b9902..85f545e5e 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
@@ -206,9 +206,11 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
InlineArea area;
if (isInline) {
area = createInlineParent();
+ area.setChangeBarList(getChangeBarList());
area.setBlockProgressionOffset(0);
} else {
area = new InlineBlockParent();
+ area.setChangeBarList(getChangeBarList());
}
if (fobj instanceof Inline || fobj instanceof BasicLink) {
TraitSetter.setProducerID(area, fobj.getId());
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
index 5b9efa43e..7a8ac8627 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
@@ -181,6 +181,7 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager
if (iAdjust != 0) {
//getLogger().debug("Add leading space: " + iAdjust);
Space ls = new Space();
+ ls.setChangeBarList(getChangeBarList());
ls.setIPD(iAdjust);
int level = parentArea.getBidiLevel();
if (level >= 0) {
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InstreamForeignObjectLM.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InstreamForeignObjectLM.java
index 4a54f582d..6936e3e94 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InstreamForeignObjectLM.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InstreamForeignObjectLM.java
@@ -46,7 +46,9 @@ public class InstreamForeignObjectLM extends AbstractGraphicsLayoutManager {
org.w3c.dom.Document doc = child.getDOMDocument();
String ns = child.getNamespaceURI();
- return new ForeignObject(doc, ns);
+ ForeignObject obj = new ForeignObject(doc, ns);
+ obj.setChangeBarList(getChangeBarList());
+ return obj;
}
}
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
index 5f65a5969..a6d695b06 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
@@ -217,6 +217,10 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager {
leaderArea.setBidiLevel(fobj.getBidiLevelRecursive());
}
}
+
+ assert leaderArea != null;
+ leaderArea.setChangeBarList(getChangeBarList());
+
TraitSetter.setProducerID(leaderArea, fobj.getId());
return leaderArea;
}
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
index 8ee5d1e70..c15c1d0be 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
@@ -1504,6 +1504,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager
LineArea lineArea = new LineArea(
(lbp.getLeafPos() < seq.size() - 1 ? textAlignment : textAlignmentLast),
lbp.difference, lbp.availableStretch, lbp.availableShrink);
+ lineArea.setChangeBarList(getChangeBarList());
+
if (lbp.startIndent != 0) {
lineArea.addTrait(Trait.START_INDENT, lbp.startIndent);
}
@@ -1619,6 +1621,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}
LineArea lineArea = new LineArea();
+ lineArea.setChangeBarList(getChangeBarList());
setCurrentArea(lineArea);
LayoutContext lc = LayoutContext.newInstance();
lc.setAlignmentContext(alignmentContext);
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
index 27bd544dd..3134ebb17 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
@@ -32,6 +32,7 @@ import org.apache.fop.area.Trait;
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FOText;
+import org.apache.fop.fo.flow.ChangeBar;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontSelector;
import org.apache.fop.fonts.GlyphMapping;
@@ -312,6 +313,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstMappingIndex,
lastMappingIndex, context.isLastArea(), mapping.font).build();
+ textArea.setChangeBarList(getChangeBarList());
// wordSpaceDim is computed in relation to wordSpaceIPD.opt
// but the renderer needs to know the adjustment in relation
@@ -411,6 +413,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
textArea = new TextArea(width.getStretch(), width.getShrink(),
adjust);
}
+ textArea.setChangeBarList(getChangeBarList());
}
private void setInlineProgressionDimension() {
@@ -1457,6 +1460,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
+ @Override
+ public List getChangeBarList() {
+ if (foText == null) {
+ return null;
+ } else {
+ return foText.getChangeBarList();
+ }
+ }
+
/** {@inheritDoc} */
public String toString() {
return super.toString() + "{"
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
index 9b37e2405..ff2c59f4a 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
@@ -68,10 +68,12 @@ public class WrapperLayoutManager extends LeafNodeLayoutManager {
if (parentLayoutManager instanceof BlockStackingLayoutManager
&& !(parentLayoutManager instanceof BlockLayoutManager)) {
Block helperBlock = new Block();
+ helperBlock.setChangeBarList(getChangeBarList());
TraitSetter.setProducerID(helperBlock, fobj.getId());
parentLayoutManager.addChildArea(helperBlock);
} else {
InlineArea area = getEffectiveArea(context);
+ area.setChangeBarList(getChangeBarList());
parentLayoutManager.addChildArea(area);
}
}
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
index d39b63477..b73abeb0d 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
@@ -216,6 +216,7 @@ public class ListBlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManag
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
// Set up dimensions
// Must get dimensions from parent area
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
index 214ba6269..0cc877e37 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
@@ -176,6 +176,7 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager imp
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
curBlockArea.setPositioning(Block.ABSOLUTE);
// set position
curBlockArea.setXOffset(xOffset);
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
index 9d9769a7c..764575ac8 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
@@ -739,6 +739,7 @@ public class ListItemLayoutManager extends SpacedBorderedPaddedBlockLayoutManage
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
// Set up dimensions
/*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/RowPainter.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/RowPainter.java
index cbc19c1ec..06dda5efe 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/RowPainter.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/RowPainter.java
@@ -468,6 +468,7 @@ class RowPainter {
//generate the block area
Block block = new Block();
+ block.setChangeBarList(tclm.getTableLM().getFObj().getChangeBarList());
block.setPositioning(Block.ABSOLUTE);
block.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
block.setIPD(ipd);
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
index aaa896ce3..d95e508c5 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
@@ -179,6 +179,8 @@ public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager {
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
+
// Set up dimensions
// Must get dimensions from parent area
Area parentArea = parentLayoutManager.getParentArea(curBlockArea);
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
index 8823c0fae..ee4cba2e4 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
@@ -175,6 +175,8 @@ public class TableCaptionLayoutManager extends BlockStackingLayoutManager {
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
+
// Set up dimensions
// Must get dimensions from parent area
Area parentArea = parentLayoutManager.getParentArea(curBlockArea);
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
index cfa064db6..a56b00ce7 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
@@ -529,11 +529,13 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager {
if (usedBPD < cellBPD) {
if (getTableCell().getDisplayAlign() == EN_CENTER) {
Block space = new Block();
+ space.setChangeBarList(getChangeBarList());
space.setBPD((cellBPD - usedBPD) / 2);
space.setBidiLevel(getTableCell().getBidiLevelRecursive());
curBlockArea.addBlock(space);
} else if (getTableCell().getDisplayAlign() == EN_AFTER) {
Block space = new Block();
+ space.setChangeBarList(getChangeBarList());
space.setBPD(cellBPD - usedBPD);
space.setBidiLevel(getTableCell().getBidiLevelRecursive());
curBlockArea.addBlock(space);
@@ -620,6 +622,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager {
boolean outer, int level) {
if (blocks[i][j] == null) {
blocks[i][j] = new Block();
+ blocks[i][j].setChangeBarList(getChangeBarList());
blocks[i][j].addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
blocks[i][j].setPositioning(Block.ABSOLUTE);
blocks[i][j].setBidiLevel(level);
@@ -651,6 +654,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager {
int paddingEnd = padding.getPaddingEnd(false, this);
Block block = new Block();
+ block.setChangeBarList(getChangeBarList());
TraitSetter.setProducerID(block, getTable().getId());
block.setPositioning(Block.ABSOLUTE);
block.setIPD(cellIPD + paddingStart + paddingEnd);
@@ -677,6 +681,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager {
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
curBlockArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
TraitSetter.setProducerID(curBlockArea, getTableCell().getId());
curBlockArea.setPositioning(Block.ABSOLUTE);
diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
index 4940c66b2..333419649 100644
--- a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
+++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
@@ -438,6 +438,8 @@ public class TableLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
+
// Set up dimensions
// Must get dimensions from parent area
/*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);
diff --git a/fop-core/src/main/java/org/apache/fop/render/AbstractPathOrientedRenderer.java b/fop-core/src/main/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
index 552d9f92f..a078509e7 100644
--- a/fop-core/src/main/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
+++ b/fop-core/src/main/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
@@ -736,6 +736,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer {
// save position and offset
int saveIP = currentIPPosition;
int saveBP = currentBPPosition;
+ int saveBO = getBeginOffset();
//Establish a new coordinate system
AffineTransform at = new AffineTransform();
@@ -743,6 +744,8 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer {
at.translate(block.getXOffset(), block.getYOffset());
at.translate(0, block.getSpaceBefore());
+ setBeginOffset(saveBO - block.getXOffset());
+
if (!at.isIdentity()) {
establishTransformationMatrix(at);
}
@@ -760,6 +763,8 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer {
restoreGraphicsState();
}
+ setBeginOffset(saveBO);
+
// stacked and relative blocks effect stacking
currentIPPosition = saveIP;
currentBPPosition = saveBP;
diff --git a/fop-core/src/main/java/org/apache/fop/render/AbstractRenderer.java b/fop-core/src/main/java/org/apache/fop/render/AbstractRenderer.java
index d57d3ce06..e8ab76d53 100644
--- a/fop-core/src/main/java/org/apache/fop/render/AbstractRenderer.java
+++ b/fop-core/src/main/java/org/apache/fop/render/AbstractRenderer.java
@@ -41,6 +41,7 @@ import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.area.Area;
import org.apache.fop.area.BeforeFloat;
import org.apache.fop.area.Block;
+import org.apache.fop.area.BlockParent;
import org.apache.fop.area.BlockViewport;
import org.apache.fop.area.BodyRegion;
import org.apache.fop.area.CTM;
@@ -61,6 +62,7 @@ import org.apache.fop.area.inline.FilledArea;
import org.apache.fop.area.inline.ForeignObject;
import org.apache.fop.area.inline.Image;
import org.apache.fop.area.inline.InlineArea;
+import org.apache.fop.area.inline.InlineBlock;
import org.apache.fop.area.inline.InlineBlockParent;
import org.apache.fop.area.inline.InlineParent;
import org.apache.fop.area.inline.InlineViewport;
@@ -70,7 +72,11 @@ import org.apache.fop.area.inline.SpaceArea;
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.area.inline.WordArea;
import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.flow.ChangeBar;
+import org.apache.fop.fo.properties.Property;
import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.traits.BorderProps;
+import org.apache.fop.traits.Direction;
import org.apache.fop.traits.Visibility;
/**
@@ -111,7 +117,74 @@ public abstract class AbstractRenderer
*/
protected int containingIPPosition;
- /** the currently active PageViewport */
+ /**
+ * The "start edge" IP Position of the current column (for change bars)
+ */
+ protected int columnStartIPPosition;
+
+ /**
+ * The "end edge" IP Position of the current column (for change bars)
+ */
+ protected int columnEndIPPosition;
+
+ /**
+ * The "left" position of the current column (for change bars)
+ */
+ protected int columnLeftIPPosition;
+
+ /**
+ * The "right" position of the current column (for change bars)
+ */
+ protected int columnRightIPPosition;
+
+ /**
+ * The number of columns in the span (for change bars)
+ */
+ protected int columnCount;
+
+ /**
+ * The index number of the current column (for change bars)
+ */
+ protected int columnIndex;
+
+ /**
+ * The column width (for change bars)
+ */
+ protected int columnWidth;
+
+ /**
+ * The size of column gap (for change bars)
+ */
+ protected int columnGap;
+
+ /**
+ * The block progression direction (for change bars)
+ */
+ protected Direction blockProgressionDirection;
+
+ /**
+ * The inline progression direction (for change bars)
+ */
+ protected Direction inlineProgressionDirection;
+
+ /**
+ * Is binding on start edge of column?
+ */
+ protected boolean bindingOnStartEdge;
+
+ /**
+ * Is binding on end edge of column?
+ */
+ protected boolean bindingOnEndEdge;
+
+ /**
+ * The IP begin offset of coordinate 0
+ */
+ private int beginOffset;
+
+ /**
+ * the currently active PageViewport
+ */
protected PageViewport currentPageViewport;
/* warned XML handlers */
@@ -407,36 +480,95 @@ public abstract class AbstractRenderer
* that are positioned into columns.
*
*
- * @param mr The main reference area
+ * @param mainReference The main reference area
*/
- protected void renderMainReference(MainReference mr) {
+ protected void renderMainReference(MainReference mainReference) {
Span span = null;
- List spans = mr.getSpans();
+ List spans = mainReference.getSpans();
int saveBPPos = currentBPPosition;
- int saveSpanBPPos = saveBPPos;
int saveIPPos = currentIPPosition;
+ int saveSpanBPPos = saveBPPos;
+
for (Object span1 : spans) {
span = (Span) span1;
+
+ columnCount = span.getColumnCount();
+ columnGap = span.getColumnGap();
+ columnWidth = span.getColumnWidth();
+
+ blockProgressionDirection = (Direction) span.getTrait(Trait.BLOCK_PROGRESSION_DIRECTION);
+ inlineProgressionDirection = (Direction) span.getTrait(Trait.INLINE_PROGRESSION_DIRECTION);
+
int level = span.getBidiLevel();
if (level < 0) {
level = 0;
}
if ((level & 1) == 1) {
currentIPPosition += span.getIPD();
- currentIPPosition += mr.getColumnGap();
+ currentIPPosition += columnGap;
}
- for (int c = 0; c < span.getColumnCount(); c++) {
- NormalFlow flow = span.getNormalFlow(c);
+
+ for (columnIndex = 0; columnIndex < columnCount; columnIndex++) {
+
+ NormalFlow flow = span.getNormalFlow(columnIndex);
+
+ boolean isLeftToRight = (inlineProgressionDirection == null)
+ || (inlineProgressionDirection.getEnumValue() == Constants.EN_LR);
+
if (flow != null) {
+
+ // if direction is right to left, then end is left edge,
+ // else end is right edge (for top-bottom/bottom-top block
+ // progression directions)
+
+ // binding edge is on left edge for odd pages and
+ // on right edge for even pages
+
+ int pageIndex = currentPageViewport.getPageIndex();
+
+ bindingOnStartEdge = false;
+ bindingOnEndEdge = false;
+
+ if (isLeftToRight) {
+
+ columnStartIPPosition = 0;
+ columnEndIPPosition = columnWidth;
+ columnLeftIPPosition = 0;
+ columnRightIPPosition = columnWidth;
+
+ if (blockProgressionDirection == null || blockProgressionDirection.isVertical()) {
+ if (pageIndex % 2 == 0) {
+ bindingOnStartEdge = true;
+ } else {
+ bindingOnEndEdge = true;
+ }
+ }
+
+ } else {
+
+ columnStartIPPosition = columnWidth;
+ columnEndIPPosition = 0;
+ columnLeftIPPosition = 0;
+ columnRightIPPosition = columnWidth;
+
+ if (blockProgressionDirection == null || blockProgressionDirection.isVertical()) {
+ if (pageIndex % 2 == 0) {
+ bindingOnEndEdge = true;
+ } else {
+ bindingOnStartEdge = true;
+ }
+ }
+ }
+
currentBPPosition = saveSpanBPPos;
if ((level & 1) == 1) {
currentIPPosition -= flow.getIPD();
- currentIPPosition -= mr.getColumnGap();
+ currentIPPosition -= columnGap;
}
renderFlow(flow);
if ((level & 1) == 0) {
currentIPPosition += flow.getIPD();
- currentIPPosition += mr.getColumnGap();
+ currentIPPosition += columnGap;
}
}
}
@@ -504,7 +636,6 @@ public abstract class AbstractRenderer
endVParea();
// clip if necessary
-
currentIPPosition = saveIP;
currentBPPosition = saveBP;
} else {
@@ -584,6 +715,18 @@ public abstract class AbstractRenderer
*/
protected void renderBlock(Block block) {
assert block != null;
+ List changeBarList = block.getChangeBarList();
+
+ if (changeBarList != null && !changeBarList.isEmpty()) {
+ int saveIP = currentIPPosition;
+ int saveBP = currentBPPosition;
+
+ drawChangeBars(block, changeBarList);
+
+ currentIPPosition = saveIP;
+ currentBPPosition = saveBP;
+ }
+
List children = block.getChildAreas();
boolean inNewLayer = false;
if (maybeStartLayer(block)) {
@@ -627,8 +770,18 @@ public abstract class AbstractRenderer
maybeEndLayer(block, inNewLayer);
}
+ /**
+ * Renders an inline block area.
+ *
+ * @param inlineBlock The inline block area
+ */
+ protected void renderInlineBlock(InlineBlock inlineBlock) {
+ renderBlock(inlineBlock.getBlock());
+ }
+
/**
* Establish new optional content group layer.
+ *
* @param layer name of layer
*/
protected abstract void startLayer(String layer);
@@ -699,6 +852,11 @@ public abstract class AbstractRenderer
* @param inlineArea inline area text to render
*/
protected void renderInlineArea(InlineArea inlineArea) {
+ List changeBarList = inlineArea.getChangeBarList();
+
+ if (changeBarList != null && !changeBarList.isEmpty()) {
+ drawChangeBars(inlineArea, changeBarList);
+ }
if (inlineArea instanceof TextArea) {
renderText((TextArea) inlineArea);
//} else if (inlineArea instanceof Character) {
@@ -707,6 +865,8 @@ public abstract class AbstractRenderer
renderWord((WordArea) inlineArea);
} else if (inlineArea instanceof SpaceArea) {
renderSpace((SpaceArea) inlineArea);
+ } else if (inlineArea instanceof InlineBlock) {
+ renderInlineBlock((InlineBlock) inlineArea);
} else if (inlineArea instanceof InlineParent) {
renderInlineParent((InlineParent) inlineArea);
} else if (inlineArea instanceof InlineBlockParent) {
@@ -757,6 +917,16 @@ public abstract class AbstractRenderer
List children = text.getChildAreas();
int saveIP = currentIPPosition;
int saveBP = currentBPPosition;
+
+ List changeBarList = text.getChangeBarList();
+
+ if (changeBarList != null && !changeBarList.isEmpty()) {
+ drawChangeBars(text, changeBarList);
+
+ currentIPPosition = saveIP;
+ currentBPPosition = saveBP;
+ }
+
for (Object aChildren : children) {
InlineArea inline = (InlineArea) aChildren;
renderInlineArea(inline);
@@ -877,6 +1047,11 @@ public abstract class AbstractRenderer
* (todo) Make renderImage() protected
*/
public void renderImage(Image image, Rectangle2D pos) {
+ List changeBarList = image.getChangeBarList();
+
+ if (changeBarList != null && !changeBarList.isEmpty()) {
+ drawChangeBars(image, changeBarList);
+ }
// Default: do nothing.
// Some renderers (ex. Text) don't support images.
}
@@ -903,6 +1078,12 @@ public abstract class AbstractRenderer
* (todo) Make renderForeignObject() protected
*/
protected void renderForeignObject(ForeignObject fo, Rectangle2D pos) {
+ List changeBarList = fo.getChangeBarList();
+
+ if (changeBarList != null && !changeBarList.isEmpty()) {
+ drawChangeBars(fo, changeBarList);
+ }
+
// Default: do nothing.
// Some renderers (ex. Text) don't support foreign objects.
}
@@ -975,4 +1156,191 @@ public abstract class AbstractRenderer
matrix[5] = Math.round(matrix[5] * 1000);
return new AffineTransform(matrix);
}
+
+ /**
+ * Draws all change bars associated with an area.
+ *
+ * @param area The area to draw change bars for
+ * @param changeBarList The list of change bars affecting the area
+ */
+ protected void drawChangeBars(Area area, List changeBarList) {
+
+ if (area.getTraitAsBoolean(Trait.IS_REFERENCE_AREA)) {
+ return;
+ }
+
+ Block changeBarArea;
+
+ int saveIP = currentIPPosition;
+ int saveBP = currentBPPosition;
+
+ int currentColumnStartIP = columnStartIPPosition;
+ int currentColumnEndIP = columnEndIPPosition;
+ int currentColumnLeftIP = columnLeftIPPosition;
+ int currentColumnRightIP = columnRightIPPosition;
+
+ for (ChangeBar changeBar : changeBarList) {
+
+ boolean isLeftToRight = (inlineProgressionDirection == null)
+ || (inlineProgressionDirection.getEnumValue() == Constants.EN_LR);
+
+ changeBarArea = new Block();
+
+ // currentIPPosition is reset to zero so from now on all multicolumn
+ // dimensions has to be calculated relatively to the given column
+ currentIPPosition = 0;
+ currentBPPosition = saveBP;
+
+ int changeBarWidth = changeBar.getWidth().getValue();
+ int changeBarOffset = changeBar.getOffset().getValue();
+
+ if (isLeftToRight) {
+ currentColumnStartIP = columnStartIPPosition - changeBarWidth;
+ currentColumnLeftIP = columnLeftIPPosition - changeBarWidth;
+ } else {
+ currentColumnEndIP = columnEndIPPosition - changeBarWidth;
+ currentColumnLeftIP = columnLeftIPPosition - changeBarWidth;
+ }
+
+ // xOffset by default is negative width for change bars placed on the
+ // start edge (overriden if placement is at the end edge)
+ int xOffset = currentColumnStartIP;
+
+ // xScale is for adding or subtracting the offset of the change bar
+ // depending on placing the bar towards or away from the edge it is
+ // bound to
+ int xScale = -1;
+
+ // determines currentIPPosition based on placement
+ switch (changeBar.getPlacement()) {
+ case EN_START:
+ xOffset = currentColumnStartIP;
+ xScale = -1;
+ break;
+ case EN_END:
+ xOffset = currentColumnEndIP;
+ xScale = 1;
+ break;
+ case EN_LEFT:
+ xOffset = currentColumnLeftIP;
+ xScale = (isLeftToRight) ? -1 : 1;
+ break;
+ case EN_RIGHT:
+ xOffset = currentColumnRightIP;
+ xScale = (isLeftToRight) ? 1 : -1;
+ break;
+ case EN_INSIDE:
+ if (bindingOnStartEdge) {
+ xOffset = currentColumnStartIP;
+ xScale = -1;
+ } else if (bindingOnEndEdge) {
+ xOffset = currentColumnEndIP;
+ xScale = 1;
+ } else {
+ xOffset = currentColumnStartIP;
+ xScale = -1;
+ }
+ break;
+ case EN_OUTSIDE:
+ if (bindingOnStartEdge) {
+ xOffset = columnEndIPPosition;
+ xScale = 1;
+ } else if (bindingOnEndEdge) {
+ xOffset = columnStartIPPosition;
+ xScale = -1;
+ } else {
+ xOffset = columnStartIPPosition;
+ xScale = -1;
+ }
+ break;
+ case EN_ALTERNATE:
+ if (columnCount == 2) {
+ if (columnIndex == 0) {
+ xOffset = columnStartIPPosition;
+ xScale = -1;
+ } else {
+ xOffset = columnEndIPPosition;
+ xScale = 1;
+ }
+ } else {
+ if (bindingOnStartEdge) {
+ xOffset = columnEndIPPosition;
+ xScale = 1;
+ } else if (bindingOnEndEdge) {
+ xOffset = columnStartIPPosition;
+ xScale = -1;
+ } else {
+ xOffset = columnStartIPPosition;
+ xScale = -1;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (isLeftToRight) {
+ xOffset += xScale * changeBarOffset;
+ } else {
+ xOffset -= xScale * changeBarOffset;
+ }
+
+ xOffset += getBeginOffset();
+
+ // Change bar area has 0 ipd, class xsl-absolute, no margin or padding
+ changeBarArea.setAreaClass(Area.CLASS_ABSOLUTE);
+ changeBarArea.setIPD(0);
+
+ BorderProps props = BorderProps.makeRectangular(
+ changeBar.getStyle(), changeBarWidth, changeBar.getColor(),
+ BorderProps.Mode.SEPARATE);
+
+ changeBarArea.addTrait(Trait.BORDER_START, props);
+ changeBarArea.addTrait(Trait.BORDER_END, props);
+
+ changeBarArea.setXOffset(xOffset);
+
+ int areaHeight = area.getAllocBPD();
+
+ if (area instanceof BlockParent) {
+ changeBarArea.setBPD(areaHeight);
+ changeBarArea.setYOffset(((BlockParent) area).getYOffset());
+ renderBlock(changeBarArea);
+
+ } else {
+ if (areaHeight > 0) {
+ Property p = changeBar.getLineHeight().getOptimum(DummyPercentBaseContext.getInstance());
+ int lineHeight = p.getLength().getValue();
+ changeBarArea.setBPD(lineHeight);
+ changeBarArea.setYOffset(areaHeight - lineHeight);
+ }
+ renderInlineBlock(new InlineBlock(changeBarArea));
+ }
+
+ // restore position on page
+ currentIPPosition = saveIP;
+ currentBPPosition = saveBP;
+ }
+ }
+
+ /**
+ * Returns the begin offset of the inline begin (changes by reference area
+ * transforms).
+ *
+ * @return the offset from current coordinate system 0 that the IP begin is
+ * at
+ */
+ protected int getBeginOffset() {
+ return beginOffset;
+ }
+
+ /**
+ * Sets the begin offset for inline progression begin (changes by reference
+ * area tranforms).
+ *
+ * @param offset the new offset from IPP 0 that true IP start is at
+ */
+ protected void setBeginOffset(int offset) {
+ beginOffset = offset;
+ }
}
diff --git a/fop-core/src/main/java/org/apache/fop/render/xml/XMLRenderer.java b/fop-core/src/main/java/org/apache/fop/render/xml/XMLRenderer.java
index f8765f280..ecad6b500 100644
--- a/fop-core/src/main/java/org/apache/fop/render/xml/XMLRenderer.java
+++ b/fop-core/src/main/java/org/apache/fop/render/xml/XMLRenderer.java
@@ -72,6 +72,7 @@ import org.apache.fop.area.inline.Container;
import org.apache.fop.area.inline.ForeignObject;
import org.apache.fop.area.inline.Image;
import org.apache.fop.area.inline.InlineArea;
+import org.apache.fop.area.inline.InlineBlock;
import org.apache.fop.area.inline.InlineBlockParent;
import org.apache.fop.area.inline.InlineParent;
import org.apache.fop.area.inline.InlineViewport;
@@ -692,6 +693,26 @@ public class XMLRenderer extends AbstractXMLRenderer {
endElement("block");
}
+ /** {@inheritDoc} */
+ @Override
+ protected void renderInlineBlock(InlineBlock inlineBlock) {
+ Block block = inlineBlock.getBlock();
+ atts.clear();
+ addAreaAttributes(block);
+ addTraitAttributes(block);
+ if (block.getXOffset() != 0) {
+ addAttribute("left-offset", block.getXOffset());
+ }
+ if (block.getYOffset() != 0) {
+ addAttribute("top-offset", block.getYOffset());
+ }
+ startElement("inlineblock", atts);
+ if (block.getChildAreas() != null) {
+ renderBlocks(null, block.getChildAreas());
+ }
+ endElement("inlineblock");
+ }
+
/**
* {@inheritDoc}
*/
@@ -943,6 +964,4 @@ public class XMLRenderer extends AbstractXMLRenderer {
addAttribute("reversed", "true");
}
}
-
-
}
diff --git a/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-datatypes.xsd b/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-datatypes.xsd
index e25556f9b..e4865f2d2 100644
--- a/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-datatypes.xsd
+++ b/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-datatypes.xsd
@@ -67,6 +67,8 @@
+
+
@@ -79,6 +81,8 @@
+
+
@@ -92,7 +96,7 @@
-
+
diff --git a/fop/test/layoutengine/standard-testcases/change-bar_block.xml b/fop/test/layoutengine/standard-testcases/change-bar_block.xml
new file mode 100644
index 000000000..9277343b5
--- /dev/null
+++ b/fop/test/layoutengine/standard-testcases/change-bar_block.xml
@@ -0,0 +1,73 @@
+
+
+
+
+
+ This test checks fo:change-bar-* on block elements.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fop/test/layoutengine/standard-testcases/change-bar_inline.xml b/fop/test/layoutengine/standard-testcases/change-bar_inline.xml
new file mode 100644
index 000000000..d90500db8
--- /dev/null
+++ b/fop/test/layoutengine/standard-testcases/change-bar_inline.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+ This test checks fo:change-bar-* on inline elements.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor incididunt ut labore et dolore magna aliqua.
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor incididunt ut labore et dolore
+ magna
+ aliqua.
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor incididunt ut labore et dolore
+ magna
+ aliqua.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fop/test/layoutengine/standard-testcases/change-bar_list.xml b/fop/test/layoutengine/standard-testcases/change-bar_list.xml
new file mode 100644
index 000000000..f1219fc84
--- /dev/null
+++ b/fop/test/layoutengine/standard-testcases/change-bar_list.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+ This test checks fo:change-bar-* on list elements.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ First
+
+
+
+
+
+
+ 2
+
+
+
+
+ Second
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fop/test/layoutengine/standard-testcases/change-bar_overlapped.xml b/fop/test/layoutengine/standard-testcases/change-bar_overlapped.xml
new file mode 100644
index 000000000..240670773
--- /dev/null
+++ b/fop/test/layoutengine/standard-testcases/change-bar_overlapped.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+ This test checks fo:change-bar-* on list elements.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ January February March April May June July
+ August September October
+ November December
+
+
+ January
+ February
+ March
+
+ April
+ May
+
+
+
+ June
+
+
+
+ July
+ August
+
+
+ September
+ October
+ November
+ December
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fop/test/layoutengine/standard-testcases/change-bar_placement-rtl.xml b/fop/test/layoutengine/standard-testcases/change-bar_placement-rtl.xml
new file mode 100644
index 000000000..f9b5b197e
--- /dev/null
+++ b/fop/test/layoutengine/standard-testcases/change-bar_placement-rtl.xml
@@ -0,0 +1,226 @@
+
+
+
+
+
+ This test checks fo:change-bar-start placement.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+ Lorem ipsum dolor sit
+ amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
+ et dolore magna aliqua.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fop/test/layoutengine/standard-testcases/change-bar_placement.xml b/fop/test/layoutengine/standard-testcases/change-bar_placement.xml
new file mode 100644
index 000000000..82d4bd9fa
--- /dev/null
+++ b/fop/test/layoutengine/standard-testcases/change-bar_placement.xml
@@ -0,0 +1,226 @@
+
+
+
+
+
+ This test checks fo:change-bar-start placement.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+ Lorem ipsum dolor sit
+ amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
+ et dolore magna aliqua.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fop/test/layoutengine/standard-testcases/change-bar_style.xml b/fop/test/layoutengine/standard-testcases/change-bar_style.xml
new file mode 100644
index 000000000..65203cfeb
--- /dev/null
+++ b/fop/test/layoutengine/standard-testcases/change-bar_style.xml
@@ -0,0 +1,102 @@
+
+
+
+
+
+ This test checks fo:change-bar-start style.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fop/test/layoutengine/standard-testcases/change-bar_table.xml b/fop/test/layoutengine/standard-testcases/change-bar_table.xml
new file mode 100644
index 000000000..39bd4b8b1
--- /dev/null
+++ b/fop/test/layoutengine/standard-testcases/change-bar_table.xml
@@ -0,0 +1,147 @@
+
+
+
+
+
+ This test checks fo:change-bar-* on table elements.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ body-row1-col1
+
+
+ body-row1-col2
+
+
+
+
+
+
+ body-row2-col1
+
+
+
+
+ body-row2-col2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+