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;
*/
protected static final Log log = LogFactory.getLog(Area.class);
+ /**
+ * The active change bar list
+ */
+ private List<ChangeBar> changeBarList;
+
+ /**
+ * Returns the active change bar list.
+ *
+ * @return The active change bar list
+ */
+ public List<ChangeBar> getChangeBarList() {
+ return changeBarList;
+ }
+
+ /**
+ * Sets the active change bar list.
+ *
+ * @param changeBarList The active change bar list
+ */
+ public void setChangeBarList(List<ChangeBar> changeBarList) {
+ this.changeBarList = changeBarList;
+ }
+
/**
* Get the area class of this area.
*
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;
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;
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());
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);
}
}
+ 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) {
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
*
}
break;
}
+ addTrait(Trait.INLINE_PROGRESSION_DIRECTION, wmtg.getInlineProgressionDirection());
+ addTrait(Trait.BLOCK_PROGRESSION_DIRECTION, wmtg.getBlockProgressionDirection());
}
/** {@inheritDoc} */
--- /dev/null
+/*
+ * 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 final Block block;
+
+ public InlineBlock(Block block) {
+ this.block = block;
+ }
+
+ /**
+ * @return the wrapped block
+ */
+ public Block getBlock() {
+ return block;
+ }
+}
WordArea wordArea = new WordArea(
blockProgressionOffset, minWordLevel, word, letterAdjust, levels, gposAdjustments);
wordArea.setIPD(ipd);
+ wordArea.setChangeBarList(getChangeBarList());
addChildArea(wordArea);
wordArea.setParentArea(this);
updateLevel(minWordLevel);
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);
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());
}
}
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);
+ }
+ }
}
package org.apache.fop.fo;
// Java
+import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Stack;
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;
/** pointer to the sibling nodes */
protected FONode[] siblings;
+ /** The list of active change bars for the given node */
+ protected List<ChangeBar> nodeChangeBarList;
+
+ /** The list of active change bars for the start of the given node */
+ protected List<ChangeBar> startOfNodeChangeBarList;
+
/**
* Marks the location of this object from the input FO
* <br>Call <code>locator.getSystemId()</code>,
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 <code>FOEventHandler</code>.
}
+ /**
+ * Returns the list of active change bars.
+ *
+ * @return The list of active change bars
+ */
+ public List<ChangeBar> getChangeBarList() {
+ return nodeChangeBarList;
+ }
+
/**
* Sets the structure tree element.
*
gp.createTableProperties();
gp.createWritingModeProperties();
gp.createMiscProperties();
+ gp.createChangeBarProperties();
// Hardcode the subproperties.
addSubpropMakerName("length", CP_LENGTH);
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;
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;
*/
public FOText(FONode parent) {
super(parent);
+
+ PageSequence pageSequence = getRoot().getLastPageSequence();
+ if (pageSequence != null && pageSequence.hasChangeBars()) {
+ nodeChangeBarList = getRoot().getLastPageSequence().getClonedChangeBarList();
+ }
}
/** {@inheritDoc} */
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);
+ }
}
}
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.
*
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;
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;
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<ChangeBar> endOfNodeChangeBarList = null;
+
+ PageSequence pageSequence = getRoot().getLastPageSequence();
+ if (pageSequence != null) {
+ endOfNodeChangeBarList = pageSequence.getClonedChangeBarList();
+ }
+
+ if (startOfNodeChangeBarList != null && endOfNodeChangeBarList != null) {
+
+ nodeChangeBarList = new LinkedList<ChangeBar>(endOfNodeChangeBarList);
+ nodeChangeBarList.retainAll(startOfNodeChangeBarList);
+
+ if (nodeChangeBarList.isEmpty()) {
+ nodeChangeBarList = null;
+ }
+
+ startOfNodeChangeBarList = null;
+ }
+
+ super.endOfNode();
}
/**
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)
--- /dev/null
+/*
+ * 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;
+ }
+
+}
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/*
+ * 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();
+ }
+ }
+}
/** {@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);
}
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;
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;
*/
private Flow mainFlow;
+ /**
+ * Active change bars
+ */
+ private final List<ChangeBar> changeBarList = new LinkedList<ChangeBar>();
+
/**
* Create a PageSequence instance that is a child of the
* given {@link FONode}.
masterReference, getLocator());
}
}
+ getRoot().addPageSequence(this);
getFOEventHandler().startPageSequence(this);
}
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<ChangeBar> getChangeBarList() {
+ return changeBarList;
+ }
+
+ /**
+ * Returns the copy of active change bars list.
+ *
+ * @return The list containing a copy of the active change bars
+ */
+ public List<ChangeBar> getClonedChangeBarList() {
+ return new LinkedList<ChangeBar>(changeBarList);
+ }
}
}
}
+ /**
+ * 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
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.
return fobj;
}
+ /**
+ * Returns the active change bar list.
+ *
+ * @return The active change bar list
+ */
+ public List<ChangeBar> getChangeBarList() {
+ if (fobj == null) {
+ return null;
+ } else {
+ return fobj.getChangeBarList();
+ }
+ }
+
/** {@inheritDoc} */
public void reset() {
throw new UnsupportedOperationException("Not implemented");
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);
}
referenceArea = new Block();
+ referenceArea.setChangeBarList(getChangeBarList());
referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
if (level >= 0) {
referenceArea.setBidiLevel(level);
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
curBlockArea.setIPD(super.getContentAreaIPD());
int sp = TraitSetter.getEffectiveSpace(adjust, minoptmax);
if (sp != 0) {
Block spacer = new Block();
+ spacer.setChangeBarList(getChangeBarList());
spacer.setBPD(sp);
parentLayoutManager.addChildArea(spacer);
}
Dimension imageSize = this.imageLayout.getViewportSize();
Block blockArea = new Block();
+ blockArea.setChangeBarList(getChangeBarList());
blockArea.setIPD(imageSize.width);
LineArea lineArea = new LineArea();
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;
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());
getPSLM().addUnresolvedArea(citation.getRefId(), unresolved);
text = unresolved;
}
+ text.setChangeBarList(getChangeBarList());
setTraits(text);
return text;
}
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;
// get breaks then add areas to title
this.parentLM = pslm;
holder = new LineArea();
+ holder.setChangeBarList(getChangeBarList());
// setUserAgent(foTitle.getUserAgent());
/** {@inheritDoc} */
protected Area getChildArea() {
- return new Image(((ExternalGraphic) fobj).getSrc());
+ Image im = new Image(((ExternalGraphic) fobj).getSrc());
+ im.setChangeBarList(getChangeBarList());
+ return im;
}
}
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());
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) {
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;
}
}
leaderArea.setBidiLevel(fobj.getBidiLevelRecursive());
}
}
+
+ leaderArea.setChangeBarList(getChangeBarList());
+
TraitSetter.setProducerID(leaderArea, fobj.getId());
return leaderArea;
}
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);
}
}
LineArea lineArea = new LineArea();
+ lineArea.setChangeBarList(getChangeBarList());
setCurrentArea(lineArea);
LayoutContext lc = LayoutContext.newInstance();
lc.setAlignmentContext(alignmentContext);
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;
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
textArea = new TextArea(width.getStretch(), width.getShrink(),
adjust);
}
+ textArea.setChangeBarList(getChangeBarList());
}
private void setInlineProgressionDimension() {
}
+ @Override
+ public List<ChangeBar> getChangeBarList() {
+ if (foText == null) {
+ return null;
+ } else {
+ return foText.getChangeBarList();
+ }
+ }
+
/** {@inheritDoc} */
public String toString() {
return super.toString() + "{"
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);
}
}
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
// Set up dimensions
// Must get dimensions from parent area
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
curBlockArea.setPositioning(Block.ABSOLUTE);
// set position
curBlockArea.setXOffset(xOffset);
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBarList(getChangeBarList());
// Set up dimensions
/*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);
//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);
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);
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);
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);
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);
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);
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);
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);
// save position and offset
int saveIP = currentIPPosition;
int saveBP = currentBPPosition;
+ int saveBO = getBeginOffset();
//Establish a new coordinate system
AffineTransform at = new AffineTransform();
at.translate(block.getXOffset(), block.getYOffset());
at.translate(0, block.getSpaceBefore());
+ setBeginOffset(saveBO - block.getXOffset());
+
if (!at.isIdentity()) {
establishTransformationMatrix(at);
}
restoreGraphicsState();
}
+ setBeginOffset(saveBO);
+
// stacked and relative blocks effect stacking
currentIPPosition = saveIP;
currentBPPosition = saveBP;
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;
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;
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;
/**
*/
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 */
* that are positioned into columns.
* </p>
*
- * @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;
}
}
}
endVParea();
// clip if necessary
-
currentIPPosition = saveIP;
currentBPPosition = saveBP;
} else {
*/
protected void renderBlock(Block block) {
assert block != null;
+ List<ChangeBar> 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)) {
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);
* @param inlineArea inline area text to render
*/
protected void renderInlineArea(InlineArea inlineArea) {
+ List<ChangeBar> changeBarList = inlineArea.getChangeBarList();
+
+ if (changeBarList != null && !changeBarList.isEmpty()) {
+ drawChangeBars(inlineArea, changeBarList);
+ }
if (inlineArea instanceof TextArea) {
renderText((TextArea) inlineArea);
//} else if (inlineArea instanceof Character) {
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) {
List children = text.getChildAreas();
int saveIP = currentIPPosition;
int saveBP = currentBPPosition;
+
+ List<ChangeBar> 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);
* (todo) Make renderImage() protected
*/
public void renderImage(Image image, Rectangle2D pos) {
+ List<ChangeBar> changeBarList = image.getChangeBarList();
+
+ if (changeBarList != null && !changeBarList.isEmpty()) {
+ drawChangeBars(image, changeBarList);
+ }
// Default: do nothing.
// Some renderers (ex. Text) don't support images.
}
* (todo) Make renderForeignObject() protected
*/
protected void renderForeignObject(ForeignObject fo, Rectangle2D pos) {
+ List<ChangeBar> changeBarList = fo.getChangeBarList();
+
+ if (changeBarList != null && !changeBarList.isEmpty()) {
+ drawChangeBars(fo, changeBarList);
+ }
+
// Default: do nothing.
// Some renderers (ex. Text) don't support foreign objects.
}
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<ChangeBar> 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;
+ }
}
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;
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}
*/
addAttribute("reversed", "true");
}
}
-
-
}
</xs:simpleType>
<xs:simpleType name="borderStyle">
<xs:restriction base="xs:string">
+ <xs:enumeration value="none"/>
+ <xs:enumeration value="hidden"/>
<xs:enumeration value="solid"/>
<xs:enumeration value="dotted"/>
<xs:enumeration value="dashed"/>
</xs:simpleType>
<xs:simpleType name="ruleStyle">
<xs:restriction base="xs:string">
+ <xs:enumeration value="none"/>
+ <xs:enumeration value="hidden"/>
<xs:enumeration value="solid"/>
<xs:enumeration value="dotted"/>
<xs:enumeration value="dashed"/>
<!-- TODO refine me: \w+ will not be good enough for CMYK color, for example
<xs:pattern value="\((solid|dotted|dashed|double|groove|ridge|inset|outset),\w+,\d+(,collapse-(inner|outer))?"/>
-->
- <xs:pattern value="\((solid|dotted|dashed|double|groove|ridge|inset|outset),.+\)"/>
+ <xs:pattern value="\((none|hidden|solid|dotted|dashed|double|groove|ridge|inset|outset),.+\)"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="lengthListType">
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>This test checks fo:change-bar-* on block elements.</p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master page-height="145mm" page-width="210mm" margin="10mm"
+ master-name="master">
+ <fo:region-body column-count="2" column-gap="10mm"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="master">
+ <fo:flow flow-name="xsl-region-body">
+
+ <fo:block change-bar-style="solid" change-bar-color="red" change-bar-offset="3mm"
+ change-bar-width="0.3mm">
+
+ <fo:change-bar-begin change-bar-class="global"/>
+ <fo:block id="red-01" color="red">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-begin change-bar-class="local-blue" change-bar-color="blue"
+ change-bar-offset="2mm"/>
+ <fo:block id="blue-01" color="blue">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="local-blue"/>
+ <fo:change-bar-begin change-bar-class="local-green" change-bar-color="green"
+ change-bar-offset="2mm"/>
+ <fo:block id="green-01" color="green">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="local-green"/>
+ <fo:block id="red-02" color="red">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="global"/>
+
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='red-01']/block[1]/@border-start"/>
+ <eval expected="-9353" xpath="//block[@prod-id='red-01']/block[1]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='blue-01']/block[1]/@border-start"/>
+ <eval expected="-9353" xpath="//block[@prod-id='blue-01']/block[1]/@left-offset"/>
+ <eval expected="(solid,#0000ff,850)" xpath="//block[@prod-id='blue-01']/block[2]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='blue-01']/block[2]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='green-01']/block[1]/@border-start"/>
+ <eval expected="-9353" xpath="//block[@prod-id='green-01']/block[1]/@left-offset"/>
+ <eval expected="(solid,#008000,850)" xpath="//block[@prod-id='green-01']/block[2]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='green-01']/block[2]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='red-02']/block[1]/@border-start"/>
+ <eval expected="-9353" xpath="//block[@prod-id='red-02']/block[1]/@left-offset"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>This test checks fo:change-bar-* on inline elements.</p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master page-height="145mm" page-width="210mm" margin="10mm"
+ master-name="master">
+ <fo:region-body column-count="2" column-gap="10mm"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="master">
+ <fo:flow flow-name="xsl-region-body">
+
+ <fo:block change-bar-style="solid" change-bar-color="red" change-bar-offset="2mm"
+ change-bar-width="0.3mm">
+
+ <fo:block>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ <fo:change-bar-begin change-bar-class="red-01"/><fo:inline id="red-01"
+ color="red">tempor incididunt</fo:inline><fo:change-bar-end
+ change-bar-class="red-01"/> ut labore et dolore magna aliqua.</fo:block>
+
+ <fo:block>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ <fo:change-bar-begin change-bar-class="red-02"/><fo:inline id="red-02"
+ color="red">tempor incididunt</fo:inline><fo:change-bar-end
+ change-bar-class="red-02"/> ut labore et <fo:change-bar-begin
+ change-bar-color="blue" change-bar-offset="3mm" change-bar-class="blue-02"
+ /><fo:inline id="blue-02" color="blue">dolore
+ magna</fo:inline><fo:change-bar-end change-bar-class="blue-02"/>
+ aliqua.</fo:block>
+
+ <fo:block>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ <fo:change-bar-begin change-bar-class="red-03"/><fo:inline id="red-03-a"
+ color="red">tempor incididunt ut </fo:inline><fo:change-bar-begin
+ change-bar-color="blue" change-bar-offset="3mm" change-bar-class="blue-03"
+ /><fo:inline id="blue-03" color="blue">labore</fo:inline><fo:change-bar-end
+ change-bar-class="blue-03"/><fo:inline id="red-03-b" color="red"> et dolore
+ magna</fo:inline><fo:change-bar-end change-bar-class="red-03"/>
+ aliqua.</fo:block>
+
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="(solid,#ff0000,850)" xpath="//inlineparent[@prod-id='red-01']/inlineblock[1]/@border-start"/>
+ <eval expected="-6519" xpath="//inlineparent[@prod-id='red-01']/inlineblock[1]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//inlineparent[@prod-id='red-02']/inlineblock[1]/@border-start"/>
+ <eval expected="-6519" xpath="//inlineparent[@prod-id='red-02']/inlineblock[1]/@left-offset"/>
+ <eval expected="(solid,#0000ff,850)" xpath="//inlineparent[@prod-id='blue-02']/inlineblock[1]/@border-start"/>
+ <eval expected="-9353" xpath="//inlineparent[@prod-id='blue-02']/inlineblock[1]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//inlineparent[@prod-id='red-03-a']/inlineblock[1]/@border-start"/>
+ <eval expected="-6519" xpath="//inlineparent[@prod-id='red-03-a']/inlineblock[1]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//inlineparent[@prod-id='blue-03']/inlineblock[1]/@border-start"/>
+ <eval expected="-6519" xpath="//inlineparent[@prod-id='blue-03']/inlineblock[1]/@left-offset"/>
+ <eval expected="(solid,#0000ff,850)" xpath="//inlineparent[@prod-id='blue-03']/inlineblock[2]/@border-start"/>
+ <eval expected="-9353" xpath="//inlineparent[@prod-id='blue-03']/inlineblock[2]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//inlineparent[@prod-id='red-03-b']/inlineblock[1]/@border-start"/>
+ <eval expected="-6519" xpath="//inlineparent[@prod-id='red-03-b']/inlineblock[1]/@left-offset"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>This test checks fo:change-bar-* on list elements.</p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master page-height="145mm" page-width="210mm" margin="10mm"
+ master-name="master">
+ <fo:region-body column-count="2" column-gap="10mm"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="master">
+ <fo:flow flow-name="xsl-region-body">
+
+ <fo:block change-bar-style="solid" change-bar-color="red" change-bar-width="0.3mm"
+ change-bar-offset="3mm">
+ <fo:change-bar-begin change-bar-class="list-block"/>
+ <fo:list-block id="list-block">
+ <fo:change-bar-begin change-bar-class="list-item-first" change-bar-offset="2mm"
+ change-bar-color="green"/>
+ <fo:list-item id="list-item-first">
+ <fo:list-item-label id="list-item-first-label" end-indent="label-end()">
+ <fo:block>1</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body id="list-item-first-body" start-indent="body-start()">
+ <fo:block>First</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:change-bar-end change-bar-class="list-item-first"/>
+ <fo:list-item id="list-item-second">
+ <fo:change-bar-begin change-bar-class="list-item-second-label"
+ change-bar-offset="2mm" change-bar-color="blue"/>
+ <fo:list-item-label id="list-item-second-label" end-indent="label-end()">
+ <fo:block>2</fo:block>
+ </fo:list-item-label>
+ <fo:change-bar-end change-bar-class="list-item-second-label"/>
+ <fo:change-bar-begin change-bar-class="list-item-second-body" change-bar-offset="1mm"
+ change-bar-color="magenta"/>
+ <fo:list-item-body id="list-item-second-body" start-indent="body-start()">
+ <fo:block>Second</fo:block>
+ </fo:list-item-body>
+ <fo:change-bar-end change-bar-class="list-item-second-body"/>
+ </fo:list-item>
+ </fo:list-block>
+ <fo:change-bar-end change-bar-class="list-block"/>
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <!-- the first -->
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='list-item-first-label']/block[1]/block[1]/@border-start"/>
+ <eval expected="-9353" xpath="//block[@prod-id='list-item-first-label']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#008000,850)" xpath="//block[@prod-id='list-item-first-label']/block[1]/block[2]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='list-item-first-label']/block[1]/block[2]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='list-item-first-body']/block[1]/block[1]/@border-start"/>
+ <eval expected="-9353" xpath="//block[@prod-id='list-item-first-body']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#008000,850)" xpath="//block[@prod-id='list-item-first-body']/block[1]/block[2]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='list-item-first-body']/block[1]/block[2]/@left-offset"/>
+ <!-- the second -->
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='list-item-second-label']/block[1]/block[1]/@border-start"/>
+ <eval expected="-9353" xpath="//block[@prod-id='list-item-second-label']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#0000ff,850)" xpath="//block[@prod-id='list-item-second-label']/block[1]/block[2]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='list-item-second-label']/block[1]/block[2]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='list-item-second-body']/block[1]/block[1]/@border-start"/>
+ <eval expected="-9353" xpath="//block[@prod-id='list-item-second-body']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#ff00ff,850)" xpath="//block[@prod-id='list-item-second-body']/block[1]/block[2]/@border-start"/>
+ <eval expected="-3684" xpath="//block[@prod-id='list-item-second-body']/block[1]/block[2]/@left-offset"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>This test checks fo:change-bar-* on list elements.</p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master page-height="145mm" page-width="210mm" margin="10mm"
+ master-name="master">
+ <fo:region-body column-count="2" column-gap="10mm"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="master">
+ <fo:flow flow-name="xsl-region-body">
+
+ <fo:block change-bar-style="solid" change-bar-color="red" change-bar-offset="2mm"
+ change-bar-width="0.3mm">
+
+ <fo:block>
+ <fo:change-bar-begin change-bar-class="first-half"/><fo:inline color="red"
+ id="first-half">January February March April May </fo:inline><fo:change-bar-begin
+ change-bar-class="summer" change-bar-color="green" change-bar-offset="1mm"
+ /><fo:inline color="brown" id="june-inline">June</fo:inline><fo:change-bar-end
+ change-bar-class="first-half"/><fo:inline color="green" id="summer"> July
+ August</fo:inline><fo:change-bar-end change-bar-class="summer"/> September October
+ November December</fo:block>
+
+ <fo:change-bar-begin change-bar-class="first-half"/>
+ <fo:block id="january">January</fo:block>
+ <fo:block id="february">February</fo:block>
+ <fo:block id="march">March</fo:block>
+ <fo:wrapper color="red">
+ <fo:block id="april">April</fo:block>
+ <fo:block id="may">May</fo:block>
+ </fo:wrapper>
+ <fo:change-bar-begin change-bar-class="summer" change-bar-color="green"
+ change-bar-offset="1mm"/>
+ <fo:wrapper color="brown">
+ <fo:block id="june-block">June</fo:block>
+ </fo:wrapper>
+ <fo:change-bar-end change-bar-class="first-half"/>
+ <fo:wrapper color="red">
+ <fo:block id="july">July</fo:block>
+ <fo:block id="august">August</fo:block>
+ </fo:wrapper>
+ <fo:change-bar-end change-bar-class="summer"/>
+ <fo:block id="september">September</fo:block>
+ <fo:block id="october">October</fo:block>
+ <fo:block id="november">November</fo:block>
+ <fo:block id="december">December</fo:block>
+
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <!-- inline -->
+ <eval expected="(solid,#ff0000,850)" xpath="//inlineparent[@prod-id='first-half']/inlineblock[1]/@border-start"/>
+ <eval expected="-6519" xpath="//inlineparent[@prod-id='first-half']/inlineblock[1]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//inlineparent[@prod-id='june-inline']/inlineblock[1]/@border-start"/>
+ <eval expected="-6519" xpath="//inlineparent[@prod-id='june-inline']/inlineblock[1]/@left-offset"/>
+ <eval expected="(solid,#008000,850)" xpath="//inlineparent[@prod-id='june-inline']/inlineblock[2]/@border-start"/>
+ <eval expected="-3684" xpath="//inlineparent[@prod-id='june-inline']/inlineblock[2]/@left-offset"/>
+ <eval expected="(solid,#008000,850)" xpath="//lineArea[2]/inlineparent[@prod-id='summer']/inlineblock[1]/@border-start"/>
+ <eval expected="-3684" xpath="//lineArea[2]/inlineparent[@prod-id='summer']/inlineblock[1]/@left-offset"/>
+ <!-- block -->
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='may']/block[1]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='may']/block[1]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='june-block']/block[1]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='june-block']/block[1]/@left-offset"/>
+ <eval expected="(solid,#008000,850)" xpath="//block[@prod-id='june-block']/block[2]/@border-start"/>
+ <eval expected="-3684" xpath="//block[@prod-id='june-block']/block[2]/@left-offset"/>
+ <eval expected="(solid,#008000,850)" xpath="//block[@prod-id='july']/block[1]/@border-start"/>
+ <eval expected="-3684" xpath="//block[@prod-id='july']/block[1]/@left-offset"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>This test checks fo:change-bar-start placement.</p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master page-height="145mm" page-width="210mm" margin="10mm"
+ master-name="master">
+ <fo:region-body column-count="2" column-gap="10mm"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="master" writing-mode="rl-tb">
+ <fo:flow flow-name="xsl-region-body">
+
+ <fo:block change-bar-style="solid" change-bar-color="red" change-bar-offset="2mm"
+ change-bar-width="0.3mm">
+
+ <fo:change-bar-begin change-bar-class="left" change-bar-placement="left"/>
+ <fo:block id="page1-col1-left">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="left"/>
+
+ <fo:change-bar-begin change-bar-class="right" change-bar-placement="right"/>
+ <fo:block id="page1-col1-right">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="right"/>
+
+ <fo:change-bar-begin change-bar-class="start" change-bar-placement="start"/>
+ <fo:block id="page1-col1-start">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="start"/>
+
+ <fo:change-bar-begin change-bar-class="end" change-bar-placement="end"/>
+ <fo:block id="page1-col1-end">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="end"/>
+
+ <fo:change-bar-begin change-bar-class="inside" change-bar-placement="inside"/>
+ <fo:block id="page1-col1-inside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="inside"/>
+
+ <fo:change-bar-begin change-bar-class="outside" change-bar-placement="outside"/>
+ <fo:block id="page1-col1-outside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="outside"/>
+
+ <fo:change-bar-begin change-bar-class="left" change-bar-placement="left"/>
+ <fo:block id="page1-col2-left">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="left"/>
+
+ <fo:change-bar-begin change-bar-class="right" change-bar-placement="right"/>
+ <fo:block id="page1-col2-right">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="right"/>
+
+ <fo:change-bar-begin change-bar-class="start" change-bar-placement="start"/>
+ <fo:block id="page1-col2-start">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="start"/>
+
+ <fo:change-bar-begin change-bar-class="end" change-bar-placement="end"/>
+ <fo:block id="page1-col2-end">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="end"/>
+
+ <fo:change-bar-begin change-bar-class="inside" change-bar-placement="inside"/>
+ <fo:block id="page1-col2-inside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="inside"/>
+
+ <fo:change-bar-begin change-bar-class="outside" change-bar-placement="outside"/>
+ <fo:block id="page1-col2-outside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="outside"/>
+
+ <fo:change-bar-begin change-bar-class="left" change-bar-placement="left"/>
+ <fo:block id="page2-col1-left">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="left"/>
+
+ <fo:change-bar-begin change-bar-class="right" change-bar-placement="right"/>
+ <fo:block id="page2-col1-right">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="right"/>
+
+ <fo:change-bar-begin change-bar-class="start" change-bar-placement="start"/>
+ <fo:block id="page2-col1-start">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="start"/>
+
+ <fo:change-bar-begin change-bar-class="end" change-bar-placement="end"/>
+ <fo:block id="page2-col1-end">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="end"/>
+
+ <fo:change-bar-begin change-bar-class="inside" change-bar-placement="inside"/>
+ <fo:block id="page2-col1-inside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="inside"/>
+
+ <fo:change-bar-begin change-bar-class="outside" change-bar-placement="outside"/>
+ <fo:block id="page2-col1-outside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="outside"/>
+
+ <fo:change-bar-begin change-bar-class="left" change-bar-placement="left"/>
+ <fo:block id="page2-col2-left">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="left"/>
+
+ <fo:change-bar-begin change-bar-class="right" change-bar-placement="right"/>
+ <fo:block id="page2-col2-right">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="right"/>
+
+ <fo:change-bar-begin change-bar-class="start" change-bar-placement="start"/>
+ <fo:block id="page2-col2-start">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="start"/>
+
+ <fo:change-bar-begin change-bar-class="end" change-bar-placement="end"/>
+ <fo:block id="page2-col2-end">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="end"/>
+
+ <fo:change-bar-begin change-bar-class="inside" change-bar-placement="inside"/>
+ <fo:block id="page2-col2-inside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="inside"/>
+
+ <fo:change-bar-begin change-bar-class="outside" change-bar-placement="outside"/>
+ <fo:block id="page2-col2-outside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="outside"/>
+
+ <fo:change-bar-begin change-bar-class="alternate" change-bar-placement="alternate"/>
+ <fo:block id="page3-col1-alternate">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:block id="page3-col2-alternate" break-before="column">Lorem ipsum dolor sit
+ amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
+ et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="alternate"/>
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col1-left']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page1-col1-right']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col1-start']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page1-col1-end']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col1-inside']/block[1]/@left-offset"/>
+ <eval expected="-5669" xpath="//block[@prod-id='page1-col1-outside']/block[1]/@left-offset"/>
+
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col2-left']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page1-col2-right']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col2-start']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page1-col2-end']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col2-inside']/block[1]/@left-offset"/>
+ <eval expected="-5669" xpath="//block[@prod-id='page1-col2-outside']/block[1]/@left-offset"/>
+
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col1-left']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page2-col1-right']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col1-start']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page2-col1-end']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col1-inside']/block[1]/@left-offset"/>
+ <eval expected="-5669" xpath="//block[@prod-id='page2-col1-outside']/block[1]/@left-offset"/>
+
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col2-left']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page2-col2-right']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col2-start']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page2-col2-end']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col2-inside']/block[1]/@left-offset"/>
+ <eval expected="-5669" xpath="//block[@prod-id='page2-col2-outside']/block[1]/@left-offset"/>
+
+ <eval expected="-5669" xpath="//block[@prod-id='page3-col1-alternate']/block[1]/@left-offset"/>
+ <eval expected="-5669" xpath="//block[@prod-id='page3-col2-alternate']/block[1]/@left-offset"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>This test checks fo:change-bar-start placement.</p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master page-height="145mm" page-width="210mm" margin="10mm"
+ master-name="master">
+ <fo:region-body column-count="2" column-gap="10mm"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="master">
+ <fo:flow flow-name="xsl-region-body">
+
+ <fo:block change-bar-style="solid" change-bar-color="red" change-bar-offset="2mm"
+ change-bar-width="0.3mm">
+
+ <fo:change-bar-begin change-bar-class="left" change-bar-placement="left"/>
+ <fo:block id="page1-col1-left">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="left"/>
+
+ <fo:change-bar-begin change-bar-class="right" change-bar-placement="right"/>
+ <fo:block id="page1-col1-right">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="right"/>
+
+ <fo:change-bar-begin change-bar-class="start" change-bar-placement="start"/>
+ <fo:block id="page1-col1-start">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="start"/>
+
+ <fo:change-bar-begin change-bar-class="end" change-bar-placement="end"/>
+ <fo:block id="page1-col1-end">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="end"/>
+
+ <fo:change-bar-begin change-bar-class="inside" change-bar-placement="inside"/>
+ <fo:block id="page1-col1-inside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="inside"/>
+
+ <fo:change-bar-begin change-bar-class="outside" change-bar-placement="outside"/>
+ <fo:block id="page1-col1-outside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="outside"/>
+
+ <fo:change-bar-begin change-bar-class="left" change-bar-placement="left"/>
+ <fo:block id="page1-col2-left">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="left"/>
+
+ <fo:change-bar-begin change-bar-class="right" change-bar-placement="right"/>
+ <fo:block id="page1-col2-right">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="right"/>
+
+ <fo:change-bar-begin change-bar-class="start" change-bar-placement="start"/>
+ <fo:block id="page1-col2-start">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="start"/>
+
+ <fo:change-bar-begin change-bar-class="end" change-bar-placement="end"/>
+ <fo:block id="page1-col2-end">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="end"/>
+
+ <fo:change-bar-begin change-bar-class="inside" change-bar-placement="inside"/>
+ <fo:block id="page1-col2-inside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="inside"/>
+
+ <fo:change-bar-begin change-bar-class="outside" change-bar-placement="outside"/>
+ <fo:block id="page1-col2-outside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="outside"/>
+
+ <fo:change-bar-begin change-bar-class="left" change-bar-placement="left"/>
+ <fo:block id="page2-col1-left">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="left"/>
+
+ <fo:change-bar-begin change-bar-class="right" change-bar-placement="right"/>
+ <fo:block id="page2-col1-right">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="right"/>
+
+ <fo:change-bar-begin change-bar-class="start" change-bar-placement="start"/>
+ <fo:block id="page2-col1-start">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="start"/>
+
+ <fo:change-bar-begin change-bar-class="end" change-bar-placement="end"/>
+ <fo:block id="page2-col1-end">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="end"/>
+
+ <fo:change-bar-begin change-bar-class="inside" change-bar-placement="inside"/>
+ <fo:block id="page2-col1-inside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="inside"/>
+
+ <fo:change-bar-begin change-bar-class="outside" change-bar-placement="outside"/>
+ <fo:block id="page2-col1-outside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="outside"/>
+
+ <fo:change-bar-begin change-bar-class="left" change-bar-placement="left"/>
+ <fo:block id="page2-col2-left">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="left"/>
+
+ <fo:change-bar-begin change-bar-class="right" change-bar-placement="right"/>
+ <fo:block id="page2-col2-right">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="right"/>
+
+ <fo:change-bar-begin change-bar-class="start" change-bar-placement="start"/>
+ <fo:block id="page2-col2-start">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="start"/>
+
+ <fo:change-bar-begin change-bar-class="end" change-bar-placement="end"/>
+ <fo:block id="page2-col2-end">Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="end"/>
+
+ <fo:change-bar-begin change-bar-class="inside" change-bar-placement="inside"/>
+ <fo:block id="page2-col2-inside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="inside"/>
+
+ <fo:change-bar-begin change-bar-class="outside" change-bar-placement="outside"/>
+ <fo:block id="page2-col2-outside">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="outside"/>
+
+ <fo:change-bar-begin change-bar-class="alternate" change-bar-placement="alternate"/>
+ <fo:block id="page3-col1-alternate">Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.</fo:block>
+ <fo:block id="page3-col2-alternate" break-before="column">Lorem ipsum dolor sit
+ amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
+ et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="alternate"/>
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col1-left']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page1-col1-right']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col1-start']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page1-col1-end']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col1-inside']/block[1]/@left-offset"/>
+ <eval expected="-5669" xpath="//block[@prod-id='page1-col1-outside']/block[1]/@left-offset"/>
+
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col2-left']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page1-col2-right']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col2-start']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page1-col2-end']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page1-col2-inside']/block[1]/@left-offset"/>
+ <eval expected="-5669" xpath="//block[@prod-id='page1-col2-outside']/block[1]/@left-offset"/>
+
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col1-left']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page2-col1-right']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col1-start']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page2-col1-end']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col1-inside']/block[1]/@left-offset"/>
+ <eval expected="-5669" xpath="//block[@prod-id='page2-col1-outside']/block[1]/@left-offset"/>
+
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col2-left']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page2-col2-right']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col2-start']/block[1]/@left-offset"/>
+ <eval expected="5669" xpath="//block[@prod-id='page2-col2-end']/block[1]/@left-offset"/>
+ <eval expected="-6519" xpath="//block[@prod-id='page2-col2-inside']/block[1]/@left-offset"/>
+ <eval expected="-5669" xpath="//block[@prod-id='page2-col2-outside']/block[1]/@left-offset"/>
+
+ <eval expected="-5669" xpath="//block[@prod-id='page3-col1-alternate']/block[1]/@left-offset"/>
+ <eval expected="-5669" xpath="//block[@prod-id='page3-col2-alternate']/block[1]/@left-offset"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>This test checks fo:change-bar-start style.</p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master page-height="145mm" page-width="210mm" margin="10mm"
+ master-name="master">
+ <fo:region-body column-count="2" column-gap="10mm"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="master">
+ <fo:flow flow-name="xsl-region-body">
+
+ <fo:block change-bar-color="red" change-bar-offset="2mm" change-bar-width="1mm">
+
+ <fo:change-bar-begin change-bar-class="none" change-bar-style="none"/>
+ <fo:block id="none">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="none"/>
+
+ <fo:change-bar-begin change-bar-class="hidden" change-bar-style="hidden"/>
+ <fo:block id="hidden">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="hidden"/>
+
+ <fo:change-bar-begin change-bar-class="dotted" change-bar-style="dotted"/>
+ <fo:block id="dotted">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="dotted"/>
+
+ <fo:change-bar-begin change-bar-class="dashed" change-bar-style="dashed"/>
+ <fo:block id="dashed">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="dashed"/>
+
+ <fo:change-bar-begin change-bar-class="solid" change-bar-style="solid"/>
+ <fo:block id="solid">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="solid"/>
+
+ <fo:change-bar-begin change-bar-class="double" change-bar-style="double"/>
+ <fo:block id="double">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="double"/>
+
+ <fo:change-bar-begin change-bar-class="groove" change-bar-style="groove"/>
+ <fo:block id="groove">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="groove"/>
+
+ <fo:change-bar-begin change-bar-class="ridge" change-bar-style="ridge"/>
+ <fo:block id="ridge">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="ridge"/>
+
+ <fo:change-bar-begin change-bar-class="inset" change-bar-style="inset"/>
+ <fo:block id="inset">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="inset"/>
+
+ <fo:change-bar-begin change-bar-class="outset" change-bar-style="outset"/>
+ <fo:block id="outset">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna aliqua.</fo:block>
+ <fo:change-bar-end change-bar-class="outset"/>
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="(none,#ff0000,2834)" xpath="//block[@prod-id='none']/block[1]/@border-start"/>
+ <eval expected="(hidden,#ff0000,2834)" xpath="//block[@prod-id='hidden']/block[1]/@border-start"/>
+ <eval expected="(dotted,#ff0000,2834)" xpath="//block[@prod-id='dotted']/block[1]/@border-start"/>
+ <eval expected="(dashed,#ff0000,2834)" xpath="//block[@prod-id='dashed']/block[1]/@border-start"/>
+ <eval expected="(solid,#ff0000,2834)" xpath="//block[@prod-id='solid']/block[1]/@border-start"/>
+ <eval expected="(double,#ff0000,2834)" xpath="//block[@prod-id='double']/block[1]/@border-start"/>
+ <eval expected="(groove,#ff0000,2834)" xpath="//block[@prod-id='groove']/block[1]/@border-start"/>
+ <eval expected="(ridge,#ff0000,2834)" xpath="//block[@prod-id='ridge']/block[1]/@border-start"/>
+ <eval expected="(inset,#ff0000,2834)" xpath="//block[@prod-id='inset']/block[1]/@border-start"/>
+ <eval expected="(outset,#ff0000,2834)" xpath="//block[@prod-id='outset']/block[1]/@border-start"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>This test checks fo:change-bar-* on table elements.</p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master page-height="145mm" page-width="210mm" margin="10mm"
+ master-name="master">
+ <fo:region-body column-count="2" column-gap="10mm"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="master">
+ <fo:flow flow-name="xsl-region-body">
+
+ <fo:table change-bar-style="solid" change-bar-color="red" change-bar-offset="2mm"
+ change-bar-width="0.3mm">
+ <fo:table-header>
+ <fo:change-bar-begin change-bar-class="headerRow" change-bar-offset="0.1mm"
+ change-bar-color="green"/>
+ <fo:table-row>
+ <fo:table-cell id="header-row1-col1">
+ <fo:block>header-row1-col1</fo:block>
+ </fo:table-cell>
+ <fo:table-cell id="header-row1-col2">
+ <fo:block>header-row1-col2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:change-bar-end change-bar-class="headerRow"/>
+ <fo:table-row>
+ <fo:change-bar-begin change-bar-class="headerCell" change-bar-color="blue"/>
+ <fo:table-cell id="header-row2-col1">
+ <fo:block>header-row2-col1</fo:block>
+ </fo:table-cell>
+ <fo:change-bar-end change-bar-class="headerCell"/>
+ <fo:table-cell id="header-row2-col2">
+ <fo:change-bar-begin change-bar-class="headerCellBlock"
+ change-bar-offset="1mm"/>
+ <fo:block>header-row2-col2</fo:block>
+ <fo:change-bar-end change-bar-class="headerCellBlock"/>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-header>
+ <fo:change-bar-begin change-bar-class="footer"/>
+ <fo:table-footer>
+ <fo:table-row>
+ <fo:change-bar-begin change-bar-class="footerRow" change-bar-offset="3mm"
+ change-bar-color="green"/>
+ <fo:table-cell id="footer-row1-col1">
+ <fo:block>footer-row1-col1</fo:block>
+ </fo:table-cell>
+ <fo:change-bar-end change-bar-class="footerRow"/>
+ <fo:table-cell id="footer-row1-col2">
+ <fo:block>footer-row1-col2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell id="footer-row2-col1">
+ <fo:block>footer-row2-col1</fo:block>
+ </fo:table-cell>
+ <fo:table-cell id="footer-row2-col2">
+ <fo:block>footer-row2-col2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-footer>
+ <fo:change-bar-end change-bar-class="footer"/>
+ <fo:table-body>
+ <fo:change-bar-begin change-bar-class="bodyRow"/>
+ <fo:table-row>
+ <fo:table-cell id="body-row1-col1">
+ <fo:block>body-row1-col1</fo:block>
+ </fo:table-cell>
+ <fo:table-cell id="body-row1-col2">
+ <fo:block>body-row1-col2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:change-bar-end change-bar-class="bodyRow"/>
+ <fo:table-row>
+ <fo:change-bar-begin change-bar-class="bodyCell" change-bar-offset="0.1mm"
+ change-bar-color="blue"/>
+ <fo:table-cell id="body-row2-col1">
+ <fo:block>body-row2-col1</fo:block>
+ </fo:table-cell>
+ <fo:change-bar-end change-bar-class="bodyCell"/>
+ <fo:table-cell id="body-row2-col2">
+ <fo:change-bar-begin change-bar-class="bodyCellBlock"
+ change-bar-offset="1mm"/>
+ <fo:block>body-row2-col2</fo:block>
+ <fo:change-bar-end change-bar-class="bodyCellBlock"/>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <!-- header -->
+ <eval expected="(solid,#008000,850)" xpath="//block[@prod-id='header-row1-col1']/block[1]/block[1]/@border-start"/>
+ <eval expected="-1133" xpath="//block[@prod-id='header-row1-col1']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#008000,850)" xpath="//block[@prod-id='header-row1-col2']/block[1]/block[1]/@border-start"/>
+ <eval expected="-1133" xpath="//block[@prod-id='header-row1-col2']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#0000ff,850)" xpath="//block[@prod-id='header-row2-col1']/block[1]/block[1]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='header-row2-col1']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='header-row2-col2']/block[1]/block[1]/@border-start"/>
+ <eval expected="-3684" xpath="//block[@prod-id='header-row2-col2']/block[1]/block[1]/@left-offset"/>
+ <!-- body -->
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='body-row1-col1']/block[1]/block[1]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='body-row1-col1']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='body-row1-col2']/block[1]/block[1]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='body-row1-col2']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#0000ff,850)" xpath="//block[@prod-id='body-row2-col1']/block[1]/block[1]/@border-start"/>
+ <eval expected="-1133" xpath="//block[@prod-id='body-row2-col1']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='body-row2-col2']/block[1]/block[1]/@border-start"/>
+ <eval expected="-3684" xpath="//block[@prod-id='body-row2-col2']/block[1]/block[1]/@left-offset"/>
+ <!-- footer -->
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='footer-row1-col1']/block[1]/block[1]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='footer-row1-col1']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#008000,850)" xpath="//block[@prod-id='footer-row1-col1']/block[1]/block[2]/@border-start"/>
+ <eval expected="-9353" xpath="//block[@prod-id='footer-row1-col1']/block[1]/block[2]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='footer-row1-col2']/block[1]/block[1]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='footer-row1-col2']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='footer-row2-col1']/block[1]/block[1]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='footer-row2-col1']/block[1]/block[1]/@left-offset"/>
+ <eval expected="(solid,#ff0000,850)" xpath="//block[@prod-id='footer-row2-col2']/block[1]/block[1]/@border-start"/>
+ <eval expected="-6519" xpath="//block[@prod-id='footer-row2-col2']/block[1]/block[1]/@left-offset"/>
+ </checks>
+</testcase>