diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java | 32 | ||||
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java | 78 |
2 files changed, 70 insertions, 40 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index fbe487cc5..e41a8f272 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -771,7 +771,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager // we only need an entry in lineLayoutsList. llPoss = new LineLayoutPossibilities(); } else { - llPoss = findOptimalBreakingPoints(alignment, (Paragraph) seq); + llPoss = findOptimalBreakingPoints(alignment, (Paragraph) seq, !paragraphsIterator.hasNext()); } lineLayoutsList[i] = llPoss; } @@ -783,12 +783,13 @@ public class LineLayoutManager extends InlineStackingLayoutManager } /** - * Fint the optimal linebreaks for a paragraph + * Find the optimal linebreaks for a paragraph * @param alignment alignment of the paragraph * @param currPar the Paragraph for which the linebreaks are found + * @param isLastPar flag indicating whether currPar is the last paragraph * @return the line layout possibilities for the paragraph */ - private LineLayoutPossibilities findOptimalBreakingPoints(int alignment, Paragraph currPar) { + private LineLayoutPossibilities findOptimalBreakingPoints(int alignment, Paragraph currPar, boolean isLastPar) { // use the member lineLayouts, which is read by LineBreakingAlgorithm.updateData1 and 2 lineLayouts = new LineLayoutPossibilities(); double maxAdjustment = 1; @@ -808,7 +809,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager if (canHyphenate && !hyphenationPerformed) { // make sure findHyphenationPoints() is bypassed if // the method is called twice (e.g. due to changing page-ipd) - hyphenationPerformed = true; + hyphenationPerformed = isLastPar; findHyphenationPoints(currPar); } @@ -1423,8 +1424,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager */ private void addInlineArea(LayoutContext context, LineBreakPosition lbp, boolean isLastPosition) { - // the TLM which created the last KnuthElement in this line - LayoutManager lastLM = null; KnuthSequence seq = (KnuthSequence) knuthParagraphs.get(lbp.parIndex); int startElementIndex = lbp.startIndex; @@ -1456,15 +1455,16 @@ public class LineLayoutManager extends InlineStackingLayoutManager } } - // Remove trailing spaces if allowed so - if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED - || whiteSpaceTreament == EN_IGNORE - || whiteSpaceTreament == EN_IGNORE_IF_BEFORE_LINEFEED) { - // ignore the last element in the line if it is a KnuthGlue object - ListIterator seqIterator = seq.listIterator(endElementIndex); - KnuthElement lastElement = (KnuthElement) seqIterator.next(); - lastLM = lastElement.getLayoutManager(); - if (lastElement.isGlue()) { + // ignore the last element in the line if it is a KnuthGlue object + ListIterator seqIterator = seq.listIterator(endElementIndex); + KnuthElement lastElement = (KnuthElement) seqIterator.next(); + // the TLM which created the last KnuthElement in this line + LayoutManager lastLM = lastElement.getLayoutManager(); + if (lastElement.isGlue()) { + // Remove trailing spaces if allowed so + if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED + || whiteSpaceTreament == EN_IGNORE + || whiteSpaceTreament == EN_IGNORE_IF_BEFORE_LINEFEED) { endElementIndex--; // this returns the same KnuthElement seqIterator.previous(); @@ -1480,7 +1480,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager || whiteSpaceTreament == EN_IGNORE_IF_AFTER_LINEFEED) { // ignore KnuthGlue and KnuthPenalty objects // at the beginning of the line - ListIterator seqIterator = seq.listIterator(startElementIndex); + seqIterator = seq.listIterator(startElementIndex); while (seqIterator.hasNext() && !((KnuthElement) seqIterator.next()).isBox()) { startElementIndex++; } diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java index cbe2e2639..05cf979de 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java @@ -165,7 +165,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager { private int hyphIPD; private boolean hasChanged = false; - private int returnedIndex = 0; + private int[] returnedIndices = {0, 0}; + private int changeOffset = 0; private int thisStart = 0; private int tempStart = 0; private List changeList = new LinkedList(); @@ -811,19 +812,19 @@ public class TextLayoutManager extends LeafNodeLayoutManager { //TODO: add kern to wordIPD? } } - int iLetterSpaces = wordLength - 1; + int letterSpaces = wordLength - 1; // if there is a break opportunity and the next one // is not a space, it could be used as a line end; // add one more letter space, in case other text follows if (breakOpportunity && !TextLayoutManager.isSpace(ch)) { - iLetterSpaces++; + letterSpaces++; } - assert iLetterSpaces >= 0; - wordIPD = wordIPD.plus(letterSpaceIPD.mult(iLetterSpaces)); + assert letterSpaces >= 0; + wordIPD = wordIPD.plus(letterSpaceIPD.mult(letterSpaces)); // create the AreaInfo object AreaInfo areaInfo = new AreaInfo(thisStart, lastIndex, 0, - iLetterSpaces, wordIPD, + letterSpaces, wordIPD, endsWithHyphen, false, breakOpportunity, font); prevAreaInfo = areaInfo; @@ -903,11 +904,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void hyphenate(Position pos, HyphContext hyphContext) { - AreaInfo areaInfo = getAreaInfo(((LeafPosition) pos).getLeafPos()); + AreaInfo areaInfo = getAreaInfo(((LeafPosition) pos).getLeafPos() + changeOffset); int startIndex = areaInfo.startIndex; int stopIndex; boolean nothingChanged = true; @@ -962,7 +961,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // the new AreaInfo object is not equal to the old one changeList.add(new PendingChange(new AreaInfo(startIndex, stopIndex, 0, letterSpaceCount, newIPD, hyphenFollows, false, false, font), - ((LeafPosition) pos).getLeafPos())); + ((LeafPosition) pos).getLeafPos() + changeOffset)); nothingChanged = false; } startIndex = stopIndex; @@ -972,11 +971,41 @@ public class TextLayoutManager extends LeafNodeLayoutManager { /** {@inheritDoc} */ public boolean applyChanges(final List oldList) { + + // make sure the LM appears unfinished in between this call + // and the next call to getChangedKnuthElements() setFinished(false); + if (oldList.isEmpty()) { + return false; + } + + // Find the first and last positions in oldList that point to an AreaInfo + // (i.e. getLeafPos() != -1) + LeafPosition startPos = null, endPos = null; + ListIterator oldListIter; + for (oldListIter = oldList.listIterator(); oldListIter.hasNext();) { + startPos = (LeafPosition) ((KnuthElement) oldListIter.next()).getPosition(); + if (startPos != null && startPos.getLeafPos() != -1) { + break; + } + } + for (oldListIter = oldList.listIterator(oldList.size()); oldListIter.hasPrevious();) { + endPos = (LeafPosition) ((KnuthElement) oldListIter.previous()).getPosition(); + if (endPos != null && endPos.getLeafPos() != -1) { + break; + } + } + + // set start/end index, taking into account any offset due to + // changes applied to previous paragraphs + returnedIndices[0] = (startPos != null ? startPos.getLeafPos() : -1) + changeOffset; + returnedIndices[1] = (endPos != null ? endPos.getLeafPos() : -1) + changeOffset; + + int areaInfosAdded = 0; + int areaInfosRemoved = 0; + if (!changeList.isEmpty()) { - int areaInfosAdded = 0; - int areaInfosRemoved = 0; int oldIndex = -1, changeIndex; PendingChange currChange; ListIterator changeListIterator = changeList.listIterator(); @@ -997,7 +1026,11 @@ public class TextLayoutManager extends LeafNodeLayoutManager { changeList.clear(); } - returnedIndex = 0; + // increase the end index for getChangedKnuthElements() + returnedIndices[1] += (areaInfosAdded - areaInfosRemoved); + // increase offset to use for subsequent paragraphs + changeOffset += (areaInfosAdded - areaInfosRemoved); + return hasChanged; } @@ -1009,27 +1042,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager { final LinkedList returnList = new LinkedList(); - while (returnedIndex < areaInfos.size()) { - AreaInfo areaInfo = getAreaInfo(returnedIndex); + 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, returnedIndex); + addElementsForAWordFragment(returnList, alignment, areaInfo, returnedIndices[0]); } else { // areaInfo refers to a space - addElementsForASpace(returnList, alignment, areaInfo, returnedIndex); + addElementsForASpace(returnList, alignment, areaInfo, returnedIndices[0]); } - returnedIndex++; } - setFinished(true); + setFinished(returnedIndices[0] == areaInfos.size() - 1); //ElementListObserver.observe(returnList, "text-changed", null); return returnList; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public String getWordChars(Position pos) { - int leafValue = ((LeafPosition) pos).getLeafPos(); + int leafValue = ((LeafPosition) pos).getLeafPos() + changeOffset; if (leafValue != -1) { AreaInfo areaInfo = getAreaInfo(leafValue); StringBuffer buffer = new StringBuffer(areaInfo.getCharLength()); |