From c55b4c72556bd66076530f4a9bff83b9d4727aca Mon Sep 17 00:00:00 2001 From: Keiron Liddle Date: Sun, 3 Nov 2002 16:29:58 +0000 Subject: [PATCH] initial implementation of lists git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195406 13f79535-47bb-0310-9956-ffa450edef68 --- src/org/apache/fop/fo/flow/ListBlock.java | 7 + src/org/apache/fop/fo/flow/ListItem.java | 77 +++-- src/org/apache/fop/fo/flow/ListItemBody.java | 6 + src/org/apache/fop/fo/flow/ListItemLabel.java | 8 +- src/org/apache/fop/layoutmgr/list/Item.java | 238 +++++++++++++++ .../list/ListBlockLayoutManager.java | 229 ++++++++++++++ .../layoutmgr/list/ListItemLayoutManager.java | 284 ++++++++++++++++++ src/org/apache/fop/layoutmgr/table/Row.java | 10 +- 8 files changed, 826 insertions(+), 33 deletions(-) create mode 100644 src/org/apache/fop/layoutmgr/list/Item.java create mode 100644 src/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java create mode 100644 src/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java diff --git a/src/org/apache/fop/fo/flow/ListBlock.java b/src/org/apache/fop/fo/flow/ListBlock.java index 56fb2f49d..5bb9e7fed 100644 --- a/src/org/apache/fop/fo/flow/ListBlock.java +++ b/src/org/apache/fop/fo/flow/ListBlock.java @@ -14,9 +14,11 @@ import org.apache.fop.datatypes.*; import org.apache.fop.layout.*; import org.apache.fop.layout.FontState; import org.apache.fop.apps.FOPException; +import org.apache.fop.layoutmgr.list.ListBlockLayoutManager; // Java import java.util.Iterator; +import java.util.List; public class ListBlock extends FObj { @@ -36,6 +38,11 @@ public class ListBlock extends FObj { super(parent); } + public void addLayoutManager(List list) { + ListBlockLayoutManager blm = new ListBlockLayoutManager(this); + list.add(blm); + } + public void setup() throws FOPException { // Common Accessibility Properties diff --git a/src/org/apache/fop/fo/flow/ListItem.java b/src/org/apache/fop/fo/flow/ListItem.java index 01304bced..9c258c79e 100644 --- a/src/org/apache/fop/fo/flow/ListItem.java +++ b/src/org/apache/fop/fo/flow/ListItem.java @@ -13,11 +13,15 @@ import org.apache.fop.fo.properties.*; import org.apache.fop.layout.*; import org.apache.fop.layout.FontState; import org.apache.fop.apps.FOPException; +import org.apache.fop.layoutmgr.list.ListItemLayoutManager; // Java import java.util.Iterator; +import java.util.List; public class ListItem extends FObj { + ListItemLabel label = null; + ListItemBody body = null; int align; int alignLast; @@ -33,43 +37,64 @@ public class ListItem extends FObj { super(parent); } + public void addLayoutManager(List list) { + if(label != null && body != null) { + ListItemLayoutManager blm = new ListItemLayoutManager(this); + blm.setLabel(label.getItemLayoutManager()); + blm.setBody(body.getItemLayoutManager()); + list.add(blm); + } + } + public void setup() { - // Common Accessibility Properties - AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); - // Common Aural Properties - AuralProps mAurProps = propMgr.getAuralProps(); + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); - // Common Border, Padding, and Background Properties - BorderAndPadding bap = propMgr.getBorderAndPadding(); - BackgroundProps bProps = propMgr.getBackgroundProps(); + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); - // Common Margin Properties-Block - MarginProps mProps = propMgr.getMarginProps(); + // Common Margin Properties-Block + MarginProps mProps = propMgr.getMarginProps(); - // Common Relative Position Properties - RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); - // this.properties.get("break-after"); - // this.properties.get("break-before"); - setupID(); - // this.properties.get("keep-together"); - // this.properties.get("keep-with-next"); - // this.properties.get("keep-with-previous"); - // this.properties.get("relative-align"); + // this.properties.get("break-after"); + // this.properties.get("break-before"); + setupID(); + // this.properties.get("keep-together"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("relative-align"); - this.align = this.properties.get("text-align").getEnum(); - this.alignLast = this.properties.get("text-align-last").getEnum(); - this.lineHeight = - this.properties.get("line-height").getLength().mvalue(); - this.spaceBefore = - this.properties.get("space-before.optimum").getLength().mvalue(); - this.spaceAfter = - this.properties.get("space-after.optimum").getLength().mvalue(); + this.align = this.properties.get("text-align").getEnum(); + this.alignLast = this.properties.get("text-align-last").getEnum(); + this.lineHeight = + this.properties.get("line-height").getLength().mvalue(); + this.spaceBefore = + this.properties.get("space-before.optimum").getLength().mvalue(); + this.spaceAfter = + this.properties.get("space-after.optimum").getLength().mvalue(); } + public void addChild(FONode child) { + if ("fo:list-item-label".equals(child.getName())) { + label = (ListItemLabel)child; + } else if ("fo:list-item-body".equals(child.getName())) { + body = (ListItemBody)child; + } else if("fo:marker".equals(child.getName())) { + // marker + } else { + // error + } + } + public boolean generatesInlineAreas() { return false; } diff --git a/src/org/apache/fop/fo/flow/ListItemBody.java b/src/org/apache/fop/fo/flow/ListItemBody.java index d27046e0b..f201aa9b3 100644 --- a/src/org/apache/fop/fo/flow/ListItemBody.java +++ b/src/org/apache/fop/fo/flow/ListItemBody.java @@ -13,6 +13,7 @@ import org.apache.fop.fo.properties.*; import org.apache.fop.layout.*; import org.apache.fop.layout.FontState; import org.apache.fop.apps.FOPException; +import org.apache.fop.layoutmgr.list.Item; // Java import java.util.Iterator; @@ -23,6 +24,11 @@ public class ListItemBody extends FObj { super(parent); } + public Item getItemLayoutManager() { + Item item = new Item(this); + return item; + } + public void setup() { // Common Accessibility Properties diff --git a/src/org/apache/fop/fo/flow/ListItemLabel.java b/src/org/apache/fop/fo/flow/ListItemLabel.java index da2ef5d30..3115b3406 100644 --- a/src/org/apache/fop/fo/flow/ListItemLabel.java +++ b/src/org/apache/fop/fo/flow/ListItemLabel.java @@ -13,6 +13,7 @@ import org.apache.fop.fo.properties.*; import org.apache.fop.layout.*; import org.apache.fop.layout.FontState; import org.apache.fop.apps.FOPException; +import org.apache.fop.layoutmgr.list.Item; // Java import java.util.Enumeration; @@ -23,7 +24,12 @@ public class ListItemLabel extends FObj { super(parent); } - public void setup() throws FOPException { + public Item getItemLayoutManager() { + Item itemLabel = new Item(this); + return itemLabel; + } + + public void setup() { // Common Accessibility Properties AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); diff --git a/src/org/apache/fop/layoutmgr/list/Item.java b/src/org/apache/fop/layoutmgr/list/Item.java new file mode 100644 index 000000000..4372757f4 --- /dev/null +++ b/src/org/apache/fop/layoutmgr/list/Item.java @@ -0,0 +1,238 @@ +/* + * $Id$ + * Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.layoutmgr.list; + +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.fo.FObj; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.area.MinOptMax; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +import java.util.ArrayList; + +/** + * LayoutManager for a table-cell FO. + * A cell contains blocks. These blocks fill the cell. + */ +public class Item extends BlockStackingLayoutManager { + + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + private Block curBlockArea; + + private ArrayList childBreaks = new ArrayList(); + + private int xoffset; + private int yoffset; + private int itemIPD; + + /** + * Create a new Cell layout manager. + * @param fobj the formatting object for the cell + */ + public Item(FObj fobj) { + super(fobj); + } + + protected void initProperties(PropertyManager propMgr) { + borderProps = propMgr.getBorderAndPadding(); + backgroundProps = propMgr.getBackgroundProps(); + } + + /** + * Get the next break possibility for this cell. + * A cell contains blocks so there are breaks around the blocks + * and inside the blocks. + * + * @param context the layout context + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + LayoutManager curLM; // currently active LM + + MinOptMax stackSize = new MinOptMax(); + // if starting add space before + // stackSize.add(spaceBefore); + BreakPoss lastPos = null; + + itemIPD = context.getRefIPD(); + + while ((curLM = getChildLM()) != null) { + if(curLM.generatesInlineAreas()) { + // error + curLM.setFinished(true); + continue; + } + // Set up a LayoutContext + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit(MinOptMax.subtract(context.getStackLimit(), + stackSize)); + childLC.setRefIPD(ipd); + + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + stackSize.add(bp.getStackingSize()); + if (stackSize.min > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + reset(lastPos.getPosition()); + } else { + curLM.resetPosition(null); + } + break; + } + lastPos = bp; + childBreaks.add(bp); + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, childBreaks.size() - 1)); + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + setFinished(true); + return null; + } + + /** + * Set the y offset of this cell. + * This offset is used to set the absolute position of the cell. + * + * @param off the y direction offset + */ + public void setYOffset(int off) { + yoffset = off; + } + + /** + * Set the x offset of this cell. + * This offset is used to set the absolute position of the cell. + * + * @param off the x offset + */ + public void setXOffset(int off) { + xoffset = off; + } + + /** + * Add the areas for the break points. + * The cell contains block stacking layout managers + * that add block areas. + * + * @param parentIter the iterator of the break positions + * @param layoutContext the layout context for adding the areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + LayoutManager childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(childBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + } + } + + if(borderProps != null) { + addBorders(curBlockArea, borderProps); + } + if(backgroundProps != null) { + addBackground(curBlockArea, backgroundProps); + } + + flush(); + + childBreaks.clear(); + curBlockArea = null; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area to get the parent for + * @return the parent area + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + curBlockArea = new Block(); + curBlockArea.setPositioning(Block.ABSOLUTE); + // set position + curBlockArea.setXOffset(xoffset); + curBlockArea.setYOffset(yoffset); + curBlockArea.setWidth(itemIPD); + //curBlockArea.setHeight(); + + // Set up dimensions + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + /** + * Add the child to the cell block area. + * + * @param childArea the child to add to the cell + * @return unused + */ + public boolean addChild(Area childArea) { + if (curBlockArea != null) { + curBlockArea.addBlock((Block) childArea); + return false; + } + return false; + } + + /** + * Reset the position of the layout. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } + } +} + diff --git a/src/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java new file mode 100644 index 000000000..fd15515f8 --- /dev/null +++ b/src/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java @@ -0,0 +1,229 @@ +/* + * $Id$ + * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.layoutmgr.list; + +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.fo.FObj; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.area.MinOptMax; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for a table FO. + * A table consists of columns, table header, table footer and multiple + * table bodies. + * The header, footer and body add the areas created from the table cells. + * The table then creates areas for the columns, bodies and rows + * the render background. + */ +public class ListBlockLayoutManager extends BlockStackingLayoutManager { + private List columns = null; + + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + private Block curBlockArea; + + private ArrayList bodyBreaks = new ArrayList(); + + private class SectionPosition extends LeafPosition { + protected List list; + protected SectionPosition(LayoutManager lm, int pos, List l) { + super(lm, pos); + list = l; + } + } + + /** + * Create a new table layout manager. + * + * @param fobj the table formatting object + */ + public ListBlockLayoutManager(FObj fobj) { + super(fobj); + } + + protected void initProperties(PropertyManager propMgr) { + borderProps = propMgr.getBorderAndPadding(); + backgroundProps = propMgr.getBackgroundProps(); + } + + /** + * Get the next break possibility. + * The break possibility depends on the height of the header and footer + * and possible breaks inside the table body. + * + * @param context the layout context for finding breaks + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + ListItemLayoutManager curLM; // currently active LM + + MinOptMax stackSize = new MinOptMax(); + // if starting add space before + // stackSize.add(spaceBefore); + BreakPoss lastPos = null; + + while ((curLM = (ListItemLayoutManager)getChildLM()) != null) { + // Make break positions + // Set up a LayoutContext + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit( + MinOptMax.subtract(context.getStackLimit(), + stackSize)); + childLC.setRefIPD(ipd); + + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + stackSize.add(bp.getStackingSize()); + if (stackSize.opt > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + reset(lastPos.getPosition()); + } else { + curLM.resetPosition(null); + } + break; + } + lastPos = bp; + bodyBreaks.add(bp); + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, bodyBreaks.size() - 1)); + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + setFinished(true); + return null; + } + + /** + * The table area is a reference area that contains areas for + * columns, bodies, rows and the contents are in cells. + * + * @param parentIter the position iterator + * @param layoutContext the layout context for adding areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + // add column, body then row areas + + // add table header areas + + int tableHeight = 0; + + ListItemLayoutManager childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(bodyBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = (ListItemLayoutManager)breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + tableHeight += childLM.getListItemHeight(); + } + } + + // add footer areas + + curBlockArea.setHeight(tableHeight); + + if(borderProps != null) { + addBorders(curBlockArea, borderProps); + } + if(backgroundProps != null) { + addBackground(curBlockArea, backgroundProps); + } + + flush(); + + bodyBreaks.clear(); + curBlockArea = null; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area + * @return the parent area of the child + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + curBlockArea = new Block(); + // Set up dimensions + // Must get dimensions from parent area + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + /** + * Add the child area to this layout manager. + * + * @param childArea the child area to add + * @return unused + */ + public boolean addChild(Area childArea) { + if (curBlockArea != null) { + curBlockArea.addBlock((Block) childArea); + + return false; + } + return false; + } + + /** + * Reset the position of this layout manager. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } + } +} + diff --git a/src/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java new file mode 100644 index 000000000..71e7f34f7 --- /dev/null +++ b/src/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java @@ -0,0 +1,284 @@ +/* + * $Id$ + * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.layoutmgr.list; + +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.fo.FObj; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.area.MinOptMax; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for a list-item FO. + * The list item contains a list item label and a list item body. + */ +public class ListItemLayoutManager extends BlockStackingLayoutManager { + private Item label; + private Item body; + + private Block curBlockArea; + + private List cellList = null; + private List columns = null; + private int listItemHeight; + private int yoffset; + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + private class ItemPosition extends LeafPosition { + protected List cellBreaks; + protected ItemPosition(LayoutManager lm, int pos, List l) { + super(lm, pos); + cellBreaks = l; + } + } + + /** + * Create a new list item layout manager. + * + * @param fobj the list-item formatting object + */ + public ListItemLayoutManager(FObj fobj) { + super(fobj); + } + + protected void initProperties(PropertyManager propMgr) { + borderProps = propMgr.getBorderAndPadding(); + backgroundProps = propMgr.getBackgroundProps(); + } + + public void setLabel(Item item) { + label = item; + label.setParentLM(this); + } + + public void setBody(Item item) { + body = item; + body.setParentLM(this); + } + + /** + * Get the next break possibility. + * + * @param context the layout context for getting breaks + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + Item curLM; // currently active LM + + BreakPoss lastPos = null; + ArrayList breakList = new ArrayList(); + + int min = 0; + int opt = 0; + int max = 0; + + int stage = 0; + while (true) { + if(stage == 0) { + curLM = label; + } else if (stage == 1) { + curLM = body; + } else { + break; + } + ArrayList childBreaks = new ArrayList(); + MinOptMax stackSize = new MinOptMax(); + + // Set up a LayoutContext + // the ipd is from the current column + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit( + MinOptMax.subtract(context.getStackLimit(), + stackSize)); + if (stage == 0) { + childLC.setRefIPD(24000); + } else if (stage == 1) { + childLC.setRefIPD(context.getRefIPD() - 24000); + } + stage++; + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + stackSize.add(bp.getStackingSize()); + if (stackSize.min > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + curLM.resetPosition(lastPos.getPosition()); + } else { + curLM.resetPosition(null); + } + break; + } + lastPos = bp; + childBreaks.add(bp); + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + // the min is the maximum min of the label and body + if (stackSize.min > min) { + min = stackSize.min; + } + // the optimum is the minimum of all optimums + if (stackSize.opt > opt) { + opt = stackSize.opt; + } + // the maximum is the largest maximum + if (stackSize.max > max) { + max = stackSize.max; + } + + breakList.add(childBreaks); + } + listItemHeight = opt; + + MinOptMax itemSize = new MinOptMax(min, opt, max); + + setFinished(true); + ItemPosition rp = new ItemPosition(this, breakList.size() - 1, breakList); + BreakPoss breakPoss = new BreakPoss(rp); + breakPoss.setStackingSize(itemSize); + return breakPoss; + } + + /** + * Set the y position offset of this list item. + * This is used to set the position of the areas returned by this list item. + * + * @param off the y offset + */ + public void setYOffset(int off) { + yoffset = off; + } + + /** + * Add the areas for the break points. + * This sets the offset of each cell as it is added. + * + * @param parentIter the position iterator + * @param layoutContext the layout context for adding areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + Item childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + ItemPosition lfp = (ItemPosition) parentIter.next(); + // Add the block areas to Area + + int xoffset = 0; + for (Iterator iter = lfp.cellBreaks.iterator(); iter.hasNext();) { + List cellsbr = (List)iter.next(); + PositionIterator breakPosIter; + breakPosIter = new BreakPossPosIter(cellsbr, 0, cellsbr.size()); + iStartPos = lfp.getLeafPos() + 1; + + while ((childLM = (Item)breakPosIter.getNextChildLM()) != null) { + if(childLM == body) { + childLM.setXOffset(24000); + } + childLM.addAreas(breakPosIter, lc); + } + xoffset += 100000; + } + } + + curBlockArea.setHeight(listItemHeight); + + flush(); + + } + + /** + * Get the height of the list item after adjusting. + * Should only be called after adding the list item areas. + * + * @return the height of this list item after adjustment + */ + public int getListItemHeight() { + return listItemHeight; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area + * @return the parent are for the child + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + curBlockArea = new Block(); + + // Set up dimensions + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + curBlockArea.setWidth(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + /** + * Add the child. + * Rows return the areas returned by the child elements. + * This simply adds the area to the parent layout manager. + * + * @param childArea the child area + * @return unused + */ + public boolean addChild(Area childArea) { + if (curBlockArea != null) { + curBlockArea.addBlock((Block) childArea); + return false; + } + return false; + } + + /** + * Reset the position of this layout manager. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } + } +} + diff --git a/src/org/apache/fop/layoutmgr/table/Row.java b/src/org/apache/fop/layoutmgr/table/Row.java index d9f2c46fd..3784bb984 100644 --- a/src/org/apache/fop/layoutmgr/table/Row.java +++ b/src/org/apache/fop/layoutmgr/table/Row.java @@ -167,8 +167,10 @@ public class Row extends BlockStackingLayoutManager { if (stackSize.min > min) { min = stackSize.min; } - // the optimum is the average of all optimums - opt += stackSize.opt; + // the optimum is the minimum of all optimums + if (stackSize.opt > opt) { + opt = stackSize.opt; + } // the maximum is the largest maximum if (stackSize.max > max) { max = stackSize.max; @@ -176,10 +178,6 @@ public class Row extends BlockStackingLayoutManager { breakList.add(childBreaks); } - opt = opt / cellcount; - if (opt < min) { - opt = min; - } rowHeight = opt; MinOptMax rowSize = new MinOptMax(min, opt, max); -- 2.39.5