public void addAreas()

in fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java [395:592]


    public void addAreas(PositionIterator parentIter, LayoutContext layoutContext, int[] spannedGridRowHeights,
            int startRow, int endRow, int borderBeforeWhich, int borderAfterWhich,
            boolean firstOnPage, boolean lastOnPage, RowPainter painter, int firstRowHeight) {
        getParentArea(null);

        addId();

        int borderBeforeWidth = primaryGridUnit.getBeforeBorderWidth(startRow, borderBeforeWhich);
        int borderAfterWidth = primaryGridUnit.getAfterBorderWidth(endRow, borderAfterWhich);

        CommonBorderPaddingBackground padding = primaryGridUnit.getCell()
                .getCommonBorderPaddingBackground();
        int paddingRectBPD = totalHeight - borderBeforeWidth - borderAfterWidth;
        int cellBPD = paddingRectBPD;
        cellBPD -= padding.getPaddingBefore(borderBeforeWhich == ConditionalBorder.REST, this);
        cellBPD -= padding.getPaddingAfter(borderAfterWhich == ConditionalBorder.REST, this);

        addBackgroundAreas(painter, firstRowHeight, borderBeforeWidth, paddingRectBPD);

        if (isSeparateBorderModel()) {
            if (!emptyCell || getTableCell().showEmptyCells()) {
                if (borderBeforeWidth > 0) {
                    int halfBorderSepBPD = getTableCell().getTable().getBorderSeparation().getBPD()
                            .getLength().getValue() / 2;
                    adjustYOffset(curBlockArea, halfBorderSepBPD);
                }
                TraitSetter.addBorders(curBlockArea,
                        getTableCell().getCommonBorderPaddingBackground(),
                        borderBeforeWidth == 0, borderAfterWidth == 0,
                        false, false, this);
            }
        } else {
            boolean inFirstColumn = (primaryGridUnit.getColIndex() == 0);
            boolean inLastColumn = (primaryGridUnit.getColIndex()
                    + getTableCell().getNumberColumnsSpanned() == getTable()
                    .getNumberOfColumns());
            if (!primaryGridUnit.hasSpanning()) {
                adjustYOffset(curBlockArea, -borderBeforeWidth);
                //Can set the borders directly if there's no span
                boolean[] outer = new boolean[] {firstOnPage, lastOnPage, inFirstColumn,
                        inLastColumn};
                TraitSetter.addCollapsingBorders(curBlockArea,
                        primaryGridUnit.getBorderBefore(borderBeforeWhich),
                        primaryGridUnit.getBorderAfter(borderAfterWhich),
                        primaryGridUnit.getBorderStart(),
                        primaryGridUnit.getBorderEnd(), outer);
            } else {
                adjustYOffset(curBlockArea, borderBeforeWidth);
                Block[][] blocks = new Block[getTableCell().getNumberRowsSpanned()][getTableCell()
                        .getNumberColumnsSpanned()];
                GridUnit[] gridUnits = primaryGridUnit.getRows().get(startRow);
                int level = getTableCell().getBidiLevelRecursive();
                for (int x = 0; x < getTableCell().getNumberColumnsSpanned(); x++) {
                    GridUnit gu = gridUnits[x];
                    BorderInfo border = gu.getBorderBefore(borderBeforeWhich);
                    int borderWidth = border.getRetainedWidth() / 2;
                    if (borderWidth > 0) {
                        addBorder(blocks, startRow, x, Trait.BORDER_BEFORE, border,
                                  firstOnPage, level);
                        adjustYOffset(blocks[startRow][x], -borderWidth);
                        adjustBPD(blocks[startRow][x], -borderWidth);
                    }
                }
                gridUnits = primaryGridUnit.getRows().get(endRow);
                for (int x = 0; x < getTableCell().getNumberColumnsSpanned(); x++) {
                    GridUnit gu = gridUnits[x];
                    BorderInfo border = gu.getBorderAfter(borderAfterWhich);
                    int borderWidth = border.getRetainedWidth() / 2;
                    if (borderWidth > 0) {
                        addBorder(blocks, endRow, x, Trait.BORDER_AFTER, border,
                                  lastOnPage, level);
                        adjustBPD(blocks[endRow][x], -borderWidth);
                    }
                }
                for (int y = startRow; y <= endRow; y++) {
                    gridUnits = primaryGridUnit.getRows().get(y);
                    BorderInfo border = gridUnits[0].getBorderStart();
                    int borderWidth = border.getRetainedWidth() / 2;
                    if (borderWidth > 0) {
                        if (level == 1) {
                            addBorder(blocks, y, gridUnits.length - 1, Trait.BORDER_START, border,
                                      inFirstColumn, level);
                            adjustIPD(blocks[y][gridUnits.length - 1], -borderWidth);
                        } else {
                            addBorder(blocks, y, 0, Trait.BORDER_START, border,
                                      inFirstColumn, level);
                            adjustXOffset(blocks[y][0], borderWidth);
                            adjustIPD(blocks[y][0], -borderWidth);
                        }
                    }
                    border = gridUnits[gridUnits.length - 1].getBorderEnd();
                    borderWidth = border.getRetainedWidth() / 2;
                    if (borderWidth > 0) {
                        if (level == 1) {
                            addBorder(blocks, y, 0, Trait.BORDER_END, border,
                                      inLastColumn, level);
                            adjustXOffset(blocks[y][0], borderWidth);
                            adjustIPD(blocks[y][0], -borderWidth);
                        } else {
                            addBorder(blocks, y, gridUnits.length - 1, Trait.BORDER_END, border,
                                    inLastColumn, level);
                            adjustIPD(blocks[y][gridUnits.length - 1], -borderWidth);
                        }
                    }
                }
                int dy = yoffset;
                for (int y = startRow; y <= endRow; y++) {
                    int bpd = spannedGridRowHeights[y - startRow];
                    int dx = xoffset;
                    for (int x = 0; x < gridUnits.length; x++) {
                        int ipd = getTable().getColumn(primaryGridUnit.getColIndex() + x)
                                .getColumnWidth().getValue(getParent());
                        if (blocks[y][x] != null) {
                            Block block = blocks[y][x];
                            adjustYOffset(block, dy);
                            adjustXOffset(block, dx);
                            adjustIPD(block, ipd);
                            adjustBPD(block, bpd);
                            parentLayoutManager.addChildArea(block);
                        }
                        dx += ipd;
                    }
                    dy += bpd;
                }
            }
        }

        TraitSetter.addPadding(curBlockArea,
                padding,
                borderBeforeWhich == ConditionalBorder.REST,
                borderAfterWhich == ConditionalBorder.REST,
                false, false, this);

        //Handle display-align
        if (usedBPD < cellBPD) {
            if (getTableCell().getDisplayAlign() == EN_CENTER) {
                Block space = new Block();
                space.setChangeBarList(getChangeBarList());
                space.setBPD((cellBPD - usedBPD) / 2);
                space.setBidiLevel(getTableCell().getBidiLevelRecursive());
                curBlockArea.addBlock(space);
            } else if (getTableCell().getDisplayAlign() == EN_AFTER) {
                Block space = new Block();
                space.setChangeBarList(getChangeBarList());
                space.setBPD(cellBPD - usedBPD);
                space.setBidiLevel(getTableCell().getBidiLevelRecursive());
                curBlockArea.addBlock(space);
            }
        }

        if (isDescendantOfTableHeaderOrFooter()) {
            if (hasRetrieveTableMarker) {
                if (isDescendantOfTableHeader && !savedAddAreasArguments) {
                    saveAddAreasArguments(parentIter, layoutContext, spannedGridRowHeights, startRow, endRow,
                            borderBeforeWhich, borderAfterWhich, firstOnPage, lastOnPage, painter,
                            firstRowHeight);
                }
                recreateChildrenLMs();
                int displayAlign = ((TableCell) this.getFObj()).getDisplayAlign();
                TableCellBreaker breaker = new TableCellBreaker(this, cellIPD, displayAlign);
                breaker.setDescendantOfTableFooter(isDescendantOfTableHeader);
                if (isDescendantOfTableHeader) {
                    breaker.setRepeatedHeader(hasRepeatedHeader);
                } else {
                    breaker.setRepeatedFooter(layoutContext.treatAsArtifact());
                }
                breaker.doLayout(usedBPD, false);
                // this is needed so the next time the LMs are recreated they look like the originals; this
                // is due to the fact that during the doLayout() above the FO tree changes when the
                // retrieve-table-markers are resolved
                clearRetrieveTableMarkerChildNodes(getChildLMs());
            }
        }

        // if hasRetrieveTableMarker == true the areas were already added when the re-layout was done above
        if (!hasRetrieveTableMarker) {
            AreaAdditionUtil.addAreas(this, parentIter, layoutContext);
        }
        // Re-adjust the cell's bpd as it may have been modified by the previous call
        // for some reason (?)
        curBlockArea.setBPD(cellBPD);

        // Add background after we know the BPD
        if (!isSeparateBorderModel() || !emptyCell || getTableCell().showEmptyCells()) {
            TraitSetter.addBackground(curBlockArea,
                    getTableCell().getCommonBorderPaddingBackground(), this);
        }

        if (flushArea) {
            flush();
        } else {
            flushArea = true;
        }

        curBlockArea = null;

        notifyEndOfLayout();
    }