Browse Source

Correction of indentation


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@653564 13f79535-47bb-0310-9956-ffa450edef68
pull/37/head
Andreas L. Delmelle 16 years ago
parent
commit
e6c23e961d
1 changed files with 54 additions and 60 deletions
  1. 54
    60
      src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java

+ 54
- 60
src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java View File



/** Used to reduce instantiation of MinOptMax with zero length. Do not modify! */ /** Used to reduce instantiation of MinOptMax with zero length. Do not modify! */
private static final MinOptMax ZERO_MINOPTMAX = new MinOptMax(0); private static final MinOptMax ZERO_MINOPTMAX = new MinOptMax(0);
private FOText foText; private FOText foText;
private char[] textArray; private char[] textArray;
/** /**
/** 1/2 of word-spacing value */ /** 1/2 of word-spacing value */
private SpaceVal halfWS; private SpaceVal halfWS;
/** 1/2 of letter-spacing value */ /** 1/2 of letter-spacing value */
private SpaceVal halfLS;
private SpaceVal halfLS;


private boolean hasChanged = false; private boolean hasChanged = false;
private int returnedIndex = 0; private int returnedIndex = 0;


private int lineStartBAP = 0; private int lineStartBAP = 0;
private int lineEndBAP = 0; private int lineEndBAP = 0;
private boolean keepTogether; private boolean keepTogether;


private final Position auxiliaryPosition;
private final Position auxiliaryPosition = new LeafPosition(this, -1);


