diff -wurN old/layoutmgr/ContentLayoutManager.java new/layoutmgr/ContentLayoutManager.java --- old/layoutmgr/ContentLayoutManager.java Mon Sep 13 12:39:45 2004 +++ new/layoutmgr/ContentLayoutManager.java Mon Sep 13 12:27:28 2004 @@ -22,6 +22,7 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.flow.Marker; import org.apache.fop.area.Area; +import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.AreaTreeHandler; import org.apache.fop.area.Resolveable; import org.apache.fop.area.PageViewport; @@ -41,12 +42,12 @@ * For use with objects that contain inline areas such as * leader use-content and title. */ -public class ContentLayoutManager implements LayoutManager { +public class ContentLayoutManager implements InlineLayoutManager { private FOUserAgent userAgent; private Area holder; private int stackSize; private LayoutManager parentLM; - private List childLMs = new ArrayList(1); + private InlineLayoutManager childLM = null; /** * logging instance @@ -138,6 +139,19 @@ stackSize = stack.opt; } + public void addAreas(PositionIterator posIter, LayoutContext context) { + // add the content areas + // the area width has already been adjusted, and it must remain unchanged + // so save its value before calling addAreas, and set it again afterwards + int savedWidth = ((InlineArea)holder).getWidth(); + // set to zero the ipd adjustment ratio, to avoid spaces in the pattern + // to be modified + LayoutContext childContext = new LayoutContext(context); + childContext.setIPDAdjust(0.0); + childLM.addAreas(posIter, childContext); + ((InlineArea)holder).setWidth(savedWidth); + } + public int getStackingSize() { return stackSize; } @@ -207,9 +221,6 @@ } /** @see org.apache.fop.layoutmgr.LayoutManager */ - public void addAreas(PositionIterator posIter, LayoutContext context) { } - - /** @see org.apache.fop.layoutmgr.LayoutManager */ public void initialize() { //to be done } @@ -264,6 +275,8 @@ * @see org.apache.fop.layoutmgr.LayoutManager#getChildLMs */ public List getChildLMs() { + List childLMs = new ArrayList(1); + childLMs.add(childLM); return childLMs; } @@ -276,7 +289,7 @@ } lm.setParent(this); lm.initialize(); - childLMs.add(lm); + childLM = (InlineLayoutManager)lm; log.trace(this.getClass().getName() + ": Adding child LM " + lm.getClass().getName()); } @@ -295,10 +308,27 @@ } } - public LinkedList getNextKnuthElements(LayoutContext context, - int alignment) { + public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { + LinkedList contentList = new LinkedList(); + LinkedList returnedList; + + while (!childLM.isFinished()) { + // get KnuthElements from childLM + returnedList = childLM.getNextKnuthElements(context, alignment); + + if (returnedList != null) { + // move elements to contentList, and accumulate their size + KnuthElement contentElement; + while (returnedList.size() > 0) { + contentElement = (KnuthElement)returnedList.removeFirst(); + stackSize += contentElement.getW(); + contentList.add(contentElement); + } + } + } + setFinished(true); - return null; + return contentList; } public KnuthElement addALetterSpaceTo(KnuthElement element) { @@ -319,10 +349,6 @@ int flaggedPenalty, int alignment) { return null; - } - - public int getWordSpaceIPD() { - return 0; } } diff -wurN old/layoutmgr/InlineLayoutManager.java new/layoutmgr/InlineLayoutManager.java --- old/layoutmgr/InlineLayoutManager.java Thu Jan 1 01:00:00 1970 +++ new/layoutmgr/InlineLayoutManager.java Mon Sep 13 12:27:28 2004 @@ -0,0 +1,84 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.layoutmgr; + +import java.util.LinkedList; +import java.util.List; + +/** + * The interface for LayoutManagers which generate inline areas + */ +public interface InlineLayoutManager extends LayoutManager { + + /** + * Get a sequence of KnuthElements representing the content + * of the node assigned to the LM + * + * @param context the LayoutContext used to store layout information + * @param alignment the desired text alignement + * @return the list of KnuthElements + */ + LinkedList getNextKnuthElements(LayoutContext context, int alignment); + + /** + * Tell the LM to modify its data, adding a letter space + * to the word fragment represented by the given element, + * and returning a corrected element + * + * @param element the element which must be given one more letter space + * @return the new element replacing the old one + */ + KnuthElement addALetterSpaceTo(KnuthElement element); + + /** + * Get the word chars corresponding to the given position + * + * @param sbChars the StringBuffer used to append word chars + * @param pos the Position referring to the needed word chars + */ + void getWordChars(StringBuffer sbChars, Position pos); + + /** + * Tell the LM to hyphenate a word + * + * @param pos the Position referring to the word + * @param hc the HyphContext storing hyphenation information + */ + void hyphenate(Position pos, HyphContext hc); + + /** + * Tell the LM to apply the changes due to hyphenation + * + * @param oldList the list of the old elements the changes refer to + * @return true if the LM had to change its data, false otherwise + */ + boolean applyChanges(List oldList); + + /** + * Get a sequence of KnuthElements representing the content + * of the node assigned to the LM, after changes have been applied + * + * @param oldList the elements to replace + * @param flaggedPenalty the penalty value for hyphenated lines + * @param alignment the desired text alignment + * @return the updated list of KnuthElements + */ + LinkedList getChangedKnuthElements(List oldList, int flaggedPenalty, + int alignment); +} diff -wurN old/layoutmgr/InlineStackingLayoutManager.java new/layoutmgr/InlineStackingLayoutManager.java --- old/layoutmgr/InlineStackingLayoutManager.java Mon Sep 13 12:39:59 2004 +++ new/layoutmgr/InlineStackingLayoutManager.java Mon Sep 13 12:27:28 2004 @@ -39,7 +39,8 @@ * LayoutManager for objects which stack children in the inline direction, * such as Inline or Line */ -public class InlineStackingLayoutManager extends AbstractLayoutManager { +public class InlineStackingLayoutManager extends AbstractLayoutManager + implements InlineLayoutManager { private static class StackingIter extends PositionIterator { @@ -233,7 +234,7 @@ public BreakPoss getNextBreakPoss(LayoutContext lc) { // Get a break from currently active child LM BreakPoss bp = null; - LayoutManager curLM; + InlineLayoutManager curLM; SpaceSpecifier leadingSpace = lc.getLeadingSpace(); if (lc.startsNewArea()) { @@ -253,7 +254,7 @@ // We only do this loop more than once if a childLM returns // a null BreakPoss, meaning it has nothing (more) to layout. - while ((curLM = getChildLM()) != null) { + while ((curLM = (InlineLayoutManager) getChildLM()) != null) { // ignore nested blocks for now if (!curLM.generatesInlineAreas()) { @@ -487,8 +488,9 @@ = new StackingIter(positionList.listIterator()); LayoutManager prevLM = null; - LayoutManager childLM ; - while ((childLM = childPosIter.getNextChildLM()) != null) { + InlineLayoutManager childLM ; + while ((childLM = (InlineLayoutManager) childPosIter.getNextChildLM()) + != null) { getContext().setFlags(LayoutContext.LAST_AREA, context.isLastArea() && childLM == lastLM); childLM.addAreas(childPosIter, getContext()); @@ -590,7 +592,7 @@ } public LinkedList getNextKnuthElements(LayoutContext lc, int alignment) { - LayoutManager curLM; + InlineLayoutManager curLM; // the list returned by child LM LinkedList returnedList; @@ -616,7 +618,7 @@ clearPrevIPD(); // Clear stored prev content dimensions } - while ((curLM = getChildLM()) != null) { + while ((curLM = (InlineLayoutManager) getChildLM()) != null) { // get KnuthElements from curLM returnedList = curLM.getNextKnuthElements(lc, alignment); if (returnedList != null) { @@ -644,7 +646,8 @@ element.setPosition(savedPos.getPosition()); KnuthElement newElement - = element.getLayoutManager().addALetterSpaceTo(element); + = ((InlineLayoutManager) + element.getLayoutManager()).addALetterSpaceTo(element); newElement.setPosition (new NonLeafPosition(this, newElement.getPosition())); element.setPosition(savedPos); @@ -653,12 +656,14 @@ public void getWordChars(StringBuffer sbChars, Position pos) { Position newPos = ((NonLeafPosition) pos).getPosition(); - newPos.getLM().getWordChars(sbChars, newPos); + ((InlineLayoutManager) + newPos.getLM()).getWordChars(sbChars, newPos); } public void hyphenate(Position pos, HyphContext hc) { Position newPos = ((NonLeafPosition) pos).getPosition(); - newPos.getLM().hyphenate(newPos, hc); + ((InlineLayoutManager) + newPos.getLM()).hyphenate(newPos, hc); } public boolean applyChanges(List oldList) { @@ -673,14 +678,14 @@ // reset the iterator oldListIterator = oldList.listIterator(); - LayoutManager prevLM = null; - LayoutManager currLM; + InlineLayoutManager prevLM = null; + InlineLayoutManager currLM; int fromIndex = 0; boolean bSomethingChanged = false; while(oldListIterator.hasNext()) { oldElement = (KnuthElement) oldListIterator.next(); - currLM = oldElement.getLayoutManager(); + currLM = (InlineLayoutManager) oldElement.getLayoutManager(); // initialize prevLM if (prevLM == null) { prevLM = currLM; @@ -733,13 +738,13 @@ KnuthElement returnedElement; LinkedList returnedList = new LinkedList(); LinkedList returnList = new LinkedList(); - LayoutManager prevLM = null; - LayoutManager currLM; + InlineLayoutManager prevLM = null; + InlineLayoutManager currLM; int fromIndex = 0; while(oldListIterator.hasNext()) { oldElement = (KnuthElement) oldListIterator.next(); - currLM = oldElement.getLayoutManager(); + currLM = (InlineLayoutManager) oldElement.getLayoutManager(); if (prevLM == null) { prevLM = currLM; } @@ -784,13 +789,5 @@ return returnList; } - public int getWordSpaceIPD() { - LayoutManager firstChild = getChildLM(); - if (firstChild != null) { - return firstChild.getWordSpaceIPD(); - } else { - return 0; - } - } } diff -wurN old/layoutmgr/LayoutManager.java new/layoutmgr/LayoutManager.java --- old/layoutmgr/LayoutManager.java Mon Sep 13 12:57:27 2004 +++ new/layoutmgr/LayoutManager.java Mon Sep 13 12:58:22 2004 @@ -18,7 +18,6 @@ package org.apache.fop.layoutmgr; -import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -244,19 +243,4 @@ * @param newLMs the list of LMs to be added */ void addChildLMs(List newLMs); - - LinkedList getNextKnuthElements(LayoutContext context, int alignment); - - KnuthElement addALetterSpaceTo(KnuthElement element); - - void getWordChars(StringBuffer sbChars, Position pos); - - void hyphenate(Position pos, HyphContext hc); - - boolean applyChanges(List oldList); - - LinkedList getChangedKnuthElements(List oldList, int flaggedPenalty, - int alignment); - - int getWordSpaceIPD(); } diff -wurN old/layoutmgr/LeaderLayoutManager.java new/layoutmgr/LeaderLayoutManager.java --- old/layoutmgr/LeaderLayoutManager.java Mon Sep 13 12:40:15 2004 +++ new/layoutmgr/LeaderLayoutManager.java Mon Sep 13 12:27:28 2004 @@ -14,7 +14,7 @@ * limitations under the License. */ -/* $Id: LeaderLayoutManager.java,v 1.5 2004/09/07 20:47:11 bckfnn Exp $ */ +/* $Id: LeaderLayoutManager.java,v 1.4 2004/09/05 18:16:32 spepping Exp $ */ package org.apache.fop.layoutmgr; @@ -23,6 +23,9 @@ import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.inline.Space; import org.apache.fop.area.inline.TextArea; +import org.apache.fop.datatypes.Length; +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.flow.Inline; import org.apache.fop.fo.flow.Leader; import org.apache.fop.fonts.Font; import org.apache.fop.traits.MinOptMax; @@ -38,6 +41,9 @@ Leader ldrNode; Font font = null; + private LinkedList contentList = null; + private ContentLayoutManager clm = null; + /** * Constructor * @@ -83,6 +89,7 @@ char dot = '.'; // userAgent.getLeaderDotCharacter(); t.setTextArea("" + dot); + t.setWidth(font.getCharWidth(dot)); t.addTrait(Trait.FONT_NAME, font.getFontName()); t.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize())); // set offset of dot within inline parent @@ -115,7 +122,8 @@ // get breaks then add areas to FilledArea FilledArea fa = new FilledArea(); - ContentLayoutManager clm = new ContentLayoutManager(fa); + //ContentLayoutManager clm = new ContentLayoutManager(fa); + clm = new ContentLayoutManager(fa); clm.setUserAgent(ldrNode.getUserAgent()); addChildLM(clm); @@ -123,7 +131,7 @@ lm = new InlineStackingLayoutManager(ldrNode); clm.addChildLM(lm); - clm.fillArea(lm); + contentList = clm.getNextKnuthElements(new LayoutContext(0), 0); int width = clm.getStackingSize(); Space spacer = null; if (ldrNode.getPatternWidth() > width) { @@ -139,6 +147,28 @@ } return leaderArea; } + + public void addAreas(PositionIterator posIter, LayoutContext context) { + if (ldrNode.getLeaderPattern() != LeaderPattern.USECONTENT) { + // use LeafNodeLayoutManager.addAreas() + super.addAreas(posIter, context); + } else { + addID(); + + offsetArea(context); + widthAdjustArea(context); + + // add content areas + KnuthPossPosIter contentIter = new KnuthPossPosIter(contentList, 0, contentList.size()); + clm.addAreas(contentIter, context); + + parentLM.addChild(curArea); + + while (posIter.hasNext()) { + posIter.next(); + } + } + } public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { diff -wurN old/layoutmgr/LeafNodeLayoutManager.java new/layoutmgr/LeafNodeLayoutManager.java --- old/layoutmgr/LeafNodeLayoutManager.java Mon Sep 13 12:40:26 2004 +++ new/layoutmgr/LeafNodeLayoutManager.java Mon Sep 13 12:27:28 2004 @@ -33,7 +33,8 @@ * This class can be extended to handle the creation and adding of the * inline area. */ -public class LeafNodeLayoutManager extends AbstractLayoutManager { +public class LeafNodeLayoutManager extends AbstractLayoutManager + implements InlineLayoutManager { /** * The inline area that this leafnode will add. */ @@ -153,49 +154,6 @@ } /** - * Get the next break position. - * Since this holds an inline area it will return a single - * break position. - * @param context the layout context for this inline area - * @return the break poisition for adding this inline area - */ - public BreakPoss getNextBreakPoss(LayoutContext context) { - curArea = get(context); - if (curArea == null) { - setFinished(true); - return null; - } - BreakPoss bp = new BreakPoss(new LeafPosition(this, 0), - BreakPoss.CAN_BREAK_AFTER - | BreakPoss.CAN_BREAK_BEFORE | BreakPoss.ISFIRST - | BreakPoss.ISLAST); - ipd = getAllocationIPD(context.getRefIPD()); - bp.setStackingSize(ipd); - bp.setNonStackingSize(new MinOptMax(curArea.getHeight())); - bp.setTrailingSpace(new SpaceSpecifier(false)); - - int bpd = curArea.getHeight(); - switch (alignment) { - case VerticalAlign.MIDDLE: - bp.setMiddle(bpd / 2 /* - fontLead/2 */); - bp.setLead(bpd / 2 /* + fontLead/2 */); - break; - case VerticalAlign.TOP: - bp.setTotal(bpd); - break; - case VerticalAlign.BOTTOM: - bp.setTotal(bpd); - break; - case VerticalAlign.BASELINE: - default: - bp.setLead(bpd); - break; - } - setFinished(true); - return bp; - } - - /** * Get the allocation ipd of the inline area. * This method may be overridden to handle percentage values. * @param refIPD the ipd of the parent reference area @@ -206,19 +164,6 @@ } /** - * Reset the position. - * If the reset position is null then this inline area should be - * restarted. - * @param resetPos the position to reset. - */ - public void resetPosition(Position resetPos) { - // only reset if setting null, start again - if (resetPos == null) { - setFinished(false); - } - } - - /** * Add the area for this layout manager. * This adds the single inline area to the parent. * @param posIter the position iterator @@ -340,9 +285,10 @@ new LeafPosition(this, 0), false); } + public void getWordChars(StringBuffer sbChars, Position pos) { + } + public void hyphenate(Position pos, HyphContext hc) { - // use the AbstractLayoutManager.hyphenate() null implementation - super.hyphenate(pos, hc); } public boolean applyChanges(List oldList) { @@ -368,5 +314,6 @@ setFinished(true); return returnList; } + } diff -wurN old/layoutmgr/LineLayoutManager.java new/layoutmgr/LineLayoutManager.java --- old/layoutmgr/LineLayoutManager.java Mon Sep 13 12:40:34 2004 +++ new/layoutmgr/LineLayoutManager.java Mon Sep 13 12:32:38 2004 @@ -136,6 +136,11 @@ // suggested modification to the "optimum" number of lines private int looseness = 0; + // this constant is used to create elements when text-align is center: + // every TextLM descendant of LineLM must use the same value, + // otherwise the line breaking algorithm does not find the right + // break point + public static final int DEFAULT_SPACE_WIDTH = 3336; private static final int INFINITE_RATIO = 1000; // this class represent a feasible breaking point @@ -257,10 +262,10 @@ // which was the first element in the paragraph // returned by each LM private class Update { - private LayoutManager inlineLM; + private InlineLayoutManager inlineLM; private int iFirstIndex; - public Update(LayoutManager lm, int index) { + public Update(InlineLayoutManager lm, int index) { inlineLM = lm; iFirstIndex = index; } @@ -273,28 +278,20 @@ public int ignoreAtEnd = 0; // minimum space at the end of the last line (in millipoints) public int lineFillerWidth; - // word space dimension (in millipoints) - private int wordSpaceIPD; public void startParagraph(int lineWidth) { - // get the word space dimension, which needs to be known - // in order to center text - LayoutManager lm; - if ((lm = getChildLM()) != null) { - wordSpaceIPD = lm.getWordSpaceIPD(); - } // set the minimum amount of empty space at the end of the // last line if (bTextAlignment == CENTER) { lineFillerWidth = 0; } else { - lineFillerWidth = (int)(lineWidth / 6); + lineFillerWidth = (int)(lineWidth / 12); } // add auxiliary elements at the beginning of the paragraph if (bTextAlignment == CENTER && bTextAlignmentLast != JUSTIFY) { - this.add(new KnuthGlue(0, 3 * wordSpaceIPD, 0, + this.add(new KnuthGlue(0, 3 * DEFAULT_SPACE_WIDTH, 0, null, false)); ignoreAtStart ++; } @@ -318,7 +315,7 @@ if (this.size() > ignoreAtStart) { if (bTextAlignment == CENTER && bTextAlignmentLast != JUSTIFY) { - this.add(new KnuthGlue(0, 3 * wordSpaceIPD, 0, + this.add(new KnuthGlue(0, 3 * DEFAULT_SPACE_WIDTH, 0, null, false)); this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false)); @@ -376,7 +373,7 @@ public BreakPoss getNextBreakPoss(LayoutContext context) { // Get a break from currently active child LM // Set up constraints for inline level managers - LayoutManager curLM ; // currently active LM + InlineLayoutManager curLM ; // currently active LM BreakPoss prev = null; BreakPoss bp = null; // proposed BreakPoss @@ -412,26 +409,21 @@ Paragraph knuthPar = new Paragraph(); knuthPar.startParagraph(availIPD.opt); - while ((curLM = getChildLM()) != null) { + while ((curLM = (InlineLayoutManager) getChildLM()) != null) { if ((returnedList = curLM.getNextKnuthElements(inlineLC, effectiveAlignment)) != null) { - // if there are two consecutive KnuthBox, the first one - // does not represent a whole word, so it must be given - // one more letter space + // look at the first element thisElement = (KnuthElement) returnedList.getFirst(); - if (returnedList.size() > 1 - || !(thisElement.isPenalty() - && ((KnuthPenalty) thisElement).getP() - == -KnuthElement.INFINITE)) { if (thisElement.isBox() && !thisElement.isAuxiliary() && bPrevWasKnuthBox) { prevBox = (KnuthBox) knuthPar.removeLast(); if (!prevBox.isAuxiliary()) { // if letter spacing is constant, // only prevBox needs to be replaced; - knuthPar.addLast(prevBox.getLayoutManager() + knuthPar.addLast(((InlineLayoutManager) + prevBox.getLayoutManager()) .addALetterSpaceTo(prevBox)); } else { // prevBox is the last element @@ -446,23 +438,34 @@ = (KnuthPenalty) knuthPar.removeLast(); prevBox = (KnuthBox) knuthPar.getLast(); knuthPar.addLast(auxPenalty); - knuthPar.addLast(prevBox.getLayoutManager() + knuthPar.addLast(((InlineLayoutManager) + prevBox.getLayoutManager()) .addALetterSpaceTo(prevBox)); knuthPar.addLast(auxBox); } } - if (((KnuthElement) returnedList.getLast()).isBox()) { + + // look at the last element + KnuthElement lastElement = (KnuthElement) returnedList.getLast(); + boolean bForceLinefeed = false; + if (lastElement.isBox()) { bPrevWasKnuthBox = true; } else { bPrevWasKnuthBox = false; + if (lastElement.isPenalty() + && ((KnuthPenalty) lastElement).getP() + == -KnuthPenalty.INFINITE) { + // a penalty item whose value is -inf + // represents a preserved linefeed, + // wich forces a line break + bForceLinefeed = true; + returnedList.removeLast(); + } } + // add the new elements to the paragraph knuthPar.addAll(returnedList); - } else { - // a list with a single penalty item - // whose value is -inf - // represents a preserved linefeed, - // wich forces a line break + if (bForceLinefeed) { knuthPar.endParagraph(); knuthPar = new Paragraph(); knuthPar.startParagraph(availIPD.opt); @@ -975,7 +978,7 @@ KnuthElement firstElement = null; KnuthElement nextElement = null; // current TextLayoutManager - LayoutManager currLM = null; + InlineLayoutManager currLM = null; // number of KnuthBox elements containing word fragments int boxCount; // number of auxiliary KnuthElements between KnuthBoxes @@ -987,7 +990,7 @@ firstElement = (KnuthElement) currParIterator.next(); // if (firstElement.getLayoutManager() != currLM) { - currLM = firstElement.getLayoutManager(); + currLM = (InlineLayoutManager) firstElement.getLayoutManager(); if (currLM != null) { updateList.add(new Update(currLM, currParIterator.previousIndex())); } else { @@ -1008,7 +1011,7 @@ if (nextElement.isBox() && !nextElement.isAuxiliary()) { // a non-auxiliary KnuthBox: append word chars if (currLM != nextElement.getLayoutManager()) { - currLM = nextElement.getLayoutManager(); + currLM = (InlineLayoutManager) nextElement.getLayoutManager(); updateList.add(new Update(currLM, currParIterator.previousIndex())); } // append text to recreate the whole word @@ -1036,7 +1039,8 @@ for (int i = 0; i < (boxCount + auxCount); i++) { element = (KnuthElement) currParIterator.next(); if (element.isBox() && !element.isAuxiliary()) { - element.getLayoutManager().hyphenate(element.getPosition(), hc); + ((InlineLayoutManager) + element.getLayoutManager()).hyphenate(element.getPosition(), hc); } else { // nothing to do, element is an auxiliary KnuthElement } @@ -1070,7 +1074,7 @@ // applyChanges() returns true if the LM modifies its data, // so it must return new KnuthElements to replace the old ones - if (currUpdate.inlineLM + if (((InlineLayoutManager) currUpdate.inlineLM) .applyChanges(currPar.subList(fromIndex + iAddedElements, toIndex + iAddedElements))) { // insert the new KnuthElements diff -wurN old/layoutmgr/TextLayoutManager.java new/layoutmgr/TextLayoutManager.java --- old/layoutmgr/TextLayoutManager.java Mon Sep 13 12:40:40 2004 +++ new/layoutmgr/TextLayoutManager.java Mon Sep 13 12:27:28 2004 @@ -24,10 +24,12 @@ import java.util.ListIterator; import org.apache.fop.fo.FOText; +import org.apache.fop.fo.Constants; import org.apache.fop.traits.SpaceVal; import org.apache.fop.area.Trait; import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.inline.TextArea; +import org.apache.fop.area.inline.Space; import org.apache.fop.util.CharUtilities; import org.apache.fop.traits.MinOptMax; @@ -35,7 +37,7 @@ * LayoutManager for text (a sequence of characters) which generates one * or more inline areas. */ -public class TextLayoutManager extends AbstractLayoutManager { +public class TextLayoutManager extends LeafNodeLayoutManager { /** * Store information about each potential text area. @@ -108,6 +110,8 @@ private SpaceVal halfWS; /** Number of space characters after previous possible break position. */ private int iNbSpacesPending; + /** Height of the textArea that will be created */ + private int textHeight; private boolean bChanged = false; private int iReturnedIndex = 0; @@ -154,6 +158,10 @@ wordSpaceIPD = new MinOptMax(spaceCharIPD + ws.getSpace().min, spaceCharIPD + ws.getSpace().opt, spaceCharIPD + ws.getSpace().max); + + // set text height + textHeight = foText.textInfo.fs.getAscender() + - foText.textInfo.fs.getDescender(); } /** @@ -637,14 +645,14 @@ (short) 1, (short) 0, wordSpaceIPD, false)); returnList.add - (new KnuthGlue(0, 3 * wordSpaceIPD.opt, 0, + (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, new LeafPosition(this, vecAreaInfo.size() - 1), false)); returnList.add (new KnuthPenalty(0, 0, false, new LeafPosition(this, -1), true)); returnList.add (new KnuthGlue(wordSpaceIPD.opt, - - 6 * wordSpaceIPD.opt, 0, + - 6 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, new LeafPosition(this, -1), true)); returnList.add (new KnuthBox(0, 0, 0, 0, @@ -653,7 +661,7 @@ (new KnuthPenalty(0, KnuthElement.INFINITE, false, new LeafPosition(this, -1), true)); returnList.add - (new KnuthGlue(0, 3 * wordSpaceIPD.opt, 0, + (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, new LeafPosition(this, -1), true)); iNextStart ++; break; @@ -718,8 +726,7 @@ iNextStart ++; } else if (textArray[iNextStart] == NEWLINE) { // linefeed; this can happen when linefeed-treatment="preserve" - // the linefeed character is the first one in textArray, - // so we can just return a list with a penalty item + // add a penalty item to the list and return returnList.add (new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false)); @@ -750,14 +757,15 @@ // constant letter space; simply return a box // whose width includes letter spaces returnList.add - (new KnuthBox(wordIPD.opt, 0, 0, 0, + (new KnuthBox(wordIPD.opt, textHeight, 0, 0, new LeafPosition(this, vecAreaInfo.size() - 1), false)); iNextStart = iTempStart; } else { // adjustable letter space; // some other KnuthElements are needed returnList.add - (new KnuthBox(wordIPD.opt - (iTempStart - iThisStart - 1) * letterSpaceIPD.opt, 0, 0, 0, + (new KnuthBox(wordIPD.opt - (iTempStart - iThisStart - 1) * letterSpaceIPD.opt, + textHeight, 0, 0, new LeafPosition(this, vecAreaInfo.size() - 1), false)); returnList.add (new KnuthPenalty(0, KnuthElement.INFINITE, false, @@ -768,7 +776,7 @@ (iTempStart - iThisStart - 1) * (letterSpaceIPD.opt - letterSpaceIPD.min), new LeafPosition(this, -1), true)); returnList.add - (new KnuthBox(0, 0, 0, 0, + (new KnuthBox(0, textHeight, 0, 0, new LeafPosition(this, -1), true)); iNextStart = iTempStart; } @@ -782,17 +790,13 @@ } } - public int getWordSpaceIPD() { - return wordSpaceIPD.opt; - } - public KnuthElement addALetterSpaceTo(KnuthElement element) { LeafPosition pos = (LeafPosition) element.getPosition(); AreaInfo ai = (AreaInfo) vecAreaInfo.get(pos.getLeafPos()); ai.iLScount ++; ai.ipdArea.add(letterSpaceIPD); if (letterSpaceIPD.min == letterSpaceIPD.max) { - return new KnuthBox(ai.ipdArea.opt, 0, 0, 0, pos, false); + return new KnuthBox(ai.ipdArea.opt, textHeight, 0, 0, pos, false); } else { return new KnuthGlue(ai.iLScount * letterSpaceIPD.opt, ai.iLScount * (letterSpaceIPD.max - letterSpaceIPD.opt), @@ -911,13 +915,13 @@ // ai refers either to a word or a word fragment if (letterSpaceIPD.min == letterSpaceIPD.max) { returnList.add - (new KnuthBox(ai.ipdArea.opt, 0, 0, 0, + (new KnuthBox(ai.ipdArea.opt, textHeight, 0, 0, new LeafPosition(this, iReturnedIndex), false)); } else { returnList.add (new KnuthBox(ai.ipdArea.opt - ai.iLScount * letterSpaceIPD.opt, - 0, 0, 0, + textHeight, 0, 0, new LeafPosition(this, iReturnedIndex), false)); returnList.add (new KnuthPenalty(0, KnuthElement.INFINITE, false, @@ -942,14 +946,14 @@ switch (alignment) { case CENTER : returnList.add - (new KnuthGlue(0, 3 * wordSpaceIPD.opt, 0, + (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, new LeafPosition(this, iReturnedIndex), false)); returnList.add (new KnuthPenalty(0, 0, false, new LeafPosition(this, -1), true)); returnList.add (new KnuthGlue(wordSpaceIPD.opt, - - 6 * wordSpaceIPD.opt, 0, + - 6 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, new LeafPosition(this, -1), true)); returnList.add (new KnuthBox(0, 0, 0, 0, @@ -958,7 +962,7 @@ (new KnuthPenalty(0, KnuthElement.INFINITE, false, new LeafPosition(this, -1), true)); returnList.add - (new KnuthGlue(0, 3 * wordSpaceIPD.opt, 0, + (new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, new LeafPosition(this, -1), true)); iReturnedIndex ++; break;