--- src/java/org/apache/fop/render/xml/XMLRenderer.java (revision 919765)
+++ src/java/org/apache/fop/render/xml/XMLRenderer.java (working copy)
@@ -27,6 +27,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Vector;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
@@ -84,6 +85,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.flow.ChangeBar;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.render.Renderer;
@@ -181,6 +183,22 @@
+ area.getBorderAndPaddingWidthEnd() + " "
+ area.getBorderAndPaddingWidthBefore() + " "
+ area.getBorderAndPaddingWidthAfter());
+
+ Vector v = area.getChangeBars();
+
+ if (null != v && v.size() > 0) {
+ StringBuffer buf = new StringBuffer();
+
+ for (int idx = 0; idx < v.size(); idx++) {
+ ChangeBar cb = (ChangeBar)v.get(idx);
+
+ if (0 != idx) {
+ buf.append(",");
+ }
+ buf.append(cb.getCBClass());
+ }
+ addAttribute("change-bars", buf.toString());
+ }
}
}
@@ -517,6 +535,8 @@
addAreaAttributes(region);
addTraitAttributes(region);
addAttribute("name", region.getRegionName());
+ addAttribute("writingMode", region.getWritingMode());
+ addAttribute("referenceOrientation", region.getReferenceOrientation());
addAttribute("ctm", region.getCTM().toString());
if (region.getRegionClass() == FO_REGION_BEFORE) {
startElement("regionBefore", atts);
--- src/java/org/apache/fop/render/pdf/PDFEventProducer.xml (revision 919765)
+++ src/java/org/apache/fop/render/pdf/PDFEventProducer.xml (working copy)
@@ -1,5 +1,5 @@
{count} link target{count,equals,1,,s} could not be fully resolved and now point{count,equals,1,,s} to the top of the page or {count,equals,1,is,are} dysfunctional.
- ‘{type}’ is not a standard structure type defined by the PDF Reference. Falling back to ‘{fallback}’.
+ ???{type}??? is not a standard structure type defined by the PDF Reference. Falling back to ???{fallback}???.
--- src/java/org/apache/fop/render/AbstractRenderer.java (revision 919765)
+++ src/java/org/apache/fop/render/AbstractRenderer.java (working copy)
@@ -28,6 +28,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.Vector;
import org.w3c.dom.Document;
@@ -68,7 +69,9 @@
import org.apache.fop.area.inline.WordArea;
import org.apache.fop.events.ResourceEventProducer;
import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.flow.ChangeBar;
import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.traits.BorderProps;
/**
* Abstract base class for all renderers. The Abstract renderer does all the
@@ -108,6 +111,48 @@
*/
protected int containingIPPosition = 0;
+ /**
+ * The "start edge" IP Position of the current column (for change bars)
+ */
+ protected int columnStartIPPosition = 0;
+
+ /**
+ * The "end edge" IP Position of the current column (for change bars)
+ */
+ protected int columnEndIPPosition = 0;
+
+ /**
+ * The "left" position of the current column (for change bars)
+ */
+ protected int columnLeftIPPosition = 0;
+
+ /**
+ * The "right" position of the current column (for change bars)
+ */
+ protected int columnRightIPPosition = 0;
+
+ /**
+ * The number of columns in the span (for change bars)
+ */
+ protected int columnCount = 0;
+
+ /**
+ * The index number of the current column (for change bars)
+ */
+ protected int columnNumber = 0;
+
+ /**
+ * Is binding on start edge of column?
+ */
+ protected boolean bindingOnStartEdge = false;
+
+ /**
+ * Is binding on end edge of column?
+ */
+ protected boolean bindingOnEndEdge = false;
+
+
+
/** the currently active PageViewport */
protected PageViewport currentPageViewport;
@@ -403,10 +448,60 @@
int saveSpanBPPos = saveBPPos;
for (int count = 0; count < spans.size(); count++) {
span = (Span) spans.get(count);
+ columnCount = span.getColumnCount();
+
for (int c = 0; c < span.getColumnCount(); c++) {
+ columnNumber = c;
+
NormalFlow flow = span.getNormalFlow(c);
+ int writingMode = mr.getParent().getWritingMode();
+ int referenceOrientation = mr.getParent().getReferenceOrientation();
+
+
+
if (flow != null) {
+ columnStartIPPosition = currentIPPosition;
+ columnEndIPPosition = currentIPPosition + flow.getIPD() + mr.getColumnGap();
+
+ // if direction is right to left, then end is left, else end is right edge
+ // if orientation is portrait, then binding edge is on left edge for odd pages
+ // and on right edge for even pages
+ int pageIndex = currentPageViewport.getPageIndex();
+ CTM trans = currentPageViewport.getBodyRegion().getCTM();
+
+ bindingOnStartEdge = false;
+ bindingOnEndEdge = false;
+
+ if (writingMode == Constants.EN_RL_TB) {
+ columnLeftIPPosition = columnEndIPPosition;
+ columnRightIPPosition = columnStartIPPosition;
+ if (0 == referenceOrientation) {
+ if (pageIndex % 2 == 0 ) {
+ bindingOnEndEdge = true;
+ }
+ else {
+ bindingOnStartEdge = true;
+ }
+ }
+ }
+ else {
+ columnLeftIPPosition = columnStartIPPosition;
+ columnRightIPPosition = columnEndIPPosition;
+ if (0 == referenceOrientation) {
+ if (pageIndex % 2 == 0 ) {
+ bindingOnStartEdge = true;
+ }
+ else {
+ bindingOnEndEdge = true;
+ }
+ }
+ }
+
+
+
+
+
currentBPPosition = saveSpanBPPos;
renderFlow(flow);
currentIPPosition += flow.getIPD();
@@ -555,6 +650,19 @@
* @param block The block area
*/
protected void renderBlock(Block block) {
+ Vector changeBars = block.getChangeBars();
+
+ if (null != changeBars && !changeBars.isEmpty()) {
+ // this block has change bars attached to it
+ int saveIP = currentIPPosition;
+ int saveBP = currentBPPosition;
+
+ drawChangeBars(block, changeBars);
+
+ currentIPPosition = saveIP;
+ currentBPPosition = saveBP;
+ }
+
List children = block.getChildAreas();
if (block instanceof BlockViewport) {
if (children != null) {
@@ -616,6 +724,13 @@
* @param inlineArea inline area text to render
*/
protected void renderInlineArea(InlineArea inlineArea) {
+ Vector changeBars = inlineArea.getChangeBars();
+
+ if (null != changeBars && !changeBars.isEmpty()) {
+ // area has change bar, handle
+ drawChangeBars(inlineArea, changeBars);
+ }
+
if (inlineArea instanceof TextArea) {
renderText((TextArea) inlineArea);
//} else if (inlineArea instanceof Character) {
@@ -758,6 +873,12 @@
* (todo) Make renderImage() protected
*/
public void renderImage(Image image, Rectangle2D pos) {
+ // handle change bars
+ Vector changeBars = image.getChangeBars();
+
+ if (null != changeBars && !changeBars.isEmpty()) {
+ drawChangeBars(image, changeBars);
+ }
// Default: do nothing.
// Some renderers (ex. Text) don't support images.
}
@@ -784,6 +905,13 @@
* (todo) Make renderForeignObject() protected
*/
protected void renderForeignObject(ForeignObject fo, Rectangle2D pos) {
+ // handle change bars
+ Vector changeBars = fo.getChangeBars();
+
+ if (null != changeBars && !changeBars.isEmpty()) {
+ drawChangeBars(fo, changeBars);
+ }
+
// Default: do nothing.
// Some renderers (ex. Text) don't support foreign objects.
}
@@ -856,4 +984,123 @@
matrix[5] = Math.round(matrix[5] * 1000);
return new AffineTransform(matrix);
}
+
+ /**
+ * Draw all change bars associated with an area
+ *
+ * @param block The area to draw change bars for
+ * @param changeBars The list of change bars affecting the area
+ */
+ private void drawChangeBars(Area block, Vector changeBars) {
+ Block cbArea;
+
+ int saveIP = currentIPPosition;
+ int saveBP = currentBPPosition;
+
+ for (int idx = 0; idx < changeBars.size(); idx++) {
+ ChangeBar bar = (ChangeBar)changeBars.get(idx);
+ cbArea = new Block();
+
+ currentIPPosition = 0;
+ currentBPPosition = saveBP;
+
+ // offset by default is negative width for change bars placed on the start edge
+ // this will be overriden if placement is at the end edge
+ // 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 xOffset = -bar.getWidth().getValue();
+ int xScale = 1;
+
+ // determine currentIPPosition based on placement
+ switch (bar.getPlacement()) {
+ case EN_START:
+ xOffset += columnStartIPPosition;
+ xScale = -1;
+ break;
+ case EN_END:
+ xOffset = columnEndIPPosition;
+ break;
+ case EN_LEFT:
+ xOffset += columnLeftIPPosition;
+ xScale = -1;
+ break;
+ case EN_RIGHT:
+ xOffset = columnRightIPPosition;
+ break;
+ case EN_INSIDE:
+ if (bindingOnStartEdge) {
+ xOffset += columnStartIPPosition;
+ xScale = -1;
+ }
+ else if (bindingOnEndEdge) {
+ xOffset = columnEndIPPosition;
+ }
+ else {
+ xOffset += columnStartIPPosition;
+ xScale = -1;
+ }
+ break;
+ case EN_OUTSIDE:
+ if (bindingOnStartEdge) {
+ xOffset = columnEndIPPosition;
+ }
+ else if (bindingOnEndEdge) {
+ xOffset += columnStartIPPosition;
+ xScale = -1;
+ }
+ else {
+ xOffset += columnStartIPPosition;
+ xScale = -1;
+ }
+ break;
+ case EN_ALTERNATE:
+ if (2 == columnCount) {
+ if ( 0 == columnNumber) {
+ xOffset += columnStartIPPosition;
+ xScale = -1;
+ }
+ else {
+ xOffset = columnEndIPPosition;
+ }
+ }
+ else {
+ if (bindingOnStartEdge) {
+ xOffset = columnEndIPPosition;
+ }
+ else if (bindingOnEndEdge) {
+ xOffset += columnStartIPPosition;
+ xScale = -1;
+ }
+ else {
+ xOffset = columnStartIPPosition;
+ xScale = -1;
+ }
+ }
+ break;
+ default:
+ // Cannot happen
+ break;
+ }
+
+ // Change bar area has 0 ipd, class xsl-absolute, no margin or padding
+ cbArea.setAreaClass(Area.CLASS_ABSOLUTE);
+ cbArea.setIPD(0);
+ cbArea.setPositioning(Block.ABSOLUTE);
+ cbArea.setBPD(block.getBPD());
+ BorderProps props = new BorderProps(bar.getStyle(), bar.getWidth().getValue(),
+ bar.getColor(), BorderProps.SEPARATE);
+
+ cbArea.addTrait(Trait.BORDER_END, props);
+
+ cbArea.setXOffset(xOffset + xScale * bar.getOffset().getValue());
+ cbArea.setYOffset(block.getSpaceBefore());
+
+ renderBlock(cbArea);
+
+ // restore position on page
+ currentIPPosition = saveIP;
+ currentBPPosition = saveBP;
+
+ }
+ }
}
--- src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java (working copy)
@@ -178,9 +178,11 @@
Dimension imageSize = this.imageLayout.getViewportSize();
Block blockArea = new Block();
+ blockArea.setChangeBars(getChangeBars());
+
blockArea.setIPD(imageSize.width);
LineArea lineArea = new LineArea();
-
+
Image imageArea = new Image(uri);
TraitSetter.setProducerID(imageArea, fobj.getId());
transferForeignAttributes(imageArea);
@@ -246,7 +248,8 @@
rv.setClip(true);
BodyRegion body = new BodyRegion(Constants.FO_REGION_BODY,
- "fop-image-region", rv, 1, 0);
+ "fop-image-region", rv, 1, 0,
+ pageSeq.getReferenceOrientation(), pageSeq.getReferenceOrientation());
body.setIPD(imageSize.width);
body.setBPD(imageSize.height);
body.setCTM(pageCTM);
--- src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java (working copy)
@@ -418,6 +418,7 @@
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBars(getChangeBars());
curBlockArea.setIPD(super.getContentAreaIPD());
--- src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java (working copy)
@@ -38,6 +38,8 @@
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.Footnote;
@@ -141,6 +143,8 @@
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());
}
/**
--- src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java (working copy)
@@ -238,6 +238,7 @@
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBars(getChangeBars());
// Set up dimensions
// Must get dimensions from parent area
--- src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java (working copy)
@@ -602,6 +602,7 @@
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBars(getChangeBars());
// Set up dimensions
/*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);
--- src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java (working copy)
@@ -192,6 +192,8 @@
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBars(getChangeBars());
+
curBlockArea.setPositioning(Block.ABSOLUTE);
// set position
curBlockArea.setXOffset(xoffset);
--- src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java (working copy)
@@ -85,6 +85,7 @@
// get breaks then add areas to title
this.parentLM = pslm;
holder = new LineArea();
+ holder.setChangeBars(getChangeBars());
// setUserAgent(foTitle.getUserAgent());
@@ -161,6 +162,7 @@
childContext.setIPDAdjust(0.0);
childLM.addAreas(posIter, childContext);
((InlineArea)holder).setIPD(savedIPD);
+
}
public int getStackingSize() {
--- src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java (working copy)
@@ -201,9 +201,11 @@
InlineArea area;
if (hasInlineParent) {
area = new InlineParent();
+ area.setChangeBars(getChangeBars());
area.setOffset(0);
} else {
area = new InlineBlockParent();
+ area.setChangeBars(getChangeBars());
}
if (fobj instanceof Inline) {
TraitSetter.setProducerID(area, getInlineFO().getId());
@@ -518,6 +520,7 @@
context.setFlags(LayoutContext.LAST_AREA, isLast);
areaCreated = true;
checkEndOfLayout(lastPos);
+
}
/** {@inheritDoc} */
--- src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java (working copy)
@@ -68,16 +68,19 @@
if (parentLayoutManager instanceof BlockStackingLayoutManager
&& !(parentLayoutManager instanceof BlockLayoutManager)) {
Block helperBlock = new Block();
+ helperBlock.setChangeBars(getChangeBars());
TraitSetter.setProducerID(helperBlock, fobj.getId());
parentLayoutManager.addChildArea(helperBlock);
} else {
InlineArea area = getEffectiveArea();
+ area.setChangeBars(getChangeBars());
parentLayoutManager.addChildArea(area);
}
}
while (posIter.hasNext()) {
posIter.next();
}
+
}
/** {@inheritDoc} */
--- src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java (working copy)
@@ -70,6 +70,8 @@
int width = getStringWidth(str);
text.setIPD(width);
}
+
+ text.setChangeBars(getChangeBars());
updateTextAreaTraits(text);
return text;
--- src/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java (working copy)
@@ -42,8 +42,10 @@
/** {@inheritDoc} */
protected Area getChildArea() {
- return new Image(((ExternalGraphic) fobj).getSrc());
- }
+ Image im = new Image(((ExternalGraphic) fobj).getSrc());
+ im.setChangeBars(getChangeBars());
+ return im;
+ }
}
--- src/java/org/apache/fop/layoutmgr/inline/InstreamForeignObjectLM.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/InstreamForeignObjectLM.java (working copy)
@@ -46,7 +46,9 @@
org.w3c.dom.Document doc = child.getDOMDocument();
String ns = child.getNamespaceURI();
- return new ForeignObject(doc, ns);
+ ForeignObject obj = new ForeignObject(doc, ns);
+ obj.setChangeBars(getChangeBars());
+ return obj;
}
}
--- src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java (working copy)
@@ -77,6 +77,8 @@
public InlineArea get(LayoutContext context) {
// get page string from parent, build area
TextArea text = new TextArea();
+ text.setChangeBars(getChangeBars());
+
String str = getCurrentPV().getPageNumberString();
int width = getStringWidth(str);
text.addWord(str, 0);
@@ -98,6 +100,8 @@
//TODO or even better: delay area creation until addAreas() stage
//TextArea is cloned because the LM is reused in static areas and the area can't be.
TextArea ta = new TextArea();
+ ta.setChangeBars(getChangeBars());
+
TraitSetter.setProducerID(ta, fobj.getId());
ta.setIPD(baseArea.getIPD());
ta.setBPD(baseArea.getBPD());
--- src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java (working copy)
@@ -1451,6 +1451,7 @@
}
}
setCurrentArea(null); // ?? necessary
+
}
/**
@@ -1471,6 +1472,8 @@
LineArea lineArea = new LineArea(
(lbp.getLeafPos() < seq.size() - 1 ? textAlignment : textAlignmentLast),
lbp.difference, lbp.availableStretch, lbp.availableShrink);
+ lineArea.setChangeBars(getChangeBars());
+
if (lbp.startIndent != 0) {
lineArea.addTrait(Trait.START_INDENT, new Integer(lbp.startIndent));
}
@@ -1609,6 +1612,8 @@
}
LineArea lineArea = new LineArea();
+ lineArea.setChangeBars(getChangeBars());
+
setCurrentArea(lineArea);
LayoutContext lc = new LayoutContext(0);
lc.setAlignmentContext(alignmentContext);
--- src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java (working copy)
@@ -75,6 +75,8 @@
private TextArea getCharacterInlineArea(Character node) {
TextArea text = new TextArea();
+ text.setChangeBars(getChangeBars());
+
char ch = node.getCharacter();
if (CharUtilities.isAnySpace(ch)) {
// add space unless it's zero-width:
--- src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java (working copy)
@@ -201,6 +201,9 @@
leaderArea.setBPD(fobj.getRuleThickness().getValue(this));
}
}
+
+ leaderArea.setChangeBars(getChangeBars());
+
TraitSetter.setProducerID(leaderArea, fobj.getId());
return leaderArea;
}
@@ -233,6 +236,7 @@
posIter.next();
}
}
+
}
/** {@inheritDoc} */
--- src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java (working copy)
@@ -198,6 +198,7 @@
if (iAdjust != 0) {
//getLogger().debug("Add leading space: " + iAdjust);
Space ls = new Space();
+ ls.setChangeBars(getChangeBars());
ls.setIPD(iAdjust);
parentArea.addChildArea(ls);
}
--- src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java (working copy)
@@ -96,6 +96,7 @@
if (!resolved) {
getPSLM().addUnresolvedArea(fobj.getRefId(), (Resolvable) curArea);
}
+
}
/**
@@ -112,6 +113,8 @@
String str = page.getPageNumberString();
// get page string from parent, build area
text = new TextArea();
+ text.setChangeBars(getChangeBars());
+
int width = getStringWidth(str);
text.addWord(str, 0);
text.setIPD(width);
@@ -119,6 +122,8 @@
} else {
resolved = false;
text = new UnresolvedPageNumber(fobj.getRefId(), font);
+ text.setChangeBars(getChangeBars());
+
String str = "MMM"; // reserve three spaces for page number
int width = getStringWidth(str);
text.setIPD(width);
--- src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java (working copy)
@@ -297,6 +297,7 @@
addAreaInfoAreas(lastAreaInfo, wordSpaceCount, letterSpaceCount, firstAreaInfoIndex,
lastAreaInfoIndex, realWidth, context);
}
+
}
private void addAreaInfoAreas(AreaInfo areaInfo, int wordSpaceCount, int letterSpaceCount,
@@ -367,7 +368,8 @@
TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstAreaInfoIndex,
lastAreaInfoIndex, context.isLastArea(), areaInfo.font).build();
-
+ textArea.setChangeBars(getChangeBars());
+
// wordSpaceDim is computed in relation to wordSpaceIPD.opt
// but the renderer needs to know the adjustment in relation
// to the size of the space character in the current font;
@@ -459,6 +461,8 @@
textArea = new TextArea(width.getStretch(), width.getShrink(),
adjust);
}
+
+ textArea.setChangeBars(getChangeBars());
}
private void setInlineProgressionDimension() {
--- src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java (working copy)
@@ -75,6 +75,7 @@
resolved = true;
}
+ text.setChangeBars(getChangeBars());
updateTextAreaTraits(text);
return text;
--- src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java (working copy)
@@ -127,6 +127,8 @@
int sp = TraitSetter.getEffectiveSpace(adjust, minoptmax);
if (sp != 0) {
Block spacer = new Block();
+ spacer.setChangeBars(getChangeBars());
+
spacer.setBPD(sp);
parentLayoutManager.addChildArea(spacer);
}
--- src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java (working copy)
@@ -405,10 +405,14 @@
if (usedBPD < cellBPD) {
if (getTableCell().getDisplayAlign() == EN_CENTER) {
Block space = new Block();
+ space.setChangeBars(getChangeBars());
+
space.setBPD((cellBPD - usedBPD) / 2);
curBlockArea.addBlock(space);
} else if (getTableCell().getDisplayAlign() == EN_AFTER) {
Block space = new Block();
+ space.setChangeBars(getChangeBars());
+
space.setBPD(cellBPD - usedBPD);
curBlockArea.addBlock(space);
}
@@ -463,6 +467,8 @@
boolean outer) {
if (blocks[i][j] == null) {
blocks[i][j] = new Block();
+ blocks[i][j].setChangeBars(getChangeBars());
+
blocks[i][j].addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
blocks[i][j].setPositioning(Block.ABSOLUTE);
}
@@ -493,6 +499,8 @@
int paddingEnd = padding.getPaddingEnd(false, this);
Block block = new Block();
+ block.setChangeBars(getChangeBars());
+
TraitSetter.setProducerID(block, getTable().getId());
block.setPositioning(Block.ABSOLUTE);
block.setIPD(cellIPD + paddingStart + paddingEnd);
@@ -518,6 +526,8 @@
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBars(getChangeBars());
+
curBlockArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
TraitSetter.setProducerID(curBlockArea, getTableCell().getId());
curBlockArea.setPositioning(Block.ABSOLUTE);
--- src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java (working copy)
@@ -402,6 +402,8 @@
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBars(getChangeBars());
+
// Set up dimensions
// Must get dimensions from parent area
/*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);
--- src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java (working copy)
@@ -179,6 +179,8 @@
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBars(getChangeBars());
+
// Set up dimensions
// Must get dimensions from parent area
Area parentArea = parentLayoutManager.getParentArea(curBlockArea);
--- src/java/org/apache/fop/layoutmgr/table/RowPainter.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/table/RowPainter.java (working copy)
@@ -465,6 +465,8 @@
//generate the block area
Block block = new Block();
+ block.setChangeBars(tclm.getTableLM().getFObj().getChangeBars());
+
block.setPositioning(Block.ABSOLUTE);
block.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
block.setIPD(ipd);
--- src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java (working copy)
@@ -175,6 +175,8 @@
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
+ curBlockArea.setChangeBars(getChangeBars());
+
// Set up dimensions
// Must get dimensions from parent area
Area parentArea = parentLayoutManager.getParentArea(curBlockArea);
--- src/java/org/apache/fop/layoutmgr/PageBreaker.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/PageBreaker.java (working copy)
@@ -470,6 +470,7 @@
parentArea.setTop(topOffset);
parentArea.setSeparator(separatorArea);
}
+
pslm.getCurrentPV().getCurrentSpan().notifyFlowsFinished();
}
--- src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java (working copy)
@@ -1184,6 +1184,8 @@
boolean allowBPDUpdate = autoHeight && !switchedProgressionDirection;
viewportBlockArea = new BlockViewport(allowBPDUpdate);
+ viewportBlockArea.setChangeBars(getChangeBars());
+
viewportBlockArea.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE);
viewportBlockArea.setIPD(getContentAreaIPD());
@@ -1229,6 +1231,8 @@
}
referenceArea = new Block();
+ referenceArea.setChangeBars(getChangeBars());
+
referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
TraitSetter.setProducerID(referenceArea, getBlockContainerFO().getId());
--- src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java (revision 919765)
+++ src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java (working copy)
@@ -21,6 +21,7 @@
import java.util.List;
import java.util.Stack;
+import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -257,6 +258,19 @@
return fobj;
}
+ /**
+ * Obtain vector of change bars affecting object in this layout.
+ * @return Vector of all change bars affecting this or null
+ */
+ public Vector/**/ getChangeBars() {
+ if (null == fobj) {
+ return null;
+ } else {
+ return fobj.getChangeBars();
+ }
+ }
+
+
/** {@inheritDoc} */
public void reset() {
throw new UnsupportedOperationException("Not implemented");
--- src/java/org/apache/fop/apps/FOUserAgent.java (revision 919765)
+++ src/java/org/apache/fop/apps/FOUserAgent.java (working copy)
@@ -24,6 +24,7 @@
import java.net.MalformedURLException;
import java.util.Date;
import java.util.Map;
+import java.util.Vector;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
@@ -46,6 +47,7 @@
import org.apache.fop.events.FOPEventListenerProxy;
import org.apache.fop.events.LoggingEventListener;
import org.apache.fop.fo.FOEventHandler;
+import org.apache.fop.fo.flow.ChangeBar;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.render.Renderer;
import org.apache.fop.render.RendererFactory;
@@ -81,7 +83,13 @@
private static Log log = LogFactory.getLog("FOP");
private FopFactory factory;
+
+ /**
+ * The change bars encountered
+ */
+ private static Vector stackedChangeBars = new Vector();
+
/**
* The base URL for all URL resolutions, especially for
* external-graphics.
@@ -692,5 +700,52 @@
public StructureTree getStructureTree() {
return this.structureTree;
}
+
+ /**
+ * Add another change bar to the stack of active change bars
+ * @param bar The change bar top add
+ */
+ public void pushChangeBar(ChangeBar bar) {
+ stackedChangeBars.addElement(bar);
+ }
+
+
+ /**
+ * Remove top level change bar from stack
+ */
+ public void popChangeBar() {
+ stackedChangeBars.removeElementAt(stackedChangeBars.size() - 1);
+ }
+
+ /**
+ * Return the nearest change bar in effect, i.e. the youngest one
+ *
+ * @return youngest change bar in effect or null
+ */
+ public ChangeBar topChangeBar() {
+ if (stackedChangeBars.isEmpty()) {
+ return null;
+ }
+ else {
+ return (ChangeBar)stackedChangeBars.lastElement();
+ }
+ }
+
+ /**
+ * Return the list of change bars in effect currently
+ * @return The vector of change bars in effect currently
+ */
+ public Vector getChangeBars() {
+ return stackedChangeBars;
+ }
+
+
+ /**
+ * Copy the change bars in affect currently
+ * @return A copy of the change bars in effect currently
+ */
+ public Vector copyChangeBars() {
+ return (Vector)(stackedChangeBars.clone());
+ }
}
--- src/java/org/apache/fop/events/EventFormatter.xml (revision 919765)
+++ src/java/org/apache/fop/events/EventFormatter.xml (working copy)
@@ -58,6 +58,9 @@
First element must be the fo:root formatting object. Found {elementName} instead. Please make sure you're producing a valid XSL-FO document.
Document is empty (something might be wrong with your XSLT stylesheet).
Unknown formatting object "{offendingNode}" encountered (a child of {elementName}}.{{locator}}
+ End class "{endName}" of {elementName} does not match latest starting class {beginName}.{{locator}}
+ An {elementName} without an fo:change-bar-begin found.{{locator}}
+ Element {elementName} not descendant of fo:flow or fo:static-content.{{locator}}
Only a value of "auto" for block-progression-dimension has a well-specified behavior on fo:table. Falling back to "auto".{{locator}}
In collapsing border model a table does not have padding (see http://www.w3.org/TR/REC-CSS2/tables.html#collapsing-borders), but a non-zero value for padding was found. The padding will be ignored.{{locator}}
Either fo:table-rows or fo:table-cells may be children of an {elementName} but not both.{{locator}}
--- src/java/org/apache/fop/fo/FOText.java (revision 919765)
+++ src/java/org/apache/fop/fo/FOText.java (working copy)
@@ -28,6 +28,7 @@
import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.flow.Block;
+import org.apache.fop.fo.flow.ChangeBar;
import org.apache.fop.fo.properties.CommonFont;
import org.apache.fop.fo.properties.CommonHyphenation;
import org.apache.fop.fo.properties.CommonTextDecoration;
@@ -90,6 +91,11 @@
*/
public FOText(FONode parent) {
super(parent);
+ // check if we are under the influence of change bars
+ if (null != getUserAgent().topChangeBar()) {
+ // OK, so copy over the stack of change bars
+ affectedByChangeBars = getUserAgent().copyChangeBars();
+ }
}
/** {@inheritDoc} */
--- src/java/org/apache/fop/fo/FONode.java (revision 919765)
+++ src/java/org/apache/fop/fo/FONode.java (working copy)
@@ -22,6 +22,7 @@
// Java
import java.util.ListIterator;
import java.util.Map;
+import java.util.Vector;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
@@ -59,6 +60,9 @@
/** pointer to the sibling nodes */
protected FONode[] siblings;
+ /** list of change bars affecting the FObj */
+ protected Vector affectedByChangeBars = null;
+
/**
* Marks the location of this object from the input FO
*
Call locator.getSystemId()
,
@@ -170,6 +174,18 @@
}
/**
+ * Convenience function to check if this element is a change bar element
+ * @param namespaceURI The name space of the element
+ * @param localName The local name of the element
+ * @return true if a member, false if not
+ */
+ public boolean isChangeBarElement(String namespaceURI, String localName) {
+ return FO_URI.equals(namespaceURI) &&
+ ( "change-bar-begin".equals(localName) ||
+ "change-bar-end".equals(localName) );
+ }
+
+ /**
* Returns the user agent that is associated with the
* tree's FOEventHandler
.
*
@@ -244,6 +260,9 @@
//nop
}
+
+
+
/**
* Static version of {@link FONode#validateChildNode(Locator, String, String)} that
* can be used by subclasses that need to validate children against a different node
@@ -252,8 +271,8 @@
*
* @param fo the {@link FONode} to validate against
* @param loc location in the source file
- * @param namespaceURI namespace of the incoming node
- * @param localName name of the incoming node (without namespace prefix)
+ * @param namespaceURI name space of the incoming node
+ * @param localName name of the incoming node (without name space prefix)
* @throws ValidationException if the incoming node is not a valid child for the given FO
*/
protected static void validateChildNode(
@@ -861,6 +880,8 @@
followingSibling.siblings[0] = precedingSibling;
}
+
+
/**
* Base iterator interface over a FO's children
*/
--- src/java/org/apache/fop/fo/FObj.java (revision 919765)
+++ src/java/org/apache/fop/fo/FObj.java (working copy)
@@ -26,6 +26,7 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.Vector;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
@@ -36,6 +37,7 @@
import org.apache.fop.fo.extensions.ExtensionAttachment;
import org.apache.fop.fo.flow.Marker;
import org.apache.fop.fo.properties.PropertyMaker;
+import org.apache.fop.fo.flow.ChangeBar;
/**
* Base class for representation of formatting objects and their processing.
@@ -68,7 +70,8 @@
// The value of properties relevant for all fo objects
private String id = null;
- // End of property values
+
+
/**
* Create a new formatting object.
@@ -118,9 +121,11 @@
setLocator(locator);
pList.addAttributesToList(attlist);
if (!inMarker()
- || "marker".equals(elementName)) {
+ || "marker".equals(elementName) ) {
pList.setWritingMode();
bind(pList);
+ } else if (elementName.startsWith("change-bar")) {
+ bind(pList);
}
}
@@ -152,9 +157,24 @@
if (id != null) {
checkId(id);
}
+
}
/**
+ * {@inheritDoc}
+ * @throws FOPException FOP Exception
+ */
+ protected void endOfNode() throws FOPException {
+ // check if we are under the influence of change bars
+ if (null != getUserAgent().topChangeBar()) {
+ // OK, so copy over the stack of change bars
+ affectedByChangeBars = getUserAgent().copyChangeBars();
+ }
+
+ super.endOfNode();
+ }
+
+ /**
* Setup the id for this formatting object.
* Most formatting objects can have an id that can be referenced.
* This methods checks that the id isn't already used by another FO
@@ -417,7 +437,9 @@
}
}
- /**
+
+
+ /**
* Convenience method for validity checking. Checks if the
* incoming node is a member of the "%block;" parameter entity
* as defined in Sect. 6.2 of the XSL 1.0 & 1.1 Recommendations
@@ -610,6 +632,12 @@
return (super.toString() + "[@id=" + this.id + "]");
}
+ public Vector/**/getChangeBars()
+ {
+ return affectedByChangeBars;
+ }
+
+
/** Basic {@link FONodeIterator} implementation */
public class FObjIterator implements FONodeIterator {
--- src/java/org/apache/fop/fo/flow/ChangeBar.java (revision 0)
+++ src/java/org/apache/fop/fo/flow/ChangeBar.java (revision 0)
@@ -0,0 +1,195 @@
+/*
+ * 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.fo.FONode;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.properties.Property;
+import org.apache.fop.datatypes.Length;
+
+/** Common change bar base class. Handles properties and local child validation */
+public abstract class ChangeBar extends FObj {
+
+
+ /**
+ * Create a new ChangeBar object
+ * @param parent The parent FObj
+ */
+ public ChangeBar(FONode parent) {
+ super(parent);
+ }
+
+
+ /**
+ * The class of the change bar, must be provided
+ */
+ protected String cbClass = null;
+
+ /**
+ * The color of the change bar
+ */
+ protected Color color = null;
+
+ /**
+ * The offset of the bar from the column
+ */
+ protected Length offset = null;
+
+ /**
+ * The placement of the bar
+ */
+ protected int placement = -1;
+
+ /**
+ * The style of the bar
+ */
+ protected int style = -1;
+
+ /**
+ * The width of the bar
+ */
+ protected Length width = null;
+
+
+ /** {@inheritDoc} */
+ public void bind(PropertyList pList) throws FOPException {
+ super.bind(pList);
+
+ Property classProperty = pList.get(PR_CHANGE_BAR_CLASS);
+ if (null == classProperty) {
+ cbClass = "inMarker";
+ }
+ else {
+ cbClass = classProperty.getString();
+ }
+
+
+ Property colorProperty = pList.get(PR_CHANGE_BAR_COLOR, true, false);
+ if (null == colorProperty) {
+ colorProperty = pList.get(PR_COLOR);
+ }
+ color = colorProperty.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();
+ }
+
+
+ /**
+ * @return the class of the change bar
+ */
+ public String getCBClass() {
+ return cbClass;
+ }
+
+ /** {@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 (cbClass == null || "".equals(cbClass)) {
+ missingPropertyError("change-bar-class");
+ }
+
+ if ( -1 == findAncestor(FO_FLOW)
+ && -1 == findAncestor(FO_STATIC_CONTENT) ) {
+ getFOValidationEventProducer().changeBarWrongAncestor(this, getName(), locator);
+ }
+ }
+
+
+ /**
+ * Push the current change bar on the stack
+ */
+ protected void push() {
+ getUserAgent().pushChangeBar(this);
+ }
+
+ /**
+ * Remove top level change bar from stack
+ */
+ protected void pop() {
+ getUserAgent().popChangeBar();
+
+ }
+
+ /**
+ * Retrieve youngest open change bar element
+ *
+ * @return null, if no change bar is open, otherwise the youngest change bar
+ */
+ protected ChangeBar top() {
+ return getUserAgent().topChangeBar();
+ }
+
+ /**
+ * @return the color
+ */
+ public Color getColor() {
+ return color;
+ }
+
+ /**
+ * @return the offset
+ */
+ public Length getOffset() {
+ return offset;
+ }
+
+ /**
+ * @return the placement
+ */
+ public int getPlacement() {
+ return placement;
+ }
+
+ /**
+ * @return the style
+ */
+ public int getStyle() {
+ return style;
+ }
+
+ /**
+ * @return the width
+ */
+ public Length getWidth() {
+ return width;
+ }
+}
+ *
--- src/java/org/apache/fop/fo/flow/ChangeBarEnd.java (revision 0)
+++ src/java/org/apache/fop/fo/flow/ChangeBarEnd.java (revision 0)
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+
+/**
+ * End of a change bar element. Notes the end of the affected objects of a change bar.
+ * */
+public class ChangeBarEnd extends ChangeBar {
+
+ /**
+ * Create a change bar end object
+ * @param parent the parent FObj
+ */
+ 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 topElement = top();
+
+ if (null == topElement) {
+ getFOValidationEventProducer().changeBarNoBegin(this, getName(), locator);
+ } else {
+ if (!topElement.cbClass.equals(cbClass)) {
+ getFOValidationEventProducer().changeBarWrongStacking(this,
+ getName(), topElement.cbClass, cbClass, locator);
+ }
+ pop();
+ }
+
+
+ }
+
+}
--- src/java/org/apache/fop/fo/flow/ChangeBarBegin.java (revision 0)
+++ src/java/org/apache/fop/fo/flow/ChangeBarBegin.java (revision 0)
@@ -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;
+
+
+
+/**
+ * Change bar begin element. Notes the beginning of change bar of a certain class.
+ *
+ */
+public class ChangeBarBegin extends ChangeBar {
+
+
+ /**
+ * Create a new change bar begin object
+ * @param parent The parent FObj
+ */
+ 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();
+ }
+}
--- src/java/org/apache/fop/fo/flow/Marker.java (revision 919765)
+++ src/java/org/apache/fop/fo/flow/Marker.java (working copy)
@@ -90,8 +90,15 @@
savePropertyListMaker = builderContext.getPropertyListMaker();
builderContext.setPropertyListMaker(new PropertyListMaker() {
public PropertyList make(FObj fobj, PropertyList parentPropertyList) {
- PropertyList pList = new MarkerPropertyList(fobj, parentPropertyList);
- descendantPropertyLists.put(fobj, pList);
+ PropertyList pList;
+
+ if (fobj.getLocalName().startsWith("change-bar-")) {
+ pList = savePropertyListMaker.make(fobj, parentPropertyList);
+ }
+ else {
+ pList = new MarkerPropertyList(fobj, parentPropertyList);
+ descendantPropertyLists.put(fobj, pList);
+ }
return pList;
}
});
--- src/java/org/apache/fop/fo/FOElementMapping.java (revision 919765)
+++ src/java/org/apache/fop/fo/FOElementMapping.java (working copy)
@@ -136,6 +136,10 @@
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());
}
}
@@ -520,4 +524,17 @@
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);
+ }
+ }
+
}
--- src/java/org/apache/fop/fo/FOValidationEventProducer.java (revision 919765)
+++ src/java/org/apache/fop/fo/FOValidationEventProducer.java (working copy)
@@ -357,6 +357,47 @@
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
--- src/java/org/apache/fop/fo/FOPropertyMapping.java (revision 919765)
+++ src/java/org/apache/fop/fo/FOPropertyMapping.java (working copy)
@@ -313,6 +313,7 @@
gp.createTableProperties();
gp.createWritingModeProperties();
gp.createMiscProperties();
+ gp.createChangeBarProperties();
// Hardcode the subproperties.
addSubpropMakerName("length", CP_LENGTH);
@@ -2500,6 +2501,60 @@
addPropertyMaker("writing-mode", m);
}
+ private void createChangeBarProperties() {
+ PropertyMaker m;
+
+ // change-bar-class
+ m = new StringProperty.Maker(PR_CHANGE_BAR_CLASS);
+ m.setInherited(false);
+ addPropertyMaker("change-bar-class", m);
+
+ // change-bar-color
+ m = new ColorProperty.Maker(PR_CHANGE_BAR_COLOR);
+ m.useGeneric(genericColor);
+ m.setInherited(true);
+ // TODO determine default color by current color profile
+ addPropertyMaker("change-bar-color", m);
+
+ // change-bar-offset
+ m = new LengthProperty.Maker(PR_CHANGE_BAR_OFFSET);
+ m.setInherited(true);
+ m.setDefault("6pt");
+ addPropertyMaker("change-bar-offset", 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;
--- src/java/org/apache/fop/fo/FOTreeBuilder.java (revision 919765)
+++ src/java/org/apache/fop/fo/FOTreeBuilder.java (working copy)
@@ -264,7 +264,9 @@
} else { // check that incoming node is valid for currentFObj
if (currentFObj.getNamespaceURI().equals(FOElementMapping.URI)
|| currentFObj.getNamespaceURI().equals(ExtensionElementMapping.URI)) {
- currentFObj.validateChildNode(locator, namespaceURI, localName);
+ if (!currentFObj.isChangeBarElement(namespaceURI, localName)) {
+ currentFObj.validateChildNode(locator, namespaceURI, localName);
+ }
}
}
--- src/java/org/apache/fop/area/BodyRegion.java (revision 919765)
+++ src/java/org/apache/fop/area/BodyRegion.java (working copy)
@@ -36,6 +36,7 @@
private int columnGap;
private int columnCount;
+
/**
* Constructor which can read traits directly
* from an fo:region-body formatting object.
@@ -43,7 +44,8 @@
* @param parent the parent region viewport
*/
public BodyRegion(RegionBody rb, RegionViewport parent) {
- this(rb.getNameId(), rb.getRegionName(), parent, rb.getColumnCount(), rb.getColumnGap());
+ this(rb.getNameId(), rb.getRegionName(), parent, rb.getColumnCount(), rb.getColumnGap(),
+ rb.getWritingMode(), rb.getReferenceOrientation());
}
/**
@@ -54,10 +56,13 @@
* @param parent the parent region viewport
* @param columnCount the number of columns
* @param columnGap the gap between columns
+ * @param wrMode writing Mode
+ * @param refOrient reference orientation
*/
public BodyRegion(int regionClass, String regionName, RegionViewport parent,
- int columnCount, int columnGap) {
- super(regionClass, regionName, parent);
+ int columnCount, int columnGap, int wrMode, int refOrient) {
+ super(regionClass, regionName, parent, wrMode, refOrient);
+
this.columnCount = columnCount;
this.columnGap = columnGap;
mainReference = new MainReference(this);
@@ -143,7 +148,7 @@
*/
public Object clone() {
BodyRegion br = new BodyRegion(getRegionClass(), getRegionName(), regionViewport,
- getColumnCount(), getColumnGap());
+ getColumnCount(), getColumnGap(), getWritingMode(), getReferenceOrientation());
br.setCTM(getCTM());
br.setIPD(getIPD());
br.beforeFloat = beforeFloat;
--- src/java/org/apache/fop/area/MainReference.java (revision 919765)
+++ src/java/org/apache/fop/area/MainReference.java (working copy)
@@ -125,5 +125,9 @@
return parent.getColumnGap();
}
+ /** @return parent area of area */
+ public BodyRegion getParent() {
+ return parent;
+ }
}
--- src/java/org/apache/fop/area/AreaTreeParser.java (revision 919765)
+++ src/java/org/apache/fop/area/AreaTreeParser.java (working copy)
@@ -571,9 +571,11 @@
String regionName = attributes.getValue("name");
int columnCount = XMLUtil.getAttributeAsInt(attributes, "columnCount", 1);
int columnGap = XMLUtil.getAttributeAsInt(attributes, "columnGap", 0);
+ int wrMode = XMLUtil.getAttributeAsInt(attributes, "writingMode", Constants.EN_LR_TB);
+ int refOrient = XMLUtil.getAttributeAsInt(attributes, "referenceOrientation", 0);
RegionViewport rv = getCurrentRegionViewport();
body = new BodyRegion(Constants.FO_REGION_BODY,
- regionName, rv, columnCount, columnGap);
+ regionName, rv, columnCount, columnGap, wrMode, refOrient);
transferForeignObjects(attributes, body);
body.setCTM(getAttributeAsCTM(attributes, "ctm"));
setAreaAttributes(attributes, body);
@@ -1019,7 +1021,8 @@
String regionName = attributes.getValue("name");
RegionViewport rv = getCurrentRegionViewport();
RegionReference reg = new RegionReference(side,
- regionName, rv);
+ regionName, rv, XMLUtil.getAttributeAsInt(attributes, "writingMode", Constants.EN_LR_TB),
+ XMLUtil.getAttributeAsInt(attributes, "referenceOrientation", 0));
transferForeignObjects(attributes, reg);
reg.setCTM(getAttributeAsCTM(attributes, "ctm"));
setAreaAttributes(attributes, reg);
--- src/java/org/apache/fop/area/inline/TextArea.java (revision 919765)
+++ src/java/org/apache/fop/area/inline/TextArea.java (working copy)
@@ -67,6 +67,8 @@
*/
public void addWord(String word, int offset, int[] letterAdjust) {
WordArea wordArea = new WordArea(word, offset, letterAdjust);
+ wordArea.setChangeBars(getChangeBars());
+
addChildArea(wordArea);
wordArea.setParentArea(this);
}
@@ -80,6 +82,8 @@
*/
public void addSpace(char space, int offset, boolean adjustable) {
SpaceArea spaceArea = new SpaceArea(space, offset, adjustable);
+ spaceArea.setChangeBars(getChangeBars());
+
addChildArea(spaceArea);
spaceArea.setParentArea(this);
}
--- src/java/org/apache/fop/area/RegionReference.java (revision 919765)
+++ src/java/org/apache/fop/area/RegionReference.java (working copy)
@@ -22,6 +22,8 @@
import java.util.ArrayList;
import java.util.List;
+import org.apache.fop.datatypes.Numeric;
+import org.apache.fop.fo.Constants;
import org.apache.fop.fo.pagination.Region;
/**
@@ -36,8 +38,9 @@
private int regionClass;
private String regionName;
private CTM ctm;
+ private int writingMode;
+ private int referenceOrientation;
-
// the list of block areas from the static flow
private ArrayList blocks = new ArrayList();
@@ -51,7 +54,8 @@
* @param parent the viewport for this region.
*/
public RegionReference(Region regionFO, RegionViewport parent) {
- this(regionFO.getNameId(), regionFO.getRegionName(), parent);
+ this(regionFO.getNameId(), regionFO.getRegionName(), parent,
+ Constants.EN_LR_TB, 0);
}
/**
@@ -60,10 +64,16 @@
* @param regionClass the region class (as returned by Region.getNameId())
* @param regionName the name of the region (as returned by Region.getRegionName())
* @param parent the viewport for this region.
+ * @param wrMode writing mode
+ * @param refOrient reference orientation
*/
- public RegionReference(int regionClass, String regionName, RegionViewport parent) {
+ public RegionReference(int regionClass, String regionName, RegionViewport parent,
+ int wrMode, int refOrient) {
this.regionClass = regionClass;
this.regionName = regionName;
+ this.writingMode = wrMode;
+ this.referenceOrientation = refOrient;
+
addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
regionViewport = parent;
}
@@ -141,7 +151,8 @@
* @return a copy of this region reference area
*/
public Object clone() {
- RegionReference rr = new RegionReference(regionClass, regionName, regionViewport);
+ RegionReference rr = new RegionReference(regionClass, regionName,
+ regionViewport, writingMode, referenceOrientation);
rr.ctm = ctm;
rr.setIPD(getIPD());
rr.blocks = (ArrayList)blocks.clone();
@@ -157,4 +168,16 @@
sb.append("}");
return sb.toString();
}
+
+
+ /** @return writing mode of region reference area */
+ public int getWritingMode() {
+ return writingMode;
+ }
+
+ /** @return reference orientation of region reference area */
+ public int getReferenceOrientation() {
+ return referenceOrientation;
+ }
+
}
--- src/java/org/apache/fop/area/Area.java (revision 919765)
+++ src/java/org/apache/fop/area/Area.java (working copy)
@@ -21,6 +21,7 @@
import java.io.Serializable;
import java.util.Map;
+import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -136,8 +137,28 @@
*/
protected static Log log = LogFactory.getLog(Area.class);
-
/**
+ * The vector of change bars this area is affected by
+ */
+ private Vector/**/ changeBars = null;
+
+ /**
+ * Return the vector of change bars this area is affected by
+ * @return Vector of change bars or null
+ */
+ public Vector/**/ getChangeBars() {
+ return changeBars;
+ }
+
+ /**
+ * Set set of change bars affecting this area
+ * @param cbs The vector of change bars affecting the area
+ */
+ public void setChangeBars(Vector/**/ cbs) {
+ changeBars = cbs;
+ }
+
+ /**
* Get the area class of this area.
*
* @return the area class