]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Content in block-containers makes better use of shrink to fit content vertically...
authorJeremias Maerki <jeremias@apache.org>
Tue, 25 Apr 2006 17:03:49 +0000 (17:03 +0000)
committerJeremias Maerki <jeremias@apache.org>
Tue, 25 Apr 2006 17:03:49 +0000 (17:03 +0000)
PageBreakingAlgorithm now writes to a different logger than its base class. Makes debugging easier.
Some minor logging improvements to improve clarity.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@396915 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java
src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
status.xml
test/layoutengine/standard-testcases/block-container_squeeze-content_1.xml [new file with mode: 0644]

index eea83f1ab5ad6ebc61433e24631c3c5f0a400df0..0192008b9fb7fd1f2cb6c3534c9300cb114e6365 100644 (file)
@@ -152,6 +152,13 @@ public abstract class AbstractBreaker {
         return true;
     }
 
+    /**
+     * @return true if one a single part should be produced if possible (ex. for block-containers)
+     */
+    protected boolean isSinglePartFavored() {
+        return false;
+    }
+    
     /**
      * Returns the PageProvider if any. PageBreaker overrides this method because each
      * page may have a different available BPD which needs to be accessible to the breaking
@@ -272,7 +279,7 @@ public abstract class AbstractBreaker {
                 PageBreakingAlgorithm alg = new PageBreakingAlgorithm(getTopLevelLM(),
                         getPageProvider(),
                         alignment, alignmentLast, footnoteSeparatorLength,
-                        isPartOverflowRecoveryActivated(), autoHeight);
+                        isPartOverflowRecoveryActivated(), autoHeight, isSinglePartFavored());
                 int iOptPageCount;
 
                 BlockSequence effectiveList;
index 56a8465b76e639b42542c6cf5cc4bd770a40fba4..fb1f82dea18a568a8abbc01db0ba4a2927dea49b 100644 (file)
@@ -41,7 +41,7 @@ public class BalancingColumnBreakingAlgorithm extends PageBreakingAlgorithm {
             boolean partOverflowRecovery,\r
             int columnCount) {\r
         super(topLevelLM, pageProvider, alignment, alignmentLast, \r
-                footnoteSeparatorLength, partOverflowRecovery, false);\r
+                footnoteSeparatorLength, partOverflowRecovery, false, false);\r
         this.columnCount = columnCount;\r
         this.considerTooShort = true; //This is important!\r
     }\r
index 1af26cb4ddc21f2a28d12d9bec29e30e77af0f9b..16b45a1a0c333deebe13018d466fe8d09433d004 100644 (file)
@@ -557,6 +557,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
             return false;
         }
 
+        /** @see org.apache.fop.layoutmgr.AbstractBreaker#isSinglePartFavored() */
+        protected boolean isSinglePartFavored() {
+            return true;
+        }
+
         public int getDifferenceOfFirstPart() {
             PageBreakPosition pbp = (PageBreakPosition)this.deferredAlg.getPageBreaks().getFirst();
             return pbp.difference;
index 0e7a554b8a804d439b21ac6fa7bb973a38381f41..a24f6fc39cad11daa44c5979b3168797617fd803 100644 (file)
@@ -41,8 +41,11 @@ import org.apache.fop.traits.MinOptMax;
  */
 public abstract class BreakingAlgorithm {
 
-    /** the logger */
-    protected static Log log = LogFactory.getLog(BreakingAlgorithm.class);
+    /** the logger for the class */
+    protected static Log classLog = LogFactory.getLog(BreakingAlgorithm.class);
+    
+    /** the logger for the instance */
+    protected Log log = classLog;
     
     protected static final int INFINITE_RATIO = 1000;
 
@@ -547,7 +550,8 @@ public abstract class BreakingAlgorithm {
     protected void considerLegalBreak(KnuthElement element, int elementIdx) {
 
         if (log.isTraceEnabled()) {
-            log.trace("Feasible breakpoint at " + par.indexOf(element) + " " + totalWidth + "+" + totalStretch + "-" + totalShrink);
+            log.trace("considerLegalBreak() at " + elementIdx 
+                    + " (" + totalWidth + "+" + totalStretch + "-" + totalShrink + "), parts/lines: "+ startLine + "-" + endLine);
             log.trace("\tCurrent active node list: " + activeNodeCount + " " + this.toString("\t"));
         }
 
@@ -691,7 +695,8 @@ public abstract class BreakingAlgorithm {
                 // the nodes in activeList must be ordered
                 // by line number and position;
                 if (log.isTraceEnabled()) {
-                    log.trace("\tInsert new break in list of " + activeNodeCount);
+                    log.trace("\tInsert new break in list of " + activeNodeCount 
+                            + " from fitness class " + i);
                 }
                 KnuthNode newNode = createNode(elementIdx, line + 1, i,
                                                newWidth, newStretch, newShrink);
index 354f2da8725af46c16f1fcc919808a880e932d71..42ac990b69f59701e018a55bd39bdfa64c04c534 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2005 The Apache Software Foundation.
+ * Copyright 2004-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.
@@ -22,6 +22,8 @@ import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.ListIterator;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FObj;
 import org.apache.fop.layoutmgr.AbstractBreaker.PageBreakPosition;
@@ -30,6 +32,9 @@ import org.apache.fop.traits.MinOptMax;
 
 class PageBreakingAlgorithm extends BreakingAlgorithm {
 
+    /** the logger for the class */
+    protected static Log classLog = LogFactory.getLog(PageBreakingAlgorithm.class);
+
     private LayoutManager topLevelLM;
     private PageSequenceLayoutManager.PageProvider pageProvider;
     private LinkedList pageBreaks = null;
@@ -68,12 +73,17 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
     //Controls whether overflows should be warned about or not
     private boolean autoHeight = false;
     
+    //Controls whether a single part should be forced if possible (ex. block-container)
+    private boolean favorSinglePart = false;
+    
     public PageBreakingAlgorithm(LayoutManager topLevelLM,
                                  PageSequenceLayoutManager.PageProvider pageProvider,
                                  int alignment, int alignmentLast,
                                  MinOptMax footnoteSeparatorLength,
-                                 boolean partOverflowRecovery, boolean autoHeight) {
+                                 boolean partOverflowRecovery, boolean autoHeight,
+                                 boolean favorSinglePart) {
         super(alignment, alignmentLast, true, partOverflowRecovery, 0);
+        this.log = classLog;
         this.topLevelLM = topLevelLM;
         this.pageProvider = pageProvider;
         best = new BestPageRecords();
@@ -83,6 +93,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
             footnoteSeparatorLength.max += 10000;
         }
         this.autoHeight = autoHeight;
+        this.favorSinglePart = favorSinglePart;
     }
 
     /**
@@ -583,9 +594,11 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
         if (footnotesPending) {
             if (footnoteListIndex < footnotesList.size() - 1) {
                 // add demerits for the deferred footnotes
-                demerits += (footnotesList.size() - 1 - footnoteListIndex) * deferredFootnoteDemerits;
+                demerits += (footnotesList.size() - 1 - footnoteListIndex) 
+                                * deferredFootnoteDemerits;
             }
-            if (footnoteElementIndex < ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1) {
+            if (footnoteElementIndex 
+                    < ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1) {
                 // add demerits for the footnote split between pages
                 demerits += splitFootnoteDemerits;
             }
@@ -781,7 +794,15 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
         KnuthNode bestActiveNode = null;
         for (int i = startLine; i < endLine; i++) {
             for (KnuthNode node = getNode(i); node != null; node = node.next) {
-                bestActiveNode = compareNodes(bestActiveNode, node);
+                if (favorSinglePart 
+                        && node.line > 1 
+                        && bestActiveNode != null
+                        && Math.abs(bestActiveNode.difference) < bestActiveNode.availableShrink) {
+                    //favor current best node, so just skip the current node because it would
+                    //result in more than one part
+                } else {
+                    bestActiveNode = compareNodes(bestActiveNode, node);
+                }
                 if (node != bestActiveNode) {
                     removeNode(i, node);
                 }
index a047d4820e36e484ef8cf4d3579465e0870fbaed..c3415aeb0b46da8bd1c2f0d3120e63dda5ed2abe 100644 (file)
@@ -373,7 +373,7 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
                     getPageProvider(),
                     alg.getAlignment(), alg.getAlignmentLast(), 
                     footnoteSeparatorLength,
-                    isPartOverflowRecoveryActivated(), false);
+                    isPartOverflowRecoveryActivated(), false, false);
             //alg.setConstantLineWidth(flowBPD);
             int iOptPageCount = algRestart.findBreakingPoints(effectiveList,
                         newStartPos,
index d99cb10e562ce37f723cab0966924f2a318f3c81..1b1a00c275653b6f8b60a5044e4d12322788e8d0 100644 (file)
 
   <changes>
     <release version="FOP Trunk">
+      <action context="Code" dev="JM" type="update">
+        Content in block-containers makes better use of shrink to fit content vertically
+        into the available area. This can be used indirectly to justify content vertically
+        in a block-container.
+      </action>
       <action context="Code" dev="JM" type="fix">
         Bugfix: basic-links with internal destinations in documents with multiple 
         page-sequences sometimes pointed at the wrong page.
diff --git a/test/layoutengine/standard-testcases/block-container_squeeze-content_1.xml b/test/layoutengine/standard-testcases/block-container_squeeze-content_1.xml
new file mode 100644 (file)
index 0000000..c3f6529
--- /dev/null
@@ -0,0 +1,51 @@
+<?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 if content is properly squeezed (spaces reduced) inside block-containers to fit content in the box if possible.
+    </p>
+    <p>
+      Note: if there are no break points and the content would overflow, the content may be squeezed by more than the available shrink.
+    </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" margin="20pt">
+          <fo:region-body/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="normal" text-align="justify">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block-container id="bc" height="10em" background-color="yellow">
+            <fo:block id="b1" space-after.optimum="3em" space-after.minimum="0pt">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam hendrerit posuere nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque placerat semper nulla.</fo:block>
+            <fo:block id="b2">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam hendrerit posuere nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque placerat semper nulla.</fo:block>
+          </fo:block-container>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="62400" xpath="//block[@prod-id = 'b1']/@bpda"/>
+    <eval expected="57600" xpath="//block[@prod-id = 'b2']/@bpda"/>
+    <eval expected="120000" xpath="//block[@prod-id = 'bc' and @is-reference-area = 'true']/@bpd"/>
+    <true xpath="//block[@prod-id = 'bc' and @is-reference-area = 'true']/@bpd = (//block[@prod-id = 'b1']/@bpda + //block[@prod-id = 'b2']/@bpda)"/>
+    <eval expected="4800" xpath="//block[@prod-id = 'b1']/@space-after"/>
+  </checks>
+</testcase>