You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2005/06/23 17:01:14 UTC
cvs commit: xml-fop/src/java/org/apache/fop/area Page.java
jeremias 2005/06/23 08:01:14
Modified: src/java/org/apache/fop/layoutmgr
PageSequenceLayoutManager.java
BlockContainerLayoutManager.java
LineLayoutManager.java AbstractBreaker.java
BreakingAlgorithm.java PageBreakingAlgorithm.java
StaticContentLayoutManager.java
src/java/org/apache/fop/area Page.java
Log:
First parts on a page which don't fit are moved to the next page. A counter avoids endless loops.
Fixes normal-breaking5.xml.
Revision Changes Path
1.71 +6 -1 xml-fop/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
Index: PageSequenceLayoutManager.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -r1.70 -r1.71
--- PageSequenceLayoutManager.java 22 Jun 2005 14:59:54 -0000 1.70
+++ PageSequenceLayoutManager.java 23 Jun 2005 15:01:14 -0000 1.71
@@ -286,6 +286,11 @@
firstPart = false;
}
+ /** @see org.apache.fop.layoutmgr.AbstractBreaker#handleEmptyContent() */
+ protected void handleEmptyContent() {
+ curPV.getPage().fakeNonEmpty();
+ }
+
protected void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp) {
// add footnote areas
if (pbp.footnoteFirstListIndex < pbp.footnoteLastListIndex
1.44 +6 -0 xml-fop/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
Index: BlockContainerLayoutManager.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- BlockContainerLayoutManager.java 7 Jun 2005 20:43:43 -0000 1.43
+++ BlockContainerLayoutManager.java 23 Jun 2005 15:01:14 -0000 1.44
@@ -447,6 +447,12 @@
this.ipd = ipd;
}
+ /** @see org.apache.fop.layoutmgr.AbstractBreaker#isPartOverflowRecoveryActivated() */
+ protected boolean isPartOverflowRecoveryActivated() {
+ //For block-containers, this must be disabled because of wanted overflow.
+ return false;
+ }
+
public int getDifferenceOfFirstPart() {
PageBreakPosition pbp = (PageBreakPosition)this.deferredAlg.getPageBreaks().getFirst();
return pbp.difference;
1.51 +1 -1 xml-fop/src/java/org/apache/fop/layoutmgr/LineLayoutManager.java
Index: LineLayoutManager.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/LineLayoutManager.java,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- LineLayoutManager.java 15 Jun 2005 09:08:34 -0000 1.50
+++ LineLayoutManager.java 23 Jun 2005 15:01:14 -0000 1.51
@@ -273,7 +273,7 @@
int indent, int fillerWidth,
int lh, int ld, int fl, int ms, boolean first,
LineLayoutManager llm) {
- super(textAlign, textAlignLast, first);
+ super(textAlign, textAlignLast, first, false);
pageAlignment = pageAlign;
textIndent = indent;
fillerMinWidth = fillerWidth;
1.11 +22 -2 xml-fop/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
Index: AbstractBreaker.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- AbstractBreaker.java 22 Jun 2005 14:59:54 -0000 1.10
+++ AbstractBreaker.java 23 Jun 2005 15:01:14 -0000 1.11
@@ -106,6 +106,15 @@
protected abstract LayoutManager getCurrentChildLM();
/**
+ * Controls the behaviour of the algorithm in cases where the first element of a part
+ * overflows a line/page.
+ * @return true if the algorithm should try to send the element to the next line/page.
+ */
+ protected boolean isPartOverflowRecoveryActivated() {
+ return true;
+ }
+
+ /**
* Returns the PageViewportProvider if any. PageBreaker overrides this method because each
* page may have a different available BPD which needs to be accessible to the breaking
* algorithm.
@@ -131,6 +140,13 @@
//nop
}
+ /**
+ * This method is called when no content is available for a part. Used to force empty pages.
+ */
+ protected void handleEmptyContent() {
+ //nop
+ }
+
protected abstract void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp);
protected LayoutContext createLayoutContext() {
@@ -182,7 +198,8 @@
+ "), flow BPD =" + flowBPD);
PageBreakingAlgorithm alg = new PageBreakingAlgorithm(getTopLevelLM(),
getPageViewportProvider(),
- alignment, alignmentLast, footnoteSeparatorLength);
+ alignment, alignmentLast, footnoteSeparatorLength,
+ isPartOverflowRecoveryActivated());
int iOptPageCount;
BlockSequence effectiveList;
@@ -328,6 +345,9 @@
addAreas(new KnuthPossPosIter(effectiveList,
startElementIndex, endElementIndex + 1), childLC);
+ } else {
+ //no content for this part
+ handleEmptyContent();
}
finishPart(alg, pbp);
1.10 +64 -19 xml-fop/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
Index: BreakingAlgorithm.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- BreakingAlgorithm.java 22 Jun 2005 14:55:33 -0000 1.9
+++ BreakingAlgorithm.java 23 Jun 2005 15:01:14 -0000 1.10
@@ -21,6 +21,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.layoutmgr.PageBreakingAlgorithm.KnuthPageNode;
import org.apache.fop.traits.MinOptMax;
/**
@@ -45,6 +46,8 @@
protected static final int INFINITE_RATIO = 1000;
+ private static final int MAX_RECOVERY_ATTEMPTS = 50;
+
// parameters of Knuth's algorithm:
// penalty value for flagged penalties
private int flaggedPenalty = 50;
@@ -117,57 +120,66 @@
protected BestRecords best;
private KnuthNode[] positions;
+ /** @see isPartOverflowRecoveryActivated() */
+ private boolean partOverflowRecoveryActivated = true;
+
public BreakingAlgorithm(int align, int alignLast,
- boolean first) {
+ boolean first, boolean partOverflowRecovery) {
alignment = align;
alignmentLast = alignLast;
bFirst = first;
+ this.partOverflowRecoveryActivated = partOverflowRecovery;
this.best = new BestRecords();
}
// this class represent a feasible breaking point
protected class KnuthNode {
- // index of the breakpoint represented by this node
+ /** index of the breakpoint represented by this node */
public int position;
- // number of the line ending at this breakpoint
+ /** number of the line ending at this breakpoint */
public int line;
- // fitness class of the line ending at his breakpoint
+ /** fitness class of the line ending at his breakpoint */
public int fitness;
- // accumulated width of the KnuthElements
+ /** accumulated width of the KnuthElements */
public int totalWidth;
- // accumulated stretchability of the KnuthElements
+ /** accumulated stretchability of the KnuthElements */
public int totalStretch;
- // accumulated shrinkability of the KnuthElements
+ /** accumulated shrinkability of the KnuthElements */
public int totalShrink;
- // adjustment ratio if the line ends at this breakpoint
+ /** adjustment ratio if the line ends at this breakpoint */
public double adjustRatio;
- // available stretch of the line ending at this breakpoint
+ /** available stretch of the line ending at this breakpoint */
public int availableShrink;
- // available shrink of the line ending at this breakpoint
+ /** available shrink of the line ending at this breakpoint */
public int availableStretch;
- // difference between target and actual line width
+ /** difference between target and actual line width */
public int difference;
- // minimum total demerits up to this breakpoint
+ /** minimum total demerits up to this breakpoint */
public double totalDemerits;
- // best node for the preceding breakpoint
+ /** best node for the preceding breakpoint */
public KnuthNode previous;
- // next possible node in the same line
+ /** next possible node in the same line */
public KnuthNode next;
-
+ /**
+ * Holds the number of subsequent recovery attempty that are made to get content fit
+ * into a line.
+ */
+ public int fitRecoveryCounter = 0;
+
public KnuthNode(int position, int line, int fitness,
int totalWidth, int totalStretch, int totalShrink,
double adjustRatio, int availableShrink, int availableStretch, int difference,
@@ -219,7 +231,7 @@
int availableShrink, int availableStretch,
int difference, int fitness) {
if (demerits > bestDemerits[fitness]) {
- log.error("New demerits value greter than the old one");
+ log.error("New demerits value greater than the old one");
}
bestDemerits[fitness] = demerits;
bestNode[fitness] = node;
@@ -282,7 +294,22 @@
}
}
-
+ /**
+ * @return the number of times the algorithm should try to move overflowing content to the
+ * next line/page.
+ */
+ protected int getMaxRecoveryAttempts() {
+ return MAX_RECOVERY_ATTEMPTS;
+ }
+
+ /**
+ * Controls the behaviour of the algorithm in cases where the first element of a part
+ * overflows a line/page.
+ * @return true if the algorithm should try to send the element to the next line/page.
+ */
+ protected boolean isPartOverflowRecoveryActivated() {
+ return this.partOverflowRecoveryActivated;
+ }
public abstract void updateData1(int total, double demerits) ;
@@ -367,7 +394,25 @@
return 0;
}
if (lastTooShort == null || lastForced.position == lastTooShort.position) {
- lastForced = lastTooLong;
+ if (isPartOverflowRecoveryActivated()) {
+ // content would overflow, insert empty line/page and try again
+ KnuthNode node = createNode(
+ lastTooLong.previous.position, lastTooLong.previous.line + 1, 1,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, lastTooLong.previous);
+ lastForced = node;
+ node.fitRecoveryCounter = lastTooLong.previous.fitRecoveryCounter + 1;
+ log.debug("first part doesn't fit into line, recovering: "
+ + node.fitRecoveryCounter);
+ if (node.fitRecoveryCounter > getMaxRecoveryAttempts()) {
+ throw new RuntimeException("Some content could not fit "
+ + "into a line/page after " + getMaxRecoveryAttempts()
+ + " attempts. Giving up to avoid an endless loop.");
+ }
+ } else {
+ lastForced = lastTooLong;
+ }
} else {
lastForced = lastTooShort;
}
1.10 +4 -3 xml-fop/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
Index: PageBreakingAlgorithm.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- PageBreakingAlgorithm.java 22 Jun 2005 14:57:13 -0000 1.9
+++ PageBreakingAlgorithm.java 23 Jun 2005 15:01:14 -0000 1.10
@@ -67,8 +67,9 @@
public PageBreakingAlgorithm(LayoutManager topLevelLM,
PageSequenceLayoutManager.PageViewportProvider pvProvider,
int alignment, int alignmentLast,
- MinOptMax fnSeparatorLength) {
- super(alignment, alignmentLast, true);
+ MinOptMax fnSeparatorLength,
+ boolean partOverflowRecovery) {
+ super(alignment, alignmentLast, true, partOverflowRecovery);
this.topLevelLM = topLevelLM;
this.pvProvider = pvProvider;
best = new BestPageRecords();
1.17 +6 -0 xml-fop/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
Index: StaticContentLayoutManager.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- StaticContentLayoutManager.java 10 Jun 2005 03:56:49 -0000 1.16
+++ StaticContentLayoutManager.java 23 Jun 2005 15:01:14 -0000 1.17
@@ -236,6 +236,12 @@
this.displayAlign = displayAlign;
}
+ /** @see org.apache.fop.layoutmgr.AbstractBreaker#isPartOverflowRecoveryActivated() */
+ protected boolean isPartOverflowRecoveryActivated() {
+ //For side regions, this must be disabled because of wanted overflow.
+ return false;
+ }
+
public boolean isOverflow() {
return this.overflow;
}
1.11 +14 -3 xml-fop/src/java/org/apache/fop/area/Page.java
Index: Page.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/area/Page.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- Page.java 14 May 2005 05:22:16 -0000 1.10
+++ Page.java 23 Jun 2005 15:01:14 -0000 1.11
@@ -55,6 +55,9 @@
// temporary map of unresolved objects used when serializing the page
private HashMap unresolved = null;
+ /** Set to true to make this page behave as if it were not empty. */
+ private boolean fakeNonEmpty = false;
+
/**
* Empty constructor, for cloning
*/
@@ -110,6 +113,13 @@
}
/**
+ * Call this method to force this page to pretend not to be empty.
+ */
+ public void fakeNonEmpty() {
+ this.fakeNonEmpty = true;
+ }
+
+ /**
* Creates a RegionViewport Area object for this pagination Region.
* @param reldims relative dimensions
* @param pageCTM page coordinate transformation matrix
@@ -197,10 +207,11 @@
* @return whether any FOs have been added to the body region
*/
public boolean isEmpty() {
- if (regionBody == null) {
+ if (fakeNonEmpty) {
+ return false;
+ } else if (regionBody == null) {
return true;
- }
- else {
+ } else {
BodyRegion body = (BodyRegion)regionBody.getRegionReference();
return body.isEmpty();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org