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 vh...@apache.org on 2009/12/22 18:20:53 UTC
svn commit: r893238 [3/4] - in /xmlgraphics/fop/trunk:
src/java/org/apache/fop/area/ src/java/org/apache/fop/fo/properties/
src/java/org/apache/fop/layoutmgr/ src/java/org/apache/fop/layoutmgr/inline/
src/java/org/apache/fop/layoutmgr/list/ src/java/or...
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java?rev=893238&r1=893237&r2=893238&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java Tue Dec 22 17:20:51 2009
@@ -19,6 +19,7 @@
package org.apache.fop.layoutmgr.inline;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
@@ -59,6 +60,9 @@
//TODO: remove all final modifiers at local variables
+ // static final int SOFT_HYPHEN_PENALTY = KnuthPenalty.FLAGGED_PENALTY / 10;
+ private static final int SOFT_HYPHEN_PENALTY = 1;
+
/**
* Store information about each potential text area.
* Index of character which ends the area, IPD of area, including
@@ -66,25 +70,27 @@
* Number of word-spaces?
*/
private class AreaInfo {
+
private final int startIndex;
private final int breakIndex;
private final int wordSpaceCount;
private int letterSpaceCount;
- private final MinOptMax areaIPD;
+ private MinOptMax areaIPD;
private final boolean isHyphenated;
private final boolean isSpace;
private boolean breakOppAfter;
private final Font font;
AreaInfo(final int startIndex,
- final int breakIndex,
- final int wordSpaceCount,
- final int letterSpaceCount,
- final MinOptMax areaIPD,
- final boolean isHyphenated,
- final boolean isSpace,
- final boolean breakOppAfter,
- final Font font) {
+ final int breakIndex,
+ final int wordSpaceCount,
+ final int letterSpaceCount,
+ final MinOptMax areaIPD,
+ final boolean isHyphenated,
+ final boolean isSpace,
+ final boolean breakOppAfter,
+ final Font font) {
+ assert startIndex <= breakIndex;
this.startIndex = startIndex;
this.breakIndex = breakIndex;
this.wordSpaceCount = wordSpaceCount;
@@ -96,28 +102,38 @@
this.font = font;
}
- public String toString() {
- return "[ lscnt=" + this.letterSpaceCount
- + ", wscnt=" + this.wordSpaceCount
- + ", ipd=" + this.areaIPD.toString()
- + ", sidx=" + this.startIndex
- + ", bidx=" + this.breakIndex
- + ", hyph=" + this.isHyphenated
- + ", space=" + this.isSpace
- + ", font=" + this.font
- + "]";
+ private int getCharLength() {
+ return breakIndex - startIndex;
+ }
+
+ private void addToAreaIPD(MinOptMax idp) {
+ areaIPD = areaIPD.plus(idp);
}
+ public String toString() {
+ return "AreaInfo["
+ + "letterSpaceCount = " + letterSpaceCount
+ + ", wordSpaceCount = " + wordSpaceCount
+ + ", areaIPD = " + areaIPD
+ + ", startIndex = " + startIndex
+ + ", breakIndex = " + breakIndex
+ + ", isHyphenated = " + isHyphenated
+ + ", isSpace = " + isSpace
+ + ", font = " + font
+ + "]";
+ }
}
- // this class stores information about changes in vecAreaInfo
- // which are not yet applied
+ /**
+ * this class stores information about changes in vecAreaInfo which are not yet applied
+ */
private final class PendingChange {
- private final AreaInfo ai;
+
+ private final AreaInfo areaInfo;
private final int index;
- private PendingChange(final AreaInfo ai, final int index) {
- this.ai = ai;
+ private PendingChange(final AreaInfo areaInfo, final int index) {
+ this.areaInfo = areaInfo;
this.index = index;
}
}
@@ -128,14 +144,11 @@
private static final Log LOG = LogFactory.getLog(TextLayoutManager.class);
// Hold all possible breaks for the text in this LM's FO.
- private final List vecAreaInfo;
+ private final List areaInfos;
/** Non-space characters on which we can end a line. */
private static final String BREAK_CHARS = "-/";
- /** Used to reduce instantiation of MinOptMax with zero length. Do not modify! */
- private static final MinOptMax ZERO_MINOPTMAX = new MinOptMax(0);
-
private final FOText foText;
/**
@@ -155,18 +168,23 @@
private MinOptMax letterSpaceIPD;
/** size of the hyphen character glyph in current font */
private int hyphIPD;
- /** 1/1 of word-spacing value */
- private SpaceVal ws;
private boolean hasChanged = false;
private int returnedIndex = 0;
private int thisStart = 0;
private int tempStart = 0;
- private List changeList = null;
+ private List changeList = new LinkedList();
private AlignmentContext alignmentContext = null;
+ /**
+ * The width to be reserved for border and padding at the start of the line.
+ */
private int lineStartBAP = 0;
+
+ /**
+ * The width to be reserved for border and padding at the end of the line.
+ */
private int lineEndBAP = 0;
private boolean keepTogether;
@@ -178,49 +196,37 @@
*
* @param node The FOText object to be rendered
*/
- public TextLayoutManager(final FOText node) {
- super();
- this.foText = node;
-
- this.letterAdjustArray = new MinOptMax[node.length() + 1];
-
- this.vecAreaInfo = new java.util.ArrayList();
- }
-
- private KnuthPenalty makeZeroWidthPenalty(final int penaltyValue) {
- return new KnuthPenalty(
- 0,
- penaltyValue,
- false,
- this.auxiliaryPosition,
- true);
+ public TextLayoutManager(FOText node) {
+ foText = node;
+ letterAdjustArray = new MinOptMax[node.length() + 1];
+ areaInfos = new ArrayList();
+ }
+
+ private KnuthPenalty makeZeroWidthPenalty(int penaltyValue) {
+ return new KnuthPenalty(0, penaltyValue, false, auxiliaryPosition, true);
}
private KnuthBox makeAuxiliaryZeroWidthBox() {
- return new KnuthInlineBox(
- 0,
- null,
- this.notifyPos(new LeafPosition(this, -1)),
- true);
+ return new KnuthInlineBox(0, null, notifyPos(new LeafPosition(this, -1)), true);
}
/** {@inheritDoc} */
public void initialize() {
- this.foText.resetBuffer();
+ foText.resetBuffer();
- this.spaceFont = FontSelector.selectFontForCharacterInText(' ', this.foText, this);
+ spaceFont = FontSelector.selectFontForCharacterInText(' ', foText, this);
- // With CID fonts, space isn't neccesary currentFontState.width(32)
- this.spaceCharIPD = this.spaceFont.getCharWidth(' ');
- // Use hyphenationChar property
+ // With CID fonts, space isn't necessary currentFontState.width(32)
+ spaceCharIPD = spaceFont.getCharWidth(' ');
+ // Use hyphenationChar property
// TODO: Use hyphen based on actual font used!
- this.hyphIPD = this.foText.getCommonHyphenation().getHyphIPD(this.spaceFont);
+ hyphIPD = foText.getCommonHyphenation().getHyphIPD(spaceFont);
- final SpaceVal ls = SpaceVal.makeLetterSpacing(this.foText.getLetterSpacing());
-
- this.ws = SpaceVal.makeWordSpacing(this.foText.getWordSpacing(), ls, this.spaceFont);
+ SpaceVal letterSpacing = SpaceVal.makeLetterSpacing(foText.getLetterSpacing());
+ SpaceVal wordSpacing = SpaceVal.makeWordSpacing(foText.getWordSpacing(), letterSpacing,
+ spaceFont);
// letter space applies only to consecutive non-space characters,
// while word space applies to space characters;
@@ -233,12 +239,9 @@
// set letter space and word space dimension;
// the default value "normal" was converted into a MinOptMax value
// in the SpaceVal.makeWordSpacing() method
- this.letterSpaceIPD = ls.getSpace();
- this.wordSpaceIPD = MinOptMax.add(new MinOptMax(this.spaceCharIPD), this.ws.getSpace());
-
- this.keepTogether = this.foText.getKeepTogether().getWithinLine()
- .getEnum() == Constants.EN_ALWAYS;
-
+ letterSpaceIPD = letterSpacing.getSpace();
+ wordSpaceIPD = MinOptMax.getInstance(spaceCharIPD).plus(wordSpacing.getSpace());
+ keepTogether = foText.getKeepTogether().getWithinLine().getEnum() == Constants.EN_ALWAYS;
}
/**
@@ -254,111 +257,103 @@
public void addAreas(final PositionIterator posIter, final LayoutContext context) {
// Add word areas
- AreaInfo ai;
+ AreaInfo areaInfo;
int wordSpaceCount = 0;
int letterSpaceCount = 0;
int firstAreaInfoIndex = -1;
int lastAreaInfoIndex = 0;
- MinOptMax realWidth = new MinOptMax(0);
+ MinOptMax realWidth = MinOptMax.ZERO;
/* On first area created, add any leading space.
* Calculate word-space stretch value.
*/
- AreaInfo lastAi = null;
+ AreaInfo lastAreaInfo = null;
while (posIter.hasNext()) {
final LeafPosition tbpNext = (LeafPosition) posIter.next();
if (tbpNext == null) {
continue; //Ignore elements without Positions
}
if (tbpNext.getLeafPos() != -1) {
- ai = (AreaInfo) this.vecAreaInfo.get(tbpNext.getLeafPos());
- if (lastAi == null || ai.font != lastAi.font) {
- if (lastAi != null) {
- this.addAreaInfoAreas(lastAi, wordSpaceCount,
+ areaInfo = (AreaInfo) areaInfos.get(tbpNext.getLeafPos());
+ if (lastAreaInfo == null || areaInfo.font != lastAreaInfo.font) {
+ if (lastAreaInfo != null) {
+ addAreaInfoAreas(lastAreaInfo, wordSpaceCount,
letterSpaceCount, firstAreaInfoIndex,
lastAreaInfoIndex, realWidth, context);
}
firstAreaInfoIndex = tbpNext.getLeafPos();
wordSpaceCount = 0;
letterSpaceCount = 0;
- realWidth = new MinOptMax(0);
+ realWidth = MinOptMax.ZERO;
}
- wordSpaceCount += ai.wordSpaceCount;
- letterSpaceCount += ai.letterSpaceCount;
- realWidth.add(ai.areaIPD);
+ wordSpaceCount += areaInfo.wordSpaceCount;
+ letterSpaceCount += areaInfo.letterSpaceCount;
+ realWidth = realWidth.plus(areaInfo.areaIPD);
lastAreaInfoIndex = tbpNext.getLeafPos();
- lastAi = ai;
+ lastAreaInfo = areaInfo;
}
}
- if (lastAi != null) {
- this.addAreaInfoAreas(lastAi, wordSpaceCount, letterSpaceCount,
- firstAreaInfoIndex, lastAreaInfoIndex, realWidth, context);
+ if (lastAreaInfo != null) {
+ addAreaInfoAreas(lastAreaInfo, wordSpaceCount, letterSpaceCount, firstAreaInfoIndex,
+ lastAreaInfoIndex, realWidth, context);
}
}
- private void addAreaInfoAreas(final AreaInfo ai, final int wordSpaceCount,
- int letterSpaceCount, final int firstAreaInfoIndex,
- final int lastAreaInfoIndex, final MinOptMax realWidth, final LayoutContext context) {
+ private void addAreaInfoAreas(AreaInfo areaInfo, int wordSpaceCount, int letterSpaceCount,
+ int firstAreaInfoIndex, int lastAreaInfoIndex,
+ MinOptMax realWidth, LayoutContext context) {
// TODO: These two statements (if, for) were like this before my recent
// changes. However, it seems as if they should use the AreaInfo from
- // firstAreaInfoIndex.. lastAreaInfoIndex rather than just the last ai.
+ // firstAreaInfoIndex.. lastAreaInfoIndex rather than just the last areaInfo.
// This needs to be checked.
- final int textLength = ai.breakIndex - ai.startIndex;
- if (ai.letterSpaceCount == textLength && !ai.isHyphenated
- && context.isLastArea()) {
+ int textLength = areaInfo.getCharLength();
+ if (areaInfo.letterSpaceCount == textLength && !areaInfo.isHyphenated
+ && context.isLastArea()) {
// the line ends at a character like "/" or "-";
// remove the letter space after the last character
- realWidth.add(MinOptMax.multiply(this.letterSpaceIPD, -1));
+ realWidth = realWidth.minus(letterSpaceIPD);
letterSpaceCount--;
}
- for (int i = ai.startIndex; i < ai.breakIndex; i++) {
- final MinOptMax ladj = this.letterAdjustArray[i + 1];
- if (ladj != null && ladj.isElastic()) {
+ for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ MinOptMax letterAdjustment = letterAdjustArray[i + 1];
+ if (letterAdjustment != null && letterAdjustment.isElastic()) {
letterSpaceCount++;
}
}
// add hyphenation character if the last word is hyphenated
- if (context.isLastArea() && ai.isHyphenated) {
- realWidth.add(new MinOptMax(this.hyphIPD));
+ if (context.isLastArea() && areaInfo.isHyphenated) {
+ realWidth = realWidth.plus(hyphIPD);
}
- // Calculate adjustments
- int difference = 0;
- int totalAdjust = 0;
- int wordSpaceDim = this.wordSpaceIPD.opt;
- int letterSpaceDim = this.letterSpaceIPD.opt;
- final double ipdAdjust = context.getIPDAdjust();
+ /* Calculate adjustments */
+ double ipdAdjust = context.getIPDAdjust();
// calculate total difference between real and available width
+ int difference;
if (ipdAdjust > 0.0) {
- difference = (int) ((realWidth.max - realWidth.opt)
- * ipdAdjust);
+ difference = (int) (realWidth.getStretch() * ipdAdjust);
} else {
- difference = (int) ((realWidth.opt - realWidth.min)
- * ipdAdjust);
+ difference = (int) (realWidth.getShrink() * ipdAdjust);
}
// set letter space adjustment
+ int letterSpaceDim = letterSpaceIPD.getOpt();
if (ipdAdjust > 0.0) {
- letterSpaceDim
- += (int) ((this.letterSpaceIPD.max - this.letterSpaceIPD.opt)
- * ipdAdjust);
- } else {
- letterSpaceDim
- += (int) ((this.letterSpaceIPD.opt - this.letterSpaceIPD.min)
- * ipdAdjust);
+ letterSpaceDim += (int) (letterSpaceIPD.getStretch() * ipdAdjust);
+ } else {
+ letterSpaceDim += (int) (letterSpaceIPD.getShrink() * ipdAdjust);
}
- totalAdjust += (letterSpaceDim - this.letterSpaceIPD.opt) * letterSpaceCount;
+ int totalAdjust = (letterSpaceDim - letterSpaceIPD.getOpt()) * letterSpaceCount;
// set word space adjustment
- //
+ int wordSpaceDim = wordSpaceIPD.getOpt();
if (wordSpaceCount > 0) {
wordSpaceDim += (difference - totalAdjust) / wordSpaceCount;
}
- totalAdjust += (wordSpaceDim - this.wordSpaceIPD.opt) * wordSpaceCount;
+ totalAdjust += (wordSpaceDim - wordSpaceIPD.getOpt()) * wordSpaceCount;
if (totalAdjust != difference) {
// the applied adjustment is greater or smaller than the needed one
TextLayoutManager.LOG
@@ -370,9 +365,8 @@
totalAdjust = difference;
}
- final TextArea t = this.createTextArea(realWidth, totalAdjust, context,
- this.wordSpaceIPD.opt - this.spaceCharIPD, firstAreaInfoIndex,
- lastAreaInfoIndex, context.isLastArea(), ai.font);
+ TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstAreaInfoIndex,
+ lastAreaInfoIndex, context.isLastArea(), areaInfo.font).build();
// wordSpaceDim is computed in relation to wordSpaceIPD.opt
// but the renderer needs to know the adjustment in relation
@@ -386,133 +380,205 @@
// = spaceCharIPD + letterSpaceAdjust +
// + (wordSpaceDim - spaceCharIPD - 2 * letterSpaceAdjust)
// = wordSpaceDim - letterSpaceAdjust
- t.setTextLetterSpaceAdjust(letterSpaceDim);
- t.setTextWordSpaceAdjust(wordSpaceDim - this.spaceCharIPD
- - 2 * t.getTextLetterSpaceAdjust());
+ textArea.setTextLetterSpaceAdjust(letterSpaceDim);
+ textArea.setTextWordSpaceAdjust(wordSpaceDim - spaceCharIPD
+ - 2 * textArea.getTextLetterSpaceAdjust());
if (context.getIPDAdjust() != 0) {
// add information about space width
- t.setSpaceDifference(this.wordSpaceIPD.opt - this.spaceCharIPD
- - 2 * t.getTextLetterSpaceAdjust());
+ textArea.setSpaceDifference(wordSpaceIPD.getOpt() - spaceCharIPD
+ - 2 * textArea.getTextLetterSpaceAdjust());
}
- this.parentLM.addChildArea(t);
+ parentLayoutManager.addChildArea(textArea);
}
- /**
- * Create an inline word area.
- * This creates a TextArea and sets up the various attributes.
- *
- * @param width the MinOptMax width of the content
- * @param adjust the total ipd adjustment with respect to the optimal width
- * @param context the layout context
- * @param spaceDiff unused
- * @param firstIndex the index of the first AreaInfo used for the TextArea
- * @param lastIndex the index of the last AreaInfo used for the TextArea
- * @param isLastArea is this TextArea the last in a line?
- * @param font Font to be used in this particular TextArea
- * @return the new text area
- */
- protected TextArea createTextArea(final MinOptMax width, final int adjust,
- final LayoutContext context, final int spaceDiff, final int firstIndex,
- final int lastIndex, final boolean isLastArea, final Font font) {
- TextArea textArea;
- if (context.getIPDAdjust() == 0.0) {
- // create just a TextArea
- textArea = new TextArea();
- } else {
- // justified area: create a TextArea with extra info
- // about potential adjustments
- textArea = new TextArea(width.max - width.opt,
- width.opt - width.min,
- adjust);
- }
- textArea.setIPD(width.opt + adjust);
- textArea.setBPD(font.getAscender() - font.getDescender());
-
- textArea.setBaselineOffset(font.getAscender());
- if (textArea.getBPD() == this.alignmentContext.getHeight()) {
- textArea.setOffset(0);
- } else {
- textArea.setOffset(this.alignmentContext.getOffset());
+ private final class TextAreaBuilder {
+
+ private final MinOptMax width;
+ private final int adjust;
+ private final LayoutContext context;
+ private final int firstIndex;
+ private final int lastIndex;
+ private final boolean isLastArea;
+ private final Font font;
+
+ private int blockProgressionDimension;
+ private AreaInfo areaInfo;
+ private StringBuffer wordChars;
+ private int[] letterAdjust;
+ private int letterAdjustIndex;
+
+ private TextArea textArea;
+
+ /**
+ * Creates a new <code>TextAreaBuilder</code> which itself builds an inline word area. This
+ * creates a TextArea and sets up the various attributes.
+ *
+ * @param width the MinOptMax width of the content
+ * @param adjust the total ipd adjustment with respect to the optimal width
+ * @param context the layout context
+ * @param firstIndex the index of the first AreaInfo used for the TextArea
+ * @param lastIndex the index of the last AreaInfo used for the TextArea
+ * @param isLastArea is this TextArea the last in a line?
+ * @param font Font to be used in this particular TextArea
+ */
+ private TextAreaBuilder(MinOptMax width, int adjust, LayoutContext context,
+ int firstIndex, int lastIndex, boolean isLastArea, Font font) {
+ this.width = width;
+ this.adjust = adjust;
+ this.context = context;
+ this.firstIndex = firstIndex;
+ this.lastIndex = lastIndex;
+ this.isLastArea = isLastArea;
+ this.font = font;
}
- // set the text of the TextArea, split into words and spaces
- int wordStartIndex = -1;
- AreaInfo areaInfo;
- int len = 0;
- for (int i = firstIndex; i <= lastIndex; i++) {
- areaInfo = (AreaInfo) this.vecAreaInfo.get(i);
- if (areaInfo.isSpace) {
- // areaInfo stores information about spaces
- // add the spaces - except zero-width spaces - to the TextArea
- for (int j = areaInfo.startIndex; j < areaInfo.breakIndex; j++) {
- final char spaceChar = this.foText.charAt(j);
- if (!CharUtilities.isZeroWidthSpace(spaceChar)) {
- textArea.addSpace(spaceChar, 0,
- CharUtilities.isAdjustableSpace(spaceChar));
- }
- }
+ private TextArea build() {
+ createTextArea();
+ setInlineProgressionDimension();
+ calcBlockProgressionDimension();
+ setBlockProgressionDimension();
+ setBaselineOffset();
+ setOffset();
+ setText();
+ TraitSetter.addFontTraits(textArea, font);
+ textArea.addTrait(Trait.COLOR, foText.getColor());
+ TraitSetter.addPtr(textArea, getPtr()); // used for accessibility
+ TraitSetter.addTextDecoration(textArea, foText.getTextDecoration());
+ TraitSetter.addFontTraits(textArea, font);
+ return textArea;
+ }
+
+ /**
+ * Creates an plain <code>TextArea</code> or a justified <code>TextArea</code> with
+ * additional information.
+ */
+ private void createTextArea() {
+ if (context.getIPDAdjust() == 0.0) {
+ textArea = new TextArea();
} else {
- // areaInfo stores information about a word fragment
- if (wordStartIndex == -1) {
- // here starts a new word
- wordStartIndex = i;
- len = 0;
- }
- len += areaInfo.breakIndex - areaInfo.startIndex;
- if (i == lastIndex || ((AreaInfo) this.vecAreaInfo.get(i + 1)).isSpace) {
- // here ends a new word
- // add a word to the TextArea
- if (isLastArea
- && i == lastIndex
- && areaInfo.isHyphenated) {
- len++;
- }
- final StringBuffer wordChars = new StringBuffer(len);
- final int[] letterAdjust = new int[len];
- int letter = 0;
- for (int j = wordStartIndex; j <= i; j++) {
- final AreaInfo ai = (AreaInfo) this.vecAreaInfo.get(j);
- int lsCount = ai.letterSpaceCount;
- /* TODO: in Java 5, StringBuffer has an append() variant
- * for CharSequence, so the below iteration can be replaced
- * by:
- * wordChars.append(this.foText, ai.startIndex,
- * ai.breakIndex - ai.startIndex);
- */
- for (int ci = ai.startIndex; ci < ai.breakIndex; ci++) {
- wordChars.append(this.foText.charAt(ci));
- }
- for (int k = 0; k < ai.breakIndex - ai.startIndex; k++) {
- final MinOptMax adj = this.letterAdjustArray[ai.startIndex + k];
- if (letter > 0) {
- letterAdjust[letter] = adj == null ? 0
- : adj.opt;
- }
- if (lsCount > 0) {
- letterAdjust[letter] += textArea.getTextLetterSpaceAdjust();
- lsCount--;
- }
- letter++;
- }
+ textArea = new TextArea(width.getStretch(), width.getShrink(),
+ adjust);
+ }
+ }
+
+ private void setInlineProgressionDimension() {
+ textArea.setIPD(width.getOpt() + adjust);
+ }
+
+ private void calcBlockProgressionDimension() {
+ blockProgressionDimension = font.getAscender() - font.getDescender();
+ }
+
+ private void setBlockProgressionDimension() {
+ textArea.setBPD(blockProgressionDimension);
+ }
+
+ private void setBaselineOffset() {
+ textArea.setBaselineOffset(font.getAscender());
+ }
+
+ private void setOffset() {
+ if (blockProgressionDimension == alignmentContext.getHeight()) {
+ textArea.setOffset(0);
+ } else {
+ textArea.setOffset(alignmentContext.getOffset());
+ }
+ }
+
+ /**
+ * Sets the text of the TextArea, split into words and spaces.
+ */
+ private void setText() {
+ int wordStartIndex = -1;
+ int wordCharLength = 0;
+ for (int wordIndex = firstIndex; wordIndex <= lastIndex; wordIndex++) {
+ areaInfo = getAreaInfo(wordIndex);
+ if (areaInfo.isSpace) {
+ addSpaces();
+ } else {
+ // areaInfo stores information about a word fragment
+ if (wordStartIndex == -1) {
+ // here starts a new word
+ wordStartIndex = wordIndex;
+ wordCharLength = 0;
}
- // String wordChars = new String(textArray, wordStartIndex, len);
- if (isLastArea
- && i == lastIndex
- && areaInfo.isHyphenated) {
- // add the hyphenation character
- wordChars.append(this.foText.getCommonHyphenation().getHyphChar(font));
+ wordCharLength += areaInfo.getCharLength();
+ if (isWordEnd(wordIndex)) {
+ addWord(wordStartIndex, wordIndex, wordCharLength);
+ wordStartIndex = -1;
}
- textArea.addWord(wordChars.toString(), 0, letterAdjust);
- wordStartIndex = -1;
}
}
}
- TraitSetter.addFontTraits(textArea, font);
- textArea.addTrait(Trait.COLOR, this.foText.getColor());
- TraitSetter.addPtr(textArea, getPtr()); // used for accessibility
- TraitSetter.addTextDecoration(textArea, this.foText.getTextDecoration());
- return textArea;
+ private boolean isWordEnd(int areaInfoIndex) {
+ return areaInfoIndex == lastIndex || getAreaInfo(areaInfoIndex + 1).isSpace;
+ }
+
+ private void addWord(int startIndex, int endIndex, int charLength) {
+ if (isHyphenated(endIndex)) {
+ charLength++;
+ }
+ initWord(charLength);
+ for (int i = startIndex; i <= endIndex; i++) {
+ AreaInfo wordAreaInfo = getAreaInfo(i);
+ addWordChars(wordAreaInfo);
+ addLetterAdjust(wordAreaInfo);
+ }
+ if (isHyphenated(endIndex)) {
+ addHyphenationChar();
+ }
+ textArea.addWord(wordChars.toString(), 0, letterAdjust);
+ }
+
+ private void initWord(int charLength) {
+ wordChars = new StringBuffer(charLength);
+ letterAdjust = new int[charLength];
+ letterAdjustIndex = 0;
+ }
+
+ private boolean isHyphenated(int endIndex) {
+ return isLastArea && endIndex == lastIndex && areaInfo.isHyphenated;
+ }
+
+ private void addHyphenationChar() {
+ wordChars.append(foText.getCommonHyphenation().getHyphChar(font));
+ }
+
+ private void addWordChars(AreaInfo wordAreaInfo) {
+ for (int i = wordAreaInfo.startIndex; i < wordAreaInfo.breakIndex; i++) {
+ wordChars.append(foText.charAt(i));
+ }
+ }
+
+ private void addLetterAdjust(AreaInfo wordAreaInfo) {
+ int letterSpaceCount = wordAreaInfo.letterSpaceCount;
+ for (int i = wordAreaInfo.startIndex; i < wordAreaInfo.breakIndex; i++) {
+ if (letterAdjustIndex > 0) {
+ MinOptMax adj = letterAdjustArray[i];
+ letterAdjust[letterAdjustIndex] = adj == null ? 0 : adj.getOpt();
+ }
+ if (letterSpaceCount > 0) {
+ letterAdjust[letterAdjustIndex] += textArea.getTextLetterSpaceAdjust();
+ letterSpaceCount--;
+ }
+ letterAdjustIndex++;
+ }
+ }
+
+ /**
+ * The <code>AreaInfo</code> stores information about spaces.
+ * <p/>
+ * Add the spaces - except zero-width spaces - to the TextArea.
+ */
+ private void addSpaces() {
+ for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ char spaceChar = foText.charAt(i);
+ if (!CharUtilities.isZeroWidthSpace(spaceChar)) {
+ textArea.addSpace(spaceChar, 0, CharUtilities.isAdjustableSpace(spaceChar));
+ }
+ }
+ }
}
/**
@@ -520,7 +586,7 @@
* @return ptr of fobj
*/
private String getPtr() {
- FObj fobj = this.parentLM.getFObj();
+ FObj fobj = parentLayoutManager.getFObj();
if (fobj instanceof StructurePointerPropertySet) {
return (((StructurePointerPropertySet) fobj).getPtr());
} else {
@@ -529,11 +595,15 @@
}
}
- private void addToLetterAdjust(final int index, final int width) {
- if (this.letterAdjustArray[index] == null) {
- this.letterAdjustArray[index] = new MinOptMax(width);
+ private AreaInfo getAreaInfo(int index) {
+ return (AreaInfo) areaInfos.get(index);
+ }
+
+ private void addToLetterAdjust(int index, int width) {
+ if (letterAdjustArray[index] == null) {
+ letterAdjustArray[index] = MinOptMax.getInstance(width);
} else {
- this.letterAdjustArray[index].add(width);
+ letterAdjustArray[index] = letterAdjustArray[index].plus(width);
}
}
@@ -544,32 +614,33 @@
*/
private static boolean isSpace(final char ch) {
return ch == CharUtilities.SPACE
- || CharUtilities.isNonBreakableSpace(ch)
- || CharUtilities.isFixedWidthSpace(ch);
+ || CharUtilities.isNonBreakableSpace(ch)
+ || CharUtilities.isFixedWidthSpace(ch);
}
/** {@inheritDoc} */
public List getNextKnuthElements(final LayoutContext context, final int alignment) {
- this.lineStartBAP = context.getLineStartBorderAndPaddingWidth();
- this.lineEndBAP = context.getLineEndBorderAndPaddingWidth();
- this.alignmentContext = context.getAlignmentContext();
+ lineStartBAP = context.getLineStartBorderAndPaddingWidth();
+ lineEndBAP = context.getLineEndBorderAndPaddingWidth();
+ alignmentContext = context.getAlignmentContext();
final List returnList = new LinkedList();
KnuthSequence sequence = new InlineKnuthSequence();
- AreaInfo ai = null;
- AreaInfo prevAi = null;
+ AreaInfo areaInfo = null;
+ AreaInfo prevAreaInfo = null;
returnList.add(sequence);
- final LineBreakStatus lbs = new LineBreakStatus();
- this.thisStart = this.nextStart;
+ LineBreakStatus lineBreakStatus = new LineBreakStatus();
+ thisStart = nextStart;
boolean inWord = false;
boolean inWhitespace = false;
char ch = 0;
- while (this.nextStart < this.foText.length()) {
- ch = this.foText.charAt(this.nextStart);
+ while (nextStart < foText.length()) {
+ ch = foText.charAt(nextStart);
boolean breakOpportunity = false;
- final byte breakAction = this.keepTogether ? LineBreakStatus.PROHIBITED_BREAK
- : lbs.nextChar(ch);
+ byte breakAction = keepTogether
+ ? LineBreakStatus.PROHIBITED_BREAK
+ : lineBreakStatus.nextChar(ch);
switch (breakAction) {
case LineBreakStatus.COMBINING_PROHIBITED_BREAK:
case LineBreakStatus.PROHIBITED_BREAK:
@@ -589,62 +660,58 @@
|| TextLayoutManager.isSpace(ch)
|| CharUtilities.isExplicitBreak(ch)) {
// this.foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN
- prevAi = this.processWord(alignment, sequence, prevAi, ch,
+ prevAreaInfo = processWord(alignment, sequence, prevAreaInfo, ch,
breakOpportunity, true);
}
} else if (inWhitespace) {
if (ch != CharUtilities.SPACE || breakOpportunity) {
- prevAi = this.processWhitespace(alignment, sequence,
- breakOpportunity);
+ prevAreaInfo = processWhitespace(alignment, sequence, breakOpportunity);
}
} else {
- if (ai != null) {
- prevAi = ai;
- ai = this.processLeftoverAi(alignment, sequence, ai, ch,
+ if (areaInfo != null) {
+ prevAreaInfo = areaInfo;
+ processLeftoverAreaInfo(alignment, sequence, areaInfo,
ch == CharUtilities.SPACE || breakOpportunity);
+ areaInfo = null;
}
if (breakAction == LineBreakStatus.EXPLICIT_BREAK) {
- sequence = this.processLinebreak(returnList, sequence);
+ sequence = processLinebreak(returnList, sequence);
}
}
if (ch == CharUtilities.SPACE
- && this.foText.getWhitespaceTreatment() == Constants.EN_PRESERVE
+ && foText.getWhitespaceTreatment() == Constants.EN_PRESERVE
|| ch == CharUtilities.NBSPACE) {
// preserved space or non-breaking space:
// create the AreaInfo object
- ai = new AreaInfo(this.nextStart, this.nextStart + 1,
- 1, 0, this.wordSpaceIPD, false, true,
- breakOpportunity, this.spaceFont);
- this.thisStart = this.nextStart + 1;
+ areaInfo = new AreaInfo(nextStart, nextStart + 1, 1, 0, wordSpaceIPD, false, true,
+ breakOpportunity, spaceFont);
+ thisStart = nextStart + 1;
} else if (CharUtilities.isFixedWidthSpace(ch) || CharUtilities.isZeroWidthSpace(ch)) {
// create the AreaInfo object
- final Font font = FontSelector.selectFontForCharacterInText(ch,
- this.foText, this);
- final MinOptMax ipd = new MinOptMax(font.getCharWidth(ch));
- ai = new AreaInfo(this.nextStart, this.nextStart + 1,
- 0, 0, ipd, false, true,
+ Font font = FontSelector.selectFontForCharacterInText(ch, foText, this);
+ MinOptMax ipd = MinOptMax.getInstance(font.getCharWidth(ch));
+ areaInfo = new AreaInfo(nextStart, nextStart + 1, 0, 0, ipd, false, true,
breakOpportunity, font);
- this.thisStart = this.nextStart + 1;
+ thisStart = nextStart + 1;
} else if (CharUtilities.isExplicitBreak(ch)) {
//mandatory break-character: only advance index
- this.thisStart = this.nextStart + 1;
+ thisStart = nextStart + 1;
}
- inWord = !TextLayoutManager.isSpace(ch)
- && !CharUtilities.isExplicitBreak(ch);
+ inWord = !TextLayoutManager.isSpace(ch) && !CharUtilities.isExplicitBreak(ch);
inWhitespace = ch == CharUtilities.SPACE
- && this.foText.getWhitespaceTreatment() != Constants.EN_PRESERVE;
- this.nextStart++;
- } // end of while
+ && foText.getWhitespaceTreatment() != Constants.EN_PRESERVE;
+ nextStart++;
+ }
// Process any last elements
if (inWord) {
- this.processWord(alignment, sequence, prevAi, ch, false, false);
+ processWord(alignment, sequence, prevAreaInfo, ch, false, false);
} else if (inWhitespace) {
- this.processWhitespace(alignment, sequence, true);
- } else if (ai != null) {
- this.processLeftoverAi(alignment, sequence, ai, ch,
+ processWhitespace(alignment, sequence, true);
+ } else if (areaInfo != null) {
+ processLeftoverAreaInfo(alignment, sequence, areaInfo,
ch == CharUtilities.ZERO_WIDTH_SPACE);
} else if (CharUtilities.isExplicitBreak(ch)) {
this.processLinebreak(returnList, sequence);
@@ -655,7 +722,7 @@
ListUtil.removeLast(returnList);
}
- this.setFinished(true);
+ setFinished(true);
if (returnList.isEmpty()) {
return null;
} else {
@@ -663,12 +730,9 @@
}
}
- private KnuthSequence processLinebreak(final List returnList,
- KnuthSequence sequence) {
- if (this.lineEndBAP != 0) {
- sequence.add(
- new KnuthGlue(this.lineEndBAP, 0, 0,
- this.auxiliaryPosition, true));
+ private KnuthSequence processLinebreak(List returnList, KnuthSequence sequence) {
+ if (lineEndBAP != 0) {
+ sequence.add(new KnuthGlue(lineEndBAP, 0, 0, auxiliaryPosition, true));
}
sequence.endSequence();
sequence = new InlineKnuthSequence();
@@ -676,32 +740,29 @@
return sequence;
}
- private AreaInfo processLeftoverAi(final int alignment,
- final KnuthSequence sequence, AreaInfo ai, final char ch,
- final boolean breakOpportunityAfter) {
- this.vecAreaInfo.add(ai);
- ai.breakOppAfter = breakOpportunityAfter;
- this.addElementsForASpace(sequence, alignment, ai, this.vecAreaInfo.size() - 1);
- ai = null;
- return ai;
+ private void processLeftoverAreaInfo(int alignment,
+ KnuthSequence sequence, AreaInfo areaInfo,
+ boolean breakOpportunityAfter) {
+ areaInfos.add(areaInfo);
+ areaInfo.breakOppAfter = breakOpportunityAfter;
+ addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1);
}
private AreaInfo processWhitespace(final int alignment,
final KnuthSequence sequence, final boolean breakOpportunity) {
// End of whitespace
// create the AreaInfo object
- AreaInfo ai = new AreaInfo(this.thisStart, this.nextStart,
- this.nextStart - this.thisStart, 0,
- MinOptMax.multiply(this.wordSpaceIPD, this.nextStart
- - this.thisStart), false, true,
- breakOpportunity, this.spaceFont);
- this.vecAreaInfo.add(ai);
+ assert nextStart >= thisStart;
+ AreaInfo areaInfo = new AreaInfo(thisStart, nextStart, nextStart - thisStart, 0,
+ wordSpaceIPD.mult(nextStart - thisStart), false, true, breakOpportunity, spaceFont);
+
+ areaInfos.add(areaInfo);
// create the elements
- this.addElementsForASpace(sequence, alignment, ai, this.vecAreaInfo.size() - 1);
+ addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1);
- this.thisStart = this.nextStart;
- return ai;
+ thisStart = nextStart;
+ return areaInfo;
}
private AreaInfo processWord(final int alignment, final KnuthSequence sequence,
@@ -709,39 +770,36 @@
final boolean checkEndsWithHyphen) {
//Word boundary found, process widths and kerning
- int lastIndex = this.nextStart;
- while (lastIndex > 0
- && foText.charAt(lastIndex - 1) == CharUtilities.SOFT_HYPHEN) {
+ int lastIndex = nextStart;
+ while (lastIndex > 0 && foText.charAt(lastIndex - 1) == CharUtilities.SOFT_HYPHEN) {
lastIndex--;
}
final boolean endsWithHyphen = checkEndsWithHyphen
&& foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN;
- final Font font = FontSelector
- .selectFontForCharactersInText(foText,
- this.thisStart, lastIndex, foText, this);
- final int wordLength = lastIndex - this.thisStart;
- final boolean kerning = font.hasKerning();
- final MinOptMax wordIPD = new MinOptMax(0);
- for (int i = this.thisStart; i < lastIndex; i++) {
- final char currentChar = foText.charAt(i);
+ Font font = FontSelector.selectFontForCharactersInText(foText, thisStart, lastIndex, foText, this);
+ int wordLength = lastIndex - thisStart;
+ boolean kerning = font.hasKerning();
+ MinOptMax wordIPD = MinOptMax.ZERO;
+ for (int i = thisStart; i < lastIndex; i++) {
+ char currentChar = foText.charAt(i);
//character width
- final int charWidth = font.getCharWidth(currentChar);
- wordIPD.add(charWidth);
+ int charWidth = font.getCharWidth(currentChar);
+ wordIPD = wordIPD.plus(charWidth);
//kerning
if (kerning) {
int kern = 0;
- if (i > this.thisStart) {
- final char previousChar = foText.charAt(i - 1);
+ if (i > thisStart) {
+ char previousChar = foText.charAt(i - 1);
kern = font.getKernValue(previousChar, currentChar);
} else if (prevAreaInfo != null && !prevAreaInfo.isSpace && prevAreaInfo.breakIndex > 0) {
- final char previousChar = foText.charAt(prevAreaInfo.breakIndex - 1);
+ char previousChar = foText.charAt(prevAreaInfo.breakIndex - 1);
kern = font.getKernValue(previousChar, currentChar);
}
if (kern != 0) {
- this.addToLetterAdjust(i, kern);
- wordIPD.add(kern);
+ addToLetterAdjust(i, kern);
+ wordIPD = wordIPD.plus(kern);
}
}
}
@@ -752,7 +810,7 @@
&& endsWithHyphen) {
final int kern = font.getKernValue(foText.charAt(lastIndex - 1), ch);
if (kern != 0) {
- this.addToLetterAdjust(lastIndex, kern);
+ addToLetterAdjust(lastIndex, kern);
//TODO: add kern to wordIPD?
}
}
@@ -763,21 +821,21 @@
if (breakOpportunity && !TextLayoutManager.isSpace(ch)) {
iLetterSpaces++;
}
- wordIPD.add(MinOptMax.multiply(this.letterSpaceIPD, iLetterSpaces));
+ assert iLetterSpaces >= 0;
+ wordIPD = wordIPD.plus(letterSpaceIPD.mult(iLetterSpaces));
// create the AreaInfo object
- AreaInfo areaInfo = new AreaInfo(this.thisStart, lastIndex, 0,
+ AreaInfo areaInfo = new AreaInfo(thisStart, lastIndex, 0,
iLetterSpaces, wordIPD,
endsWithHyphen,
false, breakOpportunity, font);
prevAreaInfo = areaInfo;
- this.vecAreaInfo.add(areaInfo);
- this.tempStart = this.nextStart;
+ areaInfos.add(areaInfo);
+ tempStart = nextStart;
//add the elements
- this.addElementsForAWordFragment(sequence, alignment, areaInfo,
- this.vecAreaInfo.size() - 1, this.letterSpaceIPD);
- this.thisStart = this.nextStart;
+ addElementsForAWordFragment(sequence, alignment, areaInfo, areaInfos.size() - 1);
+ thisStart = nextStart;
return prevAreaInfo;
}
@@ -788,49 +846,39 @@
// look at the Position stored in the first element in oldList
// which is always a box
ListIterator oldListIterator = oldList.listIterator();
- final KnuthElement el = (KnuthElement)oldListIterator.next();
- final LeafPosition pos = (LeafPosition) ((KnuthBox) el).getPosition();
- final int idx = pos.getLeafPos();
+ KnuthElement knuthElement = (KnuthElement) oldListIterator.next();
+ LeafPosition pos = (LeafPosition) ((KnuthBox) knuthElement).getPosition();
+ int index = pos.getLeafPos();
//element could refer to '-1' position, for non-collapsed spaces (?)
- if (idx > -1) {
- final AreaInfo ai = (AreaInfo) this.vecAreaInfo.get(idx);
- ai.letterSpaceCount++;
- ai.areaIPD.add(this.letterSpaceIPD);
- if (TextLayoutManager.BREAK_CHARS.indexOf(this.foText.charAt(this.tempStart - 1)) >= 0) {
+ if (index > -1) {
+ AreaInfo areaInfo = getAreaInfo(index);
+ areaInfo.letterSpaceCount++;
+ areaInfo.addToAreaIPD(letterSpaceIPD);
+ if (TextLayoutManager.BREAK_CHARS.indexOf(foText.charAt(tempStart - 1)) >= 0) {
// the last character could be used as a line break
// append new elements to oldList
oldListIterator = oldList.listIterator(oldList.size());
oldListIterator.add(new KnuthPenalty(0, KnuthPenalty.FLAGGED_PENALTY, true,
- this.auxiliaryPosition, false));
- oldListIterator.add(new KnuthGlue(this.letterSpaceIPD.opt,
- this.letterSpaceIPD.max - this.letterSpaceIPD.opt,
- this.letterSpaceIPD.opt - this.letterSpaceIPD.min,
- this.auxiliaryPosition, false));
- } else if (this.letterSpaceIPD.min == this.letterSpaceIPD.max) {
+ auxiliaryPosition, false));
+ oldListIterator.add(new KnuthGlue(letterSpaceIPD, auxiliaryPosition, false));
+ } else if (letterSpaceIPD.isStiff()) {
// constant letter space: replace the box
- oldListIterator.set(new KnuthInlineBox(ai.areaIPD.opt,
- this.alignmentContext, pos, false));
+ oldListIterator.set(new KnuthInlineBox(areaInfo.areaIPD.getOpt(),
+ alignmentContext, pos, false));
} else {
// adjustable letter space: replace the glue
oldListIterator.next(); // this would return the penalty element
oldListIterator.next(); // this would return the glue element
- oldListIterator
- .set(new KnuthGlue(
- ai.letterSpaceCount * this.letterSpaceIPD.opt,
- ai.letterSpaceCount
- * (this.letterSpaceIPD.max - this.letterSpaceIPD.opt),
- ai.letterSpaceCount
- * (this.letterSpaceIPD.opt - this.letterSpaceIPD.min),
- this.auxiliaryPosition, true));
+ oldListIterator.set(new KnuthGlue(letterSpaceIPD.mult(areaInfo.letterSpaceCount),
+ auxiliaryPosition, true));
}
}
return oldList;
}
/**
- * remove the AreaInfo object represented by the given elements,
- * so that it won't generate any element when getChangedKnuthElements
- * will be called
+ * Removes the <code>AreaInfo</code> object represented by the given elements, so that it won't
+ * generate any element when <code>getChangedKnuthElements</code> is called.
*
* @param oldList the elements representing the word space
*/
@@ -848,99 +896,91 @@
oldListIterator.next();
oldListIterator.next();
}
- final int leafValue = ((LeafPosition) ((KnuthElement) oldListIterator
- .next()).getPosition()).getLeafPos();
+ KnuthElement knuthElement = (KnuthElement) oldListIterator.next();
+ int leafValue = ((LeafPosition) knuthElement.getPosition()).getLeafPos();
// only the last word space can be a trailing space!
- if (leafValue == this.vecAreaInfo.size() - 1) {
- this.vecAreaInfo.remove(leafValue);
+ if (leafValue == areaInfos.size() - 1) {
+ areaInfos.remove(leafValue);
} else {
TextLayoutManager.LOG.error("trying to remove a non-trailing word space");
}
}
- /** {@inheritDoc} */
- public void hyphenate(final Position pos, final HyphContext hc) {
- final AreaInfo ai
- = (AreaInfo) this.vecAreaInfo.get(((LeafPosition) pos).getLeafPos());
- int startIndex = ai.startIndex;
+ /**
+ * {@inheritDoc}
+ */
+ public void hyphenate(Position pos, HyphContext hyphContext) {
+ AreaInfo areaInfo = getAreaInfo(((LeafPosition) pos).getLeafPos());
+ int startIndex = areaInfo.startIndex;
int stopIndex;
boolean nothingChanged = true;
- final Font font = ai.font;
+ Font font = areaInfo.font;
- while (startIndex < ai.breakIndex) {
- final MinOptMax newIPD = new MinOptMax(0);
+ while (startIndex < areaInfo.breakIndex) {
+ MinOptMax newIPD = MinOptMax.ZERO;
boolean hyphenFollows;
- stopIndex = startIndex + hc.getNextHyphPoint();
- if (hc.hasMoreHyphPoints() && stopIndex <= ai.breakIndex) {
+ stopIndex = startIndex + hyphContext.getNextHyphPoint();
+ if (hyphContext.hasMoreHyphPoints() && stopIndex <= areaInfo.breakIndex) {
// stopIndex is the index of the first character
// after a hyphenation point
hyphenFollows = true;
} else {
// there are no more hyphenation points,
- // or the next one is after ai.breakIndex
+ // or the next one is after areaInfo.breakIndex
hyphenFollows = false;
- stopIndex = ai.breakIndex;
+ stopIndex = areaInfo.breakIndex;
}
- hc.updateOffset(stopIndex - startIndex);
+ hyphContext.updateOffset(stopIndex - startIndex);
//log.info("Word: " + new String(textArray, startIndex, stopIndex - startIndex));
for (int i = startIndex; i < stopIndex; i++) {
- final char c = this.foText.charAt(i);
- newIPD.add(new MinOptMax(font.getCharWidth(c)));
+ char ch = foText.charAt(i);
+ newIPD = newIPD.plus(font.getCharWidth(ch));
//if (i > startIndex) {
if (i < stopIndex) {
- MinOptMax la = this.letterAdjustArray[i + 1];
+ MinOptMax letterAdjust = letterAdjustArray[i + 1];
if (i == stopIndex - 1 && hyphenFollows) {
//the letter adjust here needs to be handled further down during
//element generation because it depends on hyph/no-hyph condition
- la = null;
+ letterAdjust = null;
}
- if (la != null) {
- newIPD.add(la);
+ if (letterAdjust != null) {
+ newIPD = newIPD.plus(letterAdjust);
}
}
}
+
// add letter spaces
- final boolean isWordEnd
- = stopIndex == ai.breakIndex
- && ai.letterSpaceCount < ai.breakIndex - ai.startIndex;
- newIPD.add(MinOptMax.multiply(this.letterSpaceIPD,
- (isWordEnd
- ? stopIndex - startIndex - 1
- : stopIndex - startIndex)));
-
- if (!(nothingChanged
- && stopIndex == ai.breakIndex
- && !hyphenFollows)) {
+ boolean isWordEnd = stopIndex == areaInfo.breakIndex && areaInfo.letterSpaceCount < areaInfo.getCharLength();
+ int letterSpaceCount = isWordEnd ? stopIndex - startIndex - 1 : stopIndex - startIndex;
+
+ assert letterSpaceCount >= 0;
+ newIPD = newIPD.plus(letterSpaceIPD.mult(letterSpaceCount));
+
+ if (!(nothingChanged && stopIndex == areaInfo.breakIndex && !hyphenFollows)) {
// the new AreaInfo object is not equal to the old one
- if (this.changeList == null) {
- this.changeList = new LinkedList();
- }
- this.changeList.add(new PendingChange(new AreaInfo(
- startIndex, stopIndex, 0,
- (isWordEnd ? stopIndex - startIndex - 1
- : stopIndex - startIndex), newIPD,
- hyphenFollows, false, false, font),
+ changeList.add(new PendingChange(new AreaInfo(startIndex, stopIndex, 0,
+ letterSpaceCount, newIPD, hyphenFollows, false, false, font),
((LeafPosition) pos).getLeafPos()));
nothingChanged = false;
}
startIndex = stopIndex;
}
- this.hasChanged = (this.hasChanged || !nothingChanged);
+ hasChanged |= !nothingChanged;
}
/** {@inheritDoc} */
public boolean applyChanges(final List oldList) {
- this.setFinished(false);
+ setFinished(false);
- if (this.changeList != null && !this.changeList.isEmpty()) {
+ if (!changeList.isEmpty()) {
int areaInfosAdded = 0;
int areaInfosRemoved = 0;
int oldIndex = -1, changeIndex;
PendingChange currChange;
- final ListIterator changeListIterator = this.changeList.listIterator();
+ ListIterator changeListIterator = changeList.listIterator();
while (changeListIterator.hasNext()) {
currChange = (PendingChange) changeListIterator.next();
if (currChange.index == oldIndex) {
@@ -951,111 +991,109 @@
areaInfosAdded++;
oldIndex = currChange.index;
changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved;
- this.vecAreaInfo.remove(changeIndex);
+ areaInfos.remove(changeIndex);
}
- this.vecAreaInfo.add(changeIndex, currChange.ai);
+ areaInfos.add(changeIndex, currChange.areaInfo);
}
- this.changeList.clear();
+ changeList.clear();
}
- this.returnedIndex = 0;
- return this.hasChanged;
+ returnedIndex = 0;
+ return hasChanged;
}
/** {@inheritDoc} */
- public List getChangedKnuthElements(final List oldList,
- final int alignment) {
- if (this.isFinished()) {
+ public List getChangedKnuthElements(final List oldList, final int alignment) {
+ if (isFinished()) {
return null;
}
final LinkedList returnList = new LinkedList();
- while (this.returnedIndex < this.vecAreaInfo.size()) {
- final AreaInfo ai = (AreaInfo) this.vecAreaInfo.get(this.returnedIndex);
- if (ai.wordSpaceCount == 0) {
- // ai refers either to a word or a word fragment
- this.addElementsForAWordFragment(returnList, alignment, ai,
- this.returnedIndex, this.letterSpaceIPD);
+ while (returnedIndex < areaInfos.size()) {
+ AreaInfo areaInfo = getAreaInfo(returnedIndex);
+ if (areaInfo.wordSpaceCount == 0) {
+ // areaInfo refers either to a word or a word fragment
+ addElementsForAWordFragment(returnList, alignment, areaInfo, returnedIndex);
} else {
- // ai refers to a space
- this.addElementsForASpace(returnList, alignment, ai, this.returnedIndex);
+ // areaInfo refers to a space
+ addElementsForASpace(returnList, alignment, areaInfo, returnedIndex);
}
- this.returnedIndex++;
- } // end of while
- this.setFinished(true);
+ returnedIndex++;
+ }
+ setFinished(true);
//ElementListObserver.observe(returnList, "text-changed", null);
return returnList;
}
- /** {@inheritDoc} */
- public void getWordChars(final StringBuffer sbChars, final Position pos) {
- final int leafValue = ((LeafPosition) pos).getLeafPos();
+ /**
+ * {@inheritDoc}
+ */
+ public String getWordChars(Position pos) {
+ int leafValue = ((LeafPosition) pos).getLeafPos();
if (leafValue != -1) {
- final AreaInfo ai = (AreaInfo) this.vecAreaInfo.get(leafValue);
- for (int i = ai.startIndex; i < ai.breakIndex; ++i) {
- sbChars.append(this.foText.charAt(i));
+ AreaInfo areaInfo = getAreaInfo(leafValue);
+ StringBuffer buffer = new StringBuffer(areaInfo.getCharLength());
+ for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ buffer.append(foText.charAt(i));
}
+ return buffer.toString();
+ } else {
+ return "";
}
}
- private void addElementsForASpace(final List baseList,
- final int alignment,
- final AreaInfo ai,
- final int leafValue) {
- final LeafPosition mainPosition = new LeafPosition(this, leafValue);
+ private void addElementsForASpace(List baseList, int alignment, AreaInfo areaInfo,
+ int leafValue) {
+ LeafPosition mainPosition = new LeafPosition(this, leafValue);
- if (!ai.breakOppAfter) {
+ if (!areaInfo.breakOppAfter) {
// a non-breaking space
if (alignment == Constants.EN_JUSTIFY) {
// the space can stretch and shrink, and must be preserved
// when starting a line
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(ai.areaIPD.opt, ai.areaIPD.max - ai.areaIPD.opt,
- ai.areaIPD.opt - ai.areaIPD.min, mainPosition, false));
+ baseList.add(makeAuxiliaryZeroWidthBox());
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(areaInfo.areaIPD, mainPosition, false));
} else {
// the space does not need to stretch or shrink, and must be
// preserved when starting a line
- baseList.add(new KnuthInlineBox(ai.areaIPD.opt, null,
- mainPosition, true));
+ baseList.add(new KnuthInlineBox(areaInfo.areaIPD.getOpt(), null, mainPosition,
+ true));
}
} else {
- if (this.foText.charAt(ai.startIndex) != CharUtilities.SPACE
- || this.foText.getWhitespaceTreatment() == Constants.EN_PRESERVE) {
+ if (foText.charAt(areaInfo.startIndex) != CharUtilities.SPACE
+ || foText.getWhitespaceTreatment() == Constants.EN_PRESERVE) {
// a breaking space that needs to be preserved
- this.addElementsForBreakingSpace(baseList, alignment, ai,
- this.auxiliaryPosition, 0, mainPosition,
- ai.areaIPD.opt, true);
+ baseList.addAll(getElementsForBreakingSpace(alignment, areaInfo, auxiliaryPosition, 0,
+ mainPosition, areaInfo.areaIPD.getOpt(), true));
} else {
// a (possible block) of breaking spaces
- this.addElementsForBreakingSpace(baseList, alignment, ai,
- mainPosition, ai.areaIPD.opt,
- this.auxiliaryPosition, 0, false);
+ baseList.addAll(getElementsForBreakingSpace(alignment, areaInfo, mainPosition,
+ areaInfo.areaIPD.getOpt(), auxiliaryPosition, 0, false));
}
}
}
- private void addElementsForBreakingSpace(final List baseList,
- final int alignment, final AreaInfo ai, final Position pos2,
- final int p2WidthOffset, final Position pos3,
- final int p3WidthOffset, final boolean skipZeroCheck) {
+ private List getElementsForBreakingSpace(int alignment, AreaInfo areaInfo, Position pos2,
+ int p2WidthOffset, Position pos3,
+ int p3WidthOffset, boolean skipZeroCheck) {
+ List elements = new ArrayList();
+
switch (alignment) {
case EN_CENTER:
// centered text:
// if the second element is chosen as a line break these elements
// add a constant amount of stretch at the end of a line and at the
// beginning of the next one, otherwise they don't add any stretch
- baseList.add(new KnuthGlue(this.lineEndBAP,
- 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeZeroWidthPenalty(0));
- baseList.add(new KnuthGlue(p2WidthOffset
- - (this.lineStartBAP + this.lineEndBAP), -6
+ elements.add(new KnuthGlue(lineEndBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
+ auxiliaryPosition, false));
+ elements.add(makeZeroWidthPenalty(0));
+ elements.add(new KnuthGlue(p2WidthOffset - (lineStartBAP + lineEndBAP), -6
* LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos2, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP + p3WidthOffset,
+ elements.add(makeAuxiliaryZeroWidthBox());
+ elements.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ elements.add(new KnuthGlue(lineStartBAP + p3WidthOffset,
3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos3, false));
break;
@@ -1065,246 +1103,203 @@
// if the second element is chosen as a line break these elements
// add a constant amount of stretch at the end of a line, otherwise
// they don't add any stretch
- if (skipZeroCheck || this.lineStartBAP != 0 || this.lineEndBAP != 0) {
- baseList.add(new KnuthGlue(this.lineEndBAP,
- 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeZeroWidthPenalty(0));
- baseList.add(new KnuthGlue(p2WidthOffset
- - (this.lineStartBAP + this.lineEndBAP), -3
- * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- pos2, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP + p3WidthOffset,
- 0, 0, pos3, false));
+ if (skipZeroCheck || lineStartBAP != 0 || lineEndBAP != 0) {
+ elements.add(new KnuthGlue(lineEndBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, auxiliaryPosition, false));
+ elements.add(makeZeroWidthPenalty(0));
+ elements.add(new KnuthGlue(p2WidthOffset - (lineStartBAP + lineEndBAP), -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos2, false));
+ elements.add(makeAuxiliaryZeroWidthBox());
+ elements.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ elements.add(new KnuthGlue(lineStartBAP + p3WidthOffset, 0, 0, pos3, false));
} else {
- baseList.add(new KnuthGlue(0,
- 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeZeroWidthPenalty(0));
- baseList.add(new KnuthGlue(ai.areaIPD.opt, -3
- * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- pos2, false));
+ elements.add(new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, auxiliaryPosition, false));
+ elements.add(makeZeroWidthPenalty(0));
+ elements.add(new KnuthGlue(areaInfo.areaIPD.getOpt(), -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos2, false));
}
break;
case EN_JUSTIFY:
// justified text:
// the stretch and shrink depends on the space width
- if (skipZeroCheck || this.lineStartBAP != 0 || this.lineEndBAP != 0) {
- baseList.add(new KnuthGlue(this.lineEndBAP, 0, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeZeroWidthPenalty(0));
- baseList.add(new KnuthGlue(p2WidthOffset
- - (this.lineStartBAP + this.lineEndBAP), ai.areaIPD.max
- - ai.areaIPD.opt, ai.areaIPD.opt - ai.areaIPD.min,
- pos2, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP + p3WidthOffset,
- 0, 0, pos3, false));
- } else {
- baseList.add(new KnuthGlue(ai.areaIPD.opt, ai.areaIPD.max
- - ai.areaIPD.opt, ai.areaIPD.opt - ai.areaIPD.min,
- pos2, false));
- }
+ elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3,
+ p3WidthOffset, skipZeroCheck, areaInfo.areaIPD.getShrink()));
break;
default:
// last line justified, the other lines unjustified:
// use only the space stretch
- if (skipZeroCheck || this.lineStartBAP != 0 || this.lineEndBAP != 0) {
- baseList.add(new KnuthGlue(this.lineEndBAP, 0, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeZeroWidthPenalty(0));
- baseList.add(new KnuthGlue(p2WidthOffset
- - (this.lineStartBAP + this.lineEndBAP), ai.areaIPD.max
- - ai.areaIPD.opt, 0, pos2, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP + p3WidthOffset,
- 0, 0, pos3, false));
- } else {
- baseList.add(new KnuthGlue(ai.areaIPD.opt, ai.areaIPD.max
- - ai.areaIPD.opt, 0, pos2, false));
- }
+ elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3,
+ p3WidthOffset, skipZeroCheck, 0));
}
+ return elements;
}
- private void addElementsForAWordFragment(final List baseList,
- final int alignment,
- final AreaInfo ai,
- final int leafValue,
- final MinOptMax letterSpaceWidth) {
+ private List getElementsForJustifiedText(AreaInfo areaInfo, Position pos2, int p2WidthOffset,
+ Position pos3, int p3WidthOffset, boolean skipZeroCheck,
+ int shrinkability) {
+
+ int stretchability = areaInfo.areaIPD.getStretch();
+
+ List elements = new ArrayList();
+ if (skipZeroCheck || lineStartBAP != 0 || lineEndBAP != 0) {
+ elements.add(new KnuthGlue(lineEndBAP, 0, 0, auxiliaryPosition, false));
+ elements.add(makeZeroWidthPenalty(0));
+ elements.add(new KnuthGlue(p2WidthOffset - (lineStartBAP + lineEndBAP),
+ stretchability, shrinkability, pos2, false));
+ elements.add(makeAuxiliaryZeroWidthBox());
+ elements.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ elements.add(new KnuthGlue(lineStartBAP + p3WidthOffset, 0, 0, pos3, false));
+ } else {
+ elements.add(new KnuthGlue(areaInfo.areaIPD.getOpt(), stretchability, shrinkability,
+ pos2, false));
+ }
+ return elements;
+ }
- final LeafPosition mainPosition = new LeafPosition(this, leafValue);
+ private void addElementsForAWordFragment(List baseList, int alignment, AreaInfo areaInfo,
+ int leafValue) {
+ LeafPosition mainPosition = new LeafPosition(this, leafValue);
// if the last character of the word fragment is '-' or '/',
// the fragment could end a line; in this case, it loses one
// of its letter spaces;
- final boolean suppressibleLetterSpace = ai.breakOppAfter && !ai.isHyphenated;
+ boolean suppressibleLetterSpace = areaInfo.breakOppAfter && !areaInfo.isHyphenated;
- if (letterSpaceWidth.min == letterSpaceWidth.max) {
+ if (letterSpaceIPD.isStiff()) {
// constant letter spacing
- baseList.add(new KnuthInlineBox(
- suppressibleLetterSpace
- ? ai.areaIPD.opt - letterSpaceWidth.opt
- : ai.areaIPD.opt,
- this.alignmentContext,
- this.notifyPos(mainPosition), false));
+ baseList.add(new KnuthInlineBox(suppressibleLetterSpace
+ ? areaInfo.areaIPD.getOpt() - letterSpaceIPD.getOpt()
+ : areaInfo.areaIPD.getOpt(),
+ alignmentContext, notifyPos(mainPosition), false));
} else {
// adjustable letter spacing
- final int unsuppressibleLetterSpaces
- = suppressibleLetterSpace ? ai.letterSpaceCount - 1 : ai.letterSpaceCount;
- baseList.add
- (new KnuthInlineBox(ai.areaIPD.opt
- - ai.letterSpaceCount * letterSpaceWidth.opt,
- this.alignmentContext,
- this.notifyPos(mainPosition), false));
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add
- (new KnuthGlue(unsuppressibleLetterSpaces * letterSpaceWidth.opt,
- unsuppressibleLetterSpaces * (letterSpaceWidth.max - letterSpaceWidth.opt),
- unsuppressibleLetterSpaces * (letterSpaceWidth.opt - letterSpaceWidth.min),
- this.auxiliaryPosition, true));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
+ int unsuppressibleLetterSpaces = suppressibleLetterSpace
+ ? areaInfo.letterSpaceCount - 1
+ : areaInfo.letterSpaceCount;
+ baseList.add(new KnuthInlineBox(areaInfo.areaIPD.getOpt()
+ - areaInfo.letterSpaceCount * letterSpaceIPD.getOpt(),
+ alignmentContext, notifyPos(mainPosition), false));
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(letterSpaceIPD.mult(unsuppressibleLetterSpaces),
+ auxiliaryPosition, true));
+ baseList.add(makeAuxiliaryZeroWidthBox());
}
// extra-elements if the word fragment is the end of a syllable,
// or it ends with a character that can be used as a line break
- if (ai.isHyphenated) {
+ if (areaInfo.isHyphenated) {
MinOptMax widthIfNoBreakOccurs = null;
- if (ai.breakIndex < this.foText.length()) {
+ if (areaInfo.breakIndex < foText.length()) {
//Add in kerning in no-break condition
- widthIfNoBreakOccurs = this.letterAdjustArray[ai.breakIndex];
+ widthIfNoBreakOccurs = letterAdjustArray[areaInfo.breakIndex];
}
- //if (ai.breakIndex)
+ //if (areaInfo.breakIndex)
// the word fragment ends at the end of a syllable:
// if a break occurs the content width increases,
// otherwise nothing happens
- this.addElementsForAHyphen(baseList, alignment, this.hyphIPD,
- widthIfNoBreakOccurs, ai.breakOppAfter && ai.isHyphenated);
+ addElementsForAHyphen(baseList, alignment, hyphIPD, widthIfNoBreakOccurs,
+ areaInfo.breakOppAfter && areaInfo.isHyphenated);
} else if (suppressibleLetterSpace) {
// the word fragment ends with a character that acts as a hyphen
// if a break occurs the width does not increase,
// otherwise there is one more letter space
- this.addElementsForAHyphen(baseList, alignment, 0, letterSpaceWidth, true);
+ addElementsForAHyphen(baseList, alignment, 0, letterSpaceIPD, true);
}
}
- // static final int SOFT_HYPHEN_PENALTY = KnuthPenalty.FLAGGED_PENALTY / 10;
- private static final int SOFT_HYPHEN_PENALTY = 1;
+ private void addElementsForAHyphen(List baseList, int alignment, int widthIfBreakOccurs,
+ MinOptMax widthIfNoBreakOccurs, boolean unflagged) {
- private void addElementsForAHyphen(final List baseList,
- final int alignment,
- final int widthIfBreakOccurs,
- MinOptMax widthIfNoBreakOccurs,
- final boolean unflagged) {
if (widthIfNoBreakOccurs == null) {
- widthIfNoBreakOccurs = TextLayoutManager.ZERO_MINOPTMAX;
+ widthIfNoBreakOccurs = MinOptMax.ZERO;
}
switch (alignment) {
- case EN_CENTER :
+ case EN_CENTER:
// centered text:
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineEndBAP,
- 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, true));
- baseList.add(new KnuthPenalty(this.hyphIPD,
- unflagged ? TextLayoutManager.SOFT_HYPHEN_PENALTY
- : KnuthPenalty.FLAGGED_PENALTY, !unflagged,
- this.auxiliaryPosition, false));
- baseList.add(new KnuthGlue(-(this.lineEndBAP + this.lineStartBAP),
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineEndBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
+ auxiliaryPosition, true));
+ baseList.add(new KnuthPenalty(hyphIPD, unflagged
+ ? TextLayoutManager.SOFT_HYPHEN_PENALTY
+ : KnuthPenalty.FLAGGED_PENALTY, !unflagged, auxiliaryPosition, false));
+ baseList.add(new KnuthGlue(-(lineEndBAP + lineStartBAP),
-6 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP,
- 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, true));
+ auxiliaryPosition, false));
+ baseList.add(makeAuxiliaryZeroWidthBox());
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineStartBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH,
+ 0, auxiliaryPosition, true));
break;
- case EN_START : // fall through
- case EN_END :
+ case EN_START: // fall through
+ case EN_END:
// left- or right-aligned text:
- if (this.lineStartBAP != 0 || this.lineEndBAP != 0) {
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineEndBAP,
+ if (lineStartBAP != 0 || lineEndBAP != 0) {
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineEndBAP,
3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
baseList.add(new KnuthPenalty(widthIfBreakOccurs,
unflagged ? TextLayoutManager.SOFT_HYPHEN_PENALTY
: KnuthPenalty.FLAGGED_PENALTY, !unflagged,
- this.auxiliaryPosition, false));
- baseList.add(new KnuthGlue(widthIfNoBreakOccurs.opt
- - (this.lineStartBAP + this.lineEndBAP), -3
- * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP, 0, 0,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
+ baseList.add(new KnuthGlue(widthIfNoBreakOccurs.getOpt()
+ - (lineStartBAP + lineEndBAP),
+ -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
+ auxiliaryPosition, false));
+ baseList.add(makeAuxiliaryZeroWidthBox());
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineStartBAP, 0, 0, auxiliaryPosition, false));
} else {
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
baseList.add(new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
baseList.add(new KnuthPenalty(widthIfBreakOccurs,
unflagged ? TextLayoutManager.SOFT_HYPHEN_PENALTY
: KnuthPenalty.FLAGGED_PENALTY, !unflagged,
- this.auxiliaryPosition, false));
- baseList.add(new KnuthGlue(widthIfNoBreakOccurs.opt,
- -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
+ baseList.add(new KnuthGlue(widthIfNoBreakOccurs.getOpt(),
+ -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
+ auxiliaryPosition, false));
}
break;
default:
// justified text, or last line justified:
// just a flagged penalty
- if (this.lineStartBAP != 0 || this.lineEndBAP != 0) {
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineEndBAP, 0, 0,
- this.auxiliaryPosition, false));
+ if (lineStartBAP != 0 || lineEndBAP != 0) {
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineEndBAP, 0, 0, auxiliaryPosition, false));
baseList.add(new KnuthPenalty(widthIfBreakOccurs,
unflagged ? TextLayoutManager.SOFT_HYPHEN_PENALTY
: KnuthPenalty.FLAGGED_PENALTY, !unflagged,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
// extra elements representing a letter space that is suppressed
// if a break occurs
- if (widthIfNoBreakOccurs.min != 0
- || widthIfNoBreakOccurs.max != 0) {
- baseList
- .add(new KnuthGlue(widthIfNoBreakOccurs.opt
- - (this.lineStartBAP + this.lineEndBAP),
- widthIfNoBreakOccurs.max
- - widthIfNoBreakOccurs.opt,
- widthIfNoBreakOccurs.opt
- - widthIfNoBreakOccurs.min,
- this.auxiliaryPosition, false));
+ if (widthIfNoBreakOccurs.isNonZero()) {
+ baseList.add(new KnuthGlue(widthIfNoBreakOccurs.getOpt()
+ - (lineStartBAP + lineEndBAP),
+ widthIfNoBreakOccurs.getStretch(),
+ widthIfNoBreakOccurs.getShrink(),
+ auxiliaryPosition, false));
} else {
- baseList.add(new KnuthGlue(-(this.lineStartBAP + this.lineEndBAP), 0, 0,
- this.auxiliaryPosition, false));
+ baseList.add(new KnuthGlue(-(lineStartBAP + lineEndBAP), 0, 0,
+ auxiliaryPosition, false));
}
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP, 0, 0,
- this.auxiliaryPosition, false));
+ baseList.add(makeAuxiliaryZeroWidthBox());
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineStartBAP, 0, 0,
+ auxiliaryPosition, false));
} else {
baseList.add(new KnuthPenalty(widthIfBreakOccurs,
unflagged ? TextLayoutManager.SOFT_HYPHEN_PENALTY
: KnuthPenalty.FLAGGED_PENALTY, !unflagged,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
// extra elements representing a letter space that is suppressed
// if a break occurs
- if (widthIfNoBreakOccurs.min != 0
- || widthIfNoBreakOccurs.max != 0) {
- baseList.add(new KnuthGlue(widthIfNoBreakOccurs.opt,
- widthIfNoBreakOccurs.max - widthIfNoBreakOccurs.opt,
- widthIfNoBreakOccurs.opt - widthIfNoBreakOccurs.min,
- this.auxiliaryPosition, false));
+ if (widthIfNoBreakOccurs.isNonZero()) {
+ baseList.add(new KnuthGlue(widthIfNoBreakOccurs, auxiliaryPosition, false));
}
}
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java?rev=893238&r1=893237&r2=893238&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java Tue Dec 22 17:20:51 2009
@@ -28,8 +28,6 @@
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.TraitSetter;
-import java.util.LinkedList;
-
/**
* This is the layout manager for the fo:wrapper formatting object.
*/
@@ -67,14 +65,14 @@
public void addAreas(PositionIterator posIter, LayoutContext context) {
if (fobj.hasId()) {
addId();
- if (parentLM instanceof BlockStackingLayoutManager
- && !(parentLM instanceof BlockLayoutManager)) {
+ if (parentLayoutManager instanceof BlockStackingLayoutManager
+ && !(parentLayoutManager instanceof BlockLayoutManager)) {
Block helperBlock = new Block();
TraitSetter.setProducerID(helperBlock, fobj.getId());
- parentLM.addChildArea(helperBlock);
+ parentLayoutManager.addChildArea(helperBlock);
} else {
InlineArea area = getEffectiveArea();
- parentLM.addChildArea(area);
+ parentLayoutManager.addChildArea(area);
}
}
while (posIter.hasNext()) {
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java?rev=893238&r1=893237&r2=893238&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java Tue Dec 22 17:20:51 2009
@@ -154,7 +154,7 @@
// if this will create the first block area in a page
// and display-align is after or center, add space before
if (layoutContext.getSpaceBefore() > 0) {
- addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore()));
+ addBlockSpacing(0.0, MinOptMax.getInstance(layoutContext.getSpaceBefore()));
}
addId();
@@ -241,7 +241,7 @@
// Set up dimensions
// Must get dimensions from parent area
- /*Area parentArea =*/ parentLM.getParentArea(curBlockArea);
+ /*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);
// set traits
TraitSetter.setProducerID(curBlockArea, getListBlockFO().getId());
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org