aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java')
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java719
1 files changed, 232 insertions, 487 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
index 53f51cd32..625b43ee5 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
@@ -30,12 +30,11 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.area.Trait;
import org.apache.fop.area.inline.TextArea;
-import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
-import org.apache.fop.complexscripts.util.CharScript;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FOText;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontSelector;
+import org.apache.fop.fonts.GlyphMapping;
import org.apache.fop.layoutmgr.InlineKnuthSequence;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
@@ -65,91 +64,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
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
- * any word-space and letter-space.
- * Number of word-spaces?
- */
- private class AreaInfo {
-
- private final int startIndex;
- private final int breakIndex;
- private int wordCharLength;
- private final int wordSpaceCount;
- private int letterSpaceCount;
- private MinOptMax areaIPD;
- private final boolean isHyphenated;
- private final boolean isSpace;
- private boolean breakOppAfter;
- private final Font font;
- private final int level;
- private final int[][] gposAdjustments;
-
- AreaInfo(
- int startIndex, int breakIndex, int wordSpaceCount, int letterSpaceCount,
- MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter,
- Font font, int level, int[][] gposAdjustments) {
- assert startIndex <= breakIndex;
- this.startIndex = startIndex;
- this.breakIndex = breakIndex;
- this.wordCharLength = -1;
- this.wordSpaceCount = wordSpaceCount;
- this.letterSpaceCount = letterSpaceCount;
- this.areaIPD = areaIPD;
- this.isHyphenated = isHyphenated;
- this.isSpace = isSpace;
- this.breakOppAfter = breakOppAfter;
- this.font = font;
- this.level = level;
- this.gposAdjustments = gposAdjustments;
- }
-
- /**
- * Obtain number of 'characters' contained in word. If word
- * is mapped, then this number may be less than or greater than the
- * original length (breakIndex - startIndex). We compute and
- * memoize thius length upon first invocation of this method.
- */
- private int getWordLength() {
- if (wordCharLength == -1) {
- if (foText.hasMapping(startIndex, breakIndex)) {
- wordCharLength = foText.getMapping(startIndex, breakIndex).length();
- } else {
- assert breakIndex >= startIndex;
- wordCharLength = breakIndex - startIndex;
- }
- }
- return wordCharLength;
- }
-
- private void addToAreaIPD(MinOptMax idp) {
- areaIPD = areaIPD.plus(idp);
- }
-
- public String toString() {
- return super.toString() + "{"
- + "interval = [" + startIndex + "," + breakIndex + "]"
- + ", isSpace = " + isSpace
- + ", level = " + level
- + ", areaIPD = " + areaIPD
- + ", letterSpaceCount = " + letterSpaceCount
- + ", wordSpaceCount = " + wordSpaceCount
- + ", isHyphenated = " + isHyphenated
- + ", font = " + font
- + "}";
- }
- }
-
- /**
* this class stores information about changes in vecAreaInfo which are not yet applied
*/
private final class PendingChange {
- private final AreaInfo areaInfo;
+ private final GlyphMapping mapping;
private final int index;
- private PendingChange(final AreaInfo areaInfo, final int index) {
- this.areaInfo = areaInfo;
+ private PendingChange(final GlyphMapping mapping, final int index) {
+ this.mapping = mapping;
this.index = index;
}
}
@@ -160,7 +83,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
private static final Log LOG = LogFactory.getLog(TextLayoutManager.class);
// Hold all possible breaks for the text in this LM's FO.
- private final List areaInfos;
+ private final List<GlyphMapping> mappings;
/** Non-space characters on which we can end a line. */
private static final String BREAK_CHARS = "-/";
@@ -216,7 +139,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
public TextLayoutManager(FOText node) {
foText = node;
letterSpaceAdjustArray = new MinOptMax[node.length() + 1];
- areaInfos = new ArrayList();
+ mappings = new ArrayList<GlyphMapping>();
}
private KnuthPenalty makeZeroWidthPenalty(int penaltyValue) {
@@ -274,61 +197,61 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
public void addAreas(final PositionIterator posIter, final LayoutContext context) {
// Add word areas
- AreaInfo areaInfo;
+ GlyphMapping mapping;
int wordSpaceCount = 0;
int letterSpaceCount = 0;
- int firstAreaInfoIndex = -1;
- int lastAreaInfoIndex = 0;
+ int firstMappingIndex = -1;
+ int lastMappingIndex = 0;
MinOptMax realWidth = MinOptMax.ZERO;
/* On first area created, add any leading space.
* Calculate word-space stretch value.
*/
- AreaInfo lastAreaInfo = null;
+ GlyphMapping lastMapping = null;
while (posIter.hasNext()) {
final LeafPosition tbpNext = (LeafPosition) posIter.next();
if (tbpNext == null) {
continue; //Ignore elements without Positions
}
if (tbpNext.getLeafPos() != -1) {
- areaInfo = (AreaInfo) areaInfos.get(tbpNext.getLeafPos());
- if (lastAreaInfo == null
- || (areaInfo.font != lastAreaInfo.font)
- || (areaInfo.level != lastAreaInfo.level)) {
- if (lastAreaInfo != null) {
- addAreaInfoAreas(lastAreaInfo, wordSpaceCount,
- letterSpaceCount, firstAreaInfoIndex,
- lastAreaInfoIndex, realWidth, context);
+ mapping = mappings.get(tbpNext.getLeafPos());
+ if (lastMapping == null
+ || (mapping.font != lastMapping.font)
+ || (mapping.level != lastMapping.level)) {
+ if (lastMapping != null) {
+ addMappingAreas(lastMapping, wordSpaceCount,
+ letterSpaceCount, firstMappingIndex,
+ lastMappingIndex, realWidth, context);
}
- firstAreaInfoIndex = tbpNext.getLeafPos();
+ firstMappingIndex = tbpNext.getLeafPos();
wordSpaceCount = 0;
letterSpaceCount = 0;
realWidth = MinOptMax.ZERO;
}
- wordSpaceCount += areaInfo.wordSpaceCount;
- letterSpaceCount += areaInfo.letterSpaceCount;
- realWidth = realWidth.plus(areaInfo.areaIPD);
- lastAreaInfoIndex = tbpNext.getLeafPos();
- lastAreaInfo = areaInfo;
+ wordSpaceCount += mapping.wordSpaceCount;
+ letterSpaceCount += mapping.letterSpaceCount;
+ realWidth = realWidth.plus(mapping.areaIPD);
+ lastMappingIndex = tbpNext.getLeafPos();
+ lastMapping = mapping;
}
}
- if (lastAreaInfo != null) {
- addAreaInfoAreas(lastAreaInfo, wordSpaceCount, letterSpaceCount, firstAreaInfoIndex,
- lastAreaInfoIndex, realWidth, context);
+ if (lastMapping != null) {
+ addMappingAreas(lastMapping, wordSpaceCount, letterSpaceCount, firstMappingIndex,
+ lastMappingIndex, realWidth, context);
}
}
- private void addAreaInfoAreas(AreaInfo areaInfo, int wordSpaceCount, int letterSpaceCount,
- int firstAreaInfoIndex, int lastAreaInfoIndex,
+ private void addMappingAreas(GlyphMapping mapping, int wordSpaceCount, int letterSpaceCount,
+ int firstMappingIndex, int lastMappingIndex,
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 areaInfo.
+ // changes. However, it seems as if they should use the GlyphMapping from
+ // firstMappingIndex.. lastMappingIndex rather than just the last mapping.
// This needs to be checked.
- int textLength = areaInfo.getWordLength();
- if (areaInfo.letterSpaceCount == textLength && !areaInfo.isHyphenated
+ int textLength = mapping.getWordLength();
+ if (mapping.letterSpaceCount == textLength && !mapping.isHyphenated
&& context.isLastArea()) {
// the line ends at a character like "/" or "-";
// remove the letter space after the last character
@@ -336,7 +259,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
letterSpaceCount--;
}
- for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
MinOptMax letterSpaceAdjustment = letterSpaceAdjustArray[i + 1];
if (letterSpaceAdjustment != null && letterSpaceAdjustment.isElastic()) {
letterSpaceCount++;
@@ -344,7 +267,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
// add hyphenation character if the last word is hyphenated
- if (context.isLastArea() && areaInfo.isHyphenated) {
+ if (context.isLastArea() && mapping.isHyphenated) {
realWidth = realWidth.plus(hyphIPD);
}
@@ -385,8 +308,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
totalAdjust = difference;
}
- TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstAreaInfoIndex,
- lastAreaInfoIndex, context.isLastArea(), areaInfo.font).build();
+ TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstMappingIndex,
+ lastMappingIndex, context.isLastArea(), mapping.font).build();
// wordSpaceDim is computed in relation to wordSpaceIPD.opt
// but the renderer needs to know the adjustment in relation
@@ -417,15 +340,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
private final MinOptMax width; // content ipd
private final int adjust; // content ipd adjustment
private final LayoutContext context; // layout context
- private final int firstIndex; // index of first AreaInfo
- private final int lastIndex; // index of last AreaInfo
+ private final int firstIndex; // index of first GlyphMapping
+ private final int lastIndex; // index of last GlyphMapping
private final boolean isLastArea; // true if last inline area in line area
private final Font font; // applicable font
// other, non-constructor state
private TextArea textArea; // text area being constructed
private int blockProgressionDimension; // calculated bpd
- private AreaInfo areaInfo; // current area info when iterating over words
+ private GlyphMapping mapping; // current mapping when iterating over words
private StringBuffer wordChars; // current word's character buffer
private int[] letterSpaceAdjust; // current word's letter space adjustments
private int letterSpaceAdjustIndex; // last written letter space adjustment index
@@ -442,8 +365,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
* @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 firstIndex the index of the first GlyphMapping used for the TextArea
+ * @param lastIndex the index of the last GlyphMapping used for the TextArea
* @param isLastArea is this TextArea the last in a line?
* @param font Font to be used in this particular TextArea
*/
@@ -516,30 +439,30 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
* Sets the text of the TextArea, split into words and spaces.
*/
private void setText() {
- int areaInfoIndex = -1;
+ int mappingIndex = -1;
int wordCharLength = 0;
for (int wordIndex = firstIndex; wordIndex <= lastIndex; wordIndex++) {
- areaInfo = getAreaInfo(wordIndex);
- if (areaInfo.isSpace) {
+ mapping = getGlyphMapping(wordIndex);
+ if (mapping.isSpace) {
addSpaces();
} else {
- // areaInfo stores information about a word fragment
- if (areaInfoIndex == -1) {
+ // mapping stores information about a word fragment
+ if (mappingIndex == -1) {
// here starts a new word
- areaInfoIndex = wordIndex;
+ mappingIndex = wordIndex;
wordCharLength = 0;
}
- wordCharLength += areaInfo.getWordLength();
+ wordCharLength += mapping.getWordLength();
if (isWordEnd(wordIndex)) {
- addWord(areaInfoIndex, wordIndex, wordCharLength);
- areaInfoIndex = -1;
+ addWord(mappingIndex, wordIndex, wordCharLength);
+ mappingIndex = -1;
}
}
}
}
- private boolean isWordEnd(int areaInfoIndex) {
- return areaInfoIndex == lastIndex || getAreaInfo(areaInfoIndex + 1).isSpace;
+ private boolean isWordEnd(int mappingIndex) {
+ return mappingIndex == lastIndex || getGlyphMapping(mappingIndex + 1).isSpace;
}
/**
@@ -564,10 +487,10 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// iterate over word's fragments, adding word chars (with bidi
// levels), letter space adjustments, and glyph position adjustments
for (int i = startIndex; i <= endIndex; i++) {
- AreaInfo wordAreaInfo = getAreaInfo(i);
- addWordChars(wordAreaInfo);
- addLetterAdjust(wordAreaInfo);
- if (addGlyphPositionAdjustments(wordAreaInfo)) {
+ GlyphMapping wordMapping = getGlyphMapping(i);
+ addWordChars(wordMapping);
+ addLetterAdjust(wordMapping);
+ if (addGlyphPositionAdjustments(wordMapping)) {
gposAdjusted = true;
}
}
@@ -617,7 +540,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
private boolean isHyphenated(int endIndex) {
- return isLastArea && endIndex == lastIndex && areaInfo.isHyphenated;
+ return isLastArea && endIndex == lastIndex && mapping.isHyphenated;
}
private void addHyphenationChar() {
@@ -632,21 +555,54 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
* (1) concatenate (possibly mapped) word characters to word character buffer;
* (2) concatenante (possibly mapped) word bidi levels to levels buffer;
* (3) update word's IPD with optimal IPD of fragment.
- * @param wordAreaInfo fragment info
+ * @param wordMapping fragment info
*/
- private void addWordChars(AreaInfo wordAreaInfo) {
- int s = wordAreaInfo.startIndex;
- int e = wordAreaInfo.breakIndex;
- if (foText.hasMapping(s, e)) {
- wordChars.append(foText.getMapping(s, e));
- addWordLevels(foText.getMappingBidiLevels(s, e));
+ private void addWordChars(GlyphMapping wordMapping) {
+ int s = wordMapping.startIndex;
+ int e = wordMapping.endIndex;
+ if (wordMapping.mapping != null) {
+ wordChars.append(wordMapping.mapping);
+ addWordLevels(getMappingBidiLevels(wordMapping));
} else {
for (int i = s; i < e; i++) {
wordChars.append(foText.charAt(i));
}
addWordLevels(foText.getBidiLevels(s, e));
}
- wordIPD += wordAreaInfo.areaIPD.getOpt();
+ wordIPD += wordMapping.areaIPD.getOpt();
+ }
+
+ /**
+ * Obtain bidirectional levels of mapping of characters over specific interval.
+ * @param start index in character buffer
+ * @param end index in character buffer
+ * @return a (possibly empty) array of bidi levels or null
+ * in case no bidi levels have been assigned
+ */
+ private int[] getMappingBidiLevels(GlyphMapping mapping) {
+ if (mapping.mapping != null) {
+ int nc = mapping.endIndex - mapping.startIndex;
+ int nm = mapping.mapping.length();
+ int[] la = foText.getBidiLevels(mapping.startIndex, mapping.endIndex);
+ if (la == null) {
+ return null;
+ } else if (nm == nc) { // mapping is same length as mapped range
+ return la;
+ } else if (nm > nc) { // mapping is longer than mapped range
+ int[] ma = new int[nm];
+ System.arraycopy(la, 0, ma, 0, la.length);
+ for (int i = la.length, n = ma.length, l = (i > 0) ? la[i - 1] : 0; i < n; i++) {
+ ma[i] = l;
+ }
+ return ma;
+ } else { // mapping is shorter than mapped range
+ int[] ma = new int[nm];
+ System.arraycopy(la, 0, ma, 0, ma.length);
+ return ma;
+ }
+ } else {
+ return foText.getBidiLevels(mapping.startIndex, mapping.endIndex);
+ }
}
/**
@@ -672,16 +628,16 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
/**
* Given a word area info associated with a word fragment,
* concatenate letter space adjustments for each (possibly mapped) character.
- * @param wordAreaInfo fragment info
+ * @param wordMapping fragment info
*/
- private void addLetterAdjust(AreaInfo wordAreaInfo) {
- int letterSpaceCount = wordAreaInfo.letterSpaceCount;
- int wordLength = wordAreaInfo.getWordLength();
+ private void addLetterAdjust(GlyphMapping wordMapping) {
+ int letterSpaceCount = wordMapping.letterSpaceCount;
+ int wordLength = wordMapping.getWordLength();
int taAdjust = textArea.getTextLetterSpaceAdjust();
for (int i = 0, n = wordLength; i < n; i++) {
int j = letterSpaceAdjustIndex + i;
if (j > 0) {
- int k = wordAreaInfo.startIndex + i;
+ int k = wordMapping.startIndex + i;
MinOptMax adj = (k < letterSpaceAdjustArray.length)
? letterSpaceAdjustArray [ k ] : null;
letterSpaceAdjust [ j ] = (adj == null) ? 0 : adj.getOpt();
@@ -697,14 +653,14 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
/**
* Given a word area info associated with a word fragment,
* concatenate glyph position adjustments for each (possibly mapped) character.
- * @param wordAreaInfo fragment info
+ * @param wordMapping fragment info
* @return true if an adjustment was non-zero
*/
- private boolean addGlyphPositionAdjustments(AreaInfo wordAreaInfo) {
+ private boolean addGlyphPositionAdjustments(GlyphMapping wordMapping) {
boolean adjusted = false;
- int[][] gpa = wordAreaInfo.gposAdjustments;
+ int[][] gpa = wordMapping.gposAdjustments;
int numAdjusts = (gpa != null) ? gpa.length : 0;
- int wordLength = wordAreaInfo.getWordLength();
+ int wordLength = wordMapping.getWordLength();
if (numAdjusts > 0) {
int need = gposAdjustmentsIndex + numAdjusts;
if (need <= gposAdjustments.length) {
@@ -733,7 +689,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
/**
- * The <code>AreaInfo</code> stores information about spaces.
+ * The <code>GlyphMapping</code> stores information about spaces.
* <p/>
* Add the spaces - except zero-width spaces - to the TextArea.
*/
@@ -743,16 +699,16 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// divide the area info's allocated IPD evenly among the
// non-zero-width space characters
int numZeroWidthSpaces = 0;
- for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
char spaceChar = foText.charAt(i);
if (CharUtilities.isZeroWidthSpace(spaceChar)) {
numZeroWidthSpaces++;
}
}
- int numSpaces = areaInfo.breakIndex - areaInfo.startIndex - numZeroWidthSpaces;
- int spaceIPD = areaInfo.areaIPD.getOpt() / ((numSpaces > 0) ? numSpaces : 1);
+ int numSpaces = mapping.endIndex - mapping.startIndex - numZeroWidthSpaces;
+ int spaceIPD = mapping.areaIPD.getOpt() / ((numSpaces > 0) ? numSpaces : 1);
// add space area children, one for each non-zero-width space character
- for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
char spaceChar = foText.charAt(i);
int level = foText.bidiLevelAt(i);
if (!CharUtilities.isZeroWidthSpace(spaceChar)) {
@@ -766,39 +722,20 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
- private void addAreaInfo(AreaInfo ai) {
- addAreaInfo(areaInfos.size(), ai);
+ private void addGlyphMapping(GlyphMapping mapping) {
+ addGlyphMapping(mappings.size(), mapping);
}
- private void addAreaInfo(int index, AreaInfo ai) {
- areaInfos.add(index, ai);
+ private void addGlyphMapping(int index, GlyphMapping mapping) {
+ mappings.add(index, mapping);
}
- private void removeAreaInfo(int index) {
- areaInfos.remove(index);
+ private void removeGlyphMapping(int index) {
+ mappings.remove(index);
}
- private AreaInfo getAreaInfo(int index) {
- return (AreaInfo) areaInfos.get(index);
- }
-
- private void addToLetterAdjust(int index, int width) {
- if (letterSpaceAdjustArray[index] == null) {
- letterSpaceAdjustArray[index] = MinOptMax.getInstance(width);
- } else {
- letterSpaceAdjustArray[index] = letterSpaceAdjustArray[index].plus(width);
- }
- }
-
- /**
- * Indicates whether a character is a space in terms of this layout manager.
- * @param ch the character
- * @return true if it's a space
- */
- private static boolean isSpace(final char ch) {
- return ch == CharUtilities.SPACE
- || CharUtilities.isNonBreakableSpace(ch)
- || CharUtilities.isFixedWidthSpace(ch);
+ private GlyphMapping getGlyphMapping(int index) {
+ return mappings.get(index);
}
/** {@inheritDoc} */
@@ -810,8 +747,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
final List returnList = new LinkedList();
KnuthSequence sequence = new InlineKnuthSequence();
- AreaInfo areaInfo = null;
- AreaInfo prevAreaInfo = null;
+ GlyphMapping mapping = null;
+ GlyphMapping prevMapping = null;
returnList.add(sequence);
if (LOG.isDebugEnabled()) {
@@ -857,24 +794,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
if (inWord) {
if (breakOpportunity
- || TextLayoutManager.isSpace(ch)
+ || GlyphMapping.isSpace(ch)
|| CharUtilities.isExplicitBreak(ch)
|| ((prevLevel != -1) && (level != prevLevel))) {
// this.foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN
- prevAreaInfo = processWord(alignment, sequence, prevAreaInfo, ch,
+ prevMapping = processWord(alignment, sequence, prevMapping, ch,
breakOpportunity, true, prevLevel);
}
} else if (inWhitespace) {
if (ch != CharUtilities.SPACE || breakOpportunity) {
- prevAreaInfo = processWhitespace(alignment, sequence,
+ prevMapping = processWhitespace(alignment, sequence,
breakOpportunity, prevLevel);
}
} else {
- if (areaInfo != null) {
- prevAreaInfo = areaInfo;
- processLeftoverAreaInfo(alignment, sequence, areaInfo,
+ if (mapping != null) {
+ prevMapping = mapping;
+ processLeftoverGlyphMapping(alignment, sequence, mapping,
ch == CharUtilities.SPACE || breakOpportunity);
- areaInfo = null;
+ mapping = null;
}
if (breakAction == LineBreakStatus.EXPLICIT_BREAK) {
sequence = processLinebreak(returnList, sequence);
@@ -888,15 +825,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
this.foText, this);
font.mapChar(ch);
// preserved space or non-breaking space:
- // create the AreaInfo object
- areaInfo = new AreaInfo(nextStart, nextStart + 1, 1, 0, wordSpaceIPD, false, true,
+ // create the GlyphMapping object
+ mapping = new GlyphMapping(nextStart, nextStart + 1, 1, 0, wordSpaceIPD, false, true,
breakOpportunity, spaceFont, level, null);
thisStart = nextStart + 1;
} else if (CharUtilities.isFixedWidthSpace(ch) || CharUtilities.isZeroWidthSpace(ch)) {
- // create the AreaInfo object
+ // create the GlyphMapping object
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,
+ mapping = new GlyphMapping(nextStart, nextStart + 1, 0, 0, ipd, false, true,
breakOpportunity, font, level, null);
thisStart = nextStart + 1;
} else if (CharUtilities.isExplicitBreak(ch)) {
@@ -904,7 +841,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
thisStart = nextStart + 1;
}
- inWord = !TextLayoutManager.isSpace(ch) && !CharUtilities.isExplicitBreak(ch);
+ inWord = !GlyphMapping.isSpace(ch) && !CharUtilities.isExplicitBreak(ch);
inWhitespace = ch == CharUtilities.SPACE
&& foText.getWhitespaceTreatment() != Constants.EN_PRESERVE;
prevLevel = level;
@@ -913,11 +850,11 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// Process any last elements
if (inWord) {
- processWord(alignment, sequence, prevAreaInfo, ch, false, false, prevLevel);
+ processWord(alignment, sequence, prevMapping, ch, false, false, prevLevel);
} else if (inWhitespace) {
processWhitespace(alignment, sequence, !keepTogether, prevLevel);
- } else if (areaInfo != null) {
- processLeftoverAreaInfo(alignment, sequence, areaInfo,
+ } else if (mapping != null) {
+ processLeftoverGlyphMapping(alignment, sequence, mapping,
ch == CharUtilities.ZERO_WIDTH_SPACE);
} else if (CharUtilities.isExplicitBreak(ch)) {
this.processLinebreak(returnList, sequence);
@@ -948,15 +885,14 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
return sequence;
}
- private void processLeftoverAreaInfo(int alignment,
- KnuthSequence sequence, AreaInfo areaInfo,
- boolean breakOpportunityAfter) {
- addAreaInfo(areaInfo);
- areaInfo.breakOppAfter = breakOpportunityAfter;
- addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1);
+ private void processLeftoverGlyphMapping(int alignment, KnuthSequence sequence,
+ GlyphMapping mapping, boolean breakOpportunityAfter) {
+ addGlyphMapping(mapping);
+ mapping.breakOppAfter = breakOpportunityAfter;
+ addElementsForASpace(sequence, alignment, mapping, mappings.size() - 1);
}
- private AreaInfo processWhitespace(final int alignment,
+ private GlyphMapping processWhitespace(final int alignment,
final KnuthSequence sequence, final boolean breakOpportunity, int level) {
if (LOG.isDebugEnabled()) {
@@ -964,209 +900,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
// End of whitespace
- // create the AreaInfo object
+ // create the GlyphMapping object
assert nextStart >= thisStart;
- AreaInfo areaInfo = new AreaInfo(
- thisStart, nextStart, nextStart - thisStart, 0,
+ GlyphMapping mapping = new GlyphMapping(
+ thisStart, nextStart, nextStart - thisStart, 0,
wordSpaceIPD.mult(nextStart - thisStart),
false, true, breakOpportunity, spaceFont, level, null);
- addAreaInfo(areaInfo);
+ addGlyphMapping(mapping);
// create the elements
- addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1);
+ addElementsForASpace(sequence, alignment, mapping, mappings.size() - 1);
thisStart = nextStart;
- return areaInfo;
- }
-
- private AreaInfo processWordMapping(
- int lastIndex, final Font font, AreaInfo prevAreaInfo, final char breakOpportunityChar,
- final boolean endsWithHyphen, int level) {
- int s = this.thisStart; // start index of word in FOText character buffer
- int e = lastIndex; // end index of word in FOText character buffer
- int nLS = 0; // # of letter spaces
- String script = foText.getScript();
- String language = foText.getLanguage();
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("PW: [" + thisStart + "," + lastIndex + "]: {"
- + " +M"
- + ", level = " + level
- + " }");
- }
-
- // 1. extract unmapped character sequence
- CharSequence ics = foText.subSequence(s, e);
-
- // 2. if script is not specified (by FO property) or it is specified as 'auto',
- // then compute dominant script
- if ((script == null) || "auto".equals(script)) {
- script = CharScript.scriptTagFromCode(CharScript.dominantScript(ics));
- }
- if ((language == null) || "none".equals(language)) {
- language = "dflt";
- }
-
- // 3. perform mapping of chars to glyphs ... to glyphs ... to chars
- CharSequence mcs = font.performSubstitution(ics, script, language);
-
- // 4. compute glyph position adjustments on (substituted) characters
- int[][] gpa;
- if (font.performsPositioning()) {
- // handle GPOS adjustments
- gpa = font.performPositioning(mcs, script, language);
- } else if (font.hasKerning()) {
- // handle standard (non-GPOS) kerning adjustments
- gpa = getKerningAdjustments(mcs, font);
- } else {
- gpa = null;
- }
-
- // 5. reorder combining marks so that they precede (within the mapped char sequence) the
- // base to which they are applied; N.B. position adjustments (gpa) are reordered in place
- mcs = font.reorderCombiningMarks(mcs, gpa, script, language);
-
- // 6. if mapped sequence differs from input sequence, then memoize mapped sequence
- if (!CharUtilities.isSameSequence(mcs, ics)) {
- foText.addMapping(s, e, mcs);
- }
-
- // 7. compute word ipd based on final position adjustments
- MinOptMax ipd = MinOptMax.ZERO;
- for (int i = 0, n = mcs.length(); i < n; i++) {
- int c = mcs.charAt(i);
- // TODO !BMP
- int w = font.getCharWidth(c);
- if (w < 0) {
- w = 0;
- }
- if (gpa != null) {
- w += gpa [ i ] [ GlyphPositioningTable.Value.IDX_X_ADVANCE ];
- }
- ipd = ipd.plus(w);
- }
-
- // [TBD] - handle letter spacing
-
- return new AreaInfo(
- s, e, 0, nLS, ipd, endsWithHyphen, false,
- breakOpportunityChar != 0, font, level, gpa);
- }
-
- /**
- * Given a mapped character sequence MCS, obtain glyph position adjustments
- * from the font's kerning data.
- * @param mcs mapped character sequence
- * @param font applicable font
- * @return glyph position adjustments (or null if no kerning)
- */
- private int[][] getKerningAdjustments(CharSequence mcs, final Font font) {
- int nc = mcs.length();
- // extract kerning array
- int[] ka = new int [ nc ]; // kerning array
- for (int i = 0, n = nc, cPrev = -1; i < n; i++) {
- int c = mcs.charAt(i);
- // TODO !BMP
- if (cPrev >= 0) {
- ka[i] = font.getKernValue(cPrev, c);
- }
- cPrev = c;
- }
- // was there a non-zero kerning?
- boolean hasKerning = false;
- for (int i = 0, n = nc; i < n; i++) {
- if (ka[i] != 0) {
- hasKerning = true;
- break;
- }
- }
- // if non-zero kerning, then create and return glyph position adjustment array
- if (hasKerning) {
- int[][] gpa = new int [ nc ] [ 4 ];
- for (int i = 0, n = nc; i < n; i++) {
- if (i > 0) {
- gpa [ i - 1 ] [ GlyphPositioningTable.Value.IDX_X_ADVANCE ] = ka [ i ];
- }
- }
- return gpa;
- } else {
- return null;
- }
+ return mapping;
}
- private AreaInfo processWordNoMapping(int lastIndex, final Font font, AreaInfo prevAreaInfo,
- final char breakOpportunityChar, final boolean endsWithHyphen, int level) {
- boolean kerning = font.hasKerning();
- MinOptMax wordIPD = MinOptMax.ZERO;
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("PW: [" + thisStart + "," + lastIndex + "]: {"
- + " -M"
- + ", level = " + level
- + " }");
- }
-
- for (int i = thisStart; i < lastIndex; i++) {
- char currentChar = foText.charAt(i);
-
- //character width
- int charWidth = font.getCharWidth(currentChar);
- wordIPD = wordIPD.plus(charWidth);
-
- //kerning
- if (kerning) {
- int kern = 0;
- if (i > thisStart) {
- char previousChar = foText.charAt(i - 1);
- kern = font.getKernValue(previousChar, currentChar);
- } else if (prevAreaInfo != null
- && !prevAreaInfo.isSpace && prevAreaInfo.breakIndex > 0) {
- char previousChar = foText.charAt(prevAreaInfo.breakIndex - 1);
- kern = font.getKernValue(previousChar, currentChar);
- }
- if (kern != 0) {
- addToLetterAdjust(i, kern);
- wordIPD = wordIPD.plus(kern);
- }
- }
- }
- if (kerning
- && (breakOpportunityChar != 0)
- && !TextLayoutManager.isSpace(breakOpportunityChar)
- && lastIndex > 0
- && endsWithHyphen) {
- int kern = font.getKernValue(foText.charAt(lastIndex - 1), breakOpportunityChar);
- if (kern != 0) {
- addToLetterAdjust(lastIndex, kern);
- //TODO: add kern to wordIPD?
- }
- }
- // shy+chars at start of word: wordLength == 0 && breakOpportunity
- // shy only characters in word: wordLength == 0 && !breakOpportunity
- int wordLength = lastIndex - thisStart;
- int letterSpaces = 0;
- if (wordLength != 0) {
- letterSpaces = wordLength - 1;
- // if there is a break opportunity and the next one (break character)
- // is not a space, it could be used as a line end;
- // add one more letter space, in case other text follows
- if ((breakOpportunityChar != 0) && !TextLayoutManager.isSpace(breakOpportunityChar)) {
- letterSpaces++;
- }
- }
- assert letterSpaces >= 0;
- wordIPD = wordIPD.plus(letterSpaceIPD.mult(letterSpaces));
-
- // create and return the AreaInfo object
- return new AreaInfo(thisStart, lastIndex, 0,
- letterSpaces, wordIPD,
- endsWithHyphen,
- false, breakOpportunityChar != 0, font, level, null);
- }
-
- private AreaInfo processWord(final int alignment, final KnuthSequence sequence,
- AreaInfo prevAreaInfo, final char ch, final boolean breakOpportunity,
+ private GlyphMapping processWord(final int alignment, final KnuthSequence sequence,
+ GlyphMapping prevMapping, final char ch, final boolean breakOpportunity,
final boolean checkEndsWithHyphen, int level) {
//Word boundary found, process widths and kerning
@@ -1178,23 +929,20 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
&& foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN;
Font font = FontSelector.selectFontForCharactersInText(
foText, thisStart, lastIndex, foText, this);
- AreaInfo areaInfo;
- if (font.performsSubstitution() || font.performsPositioning()) {
- areaInfo = processWordMapping(
- lastIndex, font, prevAreaInfo, breakOpportunity ? ch : 0, endsWithHyphen, level);
- } else {
- areaInfo = processWordNoMapping(
- lastIndex, font, prevAreaInfo, breakOpportunity ? ch : 0, endsWithHyphen, level);
- }
- prevAreaInfo = areaInfo;
- addAreaInfo(areaInfo);
+ char breakOpportunityChar = breakOpportunity ? ch : 0;
+ char precedingChar = prevMapping != null && !prevMapping.isSpace
+ && prevMapping.endIndex > 0 ? foText.charAt(prevMapping.endIndex - 1) : 0;
+ GlyphMapping mapping = GlyphMapping.doGlyphMapping(foText, thisStart, lastIndex, font,
+ letterSpaceIPD, letterSpaceAdjustArray, precedingChar, breakOpportunityChar, endsWithHyphen, level);
+ prevMapping = mapping;
+ addGlyphMapping(mapping);
tempStart = nextStart;
//add the elements
- addElementsForAWordFragment(sequence, alignment, areaInfo, areaInfos.size() - 1);
+ addElementsForAWordFragment(sequence, alignment, mapping, mappings.size() - 1);
thisStart = nextStart;
- return prevAreaInfo;
+ return prevMapping;
}
/** {@inheritDoc} */
@@ -1214,9 +962,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
int index = leafPos.getLeafPos();
//element could refer to '-1' position, for non-collapsed spaces (?)
if (index > -1) {
- AreaInfo areaInfo = getAreaInfo(index);
- areaInfo.letterSpaceCount++;
- areaInfo.addToAreaIPD(letterSpaceIPD);
+ GlyphMapping mapping = getGlyphMapping(index);
+ mapping.letterSpaceCount++;
+ mapping.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
@@ -1227,13 +975,13 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
} else if (letterSpaceIPD.isStiff()) {
// constant letter space: replace the box
// give it the unwrapped position of the replaced element
- oldListIterator.set(new KnuthInlineBox(areaInfo.areaIPD.getOpt(),
+ oldListIterator.set(new KnuthInlineBox(mapping.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(letterSpaceIPD.mult(areaInfo.letterSpaceCount),
+ oldListIterator.set(new KnuthGlue(letterSpaceIPD.mult(mapping.letterSpaceCount),
auxiliaryPosition, true));
}
}
@@ -1242,26 +990,26 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
/** {@inheritDoc} */
public void hyphenate(Position pos, HyphContext hyphContext) {
- AreaInfo areaInfo = getAreaInfo(((LeafPosition) pos).getLeafPos() + changeOffset);
- int startIndex = areaInfo.startIndex;
+ GlyphMapping mapping = getGlyphMapping(((LeafPosition) pos).getLeafPos() + changeOffset);
+ int startIndex = mapping.startIndex;
int stopIndex;
boolean nothingChanged = true;
- Font font = areaInfo.font;
+ Font font = mapping.font;
- while (startIndex < areaInfo.breakIndex) {
+ while (startIndex < mapping.endIndex) {
MinOptMax newIPD = MinOptMax.ZERO;
boolean hyphenFollows;
stopIndex = startIndex + hyphContext.getNextHyphPoint();
- if (hyphContext.hasMoreHyphPoints() && stopIndex <= areaInfo.breakIndex) {
+ if (hyphContext.hasMoreHyphPoints() && stopIndex <= mapping.endIndex) {
// 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 areaInfo.breakIndex
+ // or the next one is after mapping.breakIndex
hyphenFollows = false;
- stopIndex = areaInfo.breakIndex;
+ stopIndex = mapping.endIndex;
}
hyphContext.updateOffset(stopIndex - startIndex);
@@ -1286,18 +1034,18 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// add letter spaces
boolean isWordEnd
- = (stopIndex == areaInfo.breakIndex)
- && (areaInfo.letterSpaceCount < areaInfo.getWordLength());
+ = (stopIndex == mapping.endIndex)
+ && (mapping.letterSpaceCount < mapping.getWordLength());
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 (!(nothingChanged && stopIndex == mapping.endIndex && !hyphenFollows)) {
+ // the new GlyphMapping object is not equal to the old one
changeList.add(
new PendingChange(
- new AreaInfo(startIndex, stopIndex, 0,
+ new GlyphMapping(startIndex, stopIndex, 0,
letterSpaceCount, newIPD, hyphenFollows,
false, false, font, -1, null),
((LeafPosition) pos).getLeafPos() + changeOffset));
@@ -1324,7 +1072,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
return false;
}
- // Find the first and last positions in oldList that point to an AreaInfo
+ // Find the first and last positions in oldList that point to a GlyphMapping
// (i.e. getLeafPos() != -1)
LeafPosition startPos = null;
LeafPosition endPos = null;
@@ -1349,8 +1097,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
returnedIndices[0] = (startPos != null ? startPos.getLeafPos() : -1) + changeOffset;
returnedIndices[1] = (endPos != null ? endPos.getLeafPos() : -1) + changeOffset;
- int areaInfosAdded = 0;
- int areaInfosRemoved = 0;
+ int mappingsAdded = 0;
+ int mappingsRemoved = 0;
if (!changeList.isEmpty()) {
int oldIndex = -1;
@@ -1360,24 +1108,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
while (changeListIterator.hasNext()) {
currChange = (PendingChange) changeListIterator.next();
if (currChange.index == oldIndex) {
- areaInfosAdded++;
- changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved;
+ mappingsAdded++;
+ changeIndex = currChange.index + mappingsAdded - mappingsRemoved;
} else {
- areaInfosRemoved++;
- areaInfosAdded++;
+ mappingsRemoved++;
+ mappingsAdded++;
oldIndex = currChange.index;
- changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved;
- removeAreaInfo(changeIndex);
+ changeIndex = currChange.index + mappingsAdded - mappingsRemoved;
+ removeGlyphMapping(changeIndex);
}
- addAreaInfo(changeIndex, currChange.areaInfo);
+ addGlyphMapping(changeIndex, currChange.mapping);
}
changeList.clear();
}
// increase the end index for getChangedKnuthElements()
- returnedIndices[1] += (areaInfosAdded - areaInfosRemoved);
+ returnedIndices[1] += (mappingsAdded - mappingsRemoved);
// increase offset to use for subsequent paragraphs
- changeOffset += (areaInfosAdded - areaInfosRemoved);
+ changeOffset += (mappingsAdded - mappingsRemoved);
return hasChanged;
}
@@ -1391,16 +1139,16 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
final LinkedList returnList = new LinkedList();
for (; returnedIndices[0] <= returnedIndices[1]; returnedIndices[0]++) {
- AreaInfo areaInfo = getAreaInfo(returnedIndices[0]);
- if (areaInfo.wordSpaceCount == 0) {
- // areaInfo refers either to a word or a word fragment
- addElementsForAWordFragment(returnList, alignment, areaInfo, returnedIndices[0]);
+ GlyphMapping mapping = getGlyphMapping(returnedIndices[0]);
+ if (mapping.wordSpaceCount == 0) {
+ // mapping refers either to a word or a word fragment
+ addElementsForAWordFragment(returnList, alignment, mapping, returnedIndices[0]);
} else {
- // areaInfo refers to a space
- addElementsForASpace(returnList, alignment, areaInfo, returnedIndices[0]);
+ // mapping refers to a space
+ addElementsForASpace(returnList, alignment, mapping, returnedIndices[0]);
}
}
- setFinished(returnedIndices[0] == areaInfos.size() - 1);
+ setFinished(returnedIndices[0] == mappings.size() - 1);
//ElementListObserver.observe(returnList, "text-changed", null);
return returnList;
}
@@ -1409,9 +1157,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
public String getWordChars(Position pos) {
int leafValue = ((LeafPosition) pos).getLeafPos() + changeOffset;
if (leafValue != -1) {
- AreaInfo areaInfo = getAreaInfo(leafValue);
- StringBuffer buffer = new StringBuffer(areaInfo.getWordLength());
- for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ GlyphMapping mapping = getGlyphMapping(leafValue);
+ StringBuffer buffer = new StringBuffer(mapping.getWordLength());
+ for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
buffer.append(foText.charAt(i));
}
return buffer.toString();
@@ -1420,41 +1168,39 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
}
- private void addElementsForASpace(List baseList, int alignment, AreaInfo areaInfo,
+ private void addElementsForASpace(List baseList, int alignment, GlyphMapping mapping,
int leafValue) {
LeafPosition mainPosition = new LeafPosition(this, leafValue);
- if (!areaInfo.breakOppAfter) {
+ if (!mapping.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(makeAuxiliaryZeroWidthBox());
baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(areaInfo.areaIPD, mainPosition, false));
+ baseList.add(new KnuthGlue(mapping.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(areaInfo.areaIPD.getOpt(), null, mainPosition,
+ baseList.add(new KnuthInlineBox(mapping.areaIPD.getOpt(), null, mainPosition,
true));
}
} else {
- if (foText.charAt(areaInfo.startIndex) != CharUtilities.SPACE
+ if (foText.charAt(mapping.startIndex) != CharUtilities.SPACE
|| foText.getWhitespaceTreatment() == Constants.EN_PRESERVE) {
// a breaking space that needs to be preserved
- baseList
- .addAll(getElementsForBreakingSpace(alignment, areaInfo, auxiliaryPosition, 0,
- mainPosition, areaInfo.areaIPD.getOpt(), true));
+ baseList.addAll(getElementsForBreakingSpace(alignment, mapping, auxiliaryPosition, 0,
+ mainPosition, mapping.areaIPD.getOpt(), true));
} else {
// a (possible block) of breaking spaces
- baseList
- .addAll(getElementsForBreakingSpace(alignment, areaInfo, mainPosition,
- areaInfo.areaIPD.getOpt(), auxiliaryPosition, 0, false));
+ baseList.addAll(getElementsForBreakingSpace(alignment, mapping, mainPosition,
+ mapping.areaIPD.getOpt(), auxiliaryPosition, 0, false));
}
}
}
- private List getElementsForBreakingSpace(int alignment, AreaInfo areaInfo, Position pos2,
+ private List getElementsForBreakingSpace(int alignment, GlyphMapping mapping, Position pos2,
int p2WidthOffset, Position pos3,
int p3WidthOffset, boolean skipZeroCheck) {
List elements = new ArrayList();
@@ -1504,7 +1250,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
elements.add(g);
elements.add(makeZeroWidthPenalty(0));
g = new KnuthGlue(
- areaInfo.areaIPD.getOpt(),
+ mapping.areaIPD.getOpt(),
-3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos2, false);
elements.add(g);
}
@@ -1513,25 +1259,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
case EN_JUSTIFY:
// justified text:
// the stretch and shrink depends on the space width
- elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3,
- p3WidthOffset, skipZeroCheck, areaInfo.areaIPD.getShrink()));
+ elements.addAll(getElementsForJustifiedText(mapping, pos2, p2WidthOffset, pos3,
+ p3WidthOffset, skipZeroCheck, mapping.areaIPD.getShrink()));
break;
default:
// last line justified, the other lines unjustified:
// use only the space stretch
- elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3,
+ elements.addAll(getElementsForJustifiedText(mapping, pos2, p2WidthOffset, pos3,
p3WidthOffset, skipZeroCheck, 0));
}
return elements;
}
- private List getElementsForJustifiedText(
- AreaInfo areaInfo, Position pos2, int p2WidthOffset,
- Position pos3, int p3WidthOffset, boolean skipZeroCheck,
- int shrinkability) {
+ private List getElementsForJustifiedText(GlyphMapping mapping, Position pos2, int p2WidthOffset,
+ Position pos3, int p3WidthOffset, boolean skipZeroCheck,
+ int shrinkability) {
- int stretchability = areaInfo.areaIPD.getStretch();
+ int stretchability = mapping.areaIPD.getStretch();
List elements = new ArrayList();
if (skipZeroCheck || lineStartBAP != 0 || lineEndBAP != 0) {
@@ -1543,34 +1288,34 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
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,
+ elements.add(new KnuthGlue(mapping.areaIPD.getOpt(), stretchability, shrinkability,
pos2, false));
}
return elements;
}
- private void addElementsForAWordFragment(List baseList, int alignment, AreaInfo areaInfo,
+ private void addElementsForAWordFragment(List baseList, int alignment, GlyphMapping mapping,
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;
- boolean suppressibleLetterSpace = areaInfo.breakOppAfter && !areaInfo.isHyphenated;
+ boolean suppressibleLetterSpace = mapping.breakOppAfter && !mapping.isHyphenated;
if (letterSpaceIPD.isStiff()) {
// constant letter spacing
baseList.add(new KnuthInlineBox(suppressibleLetterSpace
- ? areaInfo.areaIPD.getOpt() - letterSpaceIPD.getOpt()
- : areaInfo.areaIPD.getOpt(),
+ ? mapping.areaIPD.getOpt() - letterSpaceIPD.getOpt()
+ : mapping.areaIPD.getOpt(),
alignmentContext, notifyPos(mainPosition), false));
} else {
// adjustable letter spacing
int unsuppressibleLetterSpaces = suppressibleLetterSpace
- ? areaInfo.letterSpaceCount - 1
- : areaInfo.letterSpaceCount;
- baseList.add(new KnuthInlineBox(areaInfo.areaIPD.getOpt()
- - areaInfo.letterSpaceCount * letterSpaceIPD.getOpt(),
+ ? mapping.letterSpaceCount - 1
+ : mapping.letterSpaceCount;
+ baseList.add(new KnuthInlineBox(mapping.areaIPD.getOpt()
+ - mapping.letterSpaceCount * letterSpaceIPD.getOpt(),
alignmentContext, notifyPos(mainPosition), false));
baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
baseList.add(new KnuthGlue(letterSpaceIPD.mult(unsuppressibleLetterSpaces),
@@ -1580,19 +1325,19 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// 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 (areaInfo.isHyphenated) {
+ if (mapping.isHyphenated) {
MinOptMax widthIfNoBreakOccurs = null;
- if (areaInfo.breakIndex < foText.length()) {
+ if (mapping.endIndex < foText.length()) {
//Add in kerning in no-break condition
- widthIfNoBreakOccurs = letterSpaceAdjustArray[areaInfo.breakIndex];
+ widthIfNoBreakOccurs = letterSpaceAdjustArray[mapping.endIndex];
}
- //if (areaInfo.breakIndex)
+ //if (mapping.breakIndex)
// the word fragment ends at the end of a syllable:
// if a break occurs the content width increases,
// otherwise nothing happens
addElementsForAHyphen(baseList, alignment, hyphIPD, widthIfNoBreakOccurs,
- areaInfo.breakOppAfter && areaInfo.isHyphenated);
+ mapping.breakOppAfter && mapping.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,