package org.apache.fop.fo;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
public static PropertyMaker[] propertyListTable = null;
/** The immediate child nodes of this node. */
- public ArrayList childNodes = null;
+ public List childNodes = null;
/** Used to indicate if this FO is either an Out Of Line FO (see rec)
or a descendant of one. Used during validateChildNode() FO
addMarker((Marker) child);
} else {
if (childNodes == null) {
- childNodes = new ArrayList();
+ childNodes = new java.util.ArrayList();
}
childNodes.add(child);
}
*/
public void setLayoutDimension(PercentBase.LayoutDimension key, int dimension) {
if (layoutDimension == null) {
- layoutDimension = new HashMap();
+ layoutDimension = new java.util.HashMap();
}
layoutDimension.put(key, new Integer(dimension));
}
*/
public void setLayoutDimension(PercentBase.LayoutDimension key, float dimension) {
if (layoutDimension == null) {
- layoutDimension = new HashMap();
+ layoutDimension = new java.util.HashMap();
}
layoutDimension.put(key, new Float(dimension));
}
}
}
if (markers == null) {
- markers = new HashMap();
+ markers = new java.util.HashMap();
}
if (!markers.containsKey(mcname)) {
markers.put(mcname, marker);
public List getColumns() {
return columns;
}
+
+ /**
+ * @param index index of the table-body element.
+ * @return the requested table-body element
+ */
+ public TableBody getBody(int index) {
+ return (TableBody)childNodes.get(index);
+ }
public TableBody getTableHeader() {
return tableHeader;
getParent().removeChild(this);
}
}
+ /*
if (tableCellsFound) {
convertCellsToRows();
- }
+ }*/
savedPropertyList = null; //Release reference
}
*/
private void convertCellsToRows() throws FOPException {
//getLogger().debug("Converting cells to rows...");
- List cells = (List)childNodes.clone();
+ List cells = new java.util.ArrayList(childNodes);
childNodes.clear();
Iterator i = cells.iterator();
TableRow row = null;
if (!blockItemFound) {
missingChildElementError("marker* (%block;)+");
}
+ //TODO Complain about startsRow|endsRow=true if parent is a table-row
getFOEventHandler().endCell(this);
}
return columnNumber.getValue();
}
- /**
- * @return value for number of columns repeated
- */
+ /** @return value for number-columns-repeated. */
public int getNumberColumnsRepeated() {
return numberColumnsRepeated.getValue();
}
+ /** @return value for number-columns-spanned. */
+ public int getNumberColumnsSpanned() {
+ return numberColumnsSpanned.getValue();
+ }
+
/** @see org.apache.fop.fo.FONode#getName() */
public String getName() {
return "fo:table-column";
public int getNameId() {
return FO_TABLE_COLUMN;
}
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ StringBuffer sb = new StringBuffer("fo:table-column");
+ if (hasColumnNumber()) {
+ sb.append(" column-number=").append(getColumnNumber());
+ }
+ if (getNumberColumnsRepeated() > 1) {
+ sb.append(" number-columns-repeated=").append(getNumberColumnsRepeated());
+ }
+ if (getNumberColumnsSpanned() > 1) {
+ sb.append(" number-columns-spanned=").append(getNumberColumnsSpanned());
+ }
+ sb.append(" column-width=").append(getColumnWidth());
+ return sb.toString();
+ }
}
addKnuthElementForBorderPaddingBefore(returnList, returnPosition,
fobj.getCommonBorderPaddingBackground());
-
+
while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
LayoutContext childLC = new LayoutContext(0);
if (curLM instanceof LineLayoutManager) {
// a penalty
}
}
- contentList.addAll(returnedList);
if (returnedList.size() == 0) {
//Avoid NoSuchElementException below (happens with empty blocks)
continue;
}
+ contentList.addAll(returnedList);
if (((KnuthElement) returnedList.getLast()).isPenalty()
&& ((KnuthPenalty) returnedList.getLast()).getP() == -KnuthElement.INFINITE) {
// a descendant of this block has break-after
return returnList;
}
+ /*
+ if (allocatedSpace.min > context.getStackLimit().max) {
+ log.debug("Allocated space exceeds stack limit, returning early.");
+ return returnList;
+ }*/
}
prevLM = curLM;
}
boolean bSpaceAfter = false;
while (parentIter.hasNext()) {
pos = (Position) parentIter.next();
- /* LF *///System.out.println("pos = " + pos.getClass().getName());
- Position innerPosition = ((NonLeafPosition) pos).getPosition();
+ //log.trace("pos = " + pos.getClass().getName() + "; " + pos);
+ Position innerPosition = pos;
+ if (pos instanceof NonLeafPosition) {
+ //Not all elements are wrapped
+ innerPosition = ((NonLeafPosition) pos).getPosition();
+ }
if (innerPosition == null) {
// pos was created by this BlockLM and was inside an element
// representing space before or after
if (positionList.size() == 0) {
// pos was in the element representing space-before
bSpaceBefore = true;
- /* LF *///System.out.println(" spazio prima");
+ //log.trace(" space before");
} else {
// pos was in the element representing space-after
bSpaceAfter = true;
- /* LF *///System.out.println(" spazio dopo");
+ //log.trace(" space-after");
}
} else if (innerPosition.getLM() == this
&& !(innerPosition instanceof MappingPosition)) {
// pos was created by this BlockLM and was inside a penalty
// allowing or forbidding a page break
// nothing to do
- /* LF *///System.out.println(" penalty");
+ //log.trace(" penalty");
} else {
// innerPosition was created by another LM
positionList.add(innerPosition);
lastLM = innerPosition.getLM();
- /* LF *///System.out.println(" " +
- // innerPosition.getClass().getName());
+ //log.trace(" " + innerPosition.getClass().getName());
}
}
while (listIter.hasNext()) {
KnuthElement tempElement;
tempElement = (KnuthElement) listIter.next();
- //if (tempElement.getLayoutManager() != this) {
- tempElement.setPosition(new NonLeafPosition(this,
- tempElement.getPosition()));
- //}
+ if (tempElement.getLayoutManager() != this) {
+ tempElement.setPosition(new NonLeafPosition(this,
+ tempElement.getPosition()));
+ }
targetList.add(tempElement);
}
}
package org.apache.fop.layoutmgr;
-import org.apache.fop.datatypes.PercentBase;
import org.apache.fop.fo.flow.Marker;
import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.area.Area;
}*/
+ /**
+ * "wrap" the Position inside each element moving the elements from
+ * SourceList to targetList
+ * @param sourceList source list
+ * @param targetList target list receiving the wrapped position elements
+ */
+ protected void wrapPositionElements(List sourceList, List targetList) {
+ ListIterator listIter = sourceList.listIterator();
+ while (listIter.hasNext()) {
+ KnuthElement tempElement;
+ tempElement = (KnuthElement) listIter.next();
+ //if (tempElement.getLayoutManager() != this) {
+ tempElement.setPosition(new NonLeafPosition(this,
+ tempElement.getPosition()));
+ //}
+ targetList.add(tempElement);
+ }
+ }
+
+
//TODO Reintroduce emergency counter (generate error to avoid endless loop)
//TODO Reintroduce layout dimensions
public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
// currently active LM
BlockLevelLayoutManager curLM;
BlockLevelLayoutManager prevLM = null;
- MinOptMax stackSize = new MinOptMax();
+ //MinOptMax stackSize = new MinOptMax();
LinkedList returnedList;
LinkedList returnList = new LinkedList();
}
// Set up a LayoutContext
- MinOptMax bpd = context.getStackLimit();
- BreakPoss bp;
- bp = null;
+ //MinOptMax bpd = context.getStackLimit();
LayoutContext childLC = new LayoutContext(0);
- boolean breakPage = false;
- childLC.setStackLimit(MinOptMax.subtract(bpd, stackSize));
+ childLC.setStackLimit(context.getStackLimit());
childLC.setRefIPD(context.getRefIPD());
// get elements from curLM
returnedList = curLM.getNextKnuthElements(childLC, alignment);
-/*LF*/ //System.out.println("FLM.getNextKnuthElements> returnedList.size() = " + returnedList.size());
+ //log.debug("FLM.getNextKnuthElements> returnedList.size() = " + returnedList.size());
// "wrap" the Position inside each element
LinkedList tempList = returnedList;
- KnuthElement tempElement;
returnedList = new LinkedList();
- ListIterator listIter = tempList.listIterator();
- while (listIter.hasNext()) {
- tempElement = (KnuthElement)listIter.next();
- tempElement.setPosition(new NonLeafPosition(this, tempElement.getPosition()));
- returnedList.add(tempElement);
- }
+ wrapPositionElements(tempList, returnedList);
if (returnedList.size() == 1
&& ((KnuthElement)returnedList.getFirst()).isPenalty()
}
public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) {
-/*LF*/ System.out.println(" FLM.negotiateBPDAdjustment> " + adj);
+ log.debug(" FLM.negotiateBPDAdjustment> " + adj);
-/*LF*/ if (lastElement.getPosition() instanceof NonLeafPosition) {
+ if (lastElement.getPosition() instanceof NonLeafPosition) {
// this element was not created by this FlowLM
NonLeafPosition savedPos = (NonLeafPosition)lastElement.getPosition();
lastElement.setPosition(savedPos.getPosition());
int returnValue = ((BlockLevelLayoutManager) lastElement.getLayoutManager()).negotiateBPDAdjustment(adj, lastElement);
lastElement.setPosition(savedPos);
-/*LF*/ System.out.println(" FLM.negotiateBPDAdjustment> gestito " + returnValue);
+ log.debug(" FLM.negotiateBPDAdjustment> result " + returnValue);
return returnValue;
-/*LF*/ } else {
-/*LF*/ return 0;
-/*LF*/ }
+ } else {
+ return 0;
+ }
}
public void discardSpace(KnuthGlue spaceGlue) {
-/*LF*/ System.out.println(" FLM.discardSpace> ");
+ log.debug(" FLM.discardSpace> ");
-/*LF*/ if (spaceGlue.getPosition() instanceof NonLeafPosition) {
+ if (spaceGlue.getPosition() instanceof NonLeafPosition) {
// this element was not created by this FlowLM
NonLeafPosition savedPos = (NonLeafPosition)spaceGlue.getPosition();
spaceGlue.setPosition(savedPos.getPosition());
((BlockLevelLayoutManager) spaceGlue.getLayoutManager()).discardSpace(spaceGlue);
spaceGlue.setPosition(savedPos);
-/*LF*/ }
+ }
}
public boolean mustKeepTogether() {
new PageNumberCitationLayoutManagerMaker());
makers.put(PageSequence.class, new PageSequenceLayoutManagerMaker());
makers.put(Table.class, new TableLayoutManagerMaker());
- makers.put(TableBody.class, new TableBodyLayoutManagerMaker());
- makers.put(TableColumn.class, new TableColumnLayoutManagerMaker());
- makers.put(TableRow.class, new TableRowLayoutManagerMaker());
- makers.put(TableCell.class, new TableCellLayoutManagerMaker());
- makers.put(TableFooter.class, new TableBodyLayoutManagerMaker());
- makers.put(TableHeader.class, new TableBodyLayoutManagerMaker());
+ makers.put(TableBody.class, new /*TableBodyLayoutManager*/Maker());
+ makers.put(TableColumn.class, new /*TableColumnLayoutManager*/Maker());
+ makers.put(TableRow.class, new /*TableRowLayoutManager*/Maker());
+ makers.put(TableCell.class, new /*TableCellLayoutManager*/Maker());
+ makers.put(TableFooter.class, new /*TableBodyLayoutManager*/Maker());
+ makers.put(TableHeader.class, new /*TableBodyLayoutManager*/Maker());
makers.put(Flow.class, new FlowLayoutManagerMaker());
makers.put(StaticContent.class, new StaticContentLayoutManagerMaker());
makers.put(Wrapper.class, new WrapperLayoutManagerMaker());
public static class TableLayoutManagerMaker extends Maker {
+ /*
private List getColumnLayoutManagerList(Table table, TableLayoutManager tlm) {
List columnLMs = null;
List columns = table.getColumns();
}
}
return columnLMs;
- }
+ }*/
public void make(FONode node, List lms) {
Table table = (Table) node;
TableLayoutManager tlm = new TableLayoutManager(table);
+ /*
List columnLMs = getColumnLayoutManagerList(table, tlm);
if (columnLMs != null) {
tlm.setColumns(columnLMs);
- }
+ }*/
lms.add(tlm);
}
}
-
+
+ /*
public static class TableBodyLayoutManagerMaker extends Maker {
public void make(FONode node, List lms) {
lms.add(new Body((TableBody) node));
public void make(FONode node, List lms) {
lms.add(new Cell((TableCell) node));
}
- }
+ }*/
public static class FlowLayoutManagerMaker extends Maker {
public void make(FONode node, List lms) {
package org.apache.fop.layoutmgr.table;
+import java.util.LinkedList;
import java.util.List;
import org.apache.fop.fo.flow.TableBody;
+import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
+import org.apache.fop.layoutmgr.KnuthElement;
+import org.apache.fop.layoutmgr.KnuthGlue;
+import org.apache.fop.layoutmgr.KnuthPenalty;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.BreakPoss;
import org.apache.fop.layoutmgr.LayoutContext;
+import org.apache.fop.layoutmgr.NonLeafPosition;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.BreakPossPosIter;
import org.apache.fop.layoutmgr.Position;
* These fo objects have either rows or cells underneath.
* Cells are organised into rows.
*/
-public class Body extends BlockStackingLayoutManager {
+public class Body extends BlockStackingLayoutManager implements BlockLevelLayoutManager {
private TableBody fobj;
private List columns;
columns = cols;
}
+ /**
+ * @see org.apache.fop.layoutmgr.LayoutManager#getNextKnuthElements(org.apache.fop.layoutmgr.LayoutContext, int)
+ */
+ public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
+ LayoutContext childLC = new LayoutContext(0);
+ childLC.setStackLimit(context.getStackLimit());
+ childLC.setRefIPD(context.getRefIPD());
+
+ LinkedList returnedList = null;
+ LinkedList contentList = new LinkedList();
+ LinkedList returnList = new LinkedList();
+ Position returnPosition = new NonLeafPosition(this, null);
+
+ Row curLM; // currently active LM
+ Row prevLM = null; // previously active LM
+ while ((curLM = (Row)getChildLM()) != null) {
+
+ // get elements from curLM
+ returnedList = curLM.getNextKnuthElements(childLC, alignment);
+ /*
+ if (returnedList.size() == 1
+ && ((KnuthElement) returnedList.getFirst()).isPenalty()
+ && ((KnuthPenalty) returnedList.getFirst()).getP() == -KnuthElement.INFINITE) {
+ // a descendant of this block has break-before
+ if (returnList.size() == 0) {
+ // the first child (or its first child ...) has
+ // break-before;
+ // all this block, including space before, will be put in
+ // the
+ // following page
+ bSpaceBeforeServed = false;
+ }
+ contentList.addAll(returnedList);
+
+ // "wrap" the Position inside each element
+ // moving the elements from contentList to returnList
+ returnedList = new LinkedList();
+ wrapPositionElements(contentList, returnList);
+
+ return returnList;
+ } else*/ {
+ if (prevLM != null) {
+ // there is a block handled by prevLM
+ // before the one handled by curLM
+ if (mustKeepTogether()
+ || prevLM.mustKeepWithNext()
+ || curLM.mustKeepWithPrevious()) {
+ // add an infinite penalty to forbid a break between
+ // blocks
+ contentList.add(new KnuthPenalty(0,
+ KnuthElement.INFINITE, false,
+ new Position(this), false));
+ } else if (!((KnuthElement) contentList.getLast()).isGlue()) {
+ // add a null penalty to allow a break between blocks
+ contentList.add(new KnuthPenalty(0, 0, false,
+ new Position(this), false));
+ } else {
+ // the last element in contentList is a glue;
+ // it is a feasible breakpoint, there is no need to add
+ // a penalty
+ }
+ }
+ contentList.addAll(returnedList);
+ if (returnedList.size() == 0) {
+ //Avoid NoSuchElementException below (happens with empty blocks)
+ continue;
+ }
+ if (((KnuthElement) returnedList.getLast()).isPenalty()
+ && ((KnuthPenalty) returnedList.getLast()).getP() == -KnuthElement.INFINITE) {
+ // a descendant of this block has break-after
+ if (curLM.isFinished()) {
+ // there is no other content in this block;
+ // it's useless to add space after before a page break
+ setFinished(true);
+ }
+
+ returnedList = new LinkedList();
+ wrapPositionElements(contentList, returnList);
+
+ return returnList;
+ }
+ }
+ prevLM = curLM;
+ }
+
+ setFinished(true);
+ if (returnList.size() > 0) {
+ return returnList;
+ } else {
+ return null;
+ }
+ }
+
/**
* Breaks for this layout manager are of the form of before
* or after a row and inside a row.
* @param context the layout context for finding the breaks
* @return the next break possibility
*/
- public BreakPoss getNextBreakPoss(LayoutContext context) {
+ public BreakPoss getNextBreakPossOLDOLDOLD(LayoutContext context) {
Row curLM; // currently active LM
MinOptMax stackSize = new MinOptMax();
return curBlockArea;
}
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#negotiateBPDAdjustment(int, org.apache.fop.layoutmgr.KnuthElement)
+ */
+ public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#discardSpace(org.apache.fop.layoutmgr.KnuthGlue)
+ */
+ public void discardSpace(KnuthGlue spaceGlue) {
+ // TODO Auto-generated method stub
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether()
+ */
+ public boolean mustKeepTogether() {
+ return ((BlockLevelLayoutManager)getParent()).mustKeepTogether();
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithPrevious()
+ */
+ public boolean mustKeepWithPrevious() {
+ return false;
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithNext()
+ */
+ public boolean mustKeepWithNext() {
+ return false;
+ }
+
}
import org.apache.fop.fo.flow.TableCell;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.LengthRangeProperty;
+import org.apache.fop.layoutmgr.AreaAdditionUtil;
+import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
+import org.apache.fop.layoutmgr.KnuthElement;
+import org.apache.fop.layoutmgr.KnuthGlue;
+import org.apache.fop.layoutmgr.KnuthPenalty;
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.MinOptMaxUtil;
+import org.apache.fop.layoutmgr.NonLeafPosition;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.BreakPossPosIter;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.traits.MinOptMax;
import java.util.ArrayList;
+import java.util.LinkedList;
import java.util.List;
/**
* LayoutManager for a table-cell FO.
* A cell contains blocks. These blocks fill the cell.
*/
-public class Cell extends BlockStackingLayoutManager {
+public class Cell extends BlockStackingLayoutManager implements BlockLevelLayoutManager {
+
private TableCell fobj;
+ private PrimaryGridUnit gridUnit;
private Block curBlockArea;
private int borderAndPaddingBPD;
private boolean emptyCell = true;
- /** List of Lists containing GridUnit instances, one List per row. */
+ /** List of Lists containing OldGridUnit instances, one List per row. */
private List rows = new java.util.ArrayList();
/**
* Create a new Cell layout manager.
* @node table-cell FO for which to create the LM
*/
- public Cell(TableCell node) {
+ public Cell(TableCell node, PrimaryGridUnit pgu) {
super(node);
fobj = node;
+ this.gridUnit = pgu;
}
/** @return the table-cell FO */
for (int i = 0; i < rows.size(); i++) {
List gridUnits = (List)rows.get(i);
startBorderWidth = Math.max(startBorderWidth,
- ((GridUnit)gridUnits.get(0)).
+ ((OldGridUnit)gridUnits.get(0)).
effBorders.getBorderStartWidth(false));
endBorderWidth = Math.max(endBorderWidth,
- ((GridUnit)gridUnits.get(gridUnits.size() - 1)).
+ ((OldGridUnit)gridUnits.get(gridUnits.size() - 1)).
effBorders.getBorderEndWidth(false));
}
//iIndents += fobj.getCommonBorderPaddingBackground().getBorderStartWidth(false);
return iIndents;
}
+ /**
+ * @see org.apache.fop.layoutmgr.LayoutManager#getNextKnuthElements(org.apache.fop.layoutmgr.LayoutContext, int)
+ */
+ public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
+ MinOptMax stackSize = new MinOptMax();
+ MinOptMax stackLimit = new MinOptMax(context.getStackLimit());
+
+ BreakPoss lastPos = null;
+
+ referenceIPD = context.getRefIPD();
+ cellIPD = referenceIPD;
+ cellIPD -= getIPIndents();
+ if (fobj.isSeparateBorderModel()) {
+ int borderSep = fobj.getBorderSeparation().getLengthPair()
+ .getIPD().getLength().getValue();
+ cellIPD -= borderSep;
+ }
+
+ LinkedList returnedList = null;
+ LinkedList contentList = new LinkedList();
+ LinkedList returnList = new LinkedList();
+ Position returnPosition = new NonLeafPosition(this, null);
+
+ BlockLevelLayoutManager curLM; // currently active LM
+ BlockLevelLayoutManager prevLM = null; // previously active LM
+ while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
+ LayoutContext childLC = new LayoutContext(0);
+ // curLM is a ?
+ childLC.setStackLimit(MinOptMax.subtract(context
+ .getStackLimit(), stackLimit));
+ childLC.setRefIPD(cellIPD);
+
+ // get elements from curLM
+ returnedList = curLM.getNextKnuthElements(childLC, alignment);
+ if (returnedList.size() == 1
+ && ((KnuthElement) returnedList.getFirst()).isPenalty()
+ && ((KnuthPenalty) returnedList.getFirst()).getP() == -KnuthElement.INFINITE) {
+ // a descendant of this block has break-before
+ if (returnList.size() == 0) {
+ // the first child (or its first child ...) has
+ // break-before;
+ // all this block, including space before, will be put in
+ // the
+ // following page
+ }
+ contentList.addAll(returnedList);
+
+ // "wrap" the Position inside each element
+ // moving the elements from contentList to returnList
+ returnedList = new LinkedList();
+ wrapPositionElements(contentList, returnList);
+
+ return returnList;
+ } else {
+ if (prevLM != null) {
+ // there is a block handled by prevLM
+ // before the one handled by curLM
+ if (mustKeepTogether()
+ || prevLM.mustKeepWithNext()
+ || curLM.mustKeepWithPrevious()) {
+ // add an infinite penalty to forbid a break between
+ // blocks
+ contentList.add(new KnuthPenalty(0,
+ KnuthElement.INFINITE, false,
+ new Position(this), false));
+ } else if (!((KnuthElement) contentList.getLast()).isGlue()) {
+ // add a null penalty to allow a break between blocks
+ contentList.add(new KnuthPenalty(0, 0, false,
+ new Position(this), false));
+ } else {
+ // the last element in contentList is a glue;
+ // it is a feasible breakpoint, there is no need to add
+ // a penalty
+ }
+ }
+ contentList.addAll(returnedList);
+ if (returnedList.size() == 0) {
+ //Avoid NoSuchElementException below (happens with empty blocks)
+ continue;
+ }
+ if (((KnuthElement) returnedList.getLast()).isPenalty()
+ && ((KnuthPenalty) returnedList.getLast()).getP() == -KnuthElement.INFINITE) {
+ // a descendant of this block has break-after
+ if (curLM.isFinished()) {
+ // there is no other content in this block;
+ // it's useless to add space after before a page break
+ setFinished(true);
+ }
+
+ returnedList = new LinkedList();
+ wrapPositionElements(contentList, returnList);
+
+ return returnList;
+ }
+ }
+ prevLM = curLM;
+ }
+
+ returnedList = new LinkedList();
+ wrapPositionElements(contentList, returnList);
+
+ setFinished(true);
+ return returnList;
+ }
+
/**
* Get the next break possibility for this cell.
* A cell contains blocks so there are breaks around the blocks
* @param context the layout context
* @return the next break possibility
*/
- public BreakPoss getNextBreakPoss(LayoutContext context) {
+ public BreakPoss getNextBreakPossOLDOLDOLD(LayoutContext context) {
LayoutManager curLM; // currently active LM
MinOptMax stackSize = new MinOptMax();
public void addAreas(PositionIterator parentIter,
LayoutContext layoutContext) {
getParentArea(null);
- BreakPoss bp1 = (BreakPoss)parentIter.peekNext();
- bBogus = !bp1.generatesAreas();
+ //BreakPoss bp1 = (BreakPoss)parentIter.peekNext();
+ bBogus = false;//!bp1.generatesAreas();
if (!isBogus()) {
addID(fobj.getId());
if (rows.size() == 1 && ((List)rows.get(0)).size() == 1) {
//Can set the borders directly if there's no span
CommonBorderPaddingBackground effBorders =
- ((GridUnit)((List)rows.get(0)).get(0)).effBorders;
+ ((OldGridUnit)((List)rows.get(0)).get(0)).effBorders;
//TODO Next line is a temporary hack!
TraitSetter.addCollapsingBorders(curBlockArea,
fobj.getCommonBorderPaddingBackground(), outer);
int dx = xoffset;
int lastRowHeight = 0;
for (int x = 0; x < gridUnits.size(); x++) {
- GridUnit gu = (GridUnit)gridUnits.get(x);
+ OldGridUnit gu = (OldGridUnit)gridUnits.get(x);
if (!gu.effBorders.hasBorder()) {
continue;
}
}
}
+ AreaAdditionUtil.addAreas(parentIter, layoutContext);
+ /*
LayoutManager childLM;
int iStartPos = 0;
LayoutContext lc = new LayoutContext(0);
+ PositionIterator childPosIter;
+ childPosIter = new StackingIter(positionList.listIterator());
+ while ((childLM = childPosIter.getNextChildLM()) != null) {
+ // set last area flag
+ lc.setFlags(LayoutContext.LAST_AREA,
+ (layoutContext.isLastArea() && childLM == lastLM));
+ lc.setStackLimit(layoutContext.getStackLimit());
+ // Add the line areas to Area
+ childLM.addAreas(childPosIter, lc);
+ }
while (parentIter.hasNext()) {
LeafPosition lfp = (LeafPosition) parentIter.next();
// Add the block areas to Area
while ((childLM = breakPosIter.getNextChildLM()) != null) {
childLM.addAreas(breakPosIter, lc);
}
- }
+ }*/
int contentBPD = rowHeight;
}
}
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#negotiateBPDAdjustment(int, org.apache.fop.layoutmgr.KnuthElement)
+ */
+ public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#discardSpace(org.apache.fop.layoutmgr.KnuthGlue)
+ */
+ public void discardSpace(KnuthGlue spaceGlue) {
+ // TODO Auto-generated method stub
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether()
+ */
+ public boolean mustKeepTogether() {
+ //TODO Keeps will have to be more sophisticated sooner or later
+ return ((BlockLevelLayoutManager)getParent()).mustKeepTogether()/*
+ || !fobj.getKeepTogether().getWithinPage().isAuto()
+ || !fobj.getKeepTogether().getWithinColumn().isAuto()*/;
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithPrevious()
+ */
+ public boolean mustKeepWithPrevious() {
+ return false; //TODO FIX ME
+ /*
+ return !fobj.getKeepWithPrevious().getWithinPage().isAuto()
+ || !fobj.getKeepWithPrevious().getWithinColumn().isAuto();
+ */
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithNext()
+ */
+ public boolean mustKeepWithNext() {
+ return false; //TODO FIX ME
+ /*
+ return !fobj.getKeepWithNext().getWithinPage().isAuto()
+ || !fobj.getKeepWithNext().getWithinColumn().isAuto();
+ */
+ }
+
}
* @return the winning BorderInfo
*/
public abstract BorderInfo determineWinner(
- GridUnit current, GridUnit neighbour, int side, int flags);
+ OldGridUnit current, OldGridUnit neighbour, int side, int flags);
}
private static final int START = CommonBorderPaddingBackground.START;
private static final int END = CommonBorderPaddingBackground.END;
- public BorderInfo determineWinner(GridUnit currentGridUnit,
- GridUnit otherGridUnit, int side, int flags) {
+ public BorderInfo determineWinner(OldGridUnit currentGridUnit,
+ OldGridUnit otherGridUnit, int side, int flags) {
final boolean vertical = isVerticalRelation(side);
final int otherSide = getOtherSide(side);
--- /dev/null
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.table;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.fo.flow.Table;
+import org.apache.fop.fo.flow.TableCell;
+import org.apache.fop.fo.flow.TableColumn;
+
+/**
+ * Class holding a number of columns making up the column setup of a row.
+ */
+public class ColumnSetup {
+
+ /** Logger **/
+ private static Log log = LogFactory.getLog(ColumnSetup.class);
+
+ private Table table;
+ private List columns = new java.util.ArrayList();
+ private int maxColIndexReferenced = 0;
+
+ public ColumnSetup(Table table) {
+ this.table = table;
+ prepareExplicitColumns();
+ if (getColumnCount() == 0) {
+ createColumnsFromFirstRow();
+ }
+ }
+
+ private void prepareExplicitColumns() {
+ List rawCols = table.getColumns();
+ if (rawCols != null) {
+ int colnum = 1;
+ ListIterator iter = rawCols.listIterator();
+ while (iter.hasNext()) {
+ TableColumn col = (TableColumn)iter.next();
+ if (col.hasColumnNumber()) {
+ colnum = col.getColumnNumber();
+ }
+ for (int i = 0; i < col.getNumberColumnsRepeated(); i++) {
+ while (colnum > columns.size()) {
+ columns.add(null);
+ }
+ columns.set(colnum - 1, col);
+ colnum++;
+ }
+ }
+ //Post-processing the list (looking for gaps)
+ int pos = 1;
+ ListIterator ppIter = columns.listIterator();
+ while (ppIter.hasNext()) {
+ TableColumn col = (TableColumn)ppIter.next();
+ if (col == null) {
+ log.error("Found a gap in the table-columns at position " + pos);
+ }
+ pos++;
+ }
+ }
+ }
+
+ public TableColumn getColumn(int index) {
+ int size = columns.size();
+ if (index > size - 1) {
+ maxColIndexReferenced = index;
+ return (TableColumn)columns.get(size - 1);
+ } else {
+ return (TableColumn)columns.get(index - 1);
+ }
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ return columns.toString();
+ }
+
+ /** @return the number of columns in the setup. */
+ public int getColumnCount() {
+ if (maxColIndexReferenced > columns.size()) {
+ return maxColIndexReferenced;
+ } else {
+ return columns.size();
+ }
+ }
+
+ /** @return an Iterator over all columns */
+ public Iterator iterator() {
+ return this.columns.iterator();
+ }
+
+ private void createColumnsFromFirstRow() {
+ //TODO Create oldColumns from first row here
+ //--> rule 2 in "fixed table layout", see CSS2, 17.5.2
+ //Alternative: extend oldColumns on-the-fly, but in this case we need the
+ //new property evaluation context so proportional-column-width() works
+ //correctly.
+ if (columns.size() == 0) {
+ this.columns.add(table.getDefaultColumn());
+ }
+ }
+
+ /**
+ * @param col column index (1 is first column)
+ * @return the X offset of the requested column
+ */
+ public int getXOffset(int col) {
+ int xoffset = 0;
+ for (int i = 1; i < col; i++) {
+ xoffset += getColumn(i).getColumnWidth().getValue();
+ }
+ return xoffset;
+ }
+
+}
package org.apache.fop.layoutmgr.table;
+import org.apache.fop.fo.FONode;
import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
-import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
-
+import org.apache.fop.fo.flow.TableBody;
+import org.apache.fop.fo.flow.TableCell;
+import org.apache.fop.fo.flow.TableColumn;
+import org.apache.fop.fo.flow.TableRow;
+/**
+ * This class represents one grid unit inside a table.
+ */
public class GridUnit {
+
+ /** Table cell which occupies this grid unit */
+ private TableCell cell;
+ /** Table column that this grid unit belongs to */
+ private TableColumn column;
- /** layout manager for the cell occupying this grid unit, may be null */
- public Cell layoutManager;
- /** layout manager for the column that this grid unit belongs to */
- public Column column;
- /** layout manager for the row that this grid unit belongs to */
- public Row row;
+ /** start index of grid unit within row in column direction */
+ private int startCol;
/** index of grid unit within cell in column direction */
- public int colSpanIndex;
+ private int colSpanIndex;
/** index of grid unit within cell in row direction */
- public int rowSpanIndex;
- /** effective borders for a cell slot (used for collapsing border model) */
- public CommonBorderPaddingBackground effBorders;
+ private int rowSpanIndex;
- public GridUnit(Cell layoutManager, int colSpanIndex) {
- this.layoutManager = layoutManager;
+
+ public GridUnit(TableCell cell, TableColumn column, int startCol, int colSpanIndex) {
+ this.cell = cell;
+ this.column = column;
+ this.startCol = startCol;
this.colSpanIndex = colSpanIndex;
- this.rowSpanIndex = 0;
}
- public GridUnit(Cell layoutManager) {
- this(layoutManager, 0);
+ public TableCell getCell() {
+ return this.cell;
}
-
- /** @return true if the grid unit is the primary of a cell */
- public boolean isPrimaryGridUnit() {
- return (colSpanIndex == 0) && (rowSpanIndex == 0);
+
+ public TableColumn getColumn() {
+ return this.column;
}
- /** @return true if the grid unit is the last in column spanning direction */
- public boolean isLastGridUnitColSpan() {
- if (layoutManager != null) {
- return (colSpanIndex == layoutManager.getFObj().getNumberColumnsSpanned() - 1);
+ public TableRow getRow() {
+ if (getCell().getParent() instanceof TableRow) {
+ return (TableRow)getCell().getParent();
} else {
- return true;
+ return null;
}
}
- /** @return true if the grid unit is the last in column spanning direction */
- public boolean isLastGridUnitRowSpan() {
- if (layoutManager != null) {
- return (rowSpanIndex == layoutManager.getFObj().getNumberRowsSpanned() - 1);
- } else {
- return true;
+ public TableBody getBody() {
+ FONode node = getCell();
+ while (!(node instanceof TableBody)) {
+ node = node.getParent();
}
+ return (TableBody)node;
}
- /** @return true if the cell is part of a span in column direction */
- public boolean isColSpan() {
- return (colSpanIndex > 0);
- }
-
- public BorderInfo getOriginalBorderInfoForCell(int side) {
- if (layoutManager != null) {
- return layoutManager.getFObj().getCommonBorderPaddingBackground().getBorderInfo(side);
- } else {
- return null;
+ public Table getTable() {
+ FONode node = getCell();
+ while (!(node instanceof Table)) {
+ node = node.getParent();
}
+ return (Table)node;
}
- /**
- * Assign the borders from the given cell to this cell info. Used in
- * case of separate border model.
- * @param current cell to take the borders from
- */
- public void assignBorder(Cell current) {
- if (current != null) {
- this.effBorders = current.getFObj().getCommonBorderPaddingBackground();
- }
+ public boolean isPrimary() {
+ return false;
}
- /**
- * Assign the borders directly.
- * @param borders the borders to use
- */
- public void assignBorder(CommonBorderPaddingBackground borders) {
- if (borders != null) {
- this.effBorders = borders;
- }
+ public boolean isEmpty() {
+ return this.cell == null;
}
- /**
- * Resolve collapsing borders for the given cell and store the resulting
- * borders in this cell info. Use in case of the collapsing border model.
- * @param current cell to resolve borders for
- * @param before cell before the current cell, if any
- * @param after cell after the current cell, if any
- * @param start cell preceeding the current cell, if any
- * @param end cell succeeding of the current cell, if any
- */
- public static void resolveBorder(Table table,
- CommonBorderPaddingBackground target,
- GridUnit current, GridUnit other, int side) {
- if (current == null) {
- return;
+ public int getStartCol() {
+ return this.startCol;
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ if (isEmpty()) {
+ sb.append("EMPTY");
+ } else if (isPrimary()) {
+ sb.append("Primary");
+ }
+ sb.append("GridUnit:");
+ if (colSpanIndex > 0) {
+ sb.append(" colSpan=").append(colSpanIndex);
+ }
+ if (rowSpanIndex > 0) {
+ sb.append(" rowSpan=").append(rowSpanIndex);
}
-
- CollapsingBorderModel borderModel = CollapsingBorderModel.getBorderModelFor(
- table.getBorderCollapse());
- target.setBorderInfo(
- borderModel.determineWinner(current, other,
- side, 0), side);
+ sb.append(" startCol=").append(startCol);
+ return sb.toString();
}
-}
\ No newline at end of file
+}
--- /dev/null
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.table;
+
+import org.apache.fop.fo.flow.Table;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
+
+
+public class OldGridUnit {
+
+ /** layout manager for the cell occupying this grid unit, may be null */
+ public Cell layoutManager;
+ /** layout manager for the column that this grid unit belongs to */
+ public Column column;
+ /** layout manager for the row that this grid unit belongs to */
+ public Row row;
+ /** index of grid unit within cell in column direction */
+ public int colSpanIndex;
+ /** index of grid unit within cell in row direction */
+ public int rowSpanIndex;
+ /** effective borders for a cell slot (used for collapsing border model) */
+ public CommonBorderPaddingBackground effBorders;
+
+ public OldGridUnit(Cell layoutManager, int colSpanIndex) {
+ this.layoutManager = layoutManager;
+ this.colSpanIndex = colSpanIndex;
+ this.rowSpanIndex = 0;
+ }
+
+ public OldGridUnit(Cell layoutManager) {
+ this(layoutManager, 0);
+ }
+
+ /** @return true if the grid unit is the primary of a cell */
+ public boolean isPrimaryGridUnit() {
+ return (colSpanIndex == 0) && (rowSpanIndex == 0);
+ }
+
+ /** @return true if the grid unit is the last in column spanning direction */
+ public boolean isLastGridUnitColSpan() {
+ if (layoutManager != null) {
+ return (colSpanIndex == layoutManager.getFObj().getNumberColumnsSpanned() - 1);
+ } else {
+ return true;
+ }
+ }
+
+ /** @return true if the grid unit is the last in column spanning direction */
+ public boolean isLastGridUnitRowSpan() {
+ if (layoutManager != null) {
+ return (rowSpanIndex == layoutManager.getFObj().getNumberRowsSpanned() - 1);
+ } else {
+ return true;
+ }
+ }
+
+ /** @return true if the cell is part of a span in column direction */
+ public boolean isColSpan() {
+ return (colSpanIndex > 0);
+ }
+
+ public BorderInfo getOriginalBorderInfoForCell(int side) {
+ if (layoutManager != null) {
+ return layoutManager.getFObj().getCommonBorderPaddingBackground().getBorderInfo(side);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Assign the borders from the given cell to this cell info. Used in
+ * case of separate border model.
+ * @param current cell to take the borders from
+ */
+ public void assignBorder(Cell current) {
+ if (current != null) {
+ this.effBorders = current.getFObj().getCommonBorderPaddingBackground();
+ }
+ }
+
+ /**
+ * Assign the borders directly.
+ * @param borders the borders to use
+ */
+ public void assignBorder(CommonBorderPaddingBackground borders) {
+ if (borders != null) {
+ this.effBorders = borders;
+ }
+ }
+
+ /**
+ * Resolve collapsing borders for the given cell and store the resulting
+ * borders in this cell info. Use in case of the collapsing border model.
+ * @param current cell to resolve borders for
+ * @param before cell before the current cell, if any
+ * @param after cell after the current cell, if any
+ * @param start cell preceeding the current cell, if any
+ * @param end cell succeeding of the current cell, if any
+ */
+ public static void resolveBorder(Table table,
+ CommonBorderPaddingBackground target,
+ OldGridUnit current, OldGridUnit other, int side) {
+ if (current == null) {
+ return;
+ }
+
+ CollapsingBorderModel borderModel = CollapsingBorderModel.getBorderModelFor(
+ table.getBorderCollapse());
+ target.setBorderInfo(
+ borderModel.determineWinner(current, other,
+ side, 0), side);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.table;
+
+import java.util.LinkedList;
+
+import org.apache.fop.fo.flow.TableCell;
+import org.apache.fop.fo.flow.TableColumn;
+
+/**
+ * This class represents a primary grid unit of a spanned cell.
+ */
+public class PrimaryGridUnit extends GridUnit {
+
+ private Cell cellLM;
+ private LinkedList elements;
+ /** index of row where this cell starts */
+ private int startRow;
+
+
+ public PrimaryGridUnit(TableCell cell, TableColumn column, int startCol, int startRow) {
+ super(cell, column, startCol, 0);
+ this.startRow = startRow;
+ if (cell != null) {
+ cellLM = new Cell(cell, this);
+ }
+ }
+
+ public Cell getCellLM() {
+ return cellLM;
+ }
+
+ public boolean isPrimary() {
+ return true;
+ }
+
+ public void setElements(LinkedList elements) {
+ this.elements = elements;
+ }
+
+ public LinkedList getElements() {
+ return this.elements;
+ }
+
+ public int getStartRow() {
+ return this.startRow;
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ StringBuffer sb = new StringBuffer(super.toString());
+ sb.append(" startRow=").append(startRow);
+ return sb.toString();
+ }
+
+}
import org.apache.fop.fo.flow.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.LengthRangeProperty;
+import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
+import org.apache.fop.layoutmgr.KnuthElement;
+import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.BreakPoss;
* If there are row spanning cells then these cells belong to this row
* but effect the occupied columns of future rows.
*/
-public class Row extends BlockStackingLayoutManager {
+public class Row extends BlockStackingLayoutManager implements BlockLevelLayoutManager {
private TableRow fobj;
log.error("Overlapping cell at position " + colnum);
}
//Add cell info for primary slot
- GridUnit info = new GridUnit(cellLM);
+ OldGridUnit info = new OldGridUnit(cellLM);
info.row = this;
gridUnits.set(colnum - 1, info);
info.column = getColumn(colnum);
//Add cell infos on spanned slots if any
for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
colnum++;
- GridUnit infoSpan = new GridUnit(cellLM, j);
+ OldGridUnit infoSpan = new OldGridUnit(cellLM, j);
infoSpan.row = this;
infoSpan.column = getColumn(colnum);
if (colnum > gridUnits.size()) {
private void postProcessGridUnits() {
for (int pos = 1; pos <= gridUnits.size(); pos++) {
- GridUnit gu = (GridUnit)gridUnits.get(pos - 1);
+ OldGridUnit gu = (OldGridUnit)gridUnits.get(pos - 1);
//Empty grid units
if (gu == null) {
//Add grid unit
- gu = new GridUnit(null);
+ gu = new OldGridUnit(null);
gu.row = this;
gu.column = getColumn(pos);
gridUnits.set(pos - 1, gu);
//Border resolution now that the empty grid units are filled
for (int pos = 1; pos <= gridUnits.size(); pos++) {
- GridUnit starting = (GridUnit)gridUnits.get(pos - 1);
+ OldGridUnit starting = (OldGridUnit)gridUnits.get(pos - 1);
//Border resolution
if (getTable().isSeparateBorderModel()) {
starting.assignBorder(starting.layoutManager);
} else {
//Neighbouring grid unit at start edge
- GridUnit start = null;
+ OldGridUnit start = null;
int find = pos - 1;
while (find >= 1) {
- GridUnit candidate = (GridUnit)gridUnits.get(find - 1);
+ OldGridUnit candidate = (OldGridUnit)gridUnits.get(find - 1);
if (candidate.isLastGridUnitColSpan()) {
start = candidate;
break;
}
//Ending grid unit for current cell
- GridUnit ending = null;
+ OldGridUnit ending = null;
if (starting.layoutManager != null) {
pos += starting.layoutManager.getFObj().getNumberColumnsSpanned() - 1;
}
- ending = (GridUnit)gridUnits.get(pos - 1);
+ ending = (OldGridUnit)gridUnits.get(pos - 1);
//Neighbouring grid unit at end edge
- GridUnit end = null;
+ OldGridUnit end = null;
find = pos + 1;
while (find <= gridUnits.size()) {
- GridUnit candidate = (GridUnit)gridUnits.get(find - 1);
+ OldGridUnit candidate = (OldGridUnit)gridUnits.get(find - 1);
if (candidate.isPrimaryGridUnit()) {
end = candidate;
break;
find++;
}
CommonBorderPaddingBackground borders = new CommonBorderPaddingBackground();
- GridUnit.resolveBorder(getTable(), borders, starting,
+ OldGridUnit.resolveBorder(getTable(), borders, starting,
(start != null ? start : null),
CommonBorderPaddingBackground.START);
starting.effBorders = borders;
if (starting != ending) {
borders = new CommonBorderPaddingBackground();
}
- GridUnit.resolveBorder(getTable(), borders, ending,
+ OldGridUnit.resolveBorder(getTable(), borders, ending,
(end != null ? end : null),
CommonBorderPaddingBackground.END);
ending.effBorders = borders;
* @param pos the position of the cell (must be >= 1)
* @return the cell info object
*/
- protected GridUnit getCellInfo(int pos) {
+ protected OldGridUnit getCellInfo(int pos) {
if (gridUnits == null) {
prepareGridUnits();
}
if (pos <= gridUnits.size()) {
- return (GridUnit)gridUnits.get(pos - 1);
+ return (OldGridUnit)gridUnits.get(pos - 1);
} else {
return null;
}
*/
public BreakPoss getNextBreakPoss(LayoutContext context) {
//LayoutManager curLM; // currently active LM
- GridUnit curGridUnit; //currently active grid unit
+ OldGridUnit curGridUnit; //currently active grid unit
BreakPoss lastPos = null;
List breakList = new java.util.ArrayList();
getGridUnitsForCell(cellLM, startColumn, spannedGridUnits);
int childRefIPD = 0;
for (int i = 0; i < spannedGridUnits.size(); i++) {
- Column col = ((GridUnit)spannedGridUnits.get(i)).column;
+ Column col = ((OldGridUnit)spannedGridUnits.get(i)).column;
childRefIPD += col.getWidth().getValue();
}
childLC.setRefIPD(childRefIPD);
*/
protected void reset(Position pos) {
//LayoutManager curLM; // currently active LM
- GridUnit curGridUnit;
+ OldGridUnit curGridUnit;
int cellIndex = 1;
if (pos == null) {
}
}
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#negotiateBPDAdjustment(int, org.apache.fop.layoutmgr.KnuthElement)
+ */
+ public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#discardSpace(org.apache.fop.layoutmgr.KnuthGlue)
+ */
+ public void discardSpace(KnuthGlue spaceGlue) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether()
+ */
+ public boolean mustKeepTogether() {
+ //TODO Keeps will have to be more sophisticated sooner or later
+ return ((BlockLevelLayoutManager)getParent()).mustKeepTogether()
+ || !fobj.getKeepTogether().getWithinPage().isAuto()
+ || !fobj.getKeepTogether().getWithinColumn().isAuto();
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithPrevious()
+ */
+ public boolean mustKeepWithPrevious() {
+ return !fobj.getKeepWithPrevious().getWithinPage().isAuto()
+ || !fobj.getKeepWithPrevious().getWithinColumn().isAuto();
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithNext()
+ */
+ public boolean mustKeepWithNext() {
+ return !fobj.getKeepWithNext().getWithinPage().isAuto()
+ || !fobj.getKeepWithNext().getWithinColumn().isAuto();
+ }
+
}
--- /dev/null
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.table;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.properties.LengthRangeProperty;
+import org.apache.fop.layoutmgr.KnuthBox;
+import org.apache.fop.layoutmgr.KnuthElement;
+import org.apache.fop.layoutmgr.KnuthGlue;
+import org.apache.fop.layoutmgr.KnuthPenalty;
+import org.apache.fop.layoutmgr.KnuthPossPosIter;
+import org.apache.fop.layoutmgr.LayoutContext;
+import org.apache.fop.layoutmgr.LayoutManager;
+import org.apache.fop.layoutmgr.LeafPosition;
+import org.apache.fop.layoutmgr.NonLeafPosition;
+import org.apache.fop.layoutmgr.Position;
+import org.apache.fop.layoutmgr.PositionIterator;
+import org.apache.fop.traits.MinOptMax;
+
+/**
+ * Layout manager for table contents, particularly managing the creation of combined element lists.
+ */
+public class TableContentLayoutManager {
+
+ /** Logger **/
+ private static Log log = LogFactory.getLog(TableContentLayoutManager.class);
+
+ private TableLayoutManager tableLM;
+ private TableRowIterator trIter;
+
+
+ public TableContentLayoutManager(TableLayoutManager parent) {
+ this.tableLM = parent;
+ this.trIter = new TableRowIterator(getTableLM().getTable(), getTableLM().getColumns());
+ }
+
+ public TableLayoutManager getTableLM() {
+ return this.tableLM;
+ }
+
+ public ColumnSetup getColumns() {
+ return getTableLM().getColumns();
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.LayoutManager#getNextKnuthElements(org.apache.fop.layoutmgr.LayoutContext, int)
+ */
+ public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
+ System.out.println(getTableLM().getColumns());
+ LinkedList returnList = new LinkedList();
+ TableRowIterator.EffRow row = null;
+ while ((row = trIter.getNextRow()) != null) {
+ List pgus = new java.util.ArrayList();
+ TableRow tableRow = null;
+ int maxCellHeight = 0;
+ for (int j = 0; j < row.getGridUnits().size(); j++) {
+ GridUnit gu = (GridUnit)row.getGridUnits().get(j);
+ if (gu.isPrimary() && !gu.isEmpty()) {
+ PrimaryGridUnit primary = (PrimaryGridUnit)gu;
+ primary.getCellLM().setParent(tableLM);
+
+ //Calculate width of cell
+ int spanWidth = 0;
+ for (int i = primary.getStartRow();
+ i < primary.getStartRow() + primary.getCell().getNumberColumnsSpanned();
+ i++) {
+ spanWidth += getTableLM().getColumns().getColumn(i + 1)
+ .getColumnWidth().getValue();
+ }
+ log.info("spanWidth=" + spanWidth);
+ LayoutContext childLC = new LayoutContext(0);
+ childLC.setStackLimit(context.getStackLimit()); //necessary?
+ childLC.setRefIPD(spanWidth);
+
+ LinkedList elems = primary.getCellLM().getNextKnuthElements(childLC, alignment);
+ primary.setElements(elems);
+ log.debug("Elements: " + elems);
+ int len = calcCellHeightFromContents(elems);
+ pgus.add(primary);
+ maxCellHeight = Math.max(maxCellHeight, len);
+ if (len > row.getHeight().opt) {
+ row.setHeight(new MinOptMax(len));
+ }
+ LengthRangeProperty bpd = primary.getCell().getBlockProgressionDimension();
+ if (!bpd.getOptimum().isAuto()) {
+ if (bpd.getOptimum().getLength().getValue() > row.getHeight().opt) {
+ row.setHeight(new MinOptMax(bpd.getOptimum().getLength().getValue()));
+ }
+ }
+ if (tableRow == null) {
+ tableRow = primary.getRow();
+ }
+ }
+ }
+
+ if (tableRow != null) {
+ LengthRangeProperty bpd = tableRow.getBlockProgressionDimension();
+ if (!bpd.getOptimum().isAuto()) {
+ if (bpd.getOptimum().getLength().getValue() > row.getHeight().opt) {
+ row.setHeight(new MinOptMax(bpd.getOptimum().getLength().getValue()));
+ }
+ }
+ }
+ log.debug(row);
+
+ PrimaryGridUnit[] pguArray = new PrimaryGridUnit[pgus.size()];
+ pguArray = (PrimaryGridUnit[])pgus.toArray(pguArray);
+ LinkedList returnedList = getCombinedKnuthElementsForRow(pguArray, row);
+ if (returnedList != null) {
+ returnList.addAll(returnedList);
+ }
+
+ if (row.getHeight().opt > maxCellHeight) {
+ //TODO Fix me (additional spaces)
+ log.warn("Knuth elements for additional space coming from height/bpd propertes NYI");
+ int space = row.getHeight().opt - maxCellHeight;
+ returnList.add(new KnuthGlue(space, 0, 0, new Position(null), false));
+ }
+ }
+ return returnList;
+ }
+
+ private LinkedList getCombinedKnuthElementsForRow(PrimaryGridUnit[] pguArray,
+ TableRowIterator.EffRow row) {
+ List[] elementLists = new List[pguArray.length];
+ for (int i = 0; i < pguArray.length; i++) {
+ //Copy elements to array lists to improve element access performance
+ elementLists[i] = new java.util.ArrayList(pguArray[i].getElements());
+ }
+ int[] index = new int[pguArray.length];
+ int[] start = new int[pguArray.length];
+ int[] end = new int[pguArray.length];
+ int[] widths = new int[pguArray.length];
+ int[] fullWidths = new int[pguArray.length];
+ Arrays.fill(end, -1);
+
+ int totalHeight = 0;
+ for (int i = 0; i < pguArray.length; i++) {
+ fullWidths[i] = calcCellHeightFromContents(pguArray[i].getElements());
+ totalHeight = Math.max(totalHeight, fullWidths[i]);
+ }
+ int laststep = 0;
+ int step;
+ int addedBoxLen = 0;
+ LinkedList returnList = new LinkedList();
+ while ((step = getNextStep(laststep, elementLists, index, start, end,
+ widths, fullWidths)) > 0) {
+ int increase = step - laststep;
+ int penaltyLen = step + getMaxRemainingHeight(fullWidths, widths) - totalHeight;
+ int boxLen = step - addedBoxLen - penaltyLen;
+ addedBoxLen += boxLen;
+
+ log.debug(step + " " + increase + " box=" + boxLen + " penalty=" + penaltyLen);
+
+ //Put all involved grid units into a list
+ List gridUnitParts = new java.util.ArrayList(pguArray.length);
+ for (int i = 0; i < pguArray.length; i++) {
+ if (end[i] >= start[i]) {
+ gridUnitParts.add(new GridUnitPart(pguArray[i], start[i], end[i]));
+ }
+ }
+
+ //Create elements for step
+ TableContentPosition tcpos = new TableContentPosition(getTableLM(),
+ gridUnitParts, row);
+ returnList.add(new KnuthBox(boxLen, tcpos, false));
+ returnList.add(new KnuthPenalty(penaltyLen, 0, false, null, false));
+ laststep = step;
+ }
+ return returnList;
+ }
+
+ private int getMaxRemainingHeight(int[] fullWidths, int[] widths) {
+ int maxW = 0;
+ for (int i = 0; i < fullWidths.length; i++) {
+ maxW = Math.max(maxW, fullWidths[i] - widths[i]);
+ }
+ return maxW;
+ }
+
+ private int getNextStep(int laststep, List[] elementLists, int[] index,
+ int[] start, int[] end, int[] widths, int[] fullWidths) {
+ int backupWidths[] = new int[start.length];
+ System.arraycopy(widths, 0, backupWidths, 0, backupWidths.length);
+ //set starting points
+ for (int i = 0; i < start.length; i++) {
+ if (end[i] < elementLists[i].size()) {
+ start[i] = end[i] + 1;
+ } else {
+ start[i] = -1; //end of list reached
+ end[i] = -1;
+ }
+ }
+ //Arrays.fill(widths, laststep);
+
+ //Get next possible sequence for each cell
+ int seqCount = 0;
+ for (int i = 0; i < start.length; i++) {
+ while (end[i] + 1 < elementLists[i].size()) {
+ end[i]++;
+ KnuthElement el = (KnuthElement)elementLists[i].get(end[i]);
+ if (el.isPenalty()) {
+ if (el.getP() < KnuthElement.INFINITE) {
+ //First legal break point
+ break;
+ }
+ } else if (el.isGlue()) {
+ KnuthElement prev = (KnuthElement)elementLists[i].get(end[i] - 1);
+ if (prev.isBox()) {
+ //Second legal break point
+ break;
+ }
+ widths[i] += el.getW();
+ } else {
+ widths[i] += el.getW();
+ }
+ }
+ if (end[i] < start[i]) {
+ widths[i] = backupWidths[i];
+ } else {
+ seqCount++;
+ }
+ //System.out.println("part " + start[i] + "-" + end[i] + " " + widths[i]);
+ }
+ if (seqCount == 0) {
+ return 0;
+ }
+
+ //Determine smallest possible step
+ int minStep = Integer.MAX_VALUE;
+ for (int i = 0; i < widths.length; i++) {
+ if (end[i] >= start[i]) {
+ minStep = Math.min(widths[i], minStep);
+ }
+ }
+
+ //Reset bigger-than-minimum sequences
+ for (int i = 0; i < widths.length; i++) {
+ if (widths[i] > minStep) {
+ widths[i] = backupWidths[i];
+ end[i] = start[i] - 1;
+ }
+ }
+ if (log.isDebugEnabled()) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < widths.length; i++) {
+ if (end[i] >= start[i]) {
+ sb.append(i + ": " + start[i] + "-" + end[i] + "(" + widths[i] + "), ");
+ } else {
+ sb.append(i + ": skip, ");
+ }
+ }
+ log.debug(sb.toString());
+ }
+ return minStep;
+ }
+
+ private int calcCellHeightFromContents(List elems, int start, int end) {
+ ListIterator iter = elems.listIterator(start);
+ int count = end - start + 1;
+ int len = 0;
+ while (iter.hasNext()) {
+ KnuthElement el = (KnuthElement)iter.next();
+ if (el.isBox()) {
+ len += el.getW();
+ } else if (el.isGlue()) {
+ len += el.getW();
+ } else {
+ log.debug("Ignoring penalty: " + el);
+ //ignore penalties
+ }
+ count--;
+ if (count == 0) {
+ break;
+ }
+ }
+ return len;
+ }
+
+ private int calcCellHeightFromContents(List elems) {
+ return calcCellHeightFromContents(elems, 0, elems.size() - 1);
+ }
+
+ protected int getXOffsetOfGridUnit(GridUnit gu) {
+ int col = gu.getStartCol();
+ return getTableLM().getColumns().getXOffset(col + 1);
+ }
+
+ public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) {
+ int colCount = getColumns().getColumnCount();
+ TableRowIterator.EffRow lastRow = null;
+ int lastRowHeight = 0;
+ int yoffset = 0;
+
+ //These three variables are our buffer to recombine the individual steps into cells
+ PrimaryGridUnit[] gridUnits = new PrimaryGridUnit[colCount];
+ int[] start = new int[colCount];
+ int[] end = new int[colCount];
+
+ //Iterate over all steps
+ while (parentIter.hasNext()) {
+ Position pos = (Position)parentIter.next();
+ //NonLeafPosition nlfp = (NonLeafPosition)pos;
+ //if (nlfp.getPosition() instanceof TableContentPosition) {
+ // TableContentPosition pos = (TableContentPosition)nlfp.getPosition();
+ if (pos instanceof TableContentPosition) {
+ TableContentPosition tcpos = (TableContentPosition)pos;
+ if (lastRow != tcpos.row && lastRow != null) {
+ //yoffset += lastRow.getHeight().opt;
+ yoffset += lastRowHeight;
+ }
+ lastRow = tcpos.row;
+ Iterator iter = tcpos.gridUnitParts.iterator();
+ //Iterate over all grid units in the current step
+ while (iter.hasNext()) {
+ GridUnitPart gup = (GridUnitPart)iter.next();
+ log.debug(">" + gup);
+ int colIndex = gup.pgu.getStartCol();
+ if (gridUnits[colIndex] != gup.pgu) {
+ gridUnits[colIndex] = gup.pgu;
+ start[colIndex] = gup.start;
+ end[colIndex] = gup.end;
+ } else {
+ end[colIndex] = gup.end;
+ }
+ }
+ int maxLen = 0;
+ for (int i = 0; i < gridUnits.length; i++) {
+ if ((gridUnits[i] != null)
+ && (end[i] == gridUnits[i].getElements().size() - 1)) {
+ log.debug("getting len for " + i + " "
+ + start[i] + "-" + end[i]);
+ int len = calcCellHeightFromContents(
+ gridUnits[i].getElements(), start[i], end[i]);
+ log.debug("len of part: " + len);
+ maxLen = Math.max(maxLen, len);
+ maxLen = Math.max(maxLen, getExplicitCellHeight(gridUnits[i]));
+ }
+ }
+ lastRowHeight = maxLen;
+ for (int i = 0; i < gridUnits.length; i++) {
+ if ((gridUnits[i] != null)
+ && (end[i] == gridUnits[i].getElements().size() - 1)) {
+ log.debug("flushing..." + i + " "
+ + start[i] + "-" + end[i]);
+ addAreasForCell(gridUnits[i], start[i], end[i],
+ layoutContext, lastRow, yoffset, maxLen);
+ gridUnits[i] = null;
+ start[i] = 0;
+ end[i] = 0;
+ }
+ }
+ }
+ }
+
+ int maxLen = 0;
+ for (int i = 0; i < gridUnits.length; i++) {
+ if (gridUnits[i] != null) {
+ int len = calcCellHeightFromContents(
+ gridUnits[i].getElements(), start[i], end[i]);
+ log.debug("len of part: " + len);
+ maxLen = Math.max(maxLen, len);
+ maxLen = Math.max(maxLen, getExplicitCellHeight(gridUnits[i]));
+ }
+ }
+ for (int i = 0; i < gridUnits.length; i++) {
+ if (gridUnits[i] != null) {
+ log.debug("final flushing " + i + " " + start[i] + "-" + end[i]);
+ addAreasForCell(gridUnits[i], start[i], end[i],
+ layoutContext, lastRow, yoffset, maxLen);
+ }
+ }
+
+ }
+
+ private int getExplicitCellHeight(PrimaryGridUnit pgu) {
+ int len = 0;
+ if (!pgu.getCell().getBlockProgressionDimension().getOptimum().isAuto()) {
+ len = pgu.getCell().getBlockProgressionDimension()
+ .getOptimum().getLength().getValue();
+ }
+ if (pgu.getRow() != null
+ && !pgu.getRow().getBlockProgressionDimension().getOptimum().isAuto()) {
+ len = Math.max(len, pgu.getRow().getBlockProgressionDimension()
+ .getOptimum().getLength().getValue());
+ }
+ return len;
+ }
+
+ private void addAreasForCell(PrimaryGridUnit gu, int start, int end,
+ LayoutContext layoutContext, TableRowIterator.EffRow row,
+ int yoffset, int rowHeight) {
+ Cell cellLM = gu.getCellLM();
+ cellLM.setXOffset(getXOffsetOfGridUnit(gu));
+ cellLM.setYOffset(yoffset);
+ cellLM.setRowHeight(rowHeight);
+ //cellLM.setRowHeight(row.getHeight().opt);
+ cellLM.addAreas(new KnuthPossPosIter(gu.getElements(),
+ start, end + 1), layoutContext);
+ }
+
+ private class GridUnitPart {
+
+ protected PrimaryGridUnit pgu;
+ protected int start;
+ protected int end;
+
+ protected GridUnitPart(PrimaryGridUnit pgu, int start, int end) {
+ this.pgu = pgu;
+ this.start = start;
+ this.end = end;
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ StringBuffer sb = new StringBuffer("Part: ");
+ sb.append(start).append("-").append(end);
+ sb.append(" ").append(pgu);
+ return sb.toString();
+ }
+
+ }
+
+ public class TableContentPosition extends Position {
+
+ protected List gridUnitParts;
+ protected TableRowIterator.EffRow row;
+
+ protected TableContentPosition(LayoutManager lm, List gridUnitParts,
+ TableRowIterator.EffRow row) {
+ super(lm);
+ this.gridUnitParts = gridUnitParts;
+ this.row = row;
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ StringBuffer sb = new StringBuffer("TableContentPosition {");
+ sb.append(gridUnitParts);
+ sb.append("}");
+ return sb.toString();
+ }
+ }
+
+}
import org.apache.fop.datatypes.Length;
import org.apache.fop.datatypes.PercentBase;
import org.apache.fop.fo.flow.Table;
+import org.apache.fop.fo.flow.TableColumn;
import org.apache.fop.fo.properties.TableColLength;
+import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
+import org.apache.fop.layoutmgr.KnuthElement;
+import org.apache.fop.layoutmgr.KnuthGlue;
+import org.apache.fop.layoutmgr.KnuthPenalty;
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.NonLeafPosition;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.BreakPossPosIter;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.traits.SpaceVal;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
/**
* LayoutManager for a table FO.
- * A table consists of columns, table header, table footer and multiple
+ * A table consists of oldColumns, 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 table then creates areas for the oldColumns, bodies and rows
* the render background.
*/
-public class TableLayoutManager extends BlockStackingLayoutManager {
+public class TableLayoutManager extends BlockStackingLayoutManager
+ implements BlockLevelLayoutManager {
private Table fobj;
- private List columns = null;
+ private TableContentLayoutManager contentLM;
+ private List oldColumns = null;
+ private ColumnSetup columns = null;
private Block curBlockArea;
public TableLayoutManager(Table node) {
super(node);
fobj = node;
+ this.columns = new ColumnSetup(node);
}
/** @return the table FO */
}
/**
- * Set the columns for this table.
+ * Set the oldColumns for this table.
*
* @param cols the list of column layout managers
*/
public void setColumns(List cols) {
- columns = cols;
+ oldColumns = cols;
}
+ public ColumnSetup getColumns() {
+ return this.columns;
+ }
+
/** @see org.apache.fop.layoutmgr.AbstractLayoutManager#initProperties() */
protected void initProperties() {
super.initProperties();
return iIndents;
}
+ /**
+ * @see org.apache.fop.layoutmgr.LayoutManager#getNextKnuthElements(org.apache.fop.layoutmgr.LayoutContext, int)
+ */
+ public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
+
+ Body curLM; // currently active LM
+
+ referenceIPD = context.getRefIPD();
+ if (fobj.getInlineProgressionDimension().getOptimum().getEnum() != EN_AUTO) {
+ referenceIPD = fobj.getInlineProgressionDimension().getOptimum().getLength().getValue();
+ }
+ if (referenceIPD > context.getRefIPD()) {
+ log.warn("Allocated IPD exceeds available reference IPD");
+ }
+ int contentIPD = referenceIPD - getIPIndents();
+
+ MinOptMax stackSize = new MinOptMax();
+ //Add spacing
+ if (spaceAfter != null) {
+ stackSize.add(spaceAfter);
+ }
+ if (spaceBefore != null) {
+ stackSize.add(spaceBefore);
+ }
+
+ BreakPoss lastPos = null;
+
+ fobj.setLayoutDimension(PercentBase.BLOCK_IPD, referenceIPD);
+ fobj.setLayoutDimension(PercentBase.BLOCK_BPD, context.getStackLimit().opt);
+ fobj.setLayoutDimension(PercentBase.REFERENCE_AREA_IPD, referenceIPD);
+ fobj.setLayoutDimension(PercentBase.REFERENCE_AREA_BPD, context.getStackLimit().opt);
+
+ /*
+ if (oldColumns == null) {
+ createColumnsFromFirstRow();
+ }*/
+
+ // either works out table of column widths or if proportional-column-width function
+ // is used works out total factor, so that value of single unit can be computed.
+ int sumCols = 0;
+ float factors = 0;
+ for (Iterator i = columns.iterator(); i.hasNext(); ) {
+ TableColumn column = (TableColumn) i.next();
+ Length width = column.getColumnWidth();
+ sumCols += width.getValue();
+ if (width instanceof TableColLength) {
+ factors += ((TableColLength) width).getTableUnits();
+ }
+ }
+ // sets TABLE_UNITS in case where one or more oldColumns is defined using
+ // proportional-column-width
+ if (sumCols < contentIPD) {
+ if (fobj.getLayoutDimension(PercentBase.TABLE_UNITS).floatValue() == 0.0) {
+ fobj.setLayoutDimension(PercentBase.TABLE_UNITS,
+ (contentIPD - sumCols) / factors);
+ }
+ }
+
+ LinkedList headerElements = null;
+ LinkedList footerElements = null;
+ if (getTable().getTableHeader() != null) {
+ Body tableHeader = new Body(getTable().getTableHeader());
+ tableHeader.setParent(this);
+ headerElements = getKnuthElementsForHeaderFooter(
+ tableHeader, context, alignment);
+ }
+ if (getTable().getTableFooter() != null) {
+ Body tableFooter = new Body(getTable().getTableFooter());
+ tableFooter.setParent(this);
+ footerElements = getKnuthElementsForHeaderFooter(
+ tableFooter, context, alignment);
+ }
+
+ LinkedList returnedList = null;
+ LinkedList contentList = new LinkedList();
+ LinkedList returnList = new LinkedList();
+ Position returnPosition = new NonLeafPosition(this, null);
+ Body prevLM = null;
+
+ LayoutContext childLC = new LayoutContext(0);
+ childLC.setStackLimit(
+ MinOptMax.subtract(context.getStackLimit(),
+ stackSize));
+ childLC.setRefIPD(context.getRefIPD());
+
+ contentLM = new TableContentLayoutManager(this);
+ returnedList = contentLM.getNextKnuthElements(childLC, alignment);
+ log.debug(returnedList);
+
+ if (returnedList.size() == 1
+ && ((KnuthElement) returnedList.getFirst()).isPenalty()
+ && ((KnuthPenalty) returnedList.getFirst()).getP() == -KnuthElement.INFINITE) {
+ // a descendant of this block has break-before
+ if (returnList.size() == 0) {
+ // the first child (or its first child ...) has
+ // break-before;
+ // all this block, including space before, will be put in
+ // the
+ // following page
+ //FIX ME
+ //bSpaceBeforeServed = false;
+ }
+ contentList.addAll(returnedList);
+
+ // "wrap" the Position inside each element
+ // moving the elements from contentList to returnList
+ returnedList = new LinkedList();
+ wrapPositionElements(contentList, returnList);
+
+ return returnList;
+ } else {
+ if (prevLM != null) {
+ // there is a block handled by prevLM
+ // before the one handled by curLM
+ if (mustKeepTogether()
+ /*|| prevLM.mustKeepWithNext()
+ || curLM.mustKeepWithPrevious()*/) {
+ // add an infinite penalty to forbid a break between
+ // blocks
+ contentList.add(new KnuthPenalty(0,
+ KnuthElement.INFINITE, false,
+ new Position(this), false));
+ } else if (!((KnuthElement) contentList.getLast()).isGlue()) {
+ // add a null penalty to allow a break between blocks
+ contentList.add(new KnuthPenalty(0, 0, false,
+ new Position(this), false));
+ } else {
+ // the last element in contentList is a glue;
+ // it is a feasible breakpoint, there is no need to add
+ // a penalty
+ }
+ }
+ contentList.addAll(returnedList);
+ /*
+ if (returnedList.size() == 0) {
+ //Avoid NoSuchElementException below (happens with empty blocks)
+ continue;
+ }*/
+ if (((KnuthElement) returnedList.getLast()).isPenalty()
+ && ((KnuthPenalty) returnedList.getLast()).getP() == -KnuthElement.INFINITE) {
+ // a descendant of this block has break-after
+ if (false /*curLM.isFinished()*/) {
+ // there is no other content in this block;
+ // it's useless to add space after before a page break
+ setFinished(true);
+ }
+
+ returnedList = new LinkedList();
+ wrapPositionElements(contentList, returnList);
+
+ return returnList;
+ }
+
+ }
+ wrapPositionElements(contentList, returnList);
+ setFinished(true);
+ return returnList;
+ }
+
/**
* Get the next break possibility.
* The break possibility depends on the height of the header and footer
*
* @param context the layout context for finding breaks
* @return the next break possibility
- */
- public BreakPoss getNextBreakPoss(LayoutContext context) {
+ *//*
+ public BreakPoss getNextBreakPossOLDOLDOLD(LayoutContext context) {
Body curLM; // currently active LM
referenceIPD = context.getRefIPD();
fobj.setLayoutDimension(PercentBase.REFERENCE_AREA_IPD, referenceIPD);
fobj.setLayoutDimension(PercentBase.REFERENCE_AREA_BPD, context.getStackLimit().opt);
- if (columns == null) {
+ if (columns.getColumnCount() == 0) {
createColumnsFromFirstRow();
}
// is used works out total factor, so that value of single unit can be computed.
int sumCols = 0;
float factors = 0;
- if (columns != null) {
- for (Iterator i = columns.iterator(); i.hasNext(); ) {
+ if (oldColumns != null) {
+ for (Iterator i = oldColumns.iterator(); i.hasNext(); ) {
Column column = (Column) i.next();
Length width = column.getWidth();
sumCols += width.getValue();
}
}
}
- // sets TABLE_UNITS in case where one or more columns is defined using proportional-column-width
+ // sets TABLE_UNITS in case where one or more oldColumns is defined using
+ // proportional-column-width
if (sumCols < contentIPD) {
if (fobj.getLayoutDimension(PercentBase.TABLE_UNITS).floatValue() == 0.0) {
fobj.setLayoutDimension(PercentBase.TABLE_UNITS,
if (!getTable().omitHeaderAtBreak() || !firstRowHandled) {
Body tableHeader = new Body(getTable().getTableHeader());
tableHeader.setParent(this);
- headerBreak = getHeight(tableHeader, context);
+ headerBreak = getHeightOLDOLDOLD(tableHeader, context);
headerSize = headerBreak.getStackingSize();
stackSize.add(headerSize);
}
if (getTable().getTableFooter() != null) {
Body tableFooter = new Body(getTable().getTableFooter());
tableFooter.setParent(this);
- footerBreak = getHeight(tableFooter, context);
+ footerBreak = getHeightOLDOLDOLD(tableFooter, context);
footerSize = footerBreak.getStackingSize();
stackSize.add(footerSize);
}
stackSize));
childLC.setRefIPD(ipd);
- curLM.setColumns(columns);
+ curLM.setColumns(oldColumns);
boolean over = false;
while (!curLM.isFinished()) {
}
setFinished(true);
return null;
- }
+ }*/
+ /*
private void createColumnsFromFirstRow() {
- this.columns = new java.util.ArrayList();
- //TODO Create columns from first row here
+ this.oldColumns = new java.util.ArrayList();
+ //TODO Create oldColumns from first row here
//--> rule 2 in "fixed table layout", see CSS2, 17.5.2
- //Alternative: extend columns on-the-fly, but in this case we need the
+ //Alternative: extend oldColumns on-the-fly, but in this case we need the
//new property evaluation context so proportional-column-width() works
//correctly.
- if (columns.size() == 0) {
+ if (oldColumns.size() == 0) {
Column col = new Column(getTable().getDefaultColumn());
col.setParent(this);
- this.columns.add(col);
+ this.oldColumns.add(col);
}
- }
+ }*/
/**
* @param column the column to check
* @return true if the column is the first column
*/
public boolean isFirst(Column column) {
- return (this.columns.size() == 0 || this.columns.get(0) == column);
+ return (this.oldColumns.size() == 0 || this.oldColumns.get(0) == column);
}
/**
* @return true if the column is the last column
*/
public boolean isLast(Column column) {
- return (this.columns.size() == 0 || this.columns.get(columns.size() - 1) == column);
+ return (this.oldColumns.size() == 0 || this.oldColumns.get(oldColumns.size() - 1) == column);
}
/**
* @param context the parent layout context
* @return the break possibility containing the stacking size
*/
- protected BreakPoss getHeight(Body lm, LayoutContext context) {
+ protected LinkedList getKnuthElementsForHeaderFooter(Body lm, LayoutContext context,
+ int alignment) {
int referenceIPD = context.getRefIPD();
int contentIPD = referenceIPD - getIPIndents();
BreakPoss bp;
childLC.setStackLimit(context.getStackLimit());
childLC.setRefIPD(contentIPD);
- lm.setColumns(columns);
+ lm.setColumns(oldColumns);
+
+ LinkedList returnedList = null;
+ LinkedList contentList = new LinkedList();
+ LinkedList returnList = new LinkedList();
+ Position returnPosition = new NonLeafPosition(this, null);
+
+ Row curLM; // currently active LM
+ Row prevLM = null; // previously active LM
+ while ((curLM = (Row)getChildLM()) != null) {
+
+ // get elements from curLM
+ returnedList = curLM.getNextKnuthElements(childLC, alignment);
+ /*
+ if (returnedList.size() == 1
+ && ((KnuthElement) returnedList.getFirst()).isPenalty()
+ && ((KnuthPenalty) returnedList.getFirst()).getP() == -KnuthElement.INFINITE) {
+ // a descendant of this block has break-before
+ if (returnList.size() == 0) {
+ // the first child (or its first child ...) has
+ // break-before;
+ // all this block, including space before, will be put in
+ // the
+ // following page
+ bSpaceBeforeServed = false;
+ }
+ contentList.addAll(returnedList);
+
+ // "wrap" the Position inside each element
+ // moving the elements from contentList to returnList
+ returnedList = new LinkedList();
+ wrapPositionElements(contentList, returnList);
+
+ return returnList;
+ } else*/ {
+ if (prevLM != null) {
+ // there is a block handled by prevLM
+ // before the one handled by curLM
+ if (mustKeepTogether()
+ || prevLM.mustKeepWithNext()
+ || curLM.mustKeepWithPrevious()) {
+ // add an infinite penalty to forbid a break between
+ // blocks
+ contentList.add(new KnuthPenalty(0,
+ KnuthElement.INFINITE, false,
+ new Position(this), false));
+ } else if (!((KnuthElement) contentList.getLast()).isGlue()) {
+ // add a null penalty to allow a break between blocks
+ contentList.add(new KnuthPenalty(0, 0, false,
+ new Position(this), false));
+ } else {
+ // the last element in contentList is a glue;
+ // it is a feasible breakpoint, there is no need to add
+ // a penalty
+ }
+ }
+ contentList.addAll(returnedList);
+ if (returnedList.size() == 0) {
+ //Avoid NoSuchElementException below (happens with empty blocks)
+ continue;
+ }
+ if (((KnuthElement) returnedList.getLast()).isPenalty()
+ && ((KnuthPenalty) returnedList.getLast()).getP() == -KnuthElement.INFINITE) {
+ // a descendant of this block has break-after
+ if (curLM.isFinished()) {
+ // there is no other content in this block;
+ // it's useless to add space after before a page break
+ setFinished(true);
+ }
+
+ returnedList = new LinkedList();
+ wrapPositionElements(contentList, returnList);
+
+ return returnList;
+ }
+ }
+ prevLM = curLM;
+ }
+
+ /*
+ List breaks = new java.util.ArrayList();
+ while (!lm.isFinished()) {
+ if ((bp = lm.getNextBreakPoss(childLC)) != null) {
+ stackSize.add(bp.getStackingSize());
+ breaks.add(bp);
+ childLC.setStackLimit(MinOptMax.subtract(
+ context.getStackLimit(), stackSize));
+ }
+ }
+ BreakPoss breakPoss = new BreakPoss(
+ new SectionPosition(this, breaks.size() - 1, breaks));
+ breakPoss.setStackingSize(stackSize);
+ return breakPoss;*/
+
+ if (returnList.size() > 0) {
+ return returnList;
+ } else {
+ return null;
+ }
+
+ }
+
+ /**
+ * Get the break possibility and height of the table header or footer.
+ *
+ * @param lm the header or footer layout manager
+ * @param context the parent layout context
+ * @return the break possibility containing the stacking size
+ */
+ protected BreakPoss getHeightOLDOLDOLD(Body lm, LayoutContext context) {
+ int referenceIPD = context.getRefIPD();
+ int contentIPD = referenceIPD - getIPIndents();
+ BreakPoss bp;
+
+ MinOptMax stackSize = new MinOptMax();
+
+ LayoutContext childLC = new LayoutContext(0);
+ childLC.setStackLimit(context.getStackLimit());
+ childLC.setRefIPD(contentIPD);
+
+ lm.setColumns(oldColumns);
List breaks = new java.util.ArrayList();
while (!lm.isFinished()) {
/**
* The table area is a reference area that contains areas for
- * columns, bodies, rows and the contents are in cells.
+ * oldColumns, bodies, rows and the contents are in cells.
*
* @param parentIter the position iterator
* @param layoutContext the layout context for adding areas
}
}
- int iStartPos = 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 = (Body)breakPosIter.getNextChildLM()) != null) {
- childLM.setXOffset(startXOffset);
- childLM.setYOffset(tableHeight);
- childLM.addAreas(breakPosIter, lc);
- tableHeight += childLM.getBodyHeight();
- }
- }
+ contentLM.addAreas(parentIter, layoutContext);
// add footer areas
if (footerBreak != null) {
}
}
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#negotiateBPDAdjustment(int, org.apache.fop.layoutmgr.KnuthElement)
+ */
+ public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#discardSpace(org.apache.fop.layoutmgr.KnuthGlue)
+ */
+ public void discardSpace(KnuthGlue spaceGlue) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether()
+ */
+ public boolean mustKeepTogether() {
+ //TODO Keeps will have to be more sophisticated sooner or later
+ return ((BlockLevelLayoutManager)getParent()).mustKeepTogether()
+ || !fobj.getKeepTogether().getWithinPage().isAuto()
+ || !fobj.getKeepTogether().getWithinColumn().isAuto();
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithPrevious()
+ */
+ public boolean mustKeepWithPrevious() {
+ return !fobj.getKeepWithPrevious().getWithinPage().isAuto()
+ || !fobj.getKeepWithPrevious().getWithinColumn().isAuto();
+ }
+
+ /**
+ * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithNext()
+ */
+ public boolean mustKeepWithNext() {
+ return !fobj.getKeepWithNext().getWithinPage().isAuto()
+ || !fobj.getKeepWithNext().getWithinColumn().isAuto();
+ }
+
}
--- /dev/null
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.table;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.fo.flow.Table;
+import org.apache.fop.fo.flow.TableBody;
+import org.apache.fop.fo.flow.TableCell;
+import org.apache.fop.fo.flow.TableColumn;
+import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
+import org.apache.fop.traits.MinOptMax;
+
+/**
+ * Iterator that lets the table layout manager step over all rows of a table.
+ */
+public class TableRowIterator {
+
+ /** Logger **/
+ private static Log log = LogFactory.getLog(TableRowIterator.class);
+
+ private Table table;
+ private ColumnSetup columns;
+
+ private List currentRow = new java.util.ArrayList();
+ private int currentRowIndex = -1;
+ //TODO rows should later be a Jakarta Commons LinkedList so concurrent modifications while
+ //using a ListIterator are possible
+ private List rows = new java.util.ArrayList();
+ private int indexOfFirstRowInList;
+ private int currentIndex = -1;
+
+ //prefetch state
+ private ListIterator bodyIterator = null;
+ private ListIterator childInBodyIterator = null;
+
+ public TableRowIterator(Table table, ColumnSetup columns) {
+ this.table = table;
+ this.columns = columns;
+ this.bodyIterator = table.getChildNodes();
+ }
+
+ public void prefetchAll() {
+ while (prefetchNext()) {
+ System.out.println("found row...");
+ }
+ }
+
+ public EffRow getNextRow() {
+ currentIndex++;
+ boolean moreRows = true;
+ while (moreRows && rows.size() < currentIndex + 1) {
+ moreRows = prefetchNext();
+ }
+ if (currentIndex < rows.size()) {
+ return getCachedRow(currentIndex);
+ } else {
+ return null;
+ }
+ }
+
+ public EffRow getCachedRow(int index) {
+ return (EffRow)rows.get(index);
+ }
+
+ private boolean prefetchNext() {
+ if (childInBodyIterator != null) {
+ if (!childInBodyIterator.hasNext()) {
+ //force skip on to next body
+ childInBodyIterator = null;
+ }
+ }
+ if (childInBodyIterator == null) {
+ if (bodyIterator.hasNext()) {
+ childInBodyIterator = ((TableBody)bodyIterator.next()).getChildNodes();
+ } else {
+ //no more rows
+ return false;
+ }
+ }
+ Object node = childInBodyIterator.next();
+ this.currentRow.clear();
+ this.currentRowIndex++;
+ if (node instanceof TableRow) {
+ TableRow row = (TableRow)node;
+ ListIterator cellIterator = row.getChildNodes();
+ while (cellIterator.hasNext()) {
+ this.currentRow.add(cellIterator.next());
+ }
+ } else if (node instanceof TableCell) {
+ this.currentRow.add(node);
+ if (!((TableCell)node).endsRow()) {
+ while (childInBodyIterator.hasNext()) {
+ TableCell cell = (TableCell)childInBodyIterator.next();
+ if (cell.startsRow()) {
+ //next row already starts here, one step back
+ childInBodyIterator.previous();
+ break;
+ }
+ this.currentRow.add(cell);
+ if (cell.endsRow()) {
+ break;
+ }
+ }
+ }
+ } else {
+ throw new IllegalStateException("Illegal class found: " + node.getClass().getName());
+ }
+ EffRow gridUnits = buildGridRow(this.currentRow);
+ log.debug(gridUnits);
+ rows.add(gridUnits);
+ return true;
+ }
+
+ private EffRow buildGridRow(List cells) {
+ EffRow row = new EffRow(this.currentRowIndex);
+ List gridUnits = row.getGridUnits();
+
+ //Transfer available cells to their slots
+ int colnum = 1;
+ ListIterator iter = cells.listIterator();
+ while (iter.hasNext()) {
+ TableCell cell = (TableCell)iter.next();
+ if (cell.hasColumnNumber()) {
+ colnum = cell.getColumnNumber();
+ }
+ while (colnum > gridUnits.size()) {
+ gridUnits.add(null);
+ }
+ if (gridUnits.get(colnum - 1) != null) {
+ log.error("Overlapping cell at position " + colnum);
+ //TODO throw layout exception
+ }
+ TableColumn col = columns.getColumn(colnum);
+
+ //Add grid unit for primary grid unit
+ PrimaryGridUnit gu = new PrimaryGridUnit(cell, col, colnum - 1, this.currentRowIndex);
+ gridUnits.set(colnum - 1, gu);
+
+ //Add cell infos on spanned slots if any
+ for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
+ colnum++;
+ GridUnit guSpan = new GridUnit(cell, columns.getColumn(colnum), colnum - 1, j);
+ if (colnum > gridUnits.size()) {
+ gridUnits.add(guSpan);
+ } else {
+ if (gridUnits.get(colnum - 1) != null) {
+ log.error("Overlapping cell at position " + colnum);
+ //TODO throw layout exception
+ }
+ gridUnits.set(colnum - 1, guSpan);
+ }
+ }
+ colnum++;
+ }
+
+ //Post-processing the list (looking for gaps and resolve start and end borders)
+ postProcessGridUnits(gridUnits);
+
+ return row;
+ }
+
+ private void fillEmptyGridUnits(List gridUnits) {
+ for (int pos = 1; pos <= gridUnits.size(); pos++) {
+ GridUnit gu = (GridUnit)gridUnits.get(pos - 1);
+
+ //Empty grid units
+ if (gu == null) {
+ //Add grid unit
+ gu = new PrimaryGridUnit(null, columns.getColumn(pos),
+ pos - 1, this.currentRowIndex);
+ gridUnits.set(pos - 1, gu);
+ }
+ }
+ }
+
+ private void postProcessGridUnits(List gridUnits) {
+ fillEmptyGridUnits(gridUnits);
+
+ /*
+ //Border resolution now that the empty grid units are filled
+ for (int pos = 1; pos <= gridUnits.size(); pos++) {
+ GridUnit starting = (GridUnit)gridUnits.get(pos - 1);
+
+ //Border resolution
+ if (table.isSeparateBorderModel()) {
+ starting.assignBorder(starting.layoutManager);
+ } else {
+ //Neighbouring grid unit at start edge
+ OldGridUnit start = null;
+ int find = pos - 1;
+ while (find >= 1) {
+ OldGridUnit candidate = (OldGridUnit)gridUnits.get(find - 1);
+ if (candidate.isLastGridUnitColSpan()) {
+ start = candidate;
+ break;
+ }
+ find--;
+ }
+
+ //Ending grid unit for current cell
+ OldGridUnit ending = null;
+ if (starting.layoutManager != null) {
+ pos += starting.layoutManager.getFObj().getNumberColumnsSpanned() - 1;
+ }
+ ending = (OldGridUnit)gridUnits.get(pos - 1);
+
+ //Neighbouring grid unit at end edge
+ OldGridUnit end = null;
+ find = pos + 1;
+ while (find <= gridUnits.size()) {
+ OldGridUnit candidate = (OldGridUnit)gridUnits.get(find - 1);
+ if (candidate.isPrimaryGridUnit()) {
+ end = candidate;
+ break;
+ }
+ find++;
+ }
+ CommonBorderPaddingBackground borders = new CommonBorderPaddingBackground();
+ OldGridUnit.resolveBorder(table, borders, starting,
+ (start != null ? start : null),
+ CommonBorderPaddingBackground.START);
+ starting.effBorders = borders;
+ if (starting != ending) {
+ borders = new CommonBorderPaddingBackground();
+ }
+ OldGridUnit.resolveBorder(table, borders, ending,
+ (end != null ? end : null),
+ CommonBorderPaddingBackground.END);
+ ending.effBorders = borders;
+ //Only start and end borders here, before and after during layout
+ //TODO resolve before and after borders during layout
+ }
+ }*/
+ }
+
+ public class EffRow {
+
+ private List gridUnits = new java.util.ArrayList();
+ private int index;
+ private MinOptMax height = new MinOptMax(0);
+
+ public EffRow(int index) {
+ this.index = index;
+ this.height = height;
+ }
+
+ public int getIndex() {
+ return this.index;
+ }
+
+ public MinOptMax getHeight() {
+ return this.height;
+ }
+
+ public void setHeight(MinOptMax height) {
+ this.height = height;
+ }
+
+ public List getGridUnits() {
+ return gridUnits;
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ StringBuffer sb = new StringBuffer("EffRow {");
+ sb.append(index);
+ sb.append(", ").append(height);
+ sb.append(", ").append(gridUnits.size()).append(" gu");
+ sb.append("}");
+ return sb.toString();
+ }
+ }
+
+}