diff options
author | Simon Steiner <ssteiner@apache.org> | 2018-07-13 10:29:57 +0000 |
---|---|---|
committer | Simon Steiner <ssteiner@apache.org> | 2018-07-13 10:29:57 +0000 |
commit | e6748b4ed1522214915b2e3cd4df2db9f2b7b3b2 (patch) | |
tree | b75f62ef1a16e363f01b0ddc2cb7f4daf9ad587d | |
parent | a53d9972f9aa1f7dcff8db4a0922113f6974681f (diff) | |
download | xmlgraphics-fop-e6748b4ed1522214915b2e3cd4df2db9f2b7b3b2.tar.gz xmlgraphics-fop-e6748b4ed1522214915b2e3cd4df2db9f2b7b3b2.zip |
FOP-1760: Add change bar generation
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1835810 13f79535-47bb-0310-9956-ffa450edef68
55 files changed, 2274 insertions, 20 deletions
diff --git a/fop-core/src/main/java/org/apache/fop/area/Area.java b/fop-core/src/main/java/org/apache/fop/area/Area.java index 895367c19..87f645dd2 100644 --- a/fop-core/src/main/java/org/apache/fop/area/Area.java +++ b/fop-core/src/main/java/org/apache/fop/area/Area.java @@ -20,12 +20,14 @@ package org.apache.fop.area; import java.io.Serializable; +import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.fo.flow.ChangeBar; import org.apache.fop.traits.BorderProps; import org.apache.fop.traits.WritingModeTraitsGetter; @@ -129,6 +131,29 @@ public class Area extends AreaTreeObject implements Serializable { 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. * * @return the area class diff --git a/fop-core/src/main/java/org/apache/fop/area/AreaTreeParser.java b/fop-core/src/main/java/org/apache/fop/area/AreaTreeParser.java index 41563a85e..587e8e449 100644 --- a/fop-core/src/main/java/org/apache/fop/area/AreaTreeParser.java +++ b/fop-core/src/main/java/org/apache/fop/area/AreaTreeParser.java @@ -66,6 +66,7 @@ import org.apache.fop.area.inline.Container; import org.apache.fop.area.inline.ForeignObject; import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.InlineBlock; import org.apache.fop.area.inline.InlineBlockParent; import org.apache.fop.area.inline.InlineParent; import org.apache.fop.area.inline.InlineViewport; @@ -80,6 +81,7 @@ import org.apache.fop.fo.extensions.ExtensionAttachment; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.traits.BorderProps; +import org.apache.fop.traits.Direction; import org.apache.fop.traits.Visibility; import org.apache.fop.util.ColorUtil; import org.apache.fop.util.ContentHandlerFactory; @@ -190,6 +192,7 @@ public class AreaTreeParser { makers.put("block", new BlockMaker()); makers.put("lineArea", new LineAreaMaker()); makers.put("inline", new InlineMaker()); + makers.put("inlineblock", new InlineBlockMaker()); makers.put("inlineparent", new InlineParentMaker()); makers.put("inlineblockparent", new InlineBlockParentMaker()); makers.put("text", new TextMaker()); @@ -594,6 +597,17 @@ public class AreaTreeParser { BodyRegion body = getCurrentBodyRegion(); Span span = new Span(columnCount, body.getColumnGap(), ipd); + + String blockDirection = attributes.getValue("block-progression-direction"); + if (blockDirection != null) { + span.addTrait(Trait.BLOCK_PROGRESSION_DIRECTION, Direction.valueOf(blockDirection)); + } + + String inlineDirection = attributes.getValue("inline-progression-direction"); + if (inlineDirection != null) { + span.addTrait(Trait.INLINE_PROGRESSION_DIRECTION, Direction.valueOf(inlineDirection)); + } + transferForeignObjects(attributes, span); setAreaAttributes(attributes, span); body.getMainReference().getSpans().add(span); @@ -723,6 +737,34 @@ public class AreaTreeParser { } } + private class InlineBlockMaker extends AbstractMaker { + + public void startElement(Attributes attributes) { + + Block block = new Block(); + + if (attributes.getValue("left-offset") != null) { + block.setXOffset(XMLUtil.getAttributeAsInt(attributes, "left-offset", 0)); + } + if (attributes.getValue("top-offset") != null) { + block.setYOffset(XMLUtil.getAttributeAsInt(attributes, "top-offset", 0)); + } + transferForeignObjects(attributes, block); + setAreaAttributes(attributes, block); + setTraits(attributes, block, SUBSET_COMMON); + setTraits(attributes, block, SUBSET_BOX); + setTraits(attributes, block, SUBSET_COLOR); + Area parent = (Area)areaStack.peek(); + InlineBlock inlineBlock = new InlineBlock(block); + parent.addChildArea(inlineBlock); + areaStack.push(inlineBlock); + } + + public void endElement() { + assertObjectOfClass(areaStack.pop(), InlineBlock.class); + } + } + private class InlineParentMaker extends AbstractMaker { public void startElement(Attributes attributes) { diff --git a/fop-core/src/main/java/org/apache/fop/area/Span.java b/fop-core/src/main/java/org/apache/fop/area/Span.java index 41610f355..9fa22c6fd 100644 --- a/fop-core/src/main/java/org/apache/fop/area/Span.java +++ b/fop-core/src/main/java/org/apache/fop/area/Span.java @@ -82,6 +82,15 @@ public class Span extends Area { } /** + * 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 * * @return the width of a single column @@ -206,6 +215,8 @@ public class Span extends Area { } break; } + addTrait(Trait.INLINE_PROGRESSION_DIRECTION, wmtg.getInlineProgressionDirection()); + addTrait(Trait.BLOCK_PROGRESSION_DIRECTION, wmtg.getBlockProgressionDirection()); } /** {@inheritDoc} */ diff --git a/fop-core/src/main/java/org/apache/fop/area/inline/InlineBlock.java b/fop-core/src/main/java/org/apache/fop/area/inline/InlineBlock.java new file mode 100644 index 000000000..9b5f96708 --- /dev/null +++ b/fop-core/src/main/java/org/apache/fop/area/inline/InlineBlock.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.area.inline; + +import org.apache.fop.area.Block; + +/** + * This is the inline block area class. + * It wraps the child block when it has to be placed into inline parent. + */ +public class InlineBlock extends InlineParent { + + private static final long serialVersionUID = -3725062353292109517L; + private final Block block; + + public InlineBlock(Block block) { + this.block = block; + } + + /** + * @return the wrapped block + */ + public Block getBlock() { + return block; + } +} diff --git a/fop-core/src/main/java/org/apache/fop/area/inline/TextArea.java b/fop-core/src/main/java/org/apache/fop/area/inline/TextArea.java index 3081a38eb..a03e536ce 100644 --- a/fop-core/src/main/java/org/apache/fop/area/inline/TextArea.java +++ b/fop-core/src/main/java/org/apache/fop/area/inline/TextArea.java @@ -95,6 +95,7 @@ public class TextArea extends AbstractTextArea { WordArea wordArea = new WordArea( blockProgressionOffset, minWordLevel, word, letterAdjust, levels, gposAdjustments); wordArea.setIPD(ipd); + wordArea.setChangeBarList(getChangeBarList()); addChildArea(wordArea); wordArea.setParentArea(this); updateLevel(minWordLevel); @@ -113,6 +114,7 @@ public class TextArea extends AbstractTextArea { char space, int ipd, boolean adjustable, int blockProgressionOffset, int level) { SpaceArea spaceArea = new SpaceArea(blockProgressionOffset, level, space, adjustable); spaceArea.setIPD(ipd); + spaceArea.setChangeBarList(getChangeBarList()); addChildArea(spaceArea); spaceArea.setParentArea(this); updateLevel(level); diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOElementMapping.java b/fop-core/src/main/java/org/apache/fop/fo/FOElementMapping.java index b087e1d9c..8bf92c2b3 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/FOElementMapping.java +++ b/fop-core/src/main/java/org/apache/fop/fo/FOElementMapping.java @@ -141,6 +141,10 @@ public class FOElementMapping extends ElementMapping { foObjs.put("marker", new MarkerMaker()); foObjs.put("retrieve-marker", new RetrieveMarkerMaker()); foObjs.put("retrieve-table-marker", new RetrieveTableMarkerMaker()); + + // change bars + foObjs.put("change-bar-begin", new ChangeBarBeginMaker()); + foObjs.put("change-bar-end", new ChangeBarEndMaker()); } } @@ -527,4 +531,16 @@ public class FOElementMapping extends ElementMapping { return new org.apache.fop.fo.flow.RetrieveTableMarker(parent); } } + + static class ChangeBarBeginMaker extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.ChangeBarBegin(parent); + } + } + + static class ChangeBarEndMaker extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.ChangeBarEnd(parent); + } + } } diff --git a/fop-core/src/main/java/org/apache/fop/fo/FONode.java b/fop-core/src/main/java/org/apache/fop/fo/FONode.java index b4e0ec0fe..f3c582dd5 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/FONode.java +++ b/fop-core/src/main/java/org/apache/fop/fo/FONode.java @@ -20,6 +20,7 @@ package org.apache.fop.fo; // Java +import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Stack; @@ -42,6 +43,7 @@ import org.apache.fop.fo.extensions.ExtensionAttachment; import org.apache.fop.fo.extensions.ExtensionElementMapping; import org.apache.fop.fo.extensions.InternalElementMapping; import org.apache.fop.fo.extensions.svg.SVGElementMapping; +import org.apache.fop.fo.flow.ChangeBar; import org.apache.fop.fo.pagination.Root; import org.apache.fop.util.CharUtilities; import org.apache.fop.util.ContentHandlerFactory; @@ -63,6 +65,12 @@ public abstract class FONode implements Cloneable { /** pointer to the sibling nodes */ protected FONode[] siblings; + /** The list of active change bars for the given node */ + protected List<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>, @@ -174,6 +182,18 @@ public abstract class FONode implements Cloneable { } /** + * 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>. * @@ -1083,6 +1103,15 @@ public abstract class FONode implements Cloneable { } /** + * 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. * * @param structureTreeElement set. diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java b/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java index da92cc834..0b8da47cc 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java +++ b/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java @@ -322,6 +322,7 @@ public final class FOPropertyMapping implements Constants { gp.createTableProperties(); gp.createWritingModeProperties(); gp.createMiscProperties(); + gp.createChangeBarProperties(); // Hardcode the subproperties. addSubpropMakerName("length", CP_LENGTH); @@ -2588,6 +2589,56 @@ public final class FOPropertyMapping implements Constants { addPropertyMaker("writing-mode", m); } + private void createChangeBarProperties() { + PropertyMaker m; + + // change-bar-class + m = new StringProperty.Maker(PR_CHANGE_BAR_CLASS); + m.setInherited(false); + m.setDefault(""); + addPropertyMaker("change-bar-class", m); + + // change-bar-color + m = new ColorProperty.Maker(PR_CHANGE_BAR_COLOR); + + m.setInherited(true); + // TODO: fall back to "color" property + m.setDefault("black"); + addPropertyMaker("change-bar-color", m); + + // change-bar-placement + m = new EnumProperty.Maker(PR_CHANGE_BAR_PLACEMENT); + m.setInherited(true); + m.setDefault("start"); + m.addEnum("start", getEnumProperty(EN_START, "START")); + m.addEnum("end", getEnumProperty(EN_END, "END")); + m.addEnum("left", getEnumProperty(EN_LEFT, "LEFT")); + m.addEnum("right", getEnumProperty(EN_RIGHT, "RIGHT")); + m.addEnum("inside", getEnumProperty(EN_INSIDE, "INSIDE")); + m.addEnum("outside", getEnumProperty(EN_OUTSIDE, "OUTSIDE")); + m.addEnum("alternate", getEnumProperty(EN_ALTERNATE, "ALTERNATE")); + addPropertyMaker("change-bar-placement", m); + + // change-bar-style + m = new EnumProperty.Maker(PR_CHANGE_BAR_STYLE); + m.useGeneric(genericBorderStyle); + m.setInherited(true); + m.setDefault("solid"); + addPropertyMaker("change-bar-style", m); + + // change-bar-width + m = new LengthProperty.Maker(PR_CHANGE_BAR_WIDTH); + m.setInherited(true); + m.setDefault("6pt"); + addPropertyMaker("change-bar-width", m); + + // change-bar-offset + m = new LengthProperty.Maker(PR_CHANGE_BAR_OFFSET); + m.setInherited(true); + m.setDefault("6pt"); + addPropertyMaker("change-bar-offset", m); + } + private void createMiscProperties() { PropertyMaker m; diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOText.java b/fop-core/src/main/java/org/apache/fop/fo/FOText.java index 563d96993..207c3184c 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/FOText.java +++ b/fop-core/src/main/java/org/apache/fop/fo/FOText.java @@ -33,6 +33,7 @@ import org.apache.fop.apps.FOPException; import org.apache.fop.complexscripts.bidi.DelimitedTextRange; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.flow.Block; +import org.apache.fop.fo.pagination.PageSequence; import org.apache.fop.fo.properties.CommonFont; import org.apache.fop.fo.properties.CommonHyphenation; import org.apache.fop.fo.properties.CommonTextDecoration; @@ -109,6 +110,11 @@ public class FOText extends FONode implements CharSequence, TextFragment { */ public FOText(FONode parent) { super(parent); + + PageSequence pageSequence = getRoot().getLastPageSequence(); + if (pageSequence != null && pageSequence.hasChangeBars()) { + nodeChangeBarList = getRoot().getLastPageSequence().getClonedChangeBarList(); + } } /** {@inheritDoc} */ diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOTreeBuilder.java b/fop-core/src/main/java/org/apache/fop/fo/FOTreeBuilder.java index e3afbbb75..249f0e0fe 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/FOTreeBuilder.java +++ b/fop-core/src/main/java/org/apache/fop/fo/FOTreeBuilder.java @@ -273,7 +273,9 @@ public class FOTreeBuilder extends DefaultHandler { if (currentFObj.getNamespaceURI().equals(FOElementMapping.URI) || currentFObj.getNamespaceURI().equals(ExtensionElementMapping.URI) || currentFObj.getNamespaceURI().equals(PDFElementMapping.NAMESPACE)) { - currentFObj.validateChildNode(locator, namespaceURI, localName); + if (!currentFObj.isChangeBarElement(namespaceURI, localName)) { + currentFObj.validateChildNode(locator, namespaceURI, localName); + } } } diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOValidationEventProducer.java b/fop-core/src/main/java/org/apache/fop/fo/FOValidationEventProducer.java index a96cb3fe3..452a9f563 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/FOValidationEventProducer.java +++ b/fop-core/src/main/java/org/apache/fop/fo/FOValidationEventProducer.java @@ -382,6 +382,47 @@ public interface FOValidationEventProducer extends EventProducer { 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. * * @param source the event source diff --git a/fop-core/src/main/java/org/apache/fop/fo/FObj.java b/fop-core/src/main/java/org/apache/fop/fo/FObj.java index fc105e7e6..f57e59bd1 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/FObj.java +++ b/fop-core/src/main/java/org/apache/fop/fo/FObj.java @@ -21,6 +21,7 @@ package org.apache.fop.fo; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -34,7 +35,9 @@ import org.apache.xmlgraphics.util.QName; import org.apache.fop.apps.FOPException; import org.apache.fop.fo.extensions.ExtensionAttachment; +import org.apache.fop.fo.flow.ChangeBar; import org.apache.fop.fo.flow.Marker; +import org.apache.fop.fo.pagination.PageSequence; import org.apache.fop.fo.properties.Property; import org.apache.fop.fo.properties.PropertyMaker; @@ -182,6 +185,39 @@ public abstract class FObj extends FONode implements Constants { if (id != null) { checkId(id); } + + PageSequence pageSequence = getRoot().getLastPageSequence(); + if (pageSequence != null && pageSequence.hasChangeBars()) { + startOfNodeChangeBarList = pageSequence.getClonedChangeBarList(); + } + } + + /** + * {@inheritDoc} + * @throws FOPException FOP Exception + */ + public void endOfNode() throws FOPException { + + List<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(); } /** @@ -492,6 +528,8 @@ public abstract class FObj extends FONode implements Constants { protected boolean isInlineItem(String nsURI, String lName) { return (FO_URI.equals(nsURI) && ("bidi-override".equals(lName) + || "change-bar-begin".equals(lName) + || "change-bar-end".equals(lName) || "character".equals(lName) || "external-graphic".equals(lName) || "instream-foreign-object".equals(lName) diff --git a/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBar.java b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBar.java new file mode 100644 index 000000000..5fa12346b --- /dev/null +++ b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBar.java @@ -0,0 +1,214 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.flow; + +import java.awt.Color; + +import org.xml.sax.Attributes; +import org.xml.sax.Locator; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.datatypes.Length; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.StaticPropertyList; +import org.apache.fop.fo.ValidationException; +import org.apache.fop.fo.properties.SpaceProperty; + +/** + * Common change bar base class. Handles change bar properties and validates child nodes. + */ +public abstract class ChangeBar extends FObj { + + /** + * Constructs a ChangeBar element with common parts for both begin and end change bars. + * + * @param parent The parent node + */ + public ChangeBar(FONode parent) { + super(parent); + } + + /** + * The change bar class (required). + */ + protected String changeBarClass; + + /** + * The change bar color. + */ + protected Color color; + + /** + * The change bar offset. + */ + protected Length offset; + + /** + * The change bar placement. + */ + protected int placement = -1; + + /** + * The change bar style. + */ + protected int style = -1; + + /** + * The change bar width. + */ + protected Length width; + + /** + * The actual line height. + */ + protected SpaceProperty lineHeight; + + /** {@inheritDoc} */ + public void bind(PropertyList pList) throws FOPException { + super.bind(pList); + + changeBarClass = pList.get(PR_CHANGE_BAR_CLASS).getString(); + color = pList.get(PR_CHANGE_BAR_COLOR).getColor(getUserAgent()); + offset = pList.get(PR_CHANGE_BAR_OFFSET).getLength(); + placement = pList.get(PR_CHANGE_BAR_PLACEMENT).getEnum(); + style = pList.get(PR_CHANGE_BAR_STYLE).getEnum(); + width = pList.get(PR_CHANGE_BAR_WIDTH).getLength(); + lineHeight = pList.get(PR_LINE_HEIGHT).getSpace(); + } + + /** {@inheritDoc} */ + protected void validateChildNode( + Locator loc, + String namespaceURI, + String localName) throws ValidationException { + // no children allowed + invalidChildError(loc, namespaceURI, localName); + } + + /** {@inheritDoc} */ + public void processNode(String elementName, Locator locator, + Attributes attlist, PropertyList pList) throws FOPException { + super.processNode(elementName, locator, attlist, pList); + + if (inMarker()) { + PropertyList newPList = new StaticPropertyList(this, null); + newPList.addAttributesToList(attlist); + bind(newPList); + } + + if (changeBarClass == null || changeBarClass.isEmpty()) { + missingPropertyError("change-bar-class"); + } + + if (findAncestor(FO_FLOW) == -1 + && findAncestor(FO_STATIC_CONTENT) == -1) { + getFOValidationEventProducer().changeBarWrongAncestor(this, getName(), locator); + } + } + + /** + * Adds the current change bar to the active change bar list. + */ + protected void push() { + getRoot().getLastPageSequence().pushChangeBar(this); + } + + /** + * Removes the starting counterpart of the current change bar from the active change bar list. + */ + protected void pop() { + getRoot().getLastPageSequence().popChangeBar(this); + } + + /** + * Returns the starting counterpart of the current (ending) change bar. + * + * @return The starting counterpart of the current (ending) change bar + */ + protected ChangeBar getChangeBarBegin() { + return getRoot().getLastPageSequence().getChangeBarBegin(this); + } + + /** + * Returns the change bar class. + * + * @return The change bar class + */ + public String getChangeBarClass() { + return changeBarClass; + } + + /** + * Returns the change bar color. + * + * @return The change bar color + */ + public Color getColor() { + return color; + } + + /** + * Returns the change bar offset. + * + * @return The change bar offset + */ + public Length getOffset() { + return offset; + } + + /** + * Returns the change bar placement. + * + * @return The change bar placement + */ + public int getPlacement() { + return placement; + } + + /** + * Returns the change bar style. + * + * @return The change bar style + */ + public int getStyle() { + return style; + } + + /** + * Returns the change bar width. + * + * @return The change bar width + */ + public Length getWidth() { + return width; + } + + /** + * Returns the line height. + * + * @return The line height + */ + public SpaceProperty getLineHeight() { + return lineHeight; + } + +} diff --git a/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarBegin.java b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarBegin.java new file mode 100644 index 000000000..961a0e37f --- /dev/null +++ b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarBegin.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.flow; + +import org.xml.sax.Attributes; +import org.xml.sax.Locator; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.PropertyList; + +public class ChangeBarBegin extends ChangeBar { + + /** + * Constructs a new ChangeBarBegin element. + * + * @param parent The parent node + */ + public ChangeBarBegin(FONode parent) { + super(parent); + } + + /** {@inheritDoc} */ + public String getLocalName() { + return "change-bar-begin"; + } + + /** + * {@inheritDoc} + * @return {@link org.apache.fop.fo.Constants#FO_CHANGE_BAR_BEGIN} + */ + public int getNameId() { + return FO_CHANGE_BAR_BEGIN; + } + + /** {@inheritDoc} */ + public void processNode(String elementName, Locator locator, + Attributes attlist, PropertyList pList) throws FOPException { + super.processNode(elementName, locator, attlist, pList); + + push(); + } +} diff --git a/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarEnd.java b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarEnd.java new file mode 100644 index 000000000..4feca13a6 --- /dev/null +++ b/fop-core/src/main/java/org/apache/fop/fo/flow/ChangeBarEnd.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.flow; + +import org.xml.sax.Attributes; +import org.xml.sax.Locator; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.PropertyList; + +public class ChangeBarEnd extends ChangeBar { + + /** + * Constructs a new ChangeBarEnd element. + * + * @param parent The parent node + */ + public ChangeBarEnd(FONode parent) { + super(parent); + } + + /** {@inheritDoc} */ + public String getLocalName() { + return "change-bar-end"; + } + + /** + * {@inheritDoc} + * @return {@link org.apache.fop.fo.Constants#FO_CHANGE_BAR_END} + */ + public int getNameId() { + return FO_CHANGE_BAR_END; + } + + /** {@inheritDoc} */ + public void processNode(String elementName, Locator locator, + Attributes attlist, PropertyList pList) throws FOPException { + super.processNode(elementName, locator, attlist, pList); + + // check if we have an element on the stack at all + ChangeBar changeBarStart = getChangeBarBegin(); + + if (changeBarStart == null) { + getFOValidationEventProducer().changeBarNoBegin(this, getName(), locator); + } else { + pop(); + } + } +} diff --git a/fop-core/src/main/java/org/apache/fop/fo/flow/table/TableRow.java b/fop-core/src/main/java/org/apache/fop/fo/flow/table/TableRow.java index 2beaf2f99..024b77905 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/flow/table/TableRow.java +++ b/fop-core/src/main/java/org/apache/fop/fo/flow/table/TableRow.java @@ -90,9 +90,11 @@ public class TableRow extends TableCellContainer implements BreakPropertySet { /** {@inheritDoc} */ protected void addChildNode(FONode child) throws FOPException { if (!inMarker()) { - TableCell cell = (TableCell) child; - TablePart part = (TablePart) getParent(); - addTableCellChild(cell, part.isFirst(this)); + if (child instanceof TableCell) { + TableCell cell = (TableCell) child; + TablePart part = (TablePart) getParent(); + addTableCellChild(cell, part.isFirst(this)); + } } super.addChildNode(child); } diff --git a/fop-core/src/main/java/org/apache/fop/fo/pagination/PageSequence.java b/fop-core/src/main/java/org/apache/fop/fo/pagination/PageSequence.java index a1a966e90..3f82e6822 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/pagination/PageSequence.java +++ b/fop-core/src/main/java/org/apache/fop/fo/pagination/PageSequence.java @@ -19,6 +19,8 @@ package org.apache.fop.fo.pagination; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Stack; @@ -31,6 +33,7 @@ import org.apache.fop.datatypes.Numeric; import org.apache.fop.fo.FONode; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; +import org.apache.fop.fo.flow.ChangeBar; import org.apache.fop.fo.properties.CommonHyphenation; import org.apache.fop.traits.Direction; import org.apache.fop.traits.WritingMode; @@ -78,6 +81,11 @@ public class PageSequence extends AbstractPageSequence implements WritingModeTra 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}. * @@ -118,6 +126,7 @@ public class PageSequence extends AbstractPageSequence implements WritingModeTra masterReference, getLocator()); } } + getRoot().addPageSequence(this); getFOEventHandler().startPageSequence(this); } @@ -464,4 +473,73 @@ public class PageSequence extends AbstractPageSequence implements WritingModeTra return pageSequenceMaster.getLastSimplePageMaster(isOddPage, isFirstPage, isBlank, getMainFlow() .getFlowName()); } + + /** + * Adds the specified change bar to the active change bar list. + * + * @param changeBarBegin The starting change bar element + */ + public void pushChangeBar(ChangeBar changeBarBegin) { + changeBarList.add(changeBarBegin); + } + + /** + * Removes the couple of the specified change bar from the active change bar list. + * + * @param changeBarEnd The ending change bar element + */ + public void popChangeBar(ChangeBar changeBarEnd) { + ChangeBar changeBarBegin = getChangeBarBegin(changeBarEnd); + if (changeBarBegin != null) { + changeBarList.remove(changeBarBegin); + } + } + + /** + * Returns the starting counterpart of the specified ending change bar. + * + * @param changeBarEnd The ending change bar element + * @return The starting counterpart of the specified ending change bar + */ + public ChangeBar getChangeBarBegin(ChangeBar changeBarEnd) { + if (changeBarList.isEmpty()) { + return null; + } else { + String changeBarClass = changeBarEnd.getChangeBarClass(); + for (int i = changeBarList.size() - 1; i >= 0; i--) { + ChangeBar changeBar = changeBarList.get(i); + if (changeBar.getChangeBarClass().equals(changeBarClass)) { + return changeBar; + } + } + } + return null; + } + + /** + * Tests if there are any active change bars. + * + * @return A boolean value true if there are any active change bars + */ + public boolean hasChangeBars() { + return !changeBarList.isEmpty(); + } + + /** + * Returns the list of active change bars. + * + * @return The list of active change bars + */ + public List<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); + } } diff --git a/fop-core/src/main/java/org/apache/fop/fo/pagination/Root.java b/fop-core/src/main/java/org/apache/fop/fo/pagination/Root.java index 51309a65d..3b895b372 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/pagination/Root.java +++ b/fop-core/src/main/java/org/apache/fop/fo/pagination/Root.java @@ -282,6 +282,28 @@ public class Root extends FObj implements CommonAccessibilityHolder { } /** + * Adds the specified page sequence. + * + * @param pageSequence The page sequence to add + */ + public void addPageSequence(PageSequence pageSequence) { + pageSequences.add(pageSequence); + } + + /** + * Returns the last page sequence (current while parsing). + * + * @return The last page sequence or null + */ + public PageSequence getLastPageSequence() { + if (getPageSequenceCount() > 0) { + return pageSequences.get(getPageSequenceCount() - 1); + } else { + return null; + } + } + + /** * Returns the associated LayoutMasterSet. * @return the LayoutMasterSet instance */ diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java index b687689bc..ca5d1c507 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java @@ -28,6 +28,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.datatypes.LengthBase; import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.fo.FObj; +import org.apache.fop.fo.flow.ChangeBar; /** * The base class for nearly all LayoutManagers. @@ -257,6 +258,19 @@ public abstract class AbstractBaseLayoutManager return fobj; } + /** + * Returns the active change bar list. + * + * @return The active change bar list + */ + public List<ChangeBar> getChangeBarList() { + if (fobj == null) { + return null; + } else { + return fobj.getChangeBarList(); + } + } + /** {@inheritDoc} */ public void reset() { throw new UnsupportedOperationException("Not implemented"); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java index 9ce113d11..f0fc77577 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -854,6 +854,7 @@ public class BlockContainerLayoutManager extends SpacedBorderedPaddedBlockLayout int level = getBlockContainerFO().getBidiLevel(); viewportBlockArea = new BlockViewport(allowBPDUpdate); + viewportBlockArea.setChangeBarList(getChangeBarList()); viewportBlockArea.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE); if (level >= 0) { viewportBlockArea.setBidiLevel(level); @@ -892,6 +893,7 @@ public class BlockContainerLayoutManager extends SpacedBorderedPaddedBlockLayout } referenceArea = new Block(); + referenceArea.setChangeBarList(getChangeBarList()); referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE); if (level >= 0) { referenceArea.setBidiLevel(level); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index 722a011ae..ac0da5f6a 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -357,6 +357,7 @@ public class BlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); + curBlockArea.setChangeBarList(getChangeBarList()); curBlockArea.setIPD(super.getContentAreaIPD()); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index b8714a570..6069dbcc3 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -124,6 +124,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager int sp = TraitSetter.getEffectiveSpace(adjust, minoptmax); if (sp != 0) { Block spacer = new Block(); + spacer.setChangeBarList(getChangeBarList()); spacer.setBPD(sp); parentLayoutManager.addChildArea(spacer); } diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java index aae5a6b30..06ad4eeba 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java @@ -178,6 +178,7 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan Dimension imageSize = this.imageLayout.getViewportSize(); Block blockArea = new Block(); + blockArea.setChangeBarList(getChangeBarList()); blockArea.setIPD(imageSize.width); LineArea lineArea = new LineArea(); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java index e95cd18ec..3a706a325 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java @@ -39,6 +39,8 @@ import org.apache.fop.fo.flow.BasicLink; import org.apache.fop.fo.flow.BidiOverride; import org.apache.fop.fo.flow.Block; import org.apache.fop.fo.flow.BlockContainer; +import org.apache.fop.fo.flow.ChangeBarBegin; +import org.apache.fop.fo.flow.ChangeBarEnd; import org.apache.fop.fo.flow.Character; import org.apache.fop.fo.flow.ExternalGraphic; import org.apache.fop.fo.flow.Float; @@ -146,6 +148,8 @@ public class LayoutManagerMapping implements LayoutManagerMaker { registerMaker(TableHeader.class, new Maker()); registerMaker(Wrapper.class, new WrapperLayoutManagerMaker()); registerMaker(Title.class, new InlineLayoutManagerMaker()); + registerMaker(ChangeBarBegin.class, new Maker()); + registerMaker(ChangeBarEnd.class, new Maker()); registerMaker(MultiCase.class, new MultiCaseLayoutManagerMaker()); registerMaker(MultiSwitch.class, new MultiSwitchLayoutManagerMaker()); registerMaker(Float.class, new FloatLayoutManagerMaker()); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java index 2e1b7f2ae..c06ec522a 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java @@ -133,6 +133,7 @@ public abstract class AbstractPageNumberCitationLayoutManager extends LeafNodeLa getPSLM().addUnresolvedArea(citation.getRefId(), unresolved); text = unresolved; } + text.setChangeBarList(getChangeBarList()); setTraits(text); return text; } diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java index c959ee7be..3f68df0e2 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java @@ -75,6 +75,7 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { private TextArea createCharacterArea() { Character fobj = (Character) this.fobj; TextArea text = new TextArea(); + text.setChangeBarList(getChangeBarList()); char ch = fobj.getCharacter(); int ipd = font.getCharWidth(ch); int blockProgressionOffset = 0; diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java index af1664981..a5f128f85 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java @@ -84,6 +84,7 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager // get breaks then add areas to title this.parentLM = pslm; holder = new LineArea(); + holder.setChangeBarList(getChangeBarList()); // setUserAgent(foTitle.getUserAgent()); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java index 2719d5c96..8a204607e 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java @@ -42,7 +42,9 @@ public class ExternalGraphicLayoutManager extends AbstractGraphicsLayoutManager /** {@inheritDoc} */ protected Area getChildArea() { - return new Image(((ExternalGraphic) fobj).getSrc()); + Image im = new Image(((ExternalGraphic) fobj).getSrc()); + im.setChangeBarList(getChangeBarList()); + return im; } } diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java index df37b9902..85f545e5e 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java @@ -206,9 +206,11 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { InlineArea area; if (isInline) { area = createInlineParent(); + area.setChangeBarList(getChangeBarList()); area.setBlockProgressionOffset(0); } else { area = new InlineBlockParent(); + area.setChangeBarList(getChangeBarList()); } if (fobj instanceof Inline || fobj instanceof BasicLink) { TraitSetter.setProducerID(area, fobj.getId()); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java index 5b9efa43e..7a8ac8627 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java @@ -181,6 +181,7 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager if (iAdjust != 0) { //getLogger().debug("Add leading space: " + iAdjust); Space ls = new Space(); + ls.setChangeBarList(getChangeBarList()); ls.setIPD(iAdjust); int level = parentArea.getBidiLevel(); if (level >= 0) { diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InstreamForeignObjectLM.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InstreamForeignObjectLM.java index 4a54f582d..6936e3e94 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InstreamForeignObjectLM.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/InstreamForeignObjectLM.java @@ -46,7 +46,9 @@ public class InstreamForeignObjectLM extends AbstractGraphicsLayoutManager { org.w3c.dom.Document doc = child.getDOMDocument(); String ns = child.getNamespaceURI(); - return new ForeignObject(doc, ns); + ForeignObject obj = new ForeignObject(doc, ns); + obj.setChangeBarList(getChangeBarList()); + return obj; } } diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java index 5f65a5969..a6d695b06 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java @@ -217,6 +217,10 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { leaderArea.setBidiLevel(fobj.getBidiLevelRecursive()); } } + + assert leaderArea != null; + leaderArea.setChangeBarList(getChangeBarList()); + TraitSetter.setProducerID(leaderArea, fobj.getId()); return leaderArea; } diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index 8ee5d1e70..c15c1d0be 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -1504,6 +1504,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager LineArea lineArea = new LineArea( (lbp.getLeafPos() < seq.size() - 1 ? textAlignment : textAlignmentLast), lbp.difference, lbp.availableStretch, lbp.availableShrink); + lineArea.setChangeBarList(getChangeBarList()); + if (lbp.startIndent != 0) { lineArea.addTrait(Trait.START_INDENT, lbp.startIndent); } @@ -1619,6 +1621,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager } LineArea lineArea = new LineArea(); + lineArea.setChangeBarList(getChangeBarList()); setCurrentArea(lineArea); LayoutContext lc = LayoutContext.newInstance(); lc.setAlignmentContext(alignmentContext); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java index 27bd544dd..3134ebb17 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java @@ -32,6 +32,7 @@ import org.apache.fop.area.Trait; import org.apache.fop.area.inline.TextArea; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FOText; +import org.apache.fop.fo.flow.ChangeBar; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontSelector; import org.apache.fop.fonts.GlyphMapping; @@ -312,6 +313,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstMappingIndex, lastMappingIndex, context.isLastArea(), mapping.font).build(); + textArea.setChangeBarList(getChangeBarList()); // wordSpaceDim is computed in relation to wordSpaceIPD.opt // but the renderer needs to know the adjustment in relation @@ -411,6 +413,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { textArea = new TextArea(width.getStretch(), width.getShrink(), adjust); } + textArea.setChangeBarList(getChangeBarList()); } private void setInlineProgressionDimension() { @@ -1457,6 +1460,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } + @Override + public List<ChangeBar> getChangeBarList() { + if (foText == null) { + return null; + } else { + return foText.getChangeBarList(); + } + } + /** {@inheritDoc} */ public String toString() { return super.toString() + "{" diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java index 9b37e2405..ff2c59f4a 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java @@ -68,10 +68,12 @@ public class WrapperLayoutManager extends LeafNodeLayoutManager { if (parentLayoutManager instanceof BlockStackingLayoutManager && !(parentLayoutManager instanceof BlockLayoutManager)) { Block helperBlock = new Block(); + helperBlock.setChangeBarList(getChangeBarList()); TraitSetter.setProducerID(helperBlock, fobj.getId()); parentLayoutManager.addChildArea(helperBlock); } else { InlineArea area = getEffectiveArea(context); + area.setChangeBarList(getChangeBarList()); parentLayoutManager.addChildArea(area); } } diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java index d39b63477..b73abeb0d 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java @@ -216,6 +216,7 @@ public class ListBlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManag public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); + curBlockArea.setChangeBarList(getChangeBarList()); // Set up dimensions // Must get dimensions from parent area diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java index 214ba6269..0cc877e37 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java @@ -176,6 +176,7 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager imp public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); + curBlockArea.setChangeBarList(getChangeBarList()); curBlockArea.setPositioning(Block.ABSOLUTE); // set position curBlockArea.setXOffset(xOffset); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java index 9d9769a7c..764575ac8 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java @@ -739,6 +739,7 @@ public class ListItemLayoutManager extends SpacedBorderedPaddedBlockLayoutManage public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); + curBlockArea.setChangeBarList(getChangeBarList()); // Set up dimensions /*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/RowPainter.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/RowPainter.java index cbc19c1ec..06dda5efe 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/RowPainter.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/RowPainter.java @@ -468,6 +468,7 @@ class RowPainter { //generate the block area Block block = new Block(); + block.setChangeBarList(tclm.getTableLM().getFObj().getChangeBarList()); block.setPositioning(Block.ABSOLUTE); block.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE); block.setIPD(ipd); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java index aaa896ce3..d95e508c5 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java @@ -179,6 +179,8 @@ public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager { public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); + curBlockArea.setChangeBarList(getChangeBarList()); + // Set up dimensions // Must get dimensions from parent area Area parentArea = parentLayoutManager.getParentArea(curBlockArea); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java index 8823c0fae..ee4cba2e4 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java @@ -175,6 +175,8 @@ public class TableCaptionLayoutManager extends BlockStackingLayoutManager { public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); + curBlockArea.setChangeBarList(getChangeBarList()); + // Set up dimensions // Must get dimensions from parent area Area parentArea = parentLayoutManager.getParentArea(curBlockArea); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java index cfa064db6..a56b00ce7 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java @@ -529,11 +529,13 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager { if (usedBPD < cellBPD) { if (getTableCell().getDisplayAlign() == EN_CENTER) { Block space = new Block(); + space.setChangeBarList(getChangeBarList()); space.setBPD((cellBPD - usedBPD) / 2); space.setBidiLevel(getTableCell().getBidiLevelRecursive()); curBlockArea.addBlock(space); } else if (getTableCell().getDisplayAlign() == EN_AFTER) { Block space = new Block(); + space.setChangeBarList(getChangeBarList()); space.setBPD(cellBPD - usedBPD); space.setBidiLevel(getTableCell().getBidiLevelRecursive()); curBlockArea.addBlock(space); @@ -620,6 +622,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager { boolean outer, int level) { if (blocks[i][j] == null) { blocks[i][j] = new Block(); + blocks[i][j].setChangeBarList(getChangeBarList()); blocks[i][j].addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE); blocks[i][j].setPositioning(Block.ABSOLUTE); blocks[i][j].setBidiLevel(level); @@ -651,6 +654,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager { int paddingEnd = padding.getPaddingEnd(false, this); Block block = new Block(); + block.setChangeBarList(getChangeBarList()); TraitSetter.setProducerID(block, getTable().getId()); block.setPositioning(Block.ABSOLUTE); block.setIPD(cellIPD + paddingStart + paddingEnd); @@ -677,6 +681,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager { public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); + curBlockArea.setChangeBarList(getChangeBarList()); curBlockArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE); TraitSetter.setProducerID(curBlockArea, getTableCell().getId()); curBlockArea.setPositioning(Block.ABSOLUTE); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java index 4940c66b2..333419649 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java @@ -438,6 +438,8 @@ public class TableLayoutManager extends SpacedBorderedPaddedBlockLayoutManager public Area getParentArea(Area childArea) { if (curBlockArea == null) { curBlockArea = new Block(); + curBlockArea.setChangeBarList(getChangeBarList()); + // Set up dimensions // Must get dimensions from parent area /*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea); diff --git a/fop-core/src/main/java/org/apache/fop/render/AbstractPathOrientedRenderer.java b/fop-core/src/main/java/org/apache/fop/render/AbstractPathOrientedRenderer.java index 552d9f92f..a078509e7 100644 --- a/fop-core/src/main/java/org/apache/fop/render/AbstractPathOrientedRenderer.java +++ b/fop-core/src/main/java/org/apache/fop/render/AbstractPathOrientedRenderer.java @@ -736,6 +736,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { // save position and offset int saveIP = currentIPPosition; int saveBP = currentBPPosition; + int saveBO = getBeginOffset(); //Establish a new coordinate system AffineTransform at = new AffineTransform(); @@ -743,6 +744,8 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { at.translate(block.getXOffset(), block.getYOffset()); at.translate(0, block.getSpaceBefore()); + setBeginOffset(saveBO - block.getXOffset()); + if (!at.isIdentity()) { establishTransformationMatrix(at); } @@ -760,6 +763,8 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { restoreGraphicsState(); } + setBeginOffset(saveBO); + // stacked and relative blocks effect stacking currentIPPosition = saveIP; currentBPPosition = saveBP; diff --git a/fop-core/src/main/java/org/apache/fop/render/AbstractRenderer.java b/fop-core/src/main/java/org/apache/fop/render/AbstractRenderer.java index d57d3ce06..e8ab76d53 100644 --- a/fop-core/src/main/java/org/apache/fop/render/AbstractRenderer.java +++ b/fop-core/src/main/java/org/apache/fop/render/AbstractRenderer.java @@ -41,6 +41,7 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.area.Area; import org.apache.fop.area.BeforeFloat; import org.apache.fop.area.Block; +import org.apache.fop.area.BlockParent; import org.apache.fop.area.BlockViewport; import org.apache.fop.area.BodyRegion; import org.apache.fop.area.CTM; @@ -61,6 +62,7 @@ import org.apache.fop.area.inline.FilledArea; import org.apache.fop.area.inline.ForeignObject; import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.InlineBlock; import org.apache.fop.area.inline.InlineBlockParent; import org.apache.fop.area.inline.InlineParent; import org.apache.fop.area.inline.InlineViewport; @@ -70,7 +72,11 @@ import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.WordArea; import org.apache.fop.fo.Constants; +import org.apache.fop.fo.flow.ChangeBar; +import org.apache.fop.fo.properties.Property; import org.apache.fop.fonts.FontInfo; +import org.apache.fop.traits.BorderProps; +import org.apache.fop.traits.Direction; import org.apache.fop.traits.Visibility; /** @@ -111,7 +117,74 @@ public abstract class AbstractRenderer */ protected int containingIPPosition; - /** the currently active PageViewport */ + /** + * The "start edge" IP Position of the current column (for change bars) + */ + protected int columnStartIPPosition; + + /** + * The "end edge" IP Position of the current column (for change bars) + */ + protected int columnEndIPPosition; + + /** + * The "left" position of the current column (for change bars) + */ + protected int columnLeftIPPosition; + + /** + * The "right" position of the current column (for change bars) + */ + protected int columnRightIPPosition; + + /** + * The number of columns in the span (for change bars) + */ + protected int columnCount; + + /** + * The index number of the current column (for change bars) + */ + protected int columnIndex; + + /** + * The column width (for change bars) + */ + protected int columnWidth; + + /** + * The size of column gap (for change bars) + */ + protected int columnGap; + + /** + * The block progression direction (for change bars) + */ + protected Direction blockProgressionDirection; + + /** + * The inline progression direction (for change bars) + */ + protected Direction inlineProgressionDirection; + + /** + * Is binding on start edge of column? + */ + protected boolean bindingOnStartEdge; + + /** + * Is binding on end edge of column? + */ + protected boolean bindingOnEndEdge; + + /** + * The IP begin offset of coordinate 0 + */ + private int beginOffset; + + /** + * the currently active PageViewport + */ protected PageViewport currentPageViewport; /* warned XML handlers */ @@ -407,36 +480,95 @@ public abstract class AbstractRenderer * that are positioned into columns. * </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; } } } @@ -504,7 +636,6 @@ public abstract class AbstractRenderer endVParea(); // clip if necessary - currentIPPosition = saveIP; currentBPPosition = saveBP; } else { @@ -584,6 +715,18 @@ public abstract class AbstractRenderer */ protected void renderBlock(Block block) { assert block != null; + List<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)) { @@ -628,7 +771,17 @@ public abstract class AbstractRenderer } /** + * Renders an inline block area. + * + * @param inlineBlock The inline block area + */ + protected void renderInlineBlock(InlineBlock inlineBlock) { + renderBlock(inlineBlock.getBlock()); + } + + /** * Establish new optional content group layer. + * * @param layer name of layer */ protected abstract void startLayer(String layer); @@ -699,6 +852,11 @@ public abstract class AbstractRenderer * @param inlineArea inline area text to render */ protected void renderInlineArea(InlineArea inlineArea) { + List<ChangeBar> changeBarList = inlineArea.getChangeBarList(); + + if (changeBarList != null && !changeBarList.isEmpty()) { + drawChangeBars(inlineArea, changeBarList); + } if (inlineArea instanceof TextArea) { renderText((TextArea) inlineArea); //} else if (inlineArea instanceof Character) { @@ -707,6 +865,8 @@ public abstract class AbstractRenderer renderWord((WordArea) inlineArea); } else if (inlineArea instanceof SpaceArea) { renderSpace((SpaceArea) inlineArea); + } else if (inlineArea instanceof InlineBlock) { + renderInlineBlock((InlineBlock) inlineArea); } else if (inlineArea instanceof InlineParent) { renderInlineParent((InlineParent) inlineArea); } else if (inlineArea instanceof InlineBlockParent) { @@ -757,6 +917,16 @@ public abstract class AbstractRenderer List children = text.getChildAreas(); int saveIP = currentIPPosition; int saveBP = currentBPPosition; + + List<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); @@ -877,6 +1047,11 @@ public abstract class AbstractRenderer * (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. } @@ -903,6 +1078,12 @@ public abstract class AbstractRenderer * (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. } @@ -975,4 +1156,191 @@ public abstract class AbstractRenderer matrix[5] = Math.round(matrix[5] * 1000); return new AffineTransform(matrix); } + + /** + * Draws all change bars associated with an area. + * + * @param area The area to draw change bars for + * @param changeBarList The list of change bars affecting the area + */ + protected void drawChangeBars(Area area, List<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; + } } diff --git a/fop-core/src/main/java/org/apache/fop/render/xml/XMLRenderer.java b/fop-core/src/main/java/org/apache/fop/render/xml/XMLRenderer.java index f8765f280..ecad6b500 100644 --- a/fop-core/src/main/java/org/apache/fop/render/xml/XMLRenderer.java +++ b/fop-core/src/main/java/org/apache/fop/render/xml/XMLRenderer.java @@ -72,6 +72,7 @@ import org.apache.fop.area.inline.Container; import org.apache.fop.area.inline.ForeignObject; import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.InlineBlock; import org.apache.fop.area.inline.InlineBlockParent; import org.apache.fop.area.inline.InlineParent; import org.apache.fop.area.inline.InlineViewport; @@ -692,6 +693,26 @@ public class XMLRenderer extends AbstractXMLRenderer { endElement("block"); } + /** {@inheritDoc} */ + @Override + protected void renderInlineBlock(InlineBlock inlineBlock) { + Block block = inlineBlock.getBlock(); + atts.clear(); + addAreaAttributes(block); + addTraitAttributes(block); + if (block.getXOffset() != 0) { + addAttribute("left-offset", block.getXOffset()); + } + if (block.getYOffset() != 0) { + addAttribute("top-offset", block.getYOffset()); + } + startElement("inlineblock", atts); + if (block.getChildAreas() != null) { + renderBlocks(null, block.getChildAreas()); + } + endElement("inlineblock"); + } + /** * {@inheritDoc} */ @@ -943,6 +964,4 @@ public class XMLRenderer extends AbstractXMLRenderer { addAttribute("reversed", "true"); } } - - } diff --git a/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-datatypes.xsd b/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-datatypes.xsd index e25556f9b..e4865f2d2 100644 --- a/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-datatypes.xsd +++ b/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-datatypes.xsd @@ -67,6 +67,8 @@ </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"/> @@ -79,6 +81,8 @@ </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"/> @@ -92,7 +96,7 @@ <!-- 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"> diff --git a/fop/test/layoutengine/standard-testcases/change-bar_block.xml b/fop/test/layoutengine/standard-testcases/change-bar_block.xml new file mode 100644 index 000000000..9277343b5 --- /dev/null +++ b/fop/test/layoutengine/standard-testcases/change-bar_block.xml @@ -0,0 +1,73 @@ +<?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> diff --git a/fop/test/layoutengine/standard-testcases/change-bar_inline.xml b/fop/test/layoutengine/standard-testcases/change-bar_inline.xml new file mode 100644 index 000000000..d90500db8 --- /dev/null +++ b/fop/test/layoutengine/standard-testcases/change-bar_inline.xml @@ -0,0 +1,81 @@ +<?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> diff --git a/fop/test/layoutengine/standard-testcases/change-bar_list.xml b/fop/test/layoutengine/standard-testcases/change-bar_list.xml new file mode 100644 index 000000000..f1219fc84 --- /dev/null +++ b/fop/test/layoutengine/standard-testcases/change-bar_list.xml @@ -0,0 +1,90 @@ +<?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> diff --git a/fop/test/layoutengine/standard-testcases/change-bar_overlapped.xml b/fop/test/layoutengine/standard-testcases/change-bar_overlapped.xml new file mode 100644 index 000000000..240670773 --- /dev/null +++ b/fop/test/layoutengine/standard-testcases/change-bar_overlapped.xml @@ -0,0 +1,95 @@ +<?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> diff --git a/fop/test/layoutengine/standard-testcases/change-bar_placement-rtl.xml b/fop/test/layoutengine/standard-testcases/change-bar_placement-rtl.xml new file mode 100644 index 000000000..f9b5b197e --- /dev/null +++ b/fop/test/layoutengine/standard-testcases/change-bar_placement-rtl.xml @@ -0,0 +1,226 @@ +<?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> diff --git a/fop/test/layoutengine/standard-testcases/change-bar_placement.xml b/fop/test/layoutengine/standard-testcases/change-bar_placement.xml new file mode 100644 index 000000000..82d4bd9fa --- /dev/null +++ b/fop/test/layoutengine/standard-testcases/change-bar_placement.xml @@ -0,0 +1,226 @@ +<?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> diff --git a/fop/test/layoutengine/standard-testcases/change-bar_style.xml b/fop/test/layoutengine/standard-testcases/change-bar_style.xml new file mode 100644 index 000000000..65203cfeb --- /dev/null +++ b/fop/test/layoutengine/standard-testcases/change-bar_style.xml @@ -0,0 +1,102 @@ +<?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> diff --git a/fop/test/layoutengine/standard-testcases/change-bar_table.xml b/fop/test/layoutengine/standard-testcases/change-bar_table.xml new file mode 100644 index 000000000..39bd4b8b1 --- /dev/null +++ b/fop/test/layoutengine/standard-testcases/change-bar_table.xml @@ -0,0 +1,147 @@ +<?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> |