aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKeiron Liddle <keiron@apache.org>2002-11-03 16:29:58 +0000
committerKeiron Liddle <keiron@apache.org>2002-11-03 16:29:58 +0000
commitc55b4c72556bd66076530f4a9bff83b9d4727aca (patch)
tree0692093138ac99c8ade0ae6d3bae808407656e54 /src
parent0dafe4daaa3857d147ab4bfa41f54bb817213356 (diff)
downloadxmlgraphics-fop-c55b4c72556bd66076530f4a9bff83b9d4727aca.tar.gz
xmlgraphics-fop-c55b4c72556bd66076530f4a9bff83b9d4727aca.zip
initial implementation of lists
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195406 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/org/apache/fop/fo/flow/ListBlock.java7
-rw-r--r--src/org/apache/fop/fo/flow/ListItem.java77
-rw-r--r--src/org/apache/fop/fo/flow/ListItemBody.java6
-rw-r--r--src/org/apache/fop/fo/flow/ListItemLabel.java8
-rw-r--r--src/org/apache/fop/layoutmgr/list/Item.java238
-rw-r--r--src/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java229
-rw-r--r--src/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java284
-rw-r--r--src/org/apache/fop/layoutmgr/table/Row.java10
8 files changed, 826 insertions, 33 deletions
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);