123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.LinkedList;
- import java.util.List;
-
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
-
- import org.apache.fop.fo.Constants;
- import org.apache.fop.fo.flow.table.EffRow;
- import org.apache.fop.fo.flow.table.GridUnit;
- import org.apache.fop.fo.flow.table.PrimaryGridUnit;
- import org.apache.fop.fo.flow.table.TableColumn;
- import org.apache.fop.fo.flow.table.TableRow;
- import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
- import org.apache.fop.fo.properties.LengthRangeProperty;
- import org.apache.fop.layoutmgr.ElementListObserver;
- import org.apache.fop.layoutmgr.LayoutContext;
- import org.apache.fop.traits.MinOptMax;
- import org.apache.fop.util.BreakUtil;
-
- class RowGroupLayoutManager {
-
- private static Log log = LogFactory.getLog(RowGroupLayoutManager.class);
-
- private static final MinOptMax MAX_STRETCH = MinOptMax.getInstance(0, 0, Integer.MAX_VALUE);
-
- private EffRow[] rowGroup;
-
- private TableLayoutManager tableLM;
-
- private TableStepper tableStepper;
-
- RowGroupLayoutManager(TableLayoutManager tableLM, EffRow[] rowGroup,
- TableStepper tableStepper) {
- this.tableLM = tableLM;
- this.rowGroup = rowGroup;
- this.tableStepper = tableStepper;
- }
-
- public LinkedList getNextKnuthElements(LayoutContext context, int alignment, int bodyType) {
- LinkedList returnList = new LinkedList();
- createElementsForRowGroup(context, alignment, bodyType, returnList);
-
- context.updateKeepWithPreviousPending(rowGroup[0].getKeepWithPrevious());
- context.updateKeepWithNextPending(rowGroup[rowGroup.length - 1].getKeepWithNext());
-
- int breakBefore = Constants.EN_AUTO;
- TableRow firstRow = rowGroup[0].getTableRow();
- if (firstRow != null) {
- breakBefore = firstRow.getBreakBefore();
- }
- context.setBreakBefore(BreakUtil.compareBreakClasses(breakBefore,
- rowGroup[0].getBreakBefore()));
-
- int breakAfter = Constants.EN_AUTO;
- TableRow lastRow = rowGroup[rowGroup.length - 1].getTableRow();
- if (lastRow != null) {
- breakAfter = lastRow.getBreakAfter();
- }
- context.setBreakAfter(BreakUtil.compareBreakClasses(breakAfter,
- rowGroup[rowGroup.length - 1].getBreakAfter()));
-
- return returnList;
- }
-
- /**
- * Creates Knuth elements for a row group (see TableRowIterator.getNextRowGroup()).
- * @param context Active LayoutContext
- * @param alignment alignment indicator
- * @param bodyType Indicates what kind of body is being processed (BODY, HEADER or FOOTER)
- * @param returnList List to received the generated elements
- */
- private void createElementsForRowGroup(LayoutContext context, int alignment,
- int bodyType, LinkedList returnList) {
- log.debug("Handling row group with " + rowGroup.length + " rows...");
- EffRow row;
- for (EffRow aRowGroup : rowGroup) {
- row = aRowGroup;
- for (Object o : row.getGridUnits()) {
- GridUnit gu = (GridUnit) o;
- if (gu.isPrimary()) {
- PrimaryGridUnit primary = gu.getPrimary();
- // TODO a new LM must be created for every new static-content
- primary.createCellLM();
- primary.getCellLM().setParent(tableLM);
- //Calculate width of cell
- int spanWidth = 0;
- Iterator colIter = tableLM.getTable().getColumns().listIterator(
- primary.getColIndex());
- for (int i = 0, c = primary.getCell().getNumberColumnsSpanned(); i < c; i++) {
- spanWidth += ((TableColumn) colIter.next()).getColumnWidth().getValue(
- tableLM);
- }
- LayoutContext childLC = LayoutContext.newInstance();
- childLC.setStackLimitBP(context.getStackLimitBP()); //necessary?
- childLC.setRefIPD(spanWidth);
-
- //Get the element list for the cell contents
- List elems = primary.getCellLM().getNextKnuthElements(
- childLC, alignment);
- ElementListObserver.observe(elems, "table-cell", primary.getCell().getId());
- primary.setElements(elems);
- }
- }
- }
- computeRowHeights();
- List elements = tableStepper.getCombinedKnuthElementsForRowGroup(context,
- rowGroup, bodyType);
- returnList.addAll(elements);
- }
-
- /**
- * Calculate the heights of the rows in the row group, see CSS21, 17.5.3 Table height
- * algorithms.
- *
- * TODO this method will need to be adapted once clarification has been made by the
- * W3C regarding whether borders or border-separation must be included or not
- */
- private void computeRowHeights() {
- log.debug("rowGroup:");
- MinOptMax[] rowHeights = new MinOptMax[rowGroup.length];
- EffRow row;
- for (int rgi = 0; rgi < rowGroup.length; rgi++) {
- row = rowGroup[rgi];
- // The BPD of the biggest cell in the row
- // int maxCellBPD = 0;
- MinOptMax explicitRowHeight;
- TableRow tableRowFO = rowGroup[rgi].getTableRow();
- if (tableRowFO == null) {
- rowHeights[rgi] = MAX_STRETCH;
- explicitRowHeight = MAX_STRETCH;
- } else {
- LengthRangeProperty rowBPD = tableRowFO.getBlockProgressionDimension();
- rowHeights[rgi] = rowBPD.toMinOptMax(tableLM);
- explicitRowHeight = rowBPD.toMinOptMax(tableLM);
- }
- for (Object o : row.getGridUnits()) {
- GridUnit gu = (GridUnit) o;
- if (!gu.isEmpty() && gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan()) {
- PrimaryGridUnit primary = gu.getPrimary();
- int effectiveCellBPD = 0;
- LengthRangeProperty cellBPD = primary.getCell().getBlockProgressionDimension();
- if (!cellBPD.getMinimum(tableLM).isAuto()) {
- effectiveCellBPD = cellBPD.getMinimum(tableLM).getLength()
- .getValue(tableLM);
- }
- if (!cellBPD.getOptimum(tableLM).isAuto()) {
- effectiveCellBPD = cellBPD.getOptimum(tableLM).getLength()
- .getValue(tableLM);
- }
- if (gu.getRowSpanIndex() == 0) {
- effectiveCellBPD = Math.max(effectiveCellBPD, explicitRowHeight.getOpt());
- }
- effectiveCellBPD = Math.max(effectiveCellBPD, primary.getContentLength());
- int borderWidths = primary.getBeforeAfterBorderWidth();
- int padding = 0;
- CommonBorderPaddingBackground cbpb = primary.getCell()
- .getCommonBorderPaddingBackground();
- padding += cbpb.getPaddingBefore(false, primary.getCellLM());
- padding += cbpb.getPaddingAfter(false, primary.getCellLM());
- int effRowHeight = effectiveCellBPD + padding + borderWidths;
- for (int prev = rgi - 1; prev >= rgi - gu.getRowSpanIndex(); prev--) {
- effRowHeight -= rowHeights[prev].getOpt();
- }
- if (effRowHeight > rowHeights[rgi].getMin()) {
- // This is the new height of the (grid) row
- rowHeights[rgi] = rowHeights[rgi].extendMinimum(effRowHeight);
- }
- }
- }
-
- row.setHeight(rowHeights[rgi]);
- row.setExplicitHeight(explicitRowHeight);
- // TODO re-enable and improve after clarification
- //See http://markmail.org/message/h25ycwwu7qglr4k4
- // if (maxCellBPD > row.getExplicitHeight().max) {
- //old:
- // log.warn(FONode.decorateWithContextInfo(
- // "The contents of row " + (row.getIndex() + 1)
- // + " are taller than they should be (there is a"
- // + " block-progression-dimension or height constraint
- // + " on the indicated row)."
- // + " Due to its contents the row grows"
- // + " to " + maxCellBPD + " millipoints, but the row shouldn't get"
- // + " any taller than " + row.getExplicitHeight() + " millipoints.",
- // row.getTableRow()));
- //new (with events):
- // BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Factory.create(
- // tableRow.getUserAgent().getEventBroadcaster());
- // eventProducer.rowTooTall(this, row.getIndex() + 1,
- // maxCellBPD, row.getExplicitHeight().max, tableRow.getLocator());
- // }
- }
- }
- }
|