/** /**
* Create a Text layout manager. * Create a Text layout manager.
public TextLayoutManager(FOText node) { public TextLayoutManager(FOText node) {
super(); super();
foText = node; foText = node;
textArray = new char[node.endIndex - node.startIndex]; textArray = new char[node.endIndex - node.startIndex];
System.arraycopy(node.ca, node.startIndex, textArray, 0, System.arraycopy(node.ca, node.startIndex, textArray, 0,
node.endIndex - node.startIndex); node.endIndex - node.startIndex);
letterAdjustArray = new MinOptMax[textArray.length + 1]; letterAdjustArray = new MinOptMax[textArray.length + 1];


vecAreaInfo = new java.util.ArrayList(); vecAreaInfo = new java.util.ArrayList();

auxiliaryPosition = new LeafPosition(this, -1);
} }


private KnuthPenalty makeZeroWidthPenalty(int penaltyValue) { private KnuthPenalty makeZeroWidthPenalty(int penaltyValue) {
FontInfo fi = foText.getFOEventHandler().getFontInfo(); FontInfo fi = foText.getFOEventHandler().getFontInfo();
FontTriplet[] fontkeys = foText.getCommonFont().getFontState(fi); FontTriplet[] fontkeys = foText.getCommonFont().getFontState(fi);
font = fi.getFontInstance(fontkeys[0], foText.getCommonFont().fontSize.getValue(this)); font = fi.getFontInstance(fontkeys[0], foText.getCommonFont().fontSize.getValue(this));
// With CID fonts, space isn't neccesary currentFontState.width(32) // With CID fonts, space isn't neccesary currentFontState.width(32)
spaceCharIPD = font.getCharWidth(' '); spaceCharIPD = font.getCharWidth(' ');
// Use hyphenationChar property // Use hyphenationChar property
hyphIPD = foText.getCommonHyphenation().getHyphIPD(font); hyphIPD = foText.getCommonHyphenation().getHyphIPD(font);
SpaceVal ls = SpaceVal.makeLetterSpacing(foText.getLetterSpacing()); SpaceVal ls = SpaceVal.makeLetterSpacing(foText.getLetterSpacing());
halfLS = new SpaceVal(MinOptMax.multiply(ls.getSpace(), 0.5), halfLS = new SpaceVal(MinOptMax.multiply(ls.getSpace(), 0.5),
ls.isConditional(), ls.isForcing(), ls.getPrecedence()); ls.isConditional(), ls.isForcing(), ls.getPrecedence());
ws = SpaceVal.makeWordSpacing(foText.getWordSpacing(), ls, font); ws = SpaceVal.makeWordSpacing(foText.getWordSpacing(), ls, font);
// Make half-space: <space> on either side of a word-space) // Make half-space: <space> on either side of a word-space)
halfWS = new SpaceVal(MinOptMax.multiply(ws.getSpace(), 0.5), halfWS = new SpaceVal(MinOptMax.multiply(ws.getSpace(), 0.5),
// in the SpaceVal.makeWordSpacing() method // in the SpaceVal.makeWordSpacing() method
letterSpaceIPD = ls.getSpace(); letterSpaceIPD = ls.getSpace();
wordSpaceIPD = MinOptMax.add(new MinOptMax(spaceCharIPD), ws.getSpace()); wordSpaceIPD = MinOptMax.add(new MinOptMax(spaceCharIPD), ws.getSpace());
keepTogether = foText.getKeepTogether().getWithinLine().getEnum() == Constants.EN_ALWAYS; keepTogether = foText.getKeepTogether().getWithinLine().getEnum() == Constants.EN_ALWAYS;


} }
realWidth.add(MinOptMax.multiply(letterSpaceIPD, -1)); realWidth.add(MinOptMax.multiply(letterSpaceIPD, -1));
letterSpaceCount--; letterSpaceCount--;
} }
for (int i = ai.startIndex; i < ai.breakIndex; i++) { for (int i = ai.startIndex; i < ai.breakIndex; i++) {
MinOptMax ladj = letterAdjustArray[i + 1];
MinOptMax ladj = letterAdjustArray[i + 1];
if (ladj != null && ladj.isElastic()) { if (ladj != null && ladj.isElastic()) {
letterSpaceCount++; letterSpaceCount++;
} }
difference = (int) ((double) (realWidth.opt - realWidth.min) difference = (int) ((double) (realWidth.opt - realWidth.min)
* ipdAdjust); * ipdAdjust);
} }
// set letter space adjustment // set letter space adjustment
if (ipdAdjust > 0.0) { if (ipdAdjust > 0.0) {
letterSpaceDim letterSpaceDim
totalAdjust += (letterSpaceDim - letterSpaceIPD.opt) * letterSpaceCount; totalAdjust += (letterSpaceDim - letterSpaceIPD.opt) * letterSpaceCount;


// set word space adjustment // set word space adjustment
//
//
if (wordSpaceCount > 0) { if (wordSpaceCount > 0) {
wordSpaceDim += (difference - totalAdjust) / wordSpaceCount; wordSpaceDim += (difference - totalAdjust) / wordSpaceCount;
} else { } else {
// the last character of a word and to space characters: in order // the last character of a word and to space characters: in order
// to avoid this, we must subtract the letter space width twice; // to avoid this, we must subtract the letter space width twice;
// the renderer will compute the space width as: // the renderer will compute the space width as:
// space width =
// space width =
// = "normal" space width + letterSpaceAdjust + wordSpaceAdjust // = "normal" space width + letterSpaceAdjust + wordSpaceAdjust
// = spaceCharIPD + letterSpaceAdjust + // = spaceCharIPD + letterSpaceAdjust +
// + (wordSpaceDim - spaceCharIPD - 2 * letterSpaceAdjust) // + (wordSpaceDim - spaceCharIPD - 2 * letterSpaceAdjust)
* @param context the layout context * @param context the layout context
* @param spaceDiff unused * @param spaceDiff unused
* @param firstIndex the index of the first AreaInfo used for the TextArea * @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 lastIndex the index of the last AreaInfo used for the TextArea
* @param isLastArea is this TextArea the last in a line? * @param isLastArea is this TextArea the last in a line?
* @return the new text area * @return the new text area
*/ */
// here ends a new word // here ends a new word
// add a word to the TextArea // add a word to the TextArea
if (isLastArea if (isLastArea
&& i == lastIndex
&& i == lastIndex
&& areaInfo.isHyphenated) { && areaInfo.isHyphenated) {
len++; len++;
} }
} }
// String wordChars = new String(textArray, wordStartIndex, len); // String wordChars = new String(textArray, wordStartIndex, len);
if (isLastArea if (isLastArea
&& i == lastIndex
&& i == lastIndex
&& areaInfo.isHyphenated) { && areaInfo.isHyphenated) {
// add the hyphenation character // add the hyphenation character
wordChars.append(foText.getCommonHyphenation().getHyphChar(font)); wordChars.append(foText.getCommonHyphenation().getHyphChar(font));
} }
TraitSetter.addFontTraits(textArea, font); TraitSetter.addFontTraits(textArea, font);
textArea.addTrait(Trait.COLOR, foText.getColor()); textArea.addTrait(Trait.COLOR, foText.getColor());
TraitSetter.addTextDecoration(textArea, foText.getTextDecoration()); TraitSetter.addTextDecoration(textArea, foText.getTextDecoration());
return textArea; return textArea;
} }
private void addToLetterAdjust(int index, int width) { private void addToLetterAdjust(int index, int width) {
if (letterAdjustArray[index] == null) { if (letterAdjustArray[index] == null) {
letterAdjustArray[index] = new MinOptMax(width); letterAdjustArray[index] = new MinOptMax(width);
|| CharUtilities.isNonBreakableSpace(ch) || CharUtilities.isNonBreakableSpace(ch)
|| CharUtilities.isFixedWidthSpace(ch); || CharUtilities.isFixedWidthSpace(ch);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
lineStartBAP = context.getLineStartBorderAndPaddingWidth(); lineStartBAP = context.getLineStartBorderAndPaddingWidth();
} else if (prevAi != null && !prevAi.isSpace && prevAi.breakIndex > 0) { } else if (prevAi != null && !prevAi.isSpace && prevAi.breakIndex > 0) {
char previous = textArray[prevAi.breakIndex - 1]; char previous = textArray[prevAi.breakIndex - 1];
kern = font.getKernValue(previous, c) * font.getFontSize() / 1000; kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
}
}
if (kern != 0) { if (kern != 0) {
//log.info("Kerning between " + previous + " and " + c + ": " + kern); //log.info("Kerning between " + previous + " and " + c + ": " + kern);
addToLetterAdjust(i, kern); addToLetterAdjust(i, kern);
wordIPD.add(kern); wordIPD.add(kern);
}
}
} }
} }
if (kerning && breakOpportunity && !isSpace(ch) && lastIndex > 0 && textArray[lastIndex] == CharUtilities.SOFT_HYPHEN) { if (kerning && breakOpportunity && !isSpace(ch) && lastIndex > 0 && textArray[lastIndex] == CharUtilities.SOFT_HYPHEN) {
ai = new AreaInfo(thisStart, nextStart, ai = new AreaInfo(thisStart, nextStart,
(short) (nextStart - thisStart), (short) 0, (short) (nextStart - thisStart), (short) 0,
MinOptMax.multiply(wordSpaceIPD, nextStart - thisStart), MinOptMax.multiply(wordSpaceIPD, nextStart - thisStart),
false, true, breakOpportunity);
false, true, breakOpportunity);
vecAreaInfo.add(ai); vecAreaInfo.add(ai);
prevAi = ai; prevAi = ai;


returnList.add(sequence); returnList.add(sequence);
} }
} }
if ((ch == CharUtilities.SPACE
&& foText.getWhitespaceTreatment() == Constants.EN_PRESERVE)
if ((ch == CharUtilities.SPACE
&& foText.getWhitespaceTreatment() == Constants.EN_PRESERVE)
|| ch == CharUtilities.NBSPACE) { || ch == CharUtilities.NBSPACE) {
// preserved space or non-breaking space: // preserved space or non-breaking space:
// create the AreaInfo object // create the AreaInfo object
MinOptMax ipd = new MinOptMax(font.getCharWidth(ch)); MinOptMax ipd = new MinOptMax(font.getCharWidth(ch));
ai = new AreaInfo(nextStart, (short) (nextStart + 1), ai = new AreaInfo(nextStart, (short) (nextStart + 1),
(short) 0, (short) 0, (short) 0, (short) 0,
ipd, false, true, breakOpportunity);
ipd, false, true, breakOpportunity);
thisStart = (short) (nextStart + 1); thisStart = (short) (nextStart + 1);
} else if (ch == NEWLINE) { } else if (ch == NEWLINE) {
// linefeed; this can happen when linefeed-treatment="preserve" // linefeed; this can happen when linefeed-treatment="preserve"
inWhitespace = ch == CharUtilities.SPACE && foText.getWhitespaceTreatment() != Constants.EN_PRESERVE; inWhitespace = ch == CharUtilities.SPACE && foText.getWhitespaceTreatment() != Constants.EN_PRESERVE;
nextStart++; nextStart++;
} // end of while } // end of while
// Process any last elements // Process any last elements
if (inWord) { if (inWord) {
int lastIndex = nextStart; int lastIndex = nextStart;
} else if (prevAi != null && !prevAi.isSpace) { } else if (prevAi != null && !prevAi.isSpace) {
char previous = textArray[prevAi.breakIndex - 1]; char previous = textArray[prevAi.breakIndex - 1];
kern = font.getKernValue(previous, c) * font.getFontSize() / 1000; kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
}
}
if (kern != 0) { if (kern != 0) {
//log.info("Kerning between " + previous + " and " + c + ": " + kern); //log.info("Kerning between " + previous + " and " + c + ": " + kern);
addToLetterAdjust(i, kern); addToLetterAdjust(i, kern);
wordIPD.add(kern); wordIPD.add(kern);
}
}
} }
} }
int iLetterSpaces = wordLength - 1; int iLetterSpaces = wordLength - 1;
ai = new AreaInfo(thisStart, (short) (nextStart), ai = new AreaInfo(thisStart, (short) (nextStart),
(short) (nextStart - thisStart), (short) 0, (short) (nextStart - thisStart), (short) 0,
MinOptMax.multiply(wordSpaceIPD, nextStart - thisStart), MinOptMax.multiply(wordSpaceIPD, nextStart - thisStart),
false, true, true);
false, true, true);
vecAreaInfo.add(ai); vecAreaInfo.add(ai);


