From 4cc6b90a0f88fa93cec45d390cdb0bca52238cd6 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 8 Jun 2006 12:46:50 +0000 Subject: [PATCH] Added region-body_display-align to demonstrate the default behaviour for adjustable spaces when display-align is set to "auto". Reactivated proprietary display-align="distribute" so a block-container can cause its content to be "justified" in the reference area if it's large enough and the adjustable elements (min/opt/max) allow for it. I may be misusing the original intended behaviour of "distribute" but for block-container this seemed suitable since it's destined to produce only one viewport/reference pair if possible. Test added that demonstrates the proprietary value on block-container. Note: on normal region-body elements, display-align="distribute" has currently no effect since the code did not evolve with the changes in the layout engine. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@412735 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/fop/layoutmgr/AbstractBreaker.java | 59 ++++++++-- .../fop/layoutmgr/PageBreakingAlgorithm.java | 37 +++--- ...ock-container_display-align_distribute.xml | 108 ++++++++++++++++++ .../region-body_display-align.xml | 84 ++++++++++++++ 4 files changed, 262 insertions(+), 26 deletions(-) create mode 100644 test/layoutengine/standard-testcases/block-container_display-align_distribute.xml create mode 100644 test/layoutengine/standard-testcases/region-body_display-align.xml diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java index 55fb76ff2..4164af3ff 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java @@ -72,15 +72,32 @@ public abstract class AbstractBreaker { */ private int startOn; - public BlockSequence(int iStartOn) { + private int displayAlign; + + /** + * Creates a new BlockSequence. + * @param iStartOn the kind of page the sequence should start on. One of EN_ANY, EN_COLUMN, + * EN_ODD_PAGE, EN_EVEN_PAGE. + * @param displayAlign the value for the display-align property + */ + public BlockSequence(int iStartOn, int displayAlign) { super(); startOn = iStartOn; + this.displayAlign = displayAlign; } + /** + * @return the kind of page the sequence should start on. One of EN_ANY, EN_COLUMN, + * EN_ODD_PAGE, EN_EVEN_PAGE. + */ public int getStartOn() { return this.startOn; } + /** @return the value for the display-align property */ + public int getDisplayAlign() { + return this.displayAlign; + } /** * Finalizes a Knuth sequence. * @return a finalized sequence. @@ -103,10 +120,18 @@ public abstract class AbstractBreaker { if (this.size() > ignoreAtStart) { // add the elements representing the space at the end of the last line // and the forced break - this.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, null, false)); - this.add(new KnuthGlue(0, 10000000, 0, null, false)); - this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, breakPosition, false)); - ignoreAtEnd = 3; + if (getDisplayAlign() == Constants.EN_X_DISTRIBUTE && isSinglePartFavored()) { + this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, + false, breakPosition, false)); + ignoreAtEnd = 1; + } else { + this.add(new KnuthPenalty(0, KnuthElement.INFINITE, + false, null, false)); + this.add(new KnuthGlue(0, 10000000, 0, null, false)); + this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, + false, breakPosition, false)); + ignoreAtEnd = 3; + } return this; } else { this.clear(); @@ -117,7 +142,7 @@ public abstract class AbstractBreaker { public BlockSequence endBlockSequence(Position breakPosition) { KnuthSequence temp = endSequence(breakPosition); if (temp != null) { - BlockSequence returnSequence = new BlockSequence(startOn); + BlockSequence returnSequence = new BlockSequence(startOn, displayAlign); returnSequence.addAll(temp); returnSequence.ignoreAtEnd = this.ignoreAtEnd; return returnSequence; @@ -125,6 +150,7 @@ public abstract class AbstractBreaker { return null; } } + } /** blockListIndex of the current BlockSequence in blockLists */ @@ -238,12 +264,18 @@ public abstract class AbstractBreaker { childLC.setStackLimit(new MinOptMax(flowBPD)); if (getCurrentDisplayAlign() == Constants.EN_X_FILL) { - //EN_FILL is non-standard (by LF) + //EN_X_FILL is non-standard (by LF) + alignment = Constants.EN_JUSTIFY; + } else if (getCurrentDisplayAlign() == Constants.EN_X_DISTRIBUTE) { + //EN_X_DISTRIBUTE is non-standard (by LF) alignment = Constants.EN_JUSTIFY; } else { alignment = Constants.EN_START; } alignmentLast = Constants.EN_START; + if (isSinglePartFavored() && alignment == Constants.EN_JUSTIFY) { + alignmentLast = Constants.EN_JUSTIFY; + } childLC.setBPAlignment(alignment); BlockSequence blockList; @@ -283,7 +315,7 @@ public abstract class AbstractBreaker { int iOptPageCount; BlockSequence effectiveList; - if (alignment == Constants.EN_JUSTIFY) { + if (getCurrentDisplayAlign() == Constants.EN_X_FILL) { /* justification */ effectiveList = justifyBoxes(blockList, alg, flowBPD); } else { @@ -415,8 +447,10 @@ public abstract class AbstractBreaker { } if (startElementIndex <= endElementIndex) { - log.debug(" addAreas from " + startElementIndex - + " to " + endElementIndex); + if (log.isDebugEnabled()) { + log.debug(" addAreas from " + startElementIndex + + " to " + endElementIndex); + } childLC = new LayoutContext(0); // set the space adjustment ratio childLC.setSpaceAdjust(pbp.bpdAdjust); @@ -512,7 +546,7 @@ public abstract class AbstractBreaker { nextSequenceStartsOn = handleSpanChange(childLC, nextSequenceStartsOn); return nextSequenceStartsOn; } - blockList = new BlockSequence(nextSequenceStartsOn); + blockList = new BlockSequence(nextSequenceStartsOn, getCurrentDisplayAlign()); //Only implemented by the PSLM nextSequenceStartsOn = handleSpanChange(childLC, nextSequenceStartsOn); @@ -767,7 +801,8 @@ public abstract class AbstractBreaker { // create a new sequence: the new elements will contain the // Positions // which will be used in the addAreas() phase - BlockSequence effectiveList = new BlockSequence(blockList.getStartOn()); + BlockSequence effectiveList = new BlockSequence(blockList.getStartOn(), + blockList.getDisplayAlign()); effectiveList.addAll(getCurrentChildLM().getChangedKnuthElements( blockList.subList(0, blockList.size() - blockList.ignoreAtEnd), /* 0, */0)); diff --git a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java index 42ac990b6..0c3012426 100644 --- a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java +++ b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java @@ -24,6 +24,7 @@ import java.util.ListIterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; import org.apache.fop.fo.FObj; import org.apache.fop.layoutmgr.AbstractBreaker.PageBreakPosition; @@ -512,9 +513,9 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } else if (prevSplitLength > 0) { // prevIndex is -1 if we have added only some whole footnotes footnoteListIndex = (prevIndex != -1) ? listIndex : listIndex - 1; - footnoteElementIndex = (prevIndex != -1) ? - prevIndex : - ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1; + footnoteElementIndex = (prevIndex != -1) + ? prevIndex + : ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1; } return prevSplitLength; } @@ -636,8 +637,9 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { // add a whole footnote availableBPD -= ((Integer) lengthList.get(footnoteListIndex)).intValue() - insertedFootnotesLength; - insertedFootnotesLength = ((Integer) lengthList.get(footnoteListIndex)).intValue(); - footnoteElementIndex = ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1; + insertedFootnotesLength = ((Integer)lengthList.get(footnoteListIndex)).intValue(); + footnoteElementIndex + = ((LinkedList)footnotesList.get(footnoteListIndex)).size() - 1; } else if ((split = getFootnoteSplit(footnoteListIndex, footnoteElementIndex, insertedFootnotesLength, availableBPD, true)) > 0) { @@ -650,7 +652,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { // cannot add any content: create a new node and start again KnuthPageNode node = (KnuthPageNode) createNode(lastNode.position, prevNode.line + 1, 1, - insertedFootnotesLength - prevNode.totalFootnotes, 0, 0, + insertedFootnotesLength - prevNode.totalFootnotes, + 0, 0, 0, 0, 0, 0, 0, prevNode); addNode(node.line, node); @@ -688,15 +691,15 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } prevNode.next = n.next; if (prevNode.next == null) { - activeLines[line*2+1] = prevNode; + activeLines[line * 2 + 1] = prevNode; } } else { log.error("Should be first"); } } else { - activeLines[line*2] = node.next; + activeLines[line * 2] = node.next; if (node.next == null) { - activeLines[line*2+1] = null; + activeLines[line * 2 + 1] = null; } while (startLine < endLine && getNode(startLine) == null) { startLine++; @@ -741,7 +744,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { getFObj())); } } - int blockAlignment = (bestActiveNode.line < total) ? alignment : alignmentLast; + boolean isNonLastPage = (bestActiveNode.line < total); + int blockAlignment = isNonLastPage ? alignment : alignmentLast; // it is always allowed to adjust space, so the ratio must be set regardless of // the value of the property display-align; the ratio must be <= 1 double ratio = bestActiveNode.adjustRatio; @@ -749,7 +753,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { // page break with a negative difference: // spaces always have enough shrink difference = 0; - } else if (ratio <= 1 && bestActiveNode.line < total) { + } else if (ratio <= 1 && isNonLastPage) { // not-last page break with a positive difference smaller than the available stretch: // spaces can stretch to fill the whole difference difference = 0; @@ -761,7 +765,12 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } else { // last page with a positive difference: // spaces do not need to stretch - ratio = 0; + if (blockAlignment != Constants.EN_JUSTIFY) { + ratio = 0; + } else { + //Stretch as much as possible on last page + difference = 0; + } } // compute the indexes of the first footnote list and the first element in that list int firstListIndex = ((KnuthPageNode) bestActiveNode.previous).footnoteListIndex; @@ -769,10 +778,10 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { if (footnotesList != null && firstElementIndex == ((LinkedList) footnotesList.get(firstListIndex)).size() - 1) { // advance to the next list - firstListIndex ++; + firstListIndex++; firstElementIndex = 0; } else { - firstElementIndex ++; + firstElementIndex++; } // add nodes at the beginning of the list, as they are found diff --git a/test/layoutengine/standard-testcases/block-container_display-align_distribute.xml b/test/layoutengine/standard-testcases/block-container_display-align_distribute.xml new file mode 100644 index 000000000..58137ce56 --- /dev/null +++ b/test/layoutengine/standard-testcases/block-container_display-align_distribute.xml @@ -0,0 +1,108 @@ + + + + + +

+ This test checks display-align="distribute" (The value "distribute" is a proprietary extension to XSL-FO). +

+
+ + + + + + + + + + + + "distribute" 4.2in + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + + + "distribute" 4.8in + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + + + "distribute" 3.85in + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + + + "auto" + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + + Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 + + + + + + + + + + + + + +
diff --git a/test/layoutengine/standard-testcases/region-body_display-align.xml b/test/layoutengine/standard-testcases/region-body_display-align.xml new file mode 100644 index 000000000..d06e7dcc6 --- /dev/null +++ b/test/layoutengine/standard-testcases/region-body_display-align.xml @@ -0,0 +1,84 @@ + + + + + +

+ This test checks the behaviour of display-align on a region-body. +

+
+ + + + + + + + + + + + block-container + + + block-container + + + block-container + + + block-container + + + block-container + + + block-container + + + + + + block-container + + + block-container + + + block-container + + + block-container + + + block-container + + + block-container + + + + + + + + + + + + +
-- 2.39.5