Index: src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java =================================================================== --- src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java (revision 651860) +++ src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java Thu May 01 14:56:11 CEST 2008 @@ -22,6 +22,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; /** @@ -156,10 +157,12 @@ private KnuthNode lastRecovered; /** - * Create a new instance. - * @param align alignment of the paragraph/page. One of EN_START, EN_JUSTIFY, etc. For - * pages EN_BEFORE, EN_AFTER are mapped to the corresponding inline properties - * (EN_START, EN_END) + * Create a new BreakingAlgorithm instance. + * + * @param align alignment of the paragraph/page. One of {@link Constants#EN_START}, + * {@link Constants#EN_JUSTIFY}, etc. Note: For pages, {@link Constants#EN_BEFORE} + * and {@link Constants#EN_AFTER} are mapped to the corresponding inline properties + * {@link Constants#EN_START} and {@link Constants#EN_END}) * @param alignLast alignment of the paragraph's last line * @param first for the text-indent property (indent the first line of a paragraph) * @param partOverflowRecovery true if too long elements should be moved to the next line/part @@ -404,13 +407,19 @@ return findBreakingPoints(par, 0, threshold, force, allowedBreaks); } - /** Finds an optimal set of breakpoints for the given paragraph. + /** + * Finds an optimal set of breakpoints for the given paragraph. + * - * @param par the paragraph to break + * @param par the paragraph to break - * @param startIndex index of the Knuth element at which the breaking must start + * @param startIndex index of the {@link KnuthElement} at which + * the breaking must start - * @param threshold upper bound of the adjustment ratio + * @param threshold upper bound of the adjustment ratio - * @param force true if a set of breakpoints must be found even if there are no - * feasible ones - * @param allowedBreaks one of ONLY_FORCED_BREAKS, NO_FLAGGED_PENALTIES, ALL_BREAKS + * @param force true if a set of breakpoints must be found + * even if there are no feasible ones + * @param allowedBreaks one of {@link #ONLY_FORCED_BREAKS}, + * {@link #NO_FLAGGED_PENALTIES}, + * {@link #ALL_BREAKS} + * @return the index of the optimal set of breakpoints */ public int findBreakingPoints(KnuthSequence par, int startIndex, double threshold, boolean force, @@ -477,11 +486,11 @@ // only if its penalty is not infinite; // consider all penalties, non-flagged penalties or non-forcing penalties // according to the value of allowedBreaks - if (((KnuthPenalty) thisElement).getP() < KnuthElement.INFINITE + if ((thisElement).getP() < KnuthElement.INFINITE && (!(allowedBreaks == NO_FLAGGED_PENALTIES) || !(((KnuthPenalty) thisElement).isFlagged())) && (!(allowedBreaks == ONLY_FORCED_BREAKS) - || ((KnuthPenalty) thisElement).getP() == -KnuthElement.INFINITE)) { + || (thisElement).getP() == -KnuthElement.INFINITE)) { considerLegalBreak(thisElement, i); } previousIsBox = false; @@ -586,7 +595,7 @@ Position pos = (el != null ? el.getPosition() : null); LayoutManager lm = (pos != null ? pos.getLM() : null); while (pos instanceof NonLeafPosition) { - pos = ((NonLeafPosition)pos).getPosition(); + pos = pos.getPosition(); if (pos != null && pos.getLM() != null) { lm = pos.getLM(); } @@ -1141,4 +1150,11 @@ return this.alignmentLast; } + public int getOverflowAmount() { + return (this.totalWidth - this.totalShrink) - this.lineWidth; -} + } + + public int getTotalWidth() { + return this.totalWidth; + } +} Index: src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java Thu May 01 14:54:40 CEST 2008 +++ src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java Thu May 01 14:54:40 CEST 2008 @@ -0,0 +1,578 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.inline; + +// Java +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.awt.geom.Rectangle2D; + +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.area.Trait; +import org.apache.fop.area.CTM; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.InlineBlockParent; +import org.apache.fop.area.inline.Viewport; +import org.apache.fop.datatypes.FODimension; +import org.apache.fop.datatypes.Length; +import org.apache.fop.fo.flow.InlineContainer; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.fo.properties.SpaceProperty; +import org.apache.fop.layoutmgr.inline.InlineStackingLayoutManager.StackingIter; +import org.apache.fop.layoutmgr.AbstractBreaker; +import org.apache.fop.layoutmgr.ElementListObserver; +import org.apache.fop.layoutmgr.InlineKnuthSequence; +import org.apache.fop.layoutmgr.KnuthSequence; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.ListElement; +import org.apache.fop.layoutmgr.NonLeafPosition; +import org.apache.fop.layoutmgr.PageBreakingAlgorithm; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.SpaceResolver; +import org.apache.fop.layoutmgr.TraitSetter; +import org.apache.fop.traits.MinOptMax; +/** + * This creates a single inline container area after + * laying out the child block areas. All footnotes, floats + * and id areas are maintained for later retrieval. + */ +public class InlineContainerLayoutManager extends LeafNodeLayoutManager { + + Viewport currentViewport; + InlineArea referenceArea; + Block baseBlockArea; + + /** The Common Border, Padding and Background properties */ + private CommonBorderPaddingBackground borderProps = null; + /** The alignment adjust property */ + private Length alignmentAdjust; + /** The alignment baseline property */ + private int alignmentBaseline = EN_BASELINE; + /** The baseline shift property */ + private Length baselineShift; + /** The dominant baseline property */ + private int dominantBaseline; + /** The line height property */ + private SpaceProperty lineHeight; + + private Length height; + private Length width; + private boolean autoHeight; + private boolean autoWidth; + + private int contentAreaBPD; + private int contentAreaIPD; + private int viewportContentBPD; + private int referenceIPD; + + private FODimension relDims; + private CTM absoluteCTM; + + private LayoutManager lastChildLM = null; + + + /** + * Construct a new InlineContainerLayoutManager + * for the the given {@link InlineContainer} + * + * @param node the base {@link InlineContainer} + */ + public InlineContainerLayoutManager(InlineContainer node) { + super(node); + } + + /** {@inheritDoc} */ + public void initialize() { + InlineContainer node = (InlineContainer) fobj; + + borderProps = node.getCommonBorderPaddingBackground(); + + alignmentAdjust = node.getAlignmentAdjust(); + alignmentBaseline = node.getAlignmentBaseline(); + baselineShift = node.getBaselineShift(); + dominantBaseline = node.getDominantBaseline(); + + boolean rotated = (node.getReferenceOrientation() % 180 != 0); + if (rotated) { + height = node.getInlineProgressionDimension() + .getOptimum(this).getLength(); + width = node.getBlockProgressionDimension() + .getOptimum(this).getLength(); + } else { + height = node.getBlockProgressionDimension() + .getOptimum(this).getLength(); + width = node.getInlineProgressionDimension() + .getOptimum(this).getLength(); + } + + } + + /** {@inheritDoc} */ + public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { + + InlineContainer ic = (InlineContainer) fobj; + boolean rotated = (ic.getReferenceOrientation() % 180 != 0); + autoHeight = false; + int maxbpd = context.getStackLimitBP().opt; + int allocBPD; + if (height.getEnum() == EN_AUTO + || (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) { + //auto height when height="auto" or "if that dimension is not specified explicitly + //(i.e., it depends on content's block-progression-dimension)" (XSL 1.0, 7.14.1) + allocBPD = maxbpd; + autoHeight = true; + } else { + allocBPD = height.getValue(this); //this is the content-height + allocBPD += borderProps.getBPPaddingAndBorder(false, this); + } + if (width.getEnum() == EN_AUTO) { + autoWidth = true; + } + viewportContentBPD = allocBPD - borderProps.getBPPaddingAndBorder(false, this); + + referenceIPD = context.getRefIPD(); + + double contentRectOffsetX = 0; + //contentRectOffsetX += ic.getCommonMarginInline().spaceStart.getLength().getValue(this); + double contentRectOffsetY = 0; + contentRectOffsetY += borderProps.getBorderBeforeWidth(false); + contentRectOffsetY += borderProps.getPaddingBefore(false, this); + + updateRelDims(contentRectOffsetX, contentRectOffsetY, autoHeight); + + if (getContentAreaIPD() > referenceIPD) { + InlineLevelEventProducer eventProducer + = InlineLevelEventProducer.Provider.get( + ic.getUserAgent().getEventBroadcaster()); + eventProducer.lineOverflows( + this, 0, + (getContentAreaIPD() - referenceIPD), ic.getLocator()); + } + + LinkedList returnList = new LinkedList(); + KnuthSequence inlineSeq = new InlineKnuthSequence(); + + addKnuthElementsForBorderPaddingStart(inlineSeq); + + MinOptMax refIPD; + if (autoWidth) { + refIPD = new MinOptMax(referenceIPD); + } else { + refIPD = new MinOptMax(width.getValue(this)); + } + InlineContainerBreaker breaker = new InlineContainerBreaker(this, refIPD); + breaker.doLayout(height.getValue(this), autoHeight); + + if (!breaker.isEmpty()) { + if (autoHeight) { + //Update content BPD now that it is known + int newHeight = breaker.deferredAlg.getTotalWidth(); + if (rotated) { + setContentAreaIPD(newHeight); + } else { + viewportContentBPD = newHeight; + } + updateRelDims(contentRectOffsetX, contentRectOffsetY, false); + } + + Position icPosition = new InlineContainerPosition(this, breaker); + inlineSeq.add(new KnuthInlineBox(refIPD.opt, makeAlignmentContext(context), notifyPos(icPosition), false)); + } + + addKnuthElementsForBorderPaddingEnd(inlineSeq); + + returnList.add(inlineSeq); + + setFinished(true); + + return returnList; + } + + /** {@inheritDoc} */ + public void addChildArea(Area childArea) { + baseBlockArea.addBlock((Block) childArea); + } + + /** {@inheritDoc} */ + public void addAreas(PositionIterator posIter, LayoutContext context) { + + /* "Unwrap" the NonLeafPositions stored in parentIter and put + * them in a new list. Set lastLM to be the LayoutManager + * which created the last Position: if the LAST_AREA flag is + * set in the layout context, it must be also set in the + * layout context given to lastLM, but must be cleared in the + * layout context given to the other LMs. */ + LinkedList positionList = new LinkedList(); + Position pos; + LayoutManager lastLM = null;// last child LM in this iterator + Position lastPos = null; + InlineContainerPosition icPos = null; + while (posIter.hasNext()) { + pos = (Position) posIter.next(); + if (pos instanceof InlineContainerPosition) { + assert (icPos == null); + icPos = (InlineContainerPosition)pos; + } + if (pos != null && pos.getPosition() != null) { + positionList.add(pos.getPosition()); + lastLM = pos.getPosition().getLM(); + lastPos = pos; + } + } + + addId(); + addMarkersToPage( + true, + true, + lastPos == null || isLast(lastPos)); + + LayoutManager prevLM = null; + + if (icPos == null) { + StackingIter childPosIter + = new StackingIter(positionList.listIterator()); + + LayoutManager childLM; + while ((childLM = childPosIter.getNextChildLM()) != null) { + context.setFlags(LayoutContext.LAST_AREA, + context.isLastArea() && childLM == lastLM); + childLM.addAreas(childPosIter, context); + context.setLeadingSpace(context.getTrailingSpace()); + context.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true); + prevLM = childLM; + } + + currentViewport.setContent(referenceArea); + parentLM.addChildArea(currentViewport); + } else { + icPos.breaker.addContainedAreas(); + } + + addMarkersToPage( + false, + true, + lastPos == null || isLast(lastPos)); + + boolean isLast = (context.isLastArea() && prevLM == lastChildLM); + context.setFlags(LayoutContext.LAST_AREA, isLast); + } + + /** {@inheritDoc} */ + public int getContentAreaIPD() { + return width.getEnum() == EN_AUTO + ? referenceIPD + : width.getValue(this); + } + + /** + * Sets the IPD of the content area + * @param contentAreaIPD the IPD of the content area + */ + private void setContentAreaIPD(int contentAreaIPD) { + this.contentAreaIPD = contentAreaIPD; + } + + /** {@inheritDoc} */ + public int getContentAreaBPD() { + return height.getEnum() == EN_AUTO + ? viewportContentBPD + : height.getValue(this); + } + + /** + * Get the parent area for children of this inline-container. + * This returns the current inline-container area + * and creates it if required. + * + * {@inheritDoc} + */ + public Area getParentArea(Area childArea) { + if (referenceArea == null) { + currentViewport = new Viewport(childArea); + currentViewport.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE); + currentViewport.setIPD(getContentAreaIPD()); + currentViewport.setBPD(getContentAreaBPD()); + + TraitSetter.setProducerID(currentViewport, fobj.getId()); + TraitSetter.addBorders(currentViewport, + borderProps, + false, false, false, false, this); + TraitSetter.addPadding(currentViewport, + borderProps, + false, false, false, false, this); + TraitSetter.addBackground(currentViewport, + borderProps, + this); + + currentViewport.setCTM(absoluteCTM); + currentViewport.setClip(needClip()); + currentViewport.setContentPosition( + new java.awt.geom.Rectangle2D.Float(0, 0, getContentAreaIPD(), getContentAreaBPD())); + referenceArea = new InlineBlockParent(); + referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE); + TraitSetter.setProducerID(referenceArea, fobj.getId()); + // Set up dimensions + // Must get dimensions from parent area + parentLM.getParentArea(referenceArea); + referenceArea.setIPD(referenceIPD); + baseBlockArea = new Block(); + referenceArea.addChildArea(baseBlockArea); + // Get reference IPD from parentArea + setCurrentArea(currentViewport); // ??? for generic operations + } + return referenceArea; + } + + private boolean needClip() { + int overflow = ((InlineContainer) fobj).getOverflow(); + return (overflow == EN_HIDDEN || overflow == EN_ERROR_IF_OVERFLOW); + } + + /** + * {@inheritDoc} + */ + protected AlignmentContext makeAlignmentContext(LayoutContext context) { + return new AlignmentContext( + viewportContentBPD + , alignmentAdjust + , alignmentBaseline + , baselineShift + , dominantBaseline + , context.getAlignmentContext() + ); + } + + /** + * 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 + * @return the min/opt/max ipd of the inline area + */ + protected MinOptMax getAllocationIPD(int refIPD) { + return new MinOptMax(curArea.getIPD()); + } + + /** + * "wrap" the Position inside each element moving the elements from + * SourceList to targetList + * @param sourceList source list + * @param targetList target list receiving the wrapped position elements + */ + protected void wrapPositionElements(List sourceList, List targetList) { + wrapPositionElements(sourceList, targetList, false); + } + + /** + * "wrap" the Position inside each element moving the elements from + * SourceList to targetList + * @param sourceList source list + * @param targetList target list receiving the wrapped position elements + * @param force if true, every Position is wrapped regardless of its LM of origin + */ + protected void wrapPositionElements(List sourceList, List targetList, boolean force) { + + ListIterator listIter = sourceList.listIterator(); + Object tempElement; + while (listIter.hasNext()) { + tempElement = listIter.next(); + if (tempElement instanceof ListElement) { + wrapPositionElement( + (ListElement) tempElement, + targetList, + force); + } else if (tempElement instanceof List) { + wrapPositionElements( + (List) tempElement, + targetList, + force); + } + } + } + + /** + * "wrap" the Position inside the given element and add it to the target list. + * @param el the list element + * @param targetList target list receiving the wrapped position elements + * @param force if true, every Position is wrapped regardless of its LM of origin + */ + protected void wrapPositionElement(ListElement el, List targetList, boolean force) { + if (force || el.getLayoutManager() != this) { + el.setPosition(notifyPos(new NonLeafPosition(this, + el.getPosition()))); + } + targetList.add(el); + } + + private void updateRelDims(double xOffset, double yOffset, boolean skipAutoHeight) { + Rectangle2D rect = new Rectangle2D.Double( + xOffset, yOffset, + getContentAreaIPD(), + this.viewportContentBPD); + relDims = new FODimension(0, 0); + absoluteCTM = CTM.getCTMandRelDims( + ((InlineContainer) fobj).getReferenceOrientation(), + ((InlineContainer) fobj).getWritingMode(), + rect, relDims); + } + + private class InlineContainerPosition extends LeafPosition { + + private InlineContainerBreaker breaker; + + public InlineContainerPosition(LayoutManager lm, InlineContainerBreaker breaker) { + super(lm, 0); + this.breaker = breaker; + } + + public InlineContainerBreaker getBreaker() { + return this.breaker; + } + + } + + private class InlineContainerBreaker extends AbstractBreaker { + + private InlineContainerLayoutManager iclm; + private MinOptMax ipd; + + //Info for deferred adding of areas + private PageBreakingAlgorithm deferredAlg; + private BlockSequence deferredOriginalList; + private BlockSequence deferredEffectiveList; + + public InlineContainerBreaker(InlineContainerLayoutManager iclm, MinOptMax ipd) { + this.iclm = iclm; + this.ipd = ipd; + } + + /** {@inheritDoc} */ + protected void observeElementList(List elementList) { + ElementListObserver.observe( + elementList, + "inline-container", + iclm.fobj.getId()); + } + + /** {@inheritDoc} */ + protected boolean isPartOverflowRecoveryActivated() { + return false; + } + + /** {@inheritDoc} */ + protected boolean isSinglePartFavored() { + return true; + } + + int getDifferenceOfFirstPart() { + PageBreakPosition pbp = (PageBreakPosition)this.deferredAlg.getPageBreaks().getFirst(); + return pbp.getDifference(); + } + + boolean isOverflow() { + return !isEmpty() + && ((deferredAlg.getPageBreaks().size() > 1) + || (deferredAlg.getOverflowAmount() > 0)); + } + + int getOverflowAmount() { + return deferredAlg.getOverflowAmount(); + } + + protected LayoutManager getTopLevelLM() { + return iclm; + } + + protected LayoutContext createLayoutContext() { + LayoutContext lc = super.createLayoutContext(); + lc.setRefIPD(ipd.opt); + lc.setWritingMode(((InlineContainer) fobj).getWritingMode()); + return lc; + } + + protected LinkedList getNextKnuthElements(LayoutContext context, int alignment) { + LayoutManager curLM; // currently active LM + LinkedList returnList = new LinkedList(); + + while ((curLM = getChildLM()) != null) { + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimitBP(context.getStackLimitBP()); + childLC.setRefIPD(context.getRefIPD()); + childLC.setWritingMode(((InlineContainer)fobj).getWritingMode()); + + LinkedList returnedList = null; + if (!curLM.isFinished()) { + returnedList = curLM.getNextKnuthElements(childLC, alignment); + } + if (returnedList != null) { + iclm.wrapPositionElements(returnedList, returnList); + } + } + SpaceResolver.resolveElementList(returnList); + setFinished(true); + return returnList; + } + + protected int getCurrentDisplayAlign() { + return ((InlineContainer)fobj).getDisplayAlign(); + } + + protected boolean hasMoreContent() { + return !isFinished(); + } + + protected void addAreas(PositionIterator posIter, LayoutContext context) { + iclm.addAreas(posIter, context); + } + + protected void doPhase3(PageBreakingAlgorithm alg, int partCount, + BlockSequence originalList, BlockSequence effectiveList) { + //Defer adding of areas until addAreas is called by the parent LM + this.deferredAlg = alg; + this.deferredOriginalList = originalList; + this.deferredEffectiveList = effectiveList; + } + + protected void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp) { + //nop for bclm + } + + protected LayoutManager getCurrentChildLM() { + return curChildLM; + } + + public void addContainedAreas() { + if (isEmpty()) { + return; + } + //Rendering all parts (not just the first) at once for the case where the parts that + //overflow should be visible. + this.deferredAlg.removeAllPageBreaks(); + this.addAreas(this.deferredAlg, + this.deferredAlg.getPageBreaks().size(), + this.deferredOriginalList, this.deferredEffectiveList); + } + + } +} Index: src/java/org/apache/fop/fo/flow/InlineContainer.java =================================================================== --- src/java/org/apache/fop/fo/flow/InlineContainer.java (revision 651860) +++ src/java/org/apache/fop/fo/flow/InlineContainer.java Thu May 01 13:35:00 CEST 2008 @@ -48,6 +48,7 @@ private CommonBorderPaddingBackground commonBorderPaddingBackground; private CommonMarginInline commonMarginInline; private int clip; + private int displayAlign; private int dominantBaseline; private LengthRangeProperty inlineProgressionDimension; private KeepProperty keepTogether; @@ -57,7 +58,6 @@ private int writingMode; // Unused but valid items, commented out for performance: // private CommonRelativePosition commonRelativePosition; - // private int displayAlign; // private Length height; // private KeepProperty keepWithNext; // private KeepProperty keepWithPrevious; @@ -86,6 +86,7 @@ commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps(); commonMarginInline = pList.getMarginInlineProps(); clip = pList.get(PR_CLIP).getEnum(); + displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum(); dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum(); inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange(); keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep(); @@ -156,6 +157,11 @@ return this.commonMarginInline; } + /** @return the value of the display-align property */ + public int getDisplayAlign() { + return this.displayAlign; + } + /** @return the "dominant-baseline" property */ public int getDominantBaseline() { return dominantBaseline; Index: src/java/org/apache/fop/layoutmgr/AbstractBreaker.java =================================================================== --- src/java/org/apache/fop/layoutmgr/AbstractBreaker.java (revision 651860) +++ src/java/org/apache/fop/layoutmgr/AbstractBreaker.java Thu May 01 14:58:39 CEST 2008 @@ -56,7 +56,16 @@ footnoteLastListIndex = flli; footnoteLastElementIndex = flei; } + + /** + * Accessor for the difference member + * + * @return the difference + */ + public int getDifference() { + return difference; - } + } + } public class BlockSequence extends BlockKnuthSequence { @@ -445,8 +454,7 @@ .listIterator(startElementIndex); KnuthElement firstElement; while (effectiveListIterator.hasNext() - && !(firstElement = (KnuthElement) effectiveListIterator.next()) - .isBox()) { + && !(((KnuthElement)effectiveListIterator.next()).isBox())) { /* if (firstElement.isGlue() && firstElement.getLayoutManager() != null) { // discard the space representd by the glue element @@ -633,7 +641,7 @@ } int averageLineLength = 0; if (accumulatedLineLength > 0 && boxCount > 0) { - averageLineLength = (int) (accumulatedLineLength / boxCount); + averageLineLength = (accumulatedLineLength / boxCount); log.debug("Average line length = " + averageLineLength); if (averageLineLength < greatestMinimumLength) { averageLineLength = greatestMinimumLength; @@ -727,10 +735,8 @@ break; case BlockLevelLayoutManager.LINE_NUMBER_ADJUSTMENT: // potential line number adjustment - lineNumberMaxAdjustment.max += ((KnuthGlue) thisElement) - .getY(); - lineNumberMaxAdjustment.min -= ((KnuthGlue) thisElement) - .getZ(); + lineNumberMaxAdjustment.max += thisElement.getY(); + lineNumberMaxAdjustment.min -= thisElement.getZ(); adjustableLinesList.add(thisElement); break; case BlockLevelLayoutManager.LINE_HEIGHT_ADJUSTMENT: @@ -751,10 +757,8 @@ while (unconfirmedList.size() > 0) { KnuthGlue blockSpace = (KnuthGlue) unconfirmedList .removeFirst(); - spaceMaxAdjustment.max += ((KnuthGlue) blockSpace) - .getY(); - spaceMaxAdjustment.min -= ((KnuthGlue) blockSpace) - .getZ(); + spaceMaxAdjustment.max += blockSpace.getY(); + spaceMaxAdjustment.min -= blockSpace.getZ(); blockSpacesList.add(blockSpace); } } Index: src/java/org/apache/fop/render/AbstractRenderer.java =================================================================== --- src/java/org/apache/fop/render/AbstractRenderer.java (revision 651860) +++ src/java/org/apache/fop/render/AbstractRenderer.java Thu May 01 14:55:06 CEST 2008 @@ -398,7 +398,7 @@ for (int count = 0; count < spans.size(); count++) { span = (Span) spans.get(count); for (int c = 0; c < span.getColumnCount(); c++) { - NormalFlow flow = (NormalFlow) span.getNormalFlow(c); + NormalFlow flow = span.getNormalFlow(c); if (flow != null) { currentBPPosition = saveSpanBPPos; @@ -718,7 +718,6 @@ currentIPPosition += ibp.getBorderAndPaddingWidthStart(); // For inline content the BP position is updated by the enclosing line area int saveBP = currentBPPosition; - currentBPPosition += ibp.getOffset(); renderBlock(ibp.getChildArea()); currentBPPosition = saveBP; } @@ -738,6 +737,8 @@ renderContainer((Container) content); } else if (content instanceof ForeignObject) { renderForeignObject((ForeignObject) content, contpos); + } else if (content instanceof InlineBlockParent) { + renderInlineBlockParent((InlineBlockParent) content); } currentIPPosition += viewport.getAllocIPD(); currentBPPosition = saveBP; Index: src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java =================================================================== --- src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java (revision 651860) +++ src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java Mon Mar 24 12:18:13 CET 2008 @@ -72,7 +72,7 @@ import org.apache.fop.layoutmgr.inline.ContentLayoutManager; import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager; import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager; -import org.apache.fop.layoutmgr.inline.ICLayoutManager; +import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager; import org.apache.fop.layoutmgr.inline.InlineLayoutManager; import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager; import org.apache.fop.layoutmgr.inline.InstreamForeignObjectLM; @@ -218,7 +218,6 @@ public static class Maker { public void make(FONode node, List lms) { // no layout manager - return; } } @@ -283,9 +282,7 @@ public static class InlineContainerLayoutManagerMaker extends Maker { public void make(FONode node, List lms) { - ArrayList childList = new ArrayList(); - super.make(node, childList); - lms.add(new ICLayoutManager((InlineContainer) node, childList)); + lms.add(new InlineContainerLayoutManager((InlineContainer) node)); } } Index: src/java/org/apache/fop/area/inline/Viewport.java =================================================================== --- src/java/org/apache/fop/area/inline/Viewport.java (revision 651860) +++ src/java/org/apache/fop/area/inline/Viewport.java Thu May 01 14:41:07 CEST 2008 @@ -20,6 +20,7 @@ package org.apache.fop.area.inline; import org.apache.fop.area.Area; +import org.apache.fop.area.CTM; import java.io.IOException; import java.awt.geom.Rectangle2D; @@ -38,6 +39,8 @@ private boolean clip = false; // position of the child area relative to this area private Rectangle2D contentPosition; + // transform if rotated + private CTM viewportCTM; /** * Create a new viewport area with the content area. @@ -67,6 +70,27 @@ } /** + * Set the transform of this viewport. + * If the viewport is rotated, this transform will do the work. + * + * @param ctm the transformation + */ + public void setCTM(CTM ctm) { + viewportCTM = ctm; + } + + /** + * Get the transform of this viewport. + * + * @return the transformation of this viewport + * or null if normally stacked without rotation + */ + public CTM getCTM() { + return viewportCTM; + } + + + /** * Set the position and size of the content of this viewport. * * @param cp the position and size to place the content Index: src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java =================================================================== --- src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java (revision 651860) +++ src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java Sun Apr 27 17:48:43 CEST 2008 @@ -31,7 +31,7 @@ import org.apache.fop.layoutmgr.AbstractBreaker.PageBreakPosition; import org.apache.fop.traits.MinOptMax; -class PageBreakingAlgorithm extends BreakingAlgorithm { +public class PageBreakingAlgorithm extends BreakingAlgorithm { /** the logger for the class */ private static Log log = LogFactory.getLog(PageBreakingAlgorithm.class); @@ -313,7 +313,7 @@ int elementIndex) { KnuthPageNode pageNode = (KnuthPageNode) activeNode; int actualWidth = totalWidth - pageNode.totalWidth; - int footnoteSplit; + int footnoteSplit = 0; boolean canDeferOldFootnotes; if (element.isPenalty()) { actualWidth += element.getW();