From 68e528df282383c9edd974802d566131ae8e17b4 Mon Sep 17 00:00:00 2001 From: Luca Furini Date: Mon, 21 Nov 2005 14:21:45 +0000 Subject: [PATCH] Implementation of hyphenation-ladder-count. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@345909 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/fo/flow/Block.java | 5 +++ .../fop/layoutmgr/BreakingAlgorithm.java | 31 ++++++++++++++++++- .../fop/layoutmgr/PageBreakingAlgorithm.java | 2 +- .../layoutmgr/inline/LineLayoutManager.java | 11 ++++--- .../apache/fop/KnuthAlgorithmTestCase.java | 6 ++-- 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/java/org/apache/fop/fo/flow/Block.java b/src/java/org/apache/fop/fo/flow/Block.java index 01f779ea7..bfe7ec008 100644 --- a/src/java/org/apache/fop/fo/flow/Block.java +++ b/src/java/org/apache/fop/fo/flow/Block.java @@ -218,6 +218,11 @@ public class Block extends FObjMixed { return breakBefore; } + /** @return the "hyphenation-ladder-count" property. */ + public Numeric getHyphenationLadderCount() { + return hyphenationLadderCount; + } + /** @return the "keep-with-next" property. */ public KeepProperty getKeepWithNext() { return keepWithNext; diff --git a/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java index ce12aa161..92d5c08d3 100644 --- a/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java +++ b/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java @@ -59,6 +59,9 @@ public abstract class BreakingAlgorithm { protected int repeatedFlaggedDemerit = 50; // demerit for consecutive lines belonging to incompatible fitness classes protected int incompatibleFitnessDemerit = 50; + // maximum number of consecutive lines ending with a flagged penalty + // only a value >= 1 is a significant limit + protected int maxFlaggedPenaltiesCount; /** * The threshold for considering breaks to be acceptable. @@ -130,12 +133,14 @@ public abstract class BreakingAlgorithm { private boolean partOverflowRecoveryActivated = true; public BreakingAlgorithm(int align, int alignLast, - boolean first, boolean partOverflowRecovery) { + boolean first, boolean partOverflowRecovery, + int maxFlagCount) { alignment = align; alignmentLast = alignLast; bFirst = first; this.partOverflowRecoveryActivated = partOverflowRecovery; this.best = new BestRecords(); + maxFlaggedPenaltiesCount = maxFlagCount; } @@ -760,6 +765,30 @@ public abstract class BreakingAlgorithm { && ((KnuthPenalty) getElement(activeNode.position)).isFlagged()) { // add demerit for consecutive breaks at flagged penalties demerits += repeatedFlaggedDemerit; + // there are at least two consecutive lines ending with a flagged penalty; + // check if the previous line end with a flagged penalty too, + // and if this situation is allowed + int flaggedPenaltiesCount = 2; + for (KnuthNode prevNode = activeNode.previous; + prevNode != null && flaggedPenaltiesCount <= maxFlaggedPenaltiesCount; + prevNode = prevNode.previous) { + KnuthElement prevElement = getElement(prevNode.position); + if (prevElement.isPenalty() + && ((KnuthPenalty) prevElement).isFlagged()) { + // the previous line ends with a flagged penalty too + flaggedPenaltiesCount ++; + } else { + // the previous line does not end with a flagged penalty, + // exit the loop + break; + } + } + if (maxFlaggedPenaltiesCount >= 1 + && flaggedPenaltiesCount > maxFlaggedPenaltiesCount) { + // add infinite demerits, so this break will not be chosen + // unless there isn't any alternative break + demerits += BestRecords.INFINITE_DEMERITS; + } } if (Math.abs(fitnessClass - activeNode.fitness) > 1) { // add demerit for consecutive breaks diff --git a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java index a6d912904..5a9ede6eb 100644 --- a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java +++ b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java @@ -68,7 +68,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { int alignment, int alignmentLast, MinOptMax footnoteSeparatorLength, boolean partOverflowRecovery) { - super(alignment, alignmentLast, true, partOverflowRecovery); + super(alignment, alignmentLast, true, partOverflowRecovery, 0); this.topLevelLM = topLevelLM; this.pageViewportProvider = pageViewportProvider; best = new BestPageRecords(); diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index d70a783fb..6fe1bf5f1 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -19,6 +19,7 @@ package org.apache.fop.layoutmgr.inline; import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.Numeric; import org.apache.fop.fo.Constants; import org.apache.fop.fo.flow.Block; import org.apache.fop.fo.properties.CommonHyphenation; @@ -52,8 +53,6 @@ import java.util.ArrayList; import java.util.LinkedList; import org.apache.fop.area.Trait; import org.apache.fop.fonts.Font; -import org.apache.fop.layoutmgr.BreakingAlgorithm.KnuthNode; -import org.apache.fop.layoutmgr.inline.InlineStackingLayoutManager.StackingIter; import org.apache.fop.traits.MinOptMax; @@ -79,6 +78,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager textIndent = fobj.getTextIndent(); lastLineEndIndent = fobj.getLastLineEndIndent(); hyphenationProperties = fobj.getCommonHyphenation(); + hyphenationLadderCount = fobj.getHyphenationLadderCount(); wrapOption = fobj.getWrapOption(); // effectiveAlignment = getEffectiveAlignment(textAlignment, textAlignmentLast); @@ -140,6 +140,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager private Length lastLineEndIndent; private int iIndents = 0; private CommonHyphenation hyphenationProperties; + private Numeric hyphenationLadderCount; private int wrapOption = EN_WRAP; //private LayoutProps layoutProps; @@ -385,8 +386,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager int textAlign, int textAlignLast, int indent, int fillerWidth, int lh, int ld, int fl, boolean first, - LineLayoutManager llm) { - super(textAlign, textAlignLast, first, false); + int maxFlagCount, LineLayoutManager llm) { + super(textAlign, textAlignLast, first, false, maxFlagCount); pageAlignment = pageAlign; textIndent = indent; fillerMinWidth = fillerWidth; @@ -1045,6 +1046,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager textIndent.getValue(this), currPar.lineFiller.opt, lineHeight.getValue(this), lead, follow, (knuthParagraphs.indexOf(currPar) == 0), + hyphenationLadderCount.getEnum() == EN_NO_LIMIT ? + 0 : hyphenationLadderCount.getValue(), this); if (hyphenationProperties.hyphenate == EN_TRUE) { diff --git a/test/java/org/apache/fop/KnuthAlgorithmTestCase.java b/test/java/org/apache/fop/KnuthAlgorithmTestCase.java index 4a7047a75..39d4190ff 100644 --- a/test/java/org/apache/fop/KnuthAlgorithmTestCase.java +++ b/test/java/org/apache/fop/KnuthAlgorithmTestCase.java @@ -66,7 +66,7 @@ public class KnuthAlgorithmTestCase extends TestCase { * @throws Exception if an error occurs */ public void test1() throws Exception { - MyBreakingAlgorithm algo = new MyBreakingAlgorithm(0, 0, true, true); + MyBreakingAlgorithm algo = new MyBreakingAlgorithm(0, 0, true, true, 0); algo.setConstantLineWidth(30000); KnuthSequence seq = getKnuthSequence1(); algo.findBreakingPoints(seq, 1, true, BreakingAlgorithm.ALL_BREAKS); @@ -87,8 +87,8 @@ public class KnuthAlgorithmTestCase extends TestCase { private List parts = new java.util.ArrayList(); public MyBreakingAlgorithm(int align, int alignLast, boolean first, - boolean partOverflowRecovery) { - super(align, alignLast, first, partOverflowRecovery); + boolean partOverflowRecovery, int maxFlagCount) { + super(align, alignLast, first, partOverflowRecovery, maxFlagCount); } public Part[] getParts() { -- 2.39.5