// create the elements // create the elements
} }
startIndex = stopIndex; startIndex = stopIndex;
} }
if (!hasChanged && !nothingChanged) {
hasChanged = true;
}
hasChanged = !nothingChanged;
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
public boolean applyChanges(List oldList) { public boolean applyChanges(List oldList) {
setFinished(false); setFinished(false);


if (changeList != null) {
if (changeList != null && !changeList.isEmpty()) {
int areaInfosAdded = 0; int areaInfosAdded = 0;
int areaInfosRemoved = 0; int areaInfosRemoved = 0;
int oldIndex = -1;
PendingChange currChange = null;
int oldIndex = -1, changeIndex;
PendingChange currChange;
ListIterator changeListIterator = changeList.listIterator(); ListIterator changeListIterator = changeList.listIterator();
while (changeListIterator.hasNext()) { while (changeListIterator.hasNext()) {
currChange = (PendingChange) changeListIterator.next(); currChange = (PendingChange) changeListIterator.next();
areaInfosRemoved++; areaInfosRemoved++;
areaInfosAdded++; areaInfosAdded++;
oldIndex = currChange.index; oldIndex = currChange.index;
vecAreaInfo.remove(currChange.index + areaInfosAdded - areaInfosRemoved);
vecAreaInfo.add(currChange.index + areaInfosAdded - areaInfosRemoved,
currChange.ai);
changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved;
vecAreaInfo.remove(changeIndex);
} else { } else {
areaInfosAdded++; areaInfosAdded++;
vecAreaInfo.add(currChange.index + areaInfosAdded - areaInfosRemoved,
currChange.ai);
changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved;
} }
vecAreaInfo.add(changeIndex, currChange.ai);
} }
changeList.clear(); changeList.clear();
} }
int leafValue = ((LeafPosition) pos).getLeafPos(); int leafValue = ((LeafPosition) pos).getLeafPos();
if (leafValue != -1) { if (leafValue != -1) {
AreaInfo ai = (AreaInfo) vecAreaInfo.get(leafValue); AreaInfo ai = (AreaInfo) vecAreaInfo.get(leafValue);
sbChars.append(new String(textArray, ai.startIndex,
ai.breakIndex - ai.startIndex));
sbChars.append(textArray, ai.startIndex, ai.breakIndex - ai.startIndex);
} }
} }


