diff options
author | Jeremias Maerki <jeremias@apache.org> | 2005-05-13 19:16:54 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2005-05-13 19:16:54 +0000 |
commit | e835307c9373bed3a8f41bb43e4faee15fdaf548 (patch) | |
tree | 04b42bcff456d9216e96b4cfcb572c59baba76e1 /src/java/org/apache/fop/layoutmgr/table/Row.java | |
parent | da85c0b44d79ca790b51fcc0e2700c30e72e9260 (diff) | |
download | xmlgraphics-fop-e835307c9373bed3a8f41bb43e4faee15fdaf548.tar.gz xmlgraphics-fop-e835307c9373bed3a8f41bb43e4faee15fdaf548.zip |
Merge of branch Temp_KnuthStylePageBreaking back into HEAD.
Temp_KnuthStylePageBreaking branch and HEAD have been tagged prior to the merge, so merging uncommitted work from the branch should be easier.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198627 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/layoutmgr/table/Row.java')
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/table/Row.java | 623 |
1 files changed, 0 insertions, 623 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/table/Row.java b/src/java/org/apache/fop/layoutmgr/table/Row.java deleted file mode 100644 index c3d06d435..000000000 --- a/src/java/org/apache/fop/layoutmgr/table/Row.java +++ /dev/null @@ -1,623 +0,0 @@ -/* - * Copyright 1999-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.FONode; -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.TableRow; -import org.apache.fop.fo.properties.CommonBorderPaddingBackground; -import org.apache.fop.fo.properties.LengthRangeProperty; -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.MinOptMaxUtil; -import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.layoutmgr.BreakPossPosIter; -import org.apache.fop.layoutmgr.Position; -import org.apache.fop.layoutmgr.TraitSetter; -import org.apache.fop.area.Area; -import org.apache.fop.area.Block; -import org.apache.fop.area.Trait; -import org.apache.fop.traits.MinOptMax; - -import java.util.Iterator; -import java.util.ArrayList; -import java.util.List; -import java.util.ListIterator; - -/** - * LayoutManager for a table-row FO. - * The row contains cells that are organised according to the columns. - * A break in a table row will contain breaks for each table cell. - * 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 { - - private TableRow fobj; - - private List gridUnits = null; - private List columns = null; - private int referenceIPD; - private int rowHeight; - private int xoffset; - private int yoffset; - - private class RowPosition extends LeafPosition { - protected List cellBreaks; - protected RowPosition(LayoutManager lm, int pos, List l) { - super(lm, pos); - cellBreaks = l; - } - } - - /** - * Create a new row layout manager. - * - */ - public Row(TableRow node) { - super(node); - fobj = node; - } - - /** @return the table-row FO */ - public TableRow getFObj() { - return this.fobj; - } - - /** - * @return the table owning this row - */ - public Table getTable() { - FONode node = fobj.getParent(); - while (!(node instanceof Table)) { - node = node.getParent(); - } - return (Table)node; - } - - /** - * Set the columns from the table. - * - * @param cols the list of columns for this table - */ - public void setColumns(List cols) { - columns = cols; - } - - /** @return true if this is the layout manager for the first row in a body. */ - public boolean isFirstInBody() { - return ((TableBody)getFObj().getParent()).isFirst(getFObj()); - } - - /** @return true if this is the layout manager for the last row in a body. */ - public boolean isLastInBody() { - return ((TableBody)getFObj().getParent()).isLast(getFObj()); - } - - /** - * Gets the Column at a given index. - * @param index index of the column (index must be >= 1) - * @return the requested Column - */ - private Column getColumn(int index) { - int size = columns.size(); - if (index > size - 1) { - return (Column)columns.get(size - 1); - } else { - return (Column)columns.get(index - 1); - } - } - - private void prepareGridUnits() { - gridUnits = new java.util.ArrayList(); - List availableCells = new java.util.ArrayList(); - // add cells to list - while (childLMiter.hasNext()) { - curChildLM = (LayoutManager) childLMiter.next(); - curChildLM.setParent(this); - curChildLM.initialize(); - availableCells.add(curChildLM); - } - - //Transfer available cells to their slots - int colnum = 1; - ListIterator iter = availableCells.listIterator(); - while (iter.hasNext()) { - Cell cellLM = (Cell)iter.next(); - TableCell cell = cellLM.getFObj(); - 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); - } - //Add cell info for primary slot - GridUnit info = new GridUnit(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); - infoSpan.row = this; - infoSpan.column = getColumn(colnum); - if (colnum > gridUnits.size()) { - gridUnits.add(infoSpan); - } else { - if (gridUnits.get(colnum - 1) != null) { - log.error("Overlapping cell at position " + colnum); - //TODO throw layout exception - } - gridUnits.set(colnum - 1, infoSpan); - } - } - colnum++; - } - - //Post-processing the list (looking for gaps and resolve start and end borders) - postProcessGridUnits(); - } - - private void postProcessGridUnits() { - 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 GridUnit(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); - - //Border resolution - if (getTable().isSeparateBorderModel()) { - starting.assignBorder(starting.layoutManager); - } else { - //Neighbouring grid unit at start edge - GridUnit start = null; - int find = pos - 1; - while (find >= 1) { - GridUnit candidate = (GridUnit)gridUnits.get(find - 1); - if (candidate.isLastGridUnitColSpan()) { - start = candidate; - break; - } - find--; - } - - //Ending grid unit for current cell - GridUnit ending = null; - if (starting.layoutManager != null) { - pos += starting.layoutManager.getFObj().getNumberColumnsSpanned() - 1; - } - ending = (GridUnit)gridUnits.get(pos - 1); - - //Neighbouring grid unit at end edge - GridUnit end = null; - find = pos + 1; - while (find <= gridUnits.size()) { - GridUnit candidate = (GridUnit)gridUnits.get(find - 1); - if (candidate.isPrimaryGridUnit()) { - end = candidate; - break; - } - find++; - } - CommonBorderPaddingBackground borders = new CommonBorderPaddingBackground(); - GridUnit.resolveBorder(getTable(), borders, starting, - (start != null ? start : null), - CommonBorderPaddingBackground.START); - starting.effBorders = borders; - if (starting != ending) { - borders = new CommonBorderPaddingBackground(); - } - GridUnit.resolveBorder(getTable(), 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 - } - } - } - - /** - * Get the cell info for a cell. - * - * @param pos the position of the cell (must be >= 1) - * @return the cell info object - */ - protected GridUnit getCellInfo(int pos) { - if (gridUnits == null) { - prepareGridUnits(); - } - if (pos <= gridUnits.size()) { - return (GridUnit)gridUnits.get(pos - 1); - } else { - return null; - } - } - - /** - * Get the next break possibility. - * A row needs to get the possible breaks for each cell - * in the row and find a suitable break across all cells. - * - * @param context the layout context for getting breaks - * @return the next break possibility - */ - public BreakPoss getNextBreakPoss(LayoutContext context) { - //LayoutManager curLM; // currently active LM - GridUnit curGridUnit; //currently active grid unit - - BreakPoss lastPos = null; - List breakList = new java.util.ArrayList(); - - int min = 0; - int opt = 0; - int max = 0; - - // This is used for the displacement of the individual cells - int ipdOffset = 0; - - int startColumn = 1; - boolean over = false; - - while ((curGridUnit = getCellInfo(startColumn)) != null) { - Cell cellLM = curGridUnit.layoutManager; - if (curGridUnit.isColSpan()) { - //skip spanned slots - startColumn++; - continue; - } - - List childBreaks = new ArrayList(); - MinOptMax stackSize = new MinOptMax(); - - // Set up a LayoutContext - // the ipd is from the current column - referenceIPD = context.getRefIPD(); - BreakPoss bp; - - LayoutContext childLC = new LayoutContext(0); - childLC.setStackLimit( - MinOptMax.subtract(context.getStackLimit(), - stackSize)); - - //Determine which columns this cell will occupy - List spannedGridUnits = 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; - childRefIPD += col.getWidth().getValue(); - } - childLC.setRefIPD(childRefIPD); - - if (cellLM != null) { - cellLM.addGridUnitsFromRow(spannedGridUnits); - cellLM.setInRowIPDOffset(ipdOffset); - while (!cellLM.isFinished()) { - if ((bp = cellLM.getNextBreakPoss(childLC)) != null) { - if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { - // reset to last break - if (lastPos != null) { - LayoutManager lm = lastPos.getLayoutManager(); - lm.resetPosition(lastPos.getPosition()); - if (lm != cellLM) { - cellLM.resetPosition(null); - } - } else { - cellLM.resetPosition(null); - } - over = true; - break; - } - stackSize.add(bp.getStackingSize()); - lastPos = bp; - childBreaks.add(bp); - - if (bp.nextBreakOverflows()) { - over = true; - break; - } - - childLC.setStackLimit(MinOptMax.subtract( - context.getStackLimit(), stackSize)); - } - } - startColumn += cellLM.getFObj().getNumberColumnsSpanned(); - } else { - //Skipping empty cells - //log.debug("empty cell at pos " + startColumn); - startColumn++; - } - - //Adjust in-row x offset for individual cells - ipdOffset += childRefIPD; - - - // the min is the maximum min of all cells - if (stackSize.min > min) { - min = stackSize.min; - } - // the optimum is the maximum of all optimums - if (stackSize.opt > opt) { - opt = stackSize.opt; - } - // the maximum is the largest maximum - if (stackSize.max > max) { - max = stackSize.max; - } - - if (childBreaks.size() > 0) { - breakList.add(childBreaks); - } - } - MinOptMax rowSize = new MinOptMax(min, opt, max); - LengthRangeProperty specifiedBPD = fobj.getBlockProgressionDimension(); - if (specifiedBPD.getEnum() != EN_AUTO) { - if ((specifiedBPD.getMaximum().getEnum() != EN_AUTO) - && (specifiedBPD.getMaximum().getLength().getValue() < rowSize.min)) { - log.warn("maximum height of row is smaller than the minimum " - + "height of its contents"); - } - MinOptMaxUtil.restrict(rowSize, specifiedBPD); - } - rowHeight = rowSize.opt; - - boolean fin = true; - startColumn = 1; - //Check if any of the cell LMs haven't finished, yet - while ((curGridUnit = getCellInfo(startColumn)) != null) { - Cell cellLM = curGridUnit.layoutManager; - if (cellLM == null) { - //skip empty cell - startColumn++; - continue; - } - if (!cellLM.isFinished()) { - fin = false; - break; - } - startColumn += cellLM.getFObj().getNumberColumnsSpanned(); - } - - setFinished(fin); - RowPosition rp = new RowPosition(this, breakList.size() - 1, breakList); - BreakPoss breakPoss = new BreakPoss(rp); - if (over) { - breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); - } - breakPoss.setStackingSize(rowSize); - return breakPoss; - } - - /** - * Determines the grid units that are spanned by the given cell. - * @param cellLM table-cell LM - * @param startCell starting cell index (must be >= 1) - * @param spannedGridUnits List to receive the applicable grid units - */ - private void getGridUnitsForCell(Cell cellLM, int startCell, List spannedGridUnits) { - int count; - if (cellLM != null) { - count = cellLM.getFObj().getNumberColumnsSpanned(); - } else { - count = 1; - } - spannedGridUnits.clear(); - for (int i = 0; i < count; i++) { - spannedGridUnits.add(this.gridUnits.get(startCell + i - 1)); - } - } - - /** - * Reset the layoutmanager "iterator" so that it will start - * with the passed Position's generating LM - * on the next call to getChildLM. - * @param pos a Position returned by a child layout manager - * representing a potential break decision. - * If pos is null, then back up to the first child LM. - */ - protected void reset(Position pos) { - //LayoutManager curLM; // currently active LM - GridUnit curGridUnit; - int cellIndex = 1; - - if (pos == null) { - while ((curGridUnit = getCellInfo(cellIndex)) != null) { - if (curGridUnit.layoutManager != null) { - curGridUnit.layoutManager.resetPosition(null); - } - cellIndex++; - } - } else { - RowPosition rpos = (RowPosition)pos; - List breaks = rpos.cellBreaks; - - while ((curGridUnit = getCellInfo(cellIndex)) != null) { - if (curGridUnit.layoutManager != null) { - List childbreaks = (List)breaks.get(cellIndex); - curGridUnit.layoutManager.resetPosition( - (Position)childbreaks.get(childbreaks.size() - 1)); - } - cellIndex++; - } - } - - setFinished(false); - } - - /** - * Set the x position offset of this row. - * This is used to set the position of the areas returned by this row. - * - * @param off the x offset - */ - public void setXOffset(int off) { - xoffset = off; - } - - /** - * Set the y position offset of this row. - * This is used to set the position of the areas returned by this row. - * - * @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); - BreakPoss bp1 = (BreakPoss)parentIter.peekNext(); - bBogus = !bp1.generatesAreas(); - if (!isBogus()) { - addID(fobj.getId()); - } - - Cell childLM; - int iStartPos = 0; - LayoutContext lc = new LayoutContext(0); - while (parentIter.hasNext()) { - RowPosition lfp = (RowPosition) parentIter.next(); - - //area exclusively for painting the row background - Block rowArea = getRowArea(); - if (rowArea != null) { - rowArea.setBPD(rowHeight); - rowArea.setIPD(referenceIPD); - rowArea.setXOffset(xoffset); - rowArea.setYOffset(yoffset); - parentLM.addChildArea(rowArea); - } - - for (Iterator iter = lfp.cellBreaks.iterator(); iter.hasNext();) { - List cellsbr = (List)iter.next(); - BreakPossPosIter breakPosIter; - breakPosIter = new BreakPossPosIter(cellsbr, 0, cellsbr.size()); - iStartPos = lfp.getLeafPos() + 1; - - while ((childLM = (Cell)breakPosIter.getNextChildLM()) != null) { - childLM.setXOffset(xoffset); - childLM.setYOffset(yoffset); - childLM.setRowHeight(rowHeight); - childLM.addAreas(breakPosIter, lc); - } - } - } - - flush(); - } - - /** - * Get the row height of the row after adjusting. - * Should only be called after adding the row areas. - * - * @return the row height of this row after adjustment - */ - public int getRowHeight() { - return rowHeight; - } - - /** - * 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) { - return parentLM.getParentArea(childArea); - } - - /** - * 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 - */ - public void addChildArea(Area childArea) { - parentLM.addChildArea(childArea); - } - - /** - * Reset the position of this layout manager. - * - * @param resetPos the position to reset to - */ - public void resetPosition(Position resetPos) { - if (resetPos == null) { - reset(null); - } - } - - - /** - * Get the area for this row for background. - * - * @return the row area - */ - public Block getRowArea() { - if (fobj.getCommonBorderPaddingBackground().hasBackground()) { - Block block = new Block(); - block.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE); - block.setPositioning(Block.ABSOLUTE); - TraitSetter.addBackground(block, fobj.getCommonBorderPaddingBackground()); - return block; - } else { - return null; - } - } - -} - |