Example #1
0
        /// <summary>
        /// Layout the cells by the calculated table layout
        /// </summary>
        /// <param name="g"></param>
        private void LayoutCells(RGraphics g)
        {
            double startx     = Math.Max(_tableBox.ClientLeft + GetHorizontalSpacing(), 0);
            double starty     = Math.Max(_tableBox.ClientTop + GetVerticalSpacing(), 0);
            double cury       = starty;
            double maxRight   = startx;
            double maxBottom  = 0f;
            int    currentrow = 0;

            // change start X by if the table should align to center or right
            if (_tableBox.TextAlign == CssConstants.Center || _tableBox.TextAlign == CssConstants.Right)
            {
                double maxRightCalc = GetWidthSum();
                startx = _tableBox.TextAlign == CssConstants.Right
                    ? GetAvailableTableWidth() - maxRightCalc
                    : startx + (GetAvailableTableWidth() - maxRightCalc) / 2;

                _tableBox.Location = new RPoint(startx - _tableBox.ActualBorderLeftWidth - _tableBox.ActualPaddingLeft - GetHorizontalSpacing(), _tableBox.Location.Y);
            }

            for (int i = 0; i < _allRows.Count; i++)
            {
                var    row       = _allRows[i];
                double curx      = startx;
                int    curCol    = 0;
                bool   breakPage = false;

                for (int j = 0; j < row.Boxes.Count; j++)
                {
                    CssBox cell = row.Boxes[j];
                    if (curCol >= _columnWidths.Length)
                    {
                        break;
                    }

                    int    rowspan     = GetRowSpan(cell);
                    var    columnIndex = GetCellRealColumnIndex(row, cell);
                    double width       = GetCellWidth(columnIndex, cell);
                    cell.Location = new RPoint(curx, cury);
                    cell.Size     = new RSize(width, 0f);
                    cell.PerformLayout(g); //That will automatically set the bottom of the cell

                    //Alter max bottom only if row is cell's row + cell's rowspan - 1
                    CssSpacingBox sb = cell as CssSpacingBox;
                    if (sb != null)
                    {
                        if (sb.EndRow == currentrow)
                        {
                            maxBottom = Math.Max(maxBottom, sb.ExtendedBox.ActualBottom);
                        }
                    }
                    else if (rowspan == 1)
                    {
                        maxBottom = Math.Max(maxBottom, cell.ActualBottom);
                    }
                    maxRight = Math.Max(maxRight, cell.ActualRight);
                    curCol++;
                    curx = cell.ActualRight + GetHorizontalSpacing();
                }

                foreach (CssBox cell in row.Boxes)
                {
                    CssSpacingBox spacer = cell as CssSpacingBox;

                    if (spacer == null && GetRowSpan(cell) == 1)
                    {
                        cell.ActualBottom = maxBottom;
                        CssLayoutEngine.ApplyCellVerticalAlignment(g, cell);
                    }
                    else if (spacer != null && spacer.EndRow == currentrow)
                    {
                        spacer.ExtendedBox.ActualBottom = maxBottom;
                        CssLayoutEngine.ApplyCellVerticalAlignment(g, spacer.ExtendedBox);
                    }

                    // If one cell crosses page borders then don't need to check other cells in the row
                    if (_tableBox.PageBreakInside == CssConstants.Avoid)
                    {
                        breakPage = cell.BreakPage();
                        if (breakPage)
                        {
                            cury = cell.Location.Y;
                            break;
                        }
                    }
                }

                if (breakPage)  // go back to move the whole row to the next page
                {
                    if (i == 1) // do not leave single row in previous page
                    {
                        i = -1; // Start layout from the first row on new page
                    }
                    else
                    {
                        i--;
                    }

                    maxBottom = 0;
                    continue;
                }

                cury = maxBottom + GetVerticalSpacing();

                currentrow++;
            }

            maxRight = Math.Max(maxRight, _tableBox.Location.X + _tableBox.ActualWidth);
            _tableBox.ActualRight  = maxRight + GetHorizontalSpacing() + _tableBox.ActualBorderRightWidth;
            _tableBox.ActualBottom = Math.Max(maxBottom, starty) + GetVerticalSpacing() + _tableBox.ActualBorderBottomWidth;
        }