From 3e04d9245827bc5bcbd320728fb14ec6f7613290 Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Wed, 6 Nov 2013 19:52:38 +0000 Subject: [PATCH] Added support for default alignment of inline-container areas with their parent areas git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_InlineContainer@1539441 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/fop/fo/flow/InlineContainer.java | 8 +- .../fop/layoutmgr/AbstractLayoutManager.java | 28 ++++ .../BlockContainerLayoutManager.java | 62 +------ .../fop/layoutmgr/BlockLayoutManager.java | 62 +------ .../apache/fop/layoutmgr/LayoutManager.java | 17 ++ ...pacedBorderedPaddedBlockLayoutManager.java | 112 +++++++++++++ .../inline/ContentLayoutManager.java | 9 + .../inline/InlineContainerLayoutManager.java | 22 ++- .../layoutmgr/inline/LineLayoutManager.java | 22 ++- .../list/ListBlockLayoutManager.java | 65 +------- .../layoutmgr/list/ListItemLayoutManager.java | 84 +++------- .../layoutmgr/table/TableLayoutManager.java | 68 ++------ .../inline-container_alignment.xml | 154 ++++++++++++++++++ 13 files changed, 417 insertions(+), 296 deletions(-) create mode 100644 src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java create mode 100644 test/layoutengine/standard-testcases/inline-container_alignment.xml diff --git a/src/java/org/apache/fop/fo/flow/InlineContainer.java b/src/java/org/apache/fop/fo/flow/InlineContainer.java index d3a80eb3f..13ea9943a 100644 --- a/src/java/org/apache/fop/fo/flow/InlineContainer.java +++ b/src/java/org/apache/fop/fo/flow/InlineContainer.java @@ -29,7 +29,6 @@ import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; -import org.apache.fop.fo.properties.CommonFont; import org.apache.fop.fo.properties.CommonMarginInline; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.LengthRangeProperty; @@ -59,7 +58,6 @@ public class InlineContainer extends FObj { /** used for FO validation */ private boolean blockItemFound; - private CommonFont commonFont; /** * Creates a new instance. @@ -73,7 +71,6 @@ public class InlineContainer extends FObj { @Override public void bind(PropertyList pList) throws FOPException { super.bind(pList); - commonFont = pList.getFontProps(); // TODO get directly from parent? alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength(); alignmentBaseline = pList.get(PR_ALIGNMENT_BASELINE).getEnum(); baselineShift = pList.get(PR_BASELINE_SHIFT).getLength(); @@ -214,8 +211,9 @@ public class InlineContainer extends FObj { return false; } - public CommonFont getCommonFont() { - return commonFont; + @Override + public boolean generatesReferenceAreas() { + return true; } } diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java index 0285a41e7..2dd18e4ee 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java @@ -342,6 +342,34 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager im && isFinished()); } + public boolean hasLineAreaDescendant() { + if (childLMs == null || childLMs.isEmpty()) { + return false; + } else { + for (LayoutManager childLM : childLMs) { + if (childLM.hasLineAreaDescendant()) { + return true; + } + } + } + return false; + } + + public int getBaselineOffset() { + if (childLMs != null) { + for (LayoutManager childLM : childLMs) { + if (childLM.hasLineAreaDescendant()) { + return childLM.getBaselineOffset(); + } + } + } + throw newNoLineAreaDescendantException(); + } + + protected IllegalStateException newNoLineAreaDescendantException() { + return new IllegalStateException("getBaselineOffset called on an object that has no line-area descendant"); + } + /** * Transfers foreign attributes from the formatting object to the area. * @param targetArea the area to set the attributes on diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java index a23cd28f1..83990797b 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -37,6 +37,7 @@ import org.apache.fop.datatypes.FODimension; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.flow.BlockContainer; import org.apache.fop.fo.properties.CommonAbsolutePosition; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal; /** * LayoutManager for a block-container FO. */ -public class BlockContainerLayoutManager extends BlockStackingLayoutManager implements - ConditionalElementListener, BreakOpportunity { +public class BlockContainerLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** * logging instance @@ -79,13 +80,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl private MinOptMax foBlockSpaceBefore; private MinOptMax foBlockSpaceAfter; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private int horizontalOverflow; private double contentRectOffsetX = 0; private double contentRectOffsetY = 0; @@ -128,6 +122,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl .spaceAfter.getSpace().getOptimum(this).getLength().getValue(this); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getBlockContainerFO().getCommonBorderPaddingBackground(); + } + private void resetSpaces() { this.discardBorderBefore = false; this.discardBorderAfter = false; @@ -993,51 +992,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl return true; } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - /** {@inheritDoc} */ public boolean handleOverflow(int milliPoints) { if (milliPoints > this.horizontalOverflow) { diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index 0fb738aea..4129b65bd 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -32,6 +32,7 @@ import org.apache.fop.area.Block; import org.apache.fop.area.LineArea; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.FONode; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; @@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal; /** * LayoutManager for a block FO. */ -public class BlockLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener, - BreakOpportunity { +public class BlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** logging instance */ private static Log log = LogFactory.getLog(BlockLayoutManager.class); @@ -60,13 +61,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co private int follow = 2000; //private int middleShift = 0; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - /** * Creates a new BlockLayoutManager. * @param inBlock the block FO object to create the layout manager for. @@ -100,6 +94,11 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co .getOptimum(this).getLength().getValue(this); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getBlockFO().getCommonBorderPaddingBackground(); + } + /** {@inheritDoc} */ @Override public List getNextKnuthElements(LayoutContext context, int alignment) { @@ -456,51 +455,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co return true; } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - /** {@inheritDoc} */ @Override public boolean isRestartable() { diff --git a/src/java/org/apache/fop/layoutmgr/LayoutManager.java b/src/java/org/apache/fop/layoutmgr/LayoutManager.java index 985131bf1..107a252b0 100644 --- a/src/java/org/apache/fop/layoutmgr/LayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/LayoutManager.java @@ -177,6 +177,23 @@ public interface LayoutManager extends PercentBaseContext { */ List getChangedKnuthElements(List oldList, int alignment); + /** + * Whether the FO handled by this layout manager had a descendant (including itself) + * that will generate a line-area. + * + * @return {@code true} if a descendant line-area will be generated, {@code false} otherwise + */ + boolean hasLineAreaDescendant(); + + /** + * Returns the position of the dominant-baseline of this FO's first descendant + * line-area, if any. + * + * @return this FO's space-before plus the distance from the before-edge of its + * allocation-rectangle to the dominant-baseline of the first line-area descendant + */ + int getBaselineOffset(); + /** * Returns the IPD of the content area * @return the IPD of the content area diff --git a/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java new file mode 100644 index 000000000..2ac41e96a --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java @@ -0,0 +1,112 @@ +/* + * 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; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.traits.MinOptMax; + +/** + * A block-stacking layout manager for an FO that supports spaces, border and padding. + */ +public abstract class SpacedBorderedPaddedBlockLayoutManager extends BlockStackingLayoutManager + implements ConditionalElementListener { + + private static final Log LOG = LogFactory.getLog(BlockLayoutManager.class); + + protected MinOptMax effSpaceBefore; + + protected MinOptMax effSpaceAfter; + + protected boolean discardBorderBefore; + protected boolean discardBorderAfter; + protected boolean discardPaddingBefore; + protected boolean discardPaddingAfter; + + public SpacedBorderedPaddedBlockLayoutManager(FObj node) { + super(node); + } + + public void notifySpace(RelSide side, MinOptMax effectiveLength) { + if (RelSide.BEFORE == side) { + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Space " + side + ", " + + this.effSpaceBefore + "-> " + effectiveLength); + } + this.effSpaceBefore = effectiveLength; + } else { + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Space " + side + ", " + + this.effSpaceAfter + "-> " + effectiveLength); + } + this.effSpaceAfter = effectiveLength; + } + } + + public void notifyBorder(RelSide side, MinOptMax effectiveLength) { + if (effectiveLength == null) { + if (RelSide.BEFORE == side) { + this.discardBorderBefore = true; + } else { + this.discardBorderAfter = true; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Border " + side + " -> " + effectiveLength); + } + } + + public void notifyPadding(RelSide side, MinOptMax effectiveLength) { + if (effectiveLength == null) { + if (RelSide.BEFORE == side) { + this.discardPaddingBefore = true; + } else { + this.discardPaddingAfter = true; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(this + ": Padding " + side + " -> " + effectiveLength); + } + } + + @Override + public int getBaselineOffset() { + int baselineOffset = super.getBaselineOffset(); + if (effSpaceBefore != null) { + baselineOffset += effSpaceBefore.getOpt(); + } + if (!discardBorderBefore) { + baselineOffset += getCommonBorderPaddingBackground().getBorderBeforeWidth(false); + } + if (!discardPaddingBefore) { + baselineOffset += getCommonBorderPaddingBackground().getPaddingBefore(false, this); + } + return baselineOffset; + } + + /** + * Returns the {@link CommonBorderPaddingBackground} instance from the FO handled by this layout manager. + */ + protected abstract CommonBorderPaddingBackground getCommonBorderPaddingBackground(); + +} diff --git a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java index b3c768987..c067b040f 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java @@ -332,6 +332,15 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager return parentLM.getPSLM(); } + + public boolean hasLineAreaDescendant() { + return true; + } + + public int getBaselineOffset() { + return childLM.getBaselineOffset(); + } + // --------- Property Resolution related functions --------- // /** diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java index 75eb12d5b..9495e2c73 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java @@ -31,9 +31,6 @@ import org.apache.fop.fo.flow.InlineContainer; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.LengthRangeProperty; import org.apache.fop.fo.properties.Property; -import org.apache.fop.fonts.Font; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontTriplet; import org.apache.fop.layoutmgr.AbstractLayoutManager; import org.apache.fop.layoutmgr.AreaAdditionUtil; import org.apache.fop.layoutmgr.BlockLevelEventProducer; @@ -64,6 +61,7 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen private List childElements; private int ipdOverflow; + private AlignmentContext alignmentContext; private InlineViewport currentViewport; private Container referenceArea; @@ -84,7 +82,7 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen childLC.setRefIPD(contentAreaIPD); childElements = getChildKnuthElements(childLC, alignment); // TODO which alignment? determineBPD(); - AlignmentContext alignmentContext = makeAlignmentContext(context); // TODO correct? + alignmentContext = makeAlignmentContext(context); // TODO correct? Position position = new Position(this, 0); KnuthSequence knuthSequence = new InlineKnuthSequence(); knuthSequence.add(new KnuthInlineBox(contentAreaIPD, alignmentContext, position, false)); @@ -121,6 +119,7 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen handleIPDOverflow(); wrapPositions(allChildElements); SpaceResolver.resolveElementList(allChildElements); + SpaceResolver.performConditionalsNotification(allChildElements, 0, allChildElements.size() - 1, -1); // TODO break-before, break-after return allChildElements; } @@ -149,13 +148,13 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen protected AlignmentContext makeAlignmentContext(LayoutContext context) { InlineContainer ic = (InlineContainer) fobj; - FontInfo fi = fobj.getFOEventHandler().getFontInfo(); - FontTriplet[] fontkeys = ic.getCommonFont().getFontState(fi); - Font fs = fi.getFontInstance(fontkeys[0], ic.getCommonFont().fontSize.getValue(this)); - return new AlignmentContext(contentAreaBPD, + AlignmentContext ac = new AlignmentContext(contentAreaBPD, ic.getAlignmentAdjust(), ic.getAlignmentBaseline(), ic.getBaselineShift(), ic.getDominantBaseline(), context.getAlignmentContext()); + int baselineOffset = hasLineAreaDescendant() ? getBaselineOffset() : contentAreaBPD; + ac.resizeLine(contentAreaBPD, baselineOffset); + return ac; } private void handleIPDOverflow() { @@ -183,6 +182,11 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen return ((InlineContainer) fobj).getOverflow() != EN_ERROR_IF_OVERFLOW; } + @Override + public boolean getGeneratesReferenceArea() { + return true; + } + @Override public void addAreas(PositionIterator posIter, LayoutContext context) { Position inlineContainerPosition = null; @@ -196,7 +200,6 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen assert inlineContainerPosition.getLM() == this; } assert inlineContainerPosition != null; - SpaceResolver.performConditionalsNotification(childElements, 0, childElements.size() - 1, -1); KnuthPossPosIter childPosIter = new KnuthPossPosIter(childElements); AreaAdditionUtil.addAreas(this, childPosIter, context); @@ -212,6 +215,7 @@ public class InlineContainerLayoutManager extends AbstractLayoutManager implemen TraitSetter.setProducerID(referenceArea, fobj.getId()); referenceArea.setIPD(contentAreaIPD); currentViewport = new InlineViewport(referenceArea); + currentViewport.setBlockProgressionOffset(alignmentContext.getOffset()); currentViewport.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE); currentViewport.setIPD(getContentAreaIPD()); currentViewport.setBPD(getContentAreaBPD()); diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index b3987a075..25d8c0872 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -160,6 +160,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager private final int follow; private AlignmentContext alignmentContext; + private int baselineOffset = -1; + private List knuthParagraphs; private LineLayoutPossibilities lineLayouts; @@ -556,7 +558,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager private int constantLineHeight = 12000; - /** * Create a new Line Layout Manager. * This is used by the block layout manager to create @@ -939,7 +940,11 @@ public class LineLayoutManager extends InlineStackingLayoutManager while (listIter.hasNext()) { ListElement tempElement; tempElement = (ListElement) listIter.next(); - if (tempElement.getLayoutManager() != this) { + LayoutManager lm = tempElement.getLayoutManager(); + if (baselineOffset < 0 && lm != null && lm.hasLineAreaDescendant()) { + baselineOffset = lm.getBaselineOffset(); + } + if (lm != this) { tempElement.setPosition(notifyPos(new NonLeafPosition(this, tempElement.getPosition()))); } @@ -987,6 +992,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager } startIndex = endIndex + 1; LineBreakPosition lbp = (LineBreakPosition) llPoss.getChosenPosition(i); + if (baselineOffset < 0) { + baselineOffset = lbp.spaceBefore + lbp.baseline; + } returnList.add(new KnuthBlockBox( lbp.lineHeight + lbp.spaceBefore + lbp.spaceAfter, footnoteList, lbp, false)); @@ -1424,6 +1432,16 @@ public class LineLayoutManager extends InlineStackingLayoutManager } } + @Override + public boolean hasLineAreaDescendant() { + return true; + } + + @Override + public int getBaselineOffset() { + return baselineOffset; + } + /** * Add the areas with the break points. * diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java index 61d8a891d..44a9720a4 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java @@ -28,16 +28,15 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.area.Area; import org.apache.fop.area.Block; import org.apache.fop.fo.flow.ListBlock; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutManager; import org.apache.fop.layoutmgr.NonLeafPosition; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -47,21 +46,13 @@ import org.apache.fop.traits.SpaceVal; * A list block contains list items which are stacked within * the list block area.. */ -public class ListBlockLayoutManager extends BlockStackingLayoutManager - implements ConditionalElementListener { +public class ListBlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager { /** logging instance */ private static Log log = LogFactory.getLog(ListBlockLayoutManager.class); private Block curBlockArea; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - /** * Create a new list block layout manager. * @param node list-block to create the layout manager for @@ -70,6 +61,11 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager super(node); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getListBlockFO().getCommonBorderPaddingBackground(); + } + /** * Convenience method. * @return the ListBlock node @@ -277,50 +273,5 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager return getListBlockFO().getKeepWithNext(); } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - } diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java index 083e4ee1b..344f6722b 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java @@ -32,12 +32,11 @@ import org.apache.fop.area.Block; import org.apache.fop.fo.flow.ListItem; import org.apache.fop.fo.flow.ListItemBody; import org.apache.fop.fo.flow.ListItemLabel; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.BreakOpportunity; import org.apache.fop.layoutmgr.BreakOpportunityHelper; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.ElementListObserver; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager; @@ -53,10 +52,9 @@ import org.apache.fop.layoutmgr.ListElement; import org.apache.fop.layoutmgr.NonLeafPosition; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; import org.apache.fop.layoutmgr.SpaceResolver; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; -import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; import org.apache.fop.util.BreakUtil; @@ -64,8 +62,8 @@ import org.apache.fop.util.BreakUtil; * LayoutManager for a list-item FO. * The list item contains a list item label and a list item body. */ -public class ListItemLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener, - BreakOpportunity { +public class ListItemLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** logging instance */ private static Log log = LogFactory.getLog(ListItemLayoutManager.class); @@ -78,13 +76,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements private List labelList = null; private List bodyList = null; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private Keep keepWithNextPendingOnLabel; private Keep keepWithNextPendingOnBody; @@ -145,6 +136,11 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements setBody(node.getBody()); } + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getListItemFO().getCommonBorderPaddingBackground(); + } + /** * Convenience method. * @return the ListBlock node @@ -475,6 +471,23 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements return returnedList; } + + @Override + public boolean hasLineAreaDescendant() { + return label.hasLineAreaDescendant() || body.hasLineAreaDescendant(); + } + + @Override + public int getBaselineOffset() { + if (label.hasLineAreaDescendant()) { + return label.getBaselineOffset(); + } else if (body.hasLineAreaDescendant()) { + return body.getBaselineOffset(); + } else { + throw newNoLineAreaDescendantException(); + } + } + /** * Add the areas for the break points. * @@ -652,51 +665,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements return getListItemFO().getKeepWithNext(); } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - /** {@inheritDoc} */ @Override public void reset() { diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java index 7f1754064..afb6547c0 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java @@ -39,12 +39,11 @@ import org.apache.fop.fo.flow.Markers; import org.apache.fop.fo.flow.RetrieveTableMarker; import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TableColumn; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.layoutmgr.BlockLevelEventProducer; -import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.BreakOpportunity; -import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.LayoutContext; @@ -52,7 +51,7 @@ import org.apache.fop.layoutmgr.LeafPosition; import org.apache.fop.layoutmgr.ListElement; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.RelSide; +import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager; import org.apache.fop.layoutmgr.TraitSetter; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; @@ -66,8 +65,8 @@ import org.apache.fop.util.BreakUtil; * The table then creates areas for the columns, bodies and rows * the render background. */ -public class TableLayoutManager extends BlockStackingLayoutManager - implements ConditionalElementListener, BreakOpportunity { +public class TableLayoutManager extends SpacedBorderedPaddedBlockLayoutManager + implements BreakOpportunity { /** * logging instance @@ -82,13 +81,6 @@ public class TableLayoutManager extends BlockStackingLayoutManager private double tableUnit; private boolean autoLayout = true; - private boolean discardBorderBefore; - private boolean discardBorderAfter; - private boolean discardPaddingBefore; - private boolean discardPaddingAfter; - private MinOptMax effSpaceBefore; - private MinOptMax effSpaceAfter; - private int halfBorderSeparationBPD; private int halfBorderSeparationIPD; @@ -132,6 +124,13 @@ public class TableLayoutManager extends BlockStackingLayoutManager this.columns = new ColumnSetup(node); } + + @Override + protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() { + return getTable().getCommonBorderPaddingBackground(); + } + + /** @return the table FO */ public Table getTable() { return (Table)this.fobj; @@ -521,51 +520,6 @@ public class TableLayoutManager extends BlockStackingLayoutManager } } - /** {@inheritDoc} */ - public void notifySpace(RelSide side, MinOptMax effectiveLength) { - if (RelSide.BEFORE == side) { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceBefore + "-> " + effectiveLength); - } - this.effSpaceBefore = effectiveLength; - } else { - if (log.isDebugEnabled()) { - log.debug(this + ": Space " + side + ", " - + this.effSpaceAfter + "-> " + effectiveLength); - } - this.effSpaceAfter = effectiveLength; - } - } - - /** {@inheritDoc} */ - public void notifyBorder(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardBorderBefore = true; - } else { - this.discardBorderAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Border " + side + " -> " + effectiveLength); - } - } - - /** {@inheritDoc} */ - public void notifyPadding(RelSide side, MinOptMax effectiveLength) { - if (effectiveLength == null) { - if (RelSide.BEFORE == side) { - this.discardPaddingBefore = true; - } else { - this.discardPaddingAfter = true; - } - } - if (log.isDebugEnabled()) { - log.debug(this + ": Padding " + side + " -> " + effectiveLength); - } - } - /** {@inheritDoc} */ public void reset() { super.reset(); diff --git a/test/layoutengine/standard-testcases/inline-container_alignment.xml b/test/layoutengine/standard-testcases/inline-container_alignment.xml new file mode 100644 index 000000000..153d9a9c4 --- /dev/null +++ b/test/layoutengine/standard-testcases/inline-container_alignment.xml @@ -0,0 +1,154 @@ + + + + + +

+ Checks that the inline-container is properly aligned with the parent area. +

+
+ + + + + + + + + + By default the alignment is with the baseline of the first descendant + line-area. + The line before. The line before. Before: + Inside the inline-container. + After the inline-container. + + + + + + The line before. The line before. Before: + + + Inside the + inline-container. + + + After the inline-container. + + + + + + This inline-container has no line-area descendant. The after edge of its + allocation rectangle should be aligned with the baseline. + The line before. The line before. Before: + + After the inline-container. + + + + + + The first line-area descendant is in fo:list-item-body. + The line before. The line before. Before: + + + + + + + + List item + + + + + After the inline-container. + + + + + + This inline-container contains a block that contains an inline that contains a + block. + The line before. The line before. Before: + inline + After the inline-container. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-- 2.39.5