]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Added region-body_display-align to demonstrate the default behaviour for adjustable...
authorJeremias Maerki <jeremias@apache.org>
Thu, 8 Jun 2006 12:46:50 +0000 (12:46 +0000)
committerJeremias Maerki <jeremias@apache.org>
Thu, 8 Jun 2006 12:46:50 +0000 (12:46 +0000)
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

src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
test/layoutengine/standard-testcases/block-container_display-align_distribute.xml [new file with mode: 0644]
test/layoutengine/standard-testcases/region-body_display-align.xml [new file with mode: 0644]

index 55fb76ff20ab9709ef154ddd9dafed48ed69f741..4164af3ff6e4fac9bd12f53c55eee0c4cb3ea68a 100644 (file)
@@ -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));
index 42ac990b69f59701e018a55bd39bdfa64c04c534..0c301242689a5d68639610516ed5ea5c095e6015 100644 (file)
@@ -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 (file)
index 0000000..58137ce
--- /dev/null
@@ -0,0 +1,108 @@
+<?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>
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 (file)
index 0000000..d06e7dc
--- /dev/null
@@ -0,0 +1,84 @@
+<?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>