switch (alignment) { switch (alignment) {
case EN_CENTER: case EN_CENTER:
// centered text: // centered text:
// if the second element is chosen as a line break these elements
// 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 // 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 // beginning of the next one, otherwise they don't add any stretch
baseList.add(new KnuthGlue(lineEndBAP, baseList.add(new KnuthGlue(lineEndBAP,
case EN_START: // fall through case EN_START: // fall through
case EN_END: case EN_END:
// left- or right-aligned text: // left- or right-aligned text:
// if the second element is chosen as a line break these elements
// 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 // add a constant amount of stretch at the end of a line, otherwise
// they don't add any stretch // they don't add any stretch
baseList.add(new KnuthGlue(lineEndBAP, baseList.add(new KnuthGlue(lineEndBAP,
baseList.add(makeZeroWidthPenalty(KnuthPenalty.INFINITE)); baseList.add(makeZeroWidthPenalty(KnuthPenalty.INFINITE));
baseList.add(new KnuthGlue(lineStartBAP + ai.areaIPD.opt, 0, 0, baseList.add(new KnuthGlue(lineStartBAP + ai.areaIPD.opt, 0, 0,
mainPosition, false)); mainPosition, false));
}
}
} else { } else {
// a (possible block) of breaking spaces // a (possible block) of breaking spaces
switch (alignment) { switch (alignment) {
case EN_CENTER: case EN_CENTER:
// centered text: // centered text:
// if the second element is chosen as a line break these elements
// 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 // 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 // beginning of the next one, otherwise they don't add any stretch
baseList.add(new KnuthGlue(lineEndBAP, baseList.add(new KnuthGlue(lineEndBAP,
case EN_START: // fall through case EN_START: // fall through
case EN_END: case EN_END:
// left- or right-aligned text: // left- or right-aligned text:
// if the second element is chosen as a line break these elements
// 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 // add a constant amount of stretch at the end of a line, otherwise
// they don't add any stretch // they don't add any stretch
if (lineStartBAP != 0 || lineEndBAP != 0) { if (lineStartBAP != 0 || lineEndBAP != 0) {
} }
} }
} }
}
}
} }


private void addElementsForAWordFragment(List baseList, private void addElementsForAWordFragment(List baseList,
notifyPos(mainPosition), false)); notifyPos(mainPosition), false));
} else { } else {
// adjustable letter spacing // adjustable letter spacing
int unsuppressibleLetterSpaces
int unsuppressibleLetterSpaces
= suppressibleLetterSpace ? ai.letterSpaceCount - 1 : ai.letterSpaceCount; = suppressibleLetterSpace ? ai.letterSpaceCount - 1 : ai.letterSpaceCount;
baseList.add baseList.add
(new KnuthInlineBox(ai.areaIPD.opt (new KnuthInlineBox(ai.areaIPD.opt
auxiliaryPosition, true)); auxiliaryPosition, true));
baseList.add(makeAuxiliaryZeroWidthBox()); baseList.add(makeAuxiliaryZeroWidthBox());
} }
// extra-elements if the word fragment is the end of a syllable, // 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 // or it ends with a character that can be used as a line break
if (ai.isHyphenated) { if (ai.isHyphenated) {
widthIfNoBreakOccurs = letterAdjustArray[ai.breakIndex]; widthIfNoBreakOccurs = letterAdjustArray[ai.breakIndex];
} }
//if (ai.breakIndex) //if (ai.breakIndex)
// the word fragment ends at the end of a syllable: // the word fragment ends at the end of a syllable:
// if a break occurs the content width increases, // if a break occurs the content width increases,
// otherwise nothing happens // otherwise nothing happens
baseList.add(new KnuthGlue(lineStartBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, baseList.add(new KnuthGlue(lineStartBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
auxiliaryPosition, true)); auxiliaryPosition, true));
break; break;
case EN_START : // fall through case EN_START : // fall through
case EN_END : case EN_END :
// left- or right-aligned text: // left- or right-aligned text:
auxiliaryPosition, false)); auxiliaryPosition, false));
} }
break; break;
default: default:
// justified text, or last line justified: // justified text, or last line justified:
// just a flagged penalty // just a flagged penalty
} }
} }
} }
}
}

} }

Loading…
Cancel
Save