*/
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.
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();
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;
return null;
}
}
+
}
/** blockListIndex of the current BlockSequence in blockLists */
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;
int iOptPageCount;
BlockSequence effectiveList;
- if (alignment == Constants.EN_JUSTIFY) {
+ if (getCurrentDisplayAlign() == Constants.EN_X_FILL) {
/* justification */
effectiveList = justifyBoxes(blockList, alg, flowBPD);
} else {
}
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);
nextSequenceStartsOn = handleSpanChange(childLC, nextSequenceStartsOn);
return nextSequenceStartsOn;
}
- blockList = new BlockSequence(nextSequenceStartsOn);
+ blockList = new BlockSequence(nextSequenceStartsOn, getCurrentDisplayAlign());
//Only implemented by the PSLM
nextSequenceStartsOn = handleSpanChange(childLC, nextSequenceStartsOn);
// 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));
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;
} 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;
}
// 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) {
// 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);
}
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++;
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;
// 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;
} 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;
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
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2006 The Apache Software Foundation
+
+ Licensed 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 display-align="distribute" (The value "distribute" is a proprietary extension to XSL-FO).
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+ <fo:region-body column-count="4" column-gap="5pt"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal" white-space-collapse="true">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block-container width="100%" height="4.2in" display-align="distribute" background-color="yellow">
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ "distribute" 4.2in
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ <!-- last -->
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="4.8in" display-align="distribute" background-color="yellow">
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ "distribute" 4.8in
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ <!-- last -->
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="3.85in" display-align="distribute" background-color="yellow">
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ "distribute" 3.85in
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ <!-- last -->
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="4.2in" display-align="auto" background-color="orange">
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ "auto"
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ <fo:block space-after.minimum="0.5em" space-after.optimum="1em" space-after.maximum="2em">
+ <!-- last -->
+ Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1 Text 1
+ </fo:block>
+ </fo:block-container>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <!-- check with 3 mpt tolerance -->
+ <eval expected="0" xpath="//flow[1]/block[1]/@bpd - //flow[1]/block[1]/block[1]/@bpd" tolerance="3"/>
+ <eval expected="14400" xpath="//flow[2]/block[1]/@bpd - //flow[2]/block[1]/block[1]/@bpd" tolerance="3"/>
+ <eval expected="0" xpath="//flow[3]/block[1]/@bpd - //flow[3]/block[1]/block[1]/@bpd" tolerance="3"/>
+ <eval expected="21600" xpath="//flow[4]/block[1]/@bpd - //flow[4]/block[1]/block[1]/@bpd" tolerance="3"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2006 The Apache Software Foundation
+
+ Licensed 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 the behaviour of display-align on a region-body.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+ <fo:region-body column-count="4" column-gap="5pt" display-align="auto"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>
+ <fo:block-container width="100%" height="88pt" background-color="yellow" space-before.minimum="0.5em" space-before.optimum="1em" space-before.maximum="4em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="88pt" background-color="yellow" space-before.minimum="0.5em" space-before.optimum="1em" space-before.maximum="4em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="88pt" background-color="yellow" space-before.minimum="0.5em" space-before.optimum="1em" space-before.maximum="4em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="88pt" background-color="yellow" space-before.minimum="0.5em" space-before.optimum="1em" space-before.maximum="4em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="88pt" background-color="yellow" space-before.minimum="0.5em" space-before.optimum="1em" space-before.maximum="4em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="88pt" background-color="yellow" space-before.minimum="0.5em" space-before.optimum="1em" space-before.maximum="4em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ </fo:block>
+
+ <fo:block break-before="column">
+ <fo:block-container width="100%" height="88pt" background-color="orange" space-before="1em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="88pt" background-color="orange" space-before="1em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="88pt" background-color="orange" space-before="1em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="88pt" background-color="orange" space-before="1em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="88pt" background-color="orange" space-before="1em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ <fo:block-container width="100%" height="88pt" background-color="orange" space-before="1em">
+ <fo:block>block-container</fo:block>
+ </fo:block-container>
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="0" xpath="//regionBody/@bpd - //flow[1]/block[1]/@bpd" tolerance="3"/>
+ <eval expected="72000" xpath="//regionBody/@bpd - //flow[2]/block[1]/@bpd" tolerance="3"/>
+ <eval expected="72000" xpath="//regionBody/@bpd - //flow[3]/block[1]/@bpd" tolerance="3"/>
+ <eval expected="72000" xpath="//regionBody/@bpd - //flow[4]/block[1]/@bpd" tolerance="3"/>
+ </checks>
+</testcase>