From 1238542766fed0042d79e9b86cb6d3116799e701 Mon Sep 17 00:00:00 2001 From: Luca Furini Date: Tue, 2 Aug 2005 09:05:25 +0000 Subject: Adjusting verticals spaces (coming from space-before and space-after properties) in order to fill the region, whenever possible git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@226973 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/layoutmgr/AbstractBreaker.java | 11 +++- .../org/apache/fop/layoutmgr/AreaAdditionUtil.java | 2 + .../apache/fop/layoutmgr/BlockLayoutManager.java | 70 ++++++++++------------ .../fop/layoutmgr/BlockStackingLayoutManager.java | 21 +++++-- .../fop/layoutmgr/PageBreakingAlgorithm.java | 24 +++++++- .../fop/layoutmgr/list/ListBlockLayoutManager.java | 22 ++++--- .../list/ListItemContentLayoutManager.java | 2 + .../fop/layoutmgr/list/ListItemLayoutManager.java | 16 ++--- 8 files changed, 107 insertions(+), 61 deletions(-) (limited to 'src/java/org') diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java index df753a1a1..d5ba5513f 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java @@ -314,9 +314,16 @@ public abstract class AbstractBreaker { // at the beginning of the line effectiveListIterator = effectiveList .listIterator(startElementIndex); + KnuthElement firstElement; while (effectiveListIterator.hasNext() - && !((KnuthElement) effectiveListIterator.next()) + && !(firstElement = (KnuthElement) effectiveListIterator.next()) .isBox()) { + if (firstElement.isGlue()) { + // discard the space representd by the glue element + ((BlockLevelLayoutManager) firstElement + .getLayoutManager()) + .discardSpace((KnuthGlue) firstElement); + } startElementIndex++; } @@ -324,6 +331,8 @@ public abstract class AbstractBreaker { log.debug(" addAreas from " + startElementIndex + " to " + endElementIndex); childLC = new LayoutContext(0); + // set the space adjustment ratio + childLC.setSpaceAdjust(pbp.bpdAdjust); // add space before if display-align is center or bottom // add space after if display-align is distribute and // this is not the last page diff --git a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java index 13198cae8..44ad1496b 100644 --- a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java +++ b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java @@ -80,6 +80,8 @@ public class AreaAdditionUtil { // Add the block areas to Area lc.setFlags(LayoutContext.FIRST_AREA, childLM == firstLM); lc.setFlags(LayoutContext.LAST_AREA, childLM == lastLM); + // set the space adjustment ratio + lc.setSpaceAdjust(layoutContext.getSpaceAdjust()); // set space before for the first LM, in order to implement // display-align = center or after lc.setSpaceBefore((childLM == firstLM ? layoutContext.getSpaceBefore() : 0)); diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index 83be99b71..636055cb5 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -41,17 +41,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { /** Iterator over the child layout managers. */ protected ListIterator proxyLMiter; - /* holds the (one-time use) fo:block space-before - and -after properties. Large fo:blocks are split - into multiple Area.Blocks to accomodate the subsequent - regions (pages) they are placed on. space-before - is applied at the beginning of the first - Block and space-after at the end of the last Block - used in rendering the fo:block. - */ - private MinOptMax foBlockSpaceBefore = null; - private MinOptMax foBlockSpaceAfter = null; - private int lead = 12000; private int lineHeight = 14000; private int follow = 2000; @@ -79,17 +68,18 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { } private void initialize() { - foBlockSpaceBefore = new SpaceVal(getBlockFO().getCommonMarginBlock().spaceBefore).getSpace(); -/*LF*/ bpUnit = 0; //layoutProps.blockProgressionUnit; -/*LF*/ if (bpUnit == 0) { -/*LF*/ // use optimum space values -/*LF*/ adjustedSpaceBefore = getBlockFO().getCommonMarginBlock().spaceBefore.getSpace().getOptimum().getLength().getValue(); -/*LF*/ adjustedSpaceAfter = getBlockFO().getCommonMarginBlock().spaceAfter.getSpace().getOptimum().getLength().getValue(); -/*LF*/ } else { -/*LF*/ // use minimum space values -/*LF*/ adjustedSpaceBefore = getBlockFO().getCommonMarginBlock().spaceBefore.getSpace().getMinimum().getLength().getValue(); -/*LF*/ adjustedSpaceAfter = getBlockFO().getCommonMarginBlock().spaceAfter.getSpace().getMinimum().getLength().getValue(); -/*LF*/ } + foSpaceBefore = new SpaceVal(getBlockFO().getCommonMarginBlock().spaceBefore).getSpace(); + foSpaceAfter = new SpaceVal(getBlockFO().getCommonMarginBlock().spaceAfter).getSpace(); + bpUnit = 0; // non-standard extension + if (bpUnit == 0) { + // use optimum space values + adjustedSpaceBefore = getBlockFO().getCommonMarginBlock().spaceBefore.getSpace().getOptimum().getLength().getValue(); + adjustedSpaceAfter = getBlockFO().getCommonMarginBlock().spaceAfter.getSpace().getOptimum().getLength().getValue(); + } else { + // use minimum space values + adjustedSpaceBefore = getBlockFO().getCommonMarginBlock().spaceBefore.getSpace().getMinimum().getLength().getValue(); + adjustedSpaceAfter = getBlockFO().getCommonMarginBlock().spaceAfter.getSpace().getMinimum().getLength().getValue(); + } } /** @@ -203,7 +193,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { getParentArea(null); // if this will create the first block area in a page - // and display-align is bottom or center, add space before + // and display-align is after or center, add space before if (layoutContext.getSpaceBefore() > 0) { addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore())); } @@ -322,23 +312,23 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { // add space before and / or after the paragraph // to reach a multiple of bpUnit if (bSpaceBefore && bSpaceAfter) { - foBlockSpaceBefore = new SpaceVal(getBlockFO().getCommonMarginBlock().spaceBefore).getSpace(); - foBlockSpaceAfter = new SpaceVal(getBlockFO().getCommonMarginBlock().spaceAfter).getSpace(); + foSpaceBefore = new SpaceVal(getBlockFO().getCommonMarginBlock().spaceBefore).getSpace(); + foSpaceAfter = new SpaceVal(getBlockFO().getCommonMarginBlock().spaceAfter).getSpace(); adjustedSpaceBefore = (neededUnits(splitLength - + foBlockSpaceBefore.min - + foBlockSpaceAfter.min) + + foSpaceBefore.min + + foSpaceAfter.min) * bpUnit - splitLength) / 2; adjustedSpaceAfter = neededUnits(splitLength - + foBlockSpaceBefore.min - + foBlockSpaceAfter.min) + + foSpaceBefore.min + + foSpaceAfter.min) * bpUnit - splitLength - adjustedSpaceBefore; } else if (bSpaceBefore) { adjustedSpaceBefore = neededUnits(splitLength - + foBlockSpaceBefore.min) + + foSpaceBefore.min) * bpUnit - splitLength; } else { adjustedSpaceAfter = neededUnits(splitLength - + foBlockSpaceAfter.min) + + foSpaceAfter.min) * bpUnit - splitLength; } //System.out.println("spazio prima = " + adjustedSpaceBefore @@ -347,12 +337,15 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { childPosIter = new KnuthPossPosIter(splitList, 0, splitList .size()); //} - } + } // if adjusted space before - if (bSpaceBefore) { - addBlockSpacing(0, new MinOptMax(adjustedSpaceBefore)); - } + double adjust = layoutContext.getSpaceAdjust(); + addBlockSpacing(adjust, foSpaceBefore); + foSpaceBefore = null; + //if (bSpaceBefore) { + // addBlockSpacing(0, new MinOptMax(adjustedSpaceBefore)); + //} while ((childLM = childPosIter.getNextChildLM()) != null) { // set last area flag @@ -372,9 +365,10 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { flush(); // if adjusted space after - if (bSpaceAfter) { - addBlockSpacing(0, new MinOptMax(adjustedSpaceAfter)); - } + addBlockSpacing(adjust, foSpaceAfter); + //if (bSpaceAfter) { + // addBlockSpacing(0, new MinOptMax(adjustedSpaceAfter)); + //} curBlockArea = null; } diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index 9179e71ce..d1f656b58 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -62,7 +62,18 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager protected boolean bSpaceBeforeServed = false; /** Reference IPD available */ protected int referenceIPD = 0; - + + /* holds the (one-time use) fo:block space-before + and -after properties. Large fo:blocks are split + into multiple Area.Blocks to accomodate the subsequent + regions (pages) they are placed on. space-before + is applied at the beginning of the first + Block and space-after at the end of the last Block + used in rendering the fo:block. + */ + protected MinOptMax foSpaceBefore = null; + protected MinOptMax foSpaceAfter = null; + private int lastGeneratedPosition = -1; private int smallestPosNumberChecked = Integer.MAX_VALUE; @@ -506,22 +517,24 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } public void discardSpace(KnuthGlue spaceGlue) { -/*LF*/ //System.out.println(" BLM.discardSpace> " + spaceGlue.getPosition().getClass().getName()); + //System.out.println(" BLM.discardSpace> " + spaceGlue.getPosition().getClass().getName()); Position innerPosition = ((NonLeafPosition) spaceGlue.getPosition()).getPosition(); -/*LF*/ if (innerPosition == null || innerPosition.getLM() == this) { + if (innerPosition == null || innerPosition.getLM() == this) { // if this block has block-progression-unit > 0, innerPosition can be // a MappingPosition // spaceGlue represents space before or space after of this block if (spaceGlue.getAdjustmentClass() == SPACE_BEFORE_ADJUSTMENT) { // space-before must be discarded adjustedSpaceBefore = 0; + foSpaceBefore = new MinOptMax(0); } else { // space-after must be discarded adjustedSpaceAfter = 0; + foSpaceAfter = new MinOptMax(0); //TODO Why are both cases handled in the same way? } -/*LF*/ } else { + } else { // this element was not created by this BlockLM NonLeafPosition savedPos = (NonLeafPosition)spaceGlue.getPosition(); spaceGlue.setPosition(innerPosition); diff --git a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java index a303630e7..f0cd2c357 100644 --- a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java +++ b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java @@ -700,9 +700,27 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { //int difference = (bestActiveNode.line < total) ? bestActiveNode.difference : bestActiveNode.difference + fillerMinWidth; int difference = bestActiveNode.difference; int blockAlignment = (bestActiveNode.line < total) ? alignment : alignmentLast; - double ratio = (blockAlignment == org.apache.fop.fo.Constants.EN_JUSTIFY - || bestActiveNode.adjustRatio < 0) ? bestActiveNode.adjustRatio : 0; - + // it is always allowed to adjust space, so the ratio must be set regardless of + // the value of the property display-align; the ratio must be <= 1 + double ratio = bestActiveNode.adjustRatio; + if (ratio < 0) { + // page break with a negative difference: + // spaces always have enough shrink + difference = 0; + } else if (ratio <= 1 && bestActiveNode.line < total) { + // not-last page break with a positive difference smaller than the available stretch: + // spaces can stretch to fill the whole difference + difference = 0; + } else if (ratio > 1) { + // not-last page with a positive difference greater than the available stretch + // spaces can stretch to fill the difference only partially + ratio = 1; + difference -= bestActiveNode.availableStretch; + } else { + // last page with a positive difference: + // spaces do not need to stretch + ratio = 0; + } // compute the indexes of the first footnote list and the first element in that list int firstListIndex = ((KnuthPageNode) bestActiveNode.previous).footnoteListIndex; int firstElementIndex = ((KnuthPageNode) bestActiveNode.previous).footnoteElementIndex; diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java index 8536c062e..4d97a4a77 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java @@ -45,8 +45,6 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager { private Block curBlockArea; //TODO space-before|after: handle space-resolution rules - private MinOptMax spaceBefore; - private MinOptMax spaceAfter; private static class StackingIter extends PositionIterator { StackingIter(Iterator parentIter) { @@ -89,8 +87,8 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager { } private void initialize() { - spaceBefore = new SpaceVal(getListBlockFO().getCommonMarginBlock().spaceBefore).getSpace(); - spaceAfter = new SpaceVal(getListBlockFO().getCommonMarginBlock().spaceAfter).getSpace(); + foSpaceBefore = new SpaceVal(getListBlockFO().getCommonMarginBlock().spaceBefore).getSpace(); + foSpaceAfter = new SpaceVal(getListBlockFO().getCommonMarginBlock().spaceAfter).getSpace(); } private int getIPIndents() { @@ -116,11 +114,17 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager { public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { getParentArea(null); - + + // if this will create the first block area in a page + // and display-align is after or center, add space before + if (layoutContext.getSpaceBefore() > 0) { + addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore())); + } + // if adjusted space before double adjust = layoutContext.getSpaceAdjust(); - addBlockSpacing(adjust, spaceBefore); - spaceBefore = null; + addBlockSpacing(adjust, foSpaceBefore); + foSpaceBefore = null; getPSLM().addIDToPage(getListBlockFO().getId()); @@ -164,6 +168,8 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager { StackingIter childPosIter = new StackingIter(positionList.listIterator()); while ((childLM = childPosIter.getNextChildLM()) != null) { // Add the block areas to Area + // set the space adjustment ratio + lc.setSpaceAdjust(layoutContext.getSpaceAdjust()); lc.setFlags(LayoutContext.FIRST_AREA, childLM == firstLM); lc.setFlags(LayoutContext.LAST_AREA, childLM == lastLM); lc.setStackLimit(layoutContext.getStackLimit()); @@ -177,7 +183,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager { flush(); // if adjusted space after - addBlockSpacing(adjust, spaceAfter); + addBlockSpacing(adjust, foSpaceAfter); curBlockArea = null; } diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java index d86d06b31..a9bf81bbe 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java @@ -155,6 +155,8 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager { // Add the block areas to Area lc.setFlags(LayoutContext.FIRST_AREA, childLM == firstLM); lc.setFlags(LayoutContext.LAST_AREA, childLM == lastLM); + // set the space adjustment ratio + lc.setSpaceAdjust(layoutContext.getSpaceAdjust()); lc.setStackLimit(layoutContext.getStackLimit()); childLM.addAreas(childPosIter, lc); } diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java index 7092078cc..e0ea656dd 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java @@ -59,8 +59,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager { private int listItemHeight; //TODO space-before|after: handle space-resolution rules - private MinOptMax spaceBefore; - private MinOptMax spaceAfter; private boolean keepWithNextPendingOnLabel; private boolean keepWithNextPendingOnBody; @@ -154,8 +152,8 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager { } private void initialize() { - spaceBefore = new SpaceVal(getListItemFO().getCommonMarginBlock().spaceBefore).getSpace(); - spaceAfter = new SpaceVal(getListItemFO().getCommonMarginBlock().spaceAfter).getSpace(); + foSpaceBefore = new SpaceVal(getListItemFO().getCommonMarginBlock().spaceBefore).getSpace(); + foSpaceAfter = new SpaceVal(getListItemFO().getCommonMarginBlock().spaceAfter).getSpace(); } private int getIPIndents() { @@ -426,8 +424,8 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager { // if adjusted space before double adjust = layoutContext.getSpaceAdjust(); - addBlockSpacing(adjust, spaceBefore); - spaceBefore = null; + addBlockSpacing(adjust, foSpaceBefore); + foSpaceBefore = null; getPSLM().addIDToPage(getListItemFO().getId()); @@ -469,6 +467,8 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager { labelFirstIndex, labelLastIndex + 1); lc.setFlags(LayoutContext.FIRST_AREA, layoutContext.isFirstArea()); lc.setFlags(LayoutContext.LAST_AREA, layoutContext.isLastArea()); + // set the space adjustment ratio + lc.setSpaceAdjust(layoutContext.getSpaceAdjust()); // TO DO: use the right stack limit for the label lc.setStackLimit(layoutContext.getStackLimit()); label.addAreas(labelIter, lc); @@ -488,6 +488,8 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager { bodyFirstIndex, bodyLastIndex + 1); lc.setFlags(LayoutContext.FIRST_AREA, layoutContext.isFirstArea()); lc.setFlags(LayoutContext.LAST_AREA, layoutContext.isLastArea()); + // set the space adjustment ratio + lc.setSpaceAdjust(layoutContext.getSpaceAdjust()); // TO DO: use the right stack limit for the body lc.setStackLimit(layoutContext.getStackLimit()); body.addAreas(bodyIter, lc); @@ -505,7 +507,7 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager { flush(); // if adjusted space after - addBlockSpacing(adjust, spaceAfter); + addBlockSpacing(adjust, foSpaceAfter); curBlockArea = null; } -- cgit v1.2.3