// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "core/paint/TableSectionPainter.h"

#include "core/layout/LayoutTableCell.h"
#include "core/layout/LayoutTableCol.h"
#include "core/layout/LayoutTableRow.h"
#include "core/paint/BoxClipper.h"
#include "core/paint/BoxPainter.h"
#include "core/paint/LayoutObjectDrawingRecorder.h"
#include "core/paint/ObjectPainter.h"
#include "core/paint/PaintInfo.h"
#include "core/paint/TableCellPainter.h"
#include "core/paint/TableRowPainter.h"
#include <algorithm>

namespace blink {

inline const LayoutTableCell* TableSectionPainter::primaryCellToPaint(
    unsigned row,
    unsigned column,
    const CellSpan& dirtiedRows,
    const CellSpan& dirtiedColumns) const {
  DCHECK(row >= dirtiedRows.start() && row < dirtiedRows.end());
  DCHECK(column >= dirtiedColumns.start() && column < dirtiedColumns.end());

  const LayoutTableCell* cell = m_layoutTableSection.primaryCellAt(row, column);
  if (!cell)
    return nullptr;
  // We have painted (row, column) when painting (row - 1, column).
  if (row > dirtiedRows.start() &&
      m_layoutTableSection.primaryCellAt(row - 1, column) == cell)
    return nullptr;
  // We have painted (row, column) when painting (row, column -1).
  if (column > dirtiedColumns.start() &&
      m_layoutTableSection.primaryCellAt(row, column - 1) == cell)
    return nullptr;
  return cell;
}

void TableSectionPainter::paintRepeatingHeaderGroup(
    const PaintInfo& paintInfo,
    const LayoutPoint& paintOffset,
    const CollapsedBorderValue& currentBorderValue,
    ItemToPaint itemToPaint) {
  if (!m_layoutTableSection.isRepeatingHeaderGroup())
    return;

  LayoutTable* table = m_layoutTableSection.table();
  LayoutPoint paginationOffset = paintOffset;
  LayoutUnit pageHeight = table->pageLogicalHeightForOffset(LayoutUnit());

  // Move paginationOffset to the top of the next page.
  // The header may have a pagination strut before it so we need to account for
  // that when establishing its position.
  LayoutUnit headerGroupOffset = table->pageLogicalOffset();
  if (LayoutTableRow* row = m_layoutTableSection.firstRow())
    headerGroupOffset += row->paginationStrut();
  LayoutUnit offsetToNextPage =
      pageHeight - intMod(headerGroupOffset, pageHeight);
  paginationOffset.move(0, offsetToNextPage.toInt());
  // Now move paginationOffset to the top of the page the cull rect starts on.
  if (paintInfo.cullRect().m_rect.y() > paginationOffset.y())
    paginationOffset.move(
        0, pageHeight.toInt() *
               ((paintInfo.cullRect().m_rect.y() - paginationOffset.y()) /
                pageHeight)
                   .toInt());
  LayoutUnit bottomBound =
      std::min(LayoutUnit(paintInfo.cullRect().m_rect.maxY()),
               paintOffset.y() + table->logicalHeight());
  while (paginationOffset.y() < bottomBound) {
    LayoutPoint nestedOffset =
        paginationOffset +
        LayoutPoint(0, m_layoutTableSection.offsetForRepeatingHeader().toInt());
    if (itemToPaint == PaintCollapsedBorders)
      paintCollapsedSectionBorders(paintInfo, nestedOffset, currentBorderValue);
    else
      paintSection(paintInfo, nestedOffset);
    paginationOffset.move(0, pageHeight.toInt());
  }
}

void TableSectionPainter::paint(const PaintInfo& paintInfo,
                                const LayoutPoint& paintOffset) {
  paintSection(paintInfo, paintOffset);
  LayoutTable* table = m_layoutTableSection.table();
  if (table->header() == m_layoutTableSection)
    paintRepeatingHeaderGroup(paintInfo, paintOffset, CollapsedBorderValue(),
                              PaintSection);
}

void TableSectionPainter::paintSection(const PaintInfo& paintInfo,
                                       const LayoutPoint& paintOffset) {
  DCHECK(!m_layoutTableSection.needsLayout());
  // avoid crashing on bugs that cause us to paint with dirty layout
  if (m_layoutTableSection.needsLayout())
    return;

  unsigned totalRows = m_layoutTableSection.numRows();
  unsigned totalCols = m_layoutTableSection.table()->numEffectiveColumns();

  if (!totalRows || !totalCols)
    return;

  LayoutPoint adjustedPaintOffset =
      paintOffset + m_layoutTableSection.location();

  if (paintInfo.phase != PaintPhaseSelfOutlineOnly) {
    Optional<BoxClipper> boxClipper;
    if (paintInfo.phase != PaintPhaseSelfBlockBackgroundOnly)
      boxClipper.emplace(m_layoutTableSection, paintInfo, adjustedPaintOffset,
                         ForceContentsClip);
    paintObject(paintInfo, adjustedPaintOffset);
  }

  if (shouldPaintSelfOutline(paintInfo.phase))
    ObjectPainter(m_layoutTableSection)
        .paintOutline(paintInfo, adjustedPaintOffset);
}

static inline bool compareCellPositions(LayoutTableCell* elem1,
                                        LayoutTableCell* elem2) {
  return elem1->rowIndex() < elem2->rowIndex();
}

// This comparison is used only when we have overflowing cells as we have an
// unsorted array to sort. We thus need to sort both on rows and columns to
// properly issue paint invalidations.
static inline bool compareCellPositionsWithOverflowingCells(
    LayoutTableCell* elem1,
    LayoutTableCell* elem2) {
  if (elem1->rowIndex() != elem2->rowIndex())
    return elem1->rowIndex() < elem2->rowIndex();

  return elem1->absoluteColumnIndex() < elem2->absoluteColumnIndex();
}

void TableSectionPainter::paintCollapsedBorders(
    const PaintInfo& paintInfo,
    const LayoutPoint& paintOffset,
    const CollapsedBorderValue& currentBorderValue) {
  paintCollapsedSectionBorders(paintInfo, paintOffset, currentBorderValue);
  LayoutTable* table = m_layoutTableSection.table();
  if (table->header() == m_layoutTableSection)
    paintRepeatingHeaderGroup(paintInfo, paintOffset, currentBorderValue,
                              PaintCollapsedBorders);
}

void TableSectionPainter::paintCollapsedSectionBorders(
    const PaintInfo& paintInfo,
    const LayoutPoint& paintOffset,
    const CollapsedBorderValue& currentBorderValue) {
  if (!m_layoutTableSection.numRows() ||
      !m_layoutTableSection.table()->effectiveColumns().size())
    return;

  LayoutPoint adjustedPaintOffset =
      paintOffset + m_layoutTableSection.location();
  BoxClipper boxClipper(m_layoutTableSection, paintInfo, adjustedPaintOffset,
                        ForceContentsClip);

  LayoutRect localPaintInvalidationRect =
      LayoutRect(paintInfo.cullRect().m_rect);
  localPaintInvalidationRect.moveBy(-adjustedPaintOffset);

  LayoutRect tableAlignedRect =
      m_layoutTableSection.logicalRectForWritingModeAndDirection(
          localPaintInvalidationRect);

  CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect);
  CellSpan dirtiedColumns =
      m_layoutTableSection.dirtiedEffectiveColumns(tableAlignedRect);

  if (dirtiedColumns.start() >= dirtiedColumns.end())
    return;

  // Collapsed borders are painted from the bottom right to the top left so that
  // precedence due to cell position is respected.
  for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r--) {
    unsigned row = r - 1;
    for (unsigned c = dirtiedColumns.end(); c > dirtiedColumns.start(); c--) {
      unsigned col = c - 1;
      const LayoutTableSection::CellStruct& current =
          m_layoutTableSection.cellAt(row, col);
      const LayoutTableCell* cell = current.primaryCell();
      if (!cell || (row > dirtiedRows.start() &&
                    m_layoutTableSection.primaryCellAt(row - 1, col) == cell) ||
          (col > dirtiedColumns.start() &&
           m_layoutTableSection.primaryCellAt(row, col - 1) == cell))
        continue;
      LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(
          cell, adjustedPaintOffset);
      TableCellPainter(*cell).paintCollapsedBorders(paintInfo, cellPoint,
                                                    currentBorderValue);
    }
  }
}

void TableSectionPainter::paintObject(const PaintInfo& paintInfo,
                                      const LayoutPoint& paintOffset) {
  LayoutRect localPaintInvalidationRect =
      LayoutRect(paintInfo.cullRect().m_rect);
  localPaintInvalidationRect.moveBy(-paintOffset);

  LayoutRect tableAlignedRect =
      m_layoutTableSection.logicalRectForWritingModeAndDirection(
          localPaintInvalidationRect);

  CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect);
  CellSpan dirtiedColumns =
      m_layoutTableSection.dirtiedEffectiveColumns(tableAlignedRect);

  if (dirtiedColumns.start() >= dirtiedColumns.end())
    return;

  PaintInfo paintInfoForDescendants = paintInfo.forDescendants();

  if (shouldPaintSelfBlockBackground(paintInfo.phase)) {
    paintBoxShadow(paintInfo, paintOffset, Normal);
    for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
      for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
        if (const LayoutTableCell* cell =
                primaryCellToPaint(r, c, dirtiedRows, dirtiedColumns))
          paintBackgroundsBehindCell(*cell, paintInfoForDescendants,
                                     paintOffset);
      }
    }
    paintBoxShadow(paintInfo, paintOffset, Inset);
  }

  if (paintInfo.phase == PaintPhaseSelfBlockBackgroundOnly)
    return;

  if (shouldPaintDescendantBlockBackgrounds(paintInfo.phase)) {
    for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
      const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r);
      // If a row has a layer, we'll paint row background in TableRowPainter.
      if (!row || row->hasSelfPaintingLayer())
        continue;

      TableRowPainter rowPainter(*row);
      rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Normal);
      if (row->styleRef().hasBackground()) {
        for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end();
             c++) {
          if (const LayoutTableCell* cell =
                  primaryCellToPaint(r, c, dirtiedRows, dirtiedColumns))
            rowPainter.paintBackgroundBehindCell(*cell, paintInfoForDescendants,
                                                 paintOffset);
        }
      }
      rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Inset);
    }
  }

  const HashSet<LayoutTableCell*>& overflowingCells =
      m_layoutTableSection.overflowingCells();
  if (!m_layoutTableSection.hasMultipleCellLevels() &&
      overflowingCells.isEmpty()) {
    for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
      const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r);
      // TODO(crbug.com/577282): This painting order is inconsistent with other
      // outlines.
      if (row && !row->hasSelfPaintingLayer() &&
          shouldPaintSelfOutline(paintInfoForDescendants.phase))
        TableRowPainter(*row).paintOutline(paintInfoForDescendants,
                                           paintOffset);
      for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
        if (const LayoutTableCell* cell =
                primaryCellToPaint(r, c, dirtiedRows, dirtiedColumns))
          paintCell(*cell, paintInfoForDescendants, paintOffset);
      }
    }
  } else {
    // The overflowing cells should be scarce to avoid adding a lot of cells to
    // the HashSet.
    DCHECK(overflowingCells.size() <
           m_layoutTableSection.numRows() *
               m_layoutTableSection.table()->effectiveColumns().size() *
               gMaxAllowedOverflowingCellRatioForFastPaintPath);

    // To make sure we properly paint the section, we paint all the overflowing
    // cells that we collected.
    Vector<LayoutTableCell*> cells;
    copyToVector(overflowingCells, cells);

    HashSet<LayoutTableCell*> spanningCells;
    for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
      const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r);
      // TODO(crbug.com/577282): This painting order is inconsistent with other
      // outlines.
      if (row && !row->hasSelfPaintingLayer() &&
          shouldPaintSelfOutline(paintInfoForDescendants.phase))
        TableRowPainter(*row).paintOutline(paintInfoForDescendants,
                                           paintOffset);
      for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
        const LayoutTableSection::CellStruct& current =
            m_layoutTableSection.cellAt(r, c);
        for (LayoutTableCell* cell : current.cells) {
          if (overflowingCells.contains(cell))
            continue;
          if (cell->rowSpan() > 1 || cell->colSpan() > 1) {
            if (!spanningCells.add(cell).isNewEntry)
              continue;
          }
          cells.append(cell);
        }
      }
    }

    // Sort the dirty cells by paint order.
    if (!overflowingCells.size())
      std::stable_sort(cells.begin(), cells.end(), compareCellPositions);
    else
      std::sort(cells.begin(), cells.end(),
                compareCellPositionsWithOverflowingCells);

    for (const LayoutTableCell* cell : cells)
      paintCell(*cell, paintInfoForDescendants, paintOffset);
  }
}

void TableSectionPainter::paintBackgroundsBehindCell(
    const LayoutTableCell& cell,
    const PaintInfo& paintInfoForCells,
    const LayoutPoint& paintOffset) {
  LayoutPoint cellPoint =
      m_layoutTableSection.flipForWritingModeForChild(&cell, paintOffset);

  // We need to handle painting a stack of backgrounds. This stack (from bottom
  // to top) consists of the column group, column, row group, row, and then the
  // cell.

  LayoutTable::ColAndColGroup colAndColGroup =
      m_layoutTableSection.table()->colElementAtAbsoluteColumn(
          cell.absoluteColumnIndex());
  LayoutTableCol* column = colAndColGroup.col;
  LayoutTableCol* columnGroup = colAndColGroup.colgroup;
  TableCellPainter tableCellPainter(cell);

  // Column groups and columns first.
  // FIXME: Columns and column groups do not currently support opacity, and they
  // are being painted "too late" in the stack, since we have already opened a
  // transparency layer (potentially) for the table row group.  Note that we
  // deliberately ignore whether or not the cell has a layer, since these
  // backgrounds paint "behind" the cell.
  if (columnGroup && columnGroup->styleRef().hasBackground())
    tableCellPainter.paintContainerBackgroundBehindCell(
        paintInfoForCells, cellPoint, *columnGroup,
        DisplayItem::kTableCellBackgroundFromColumnGroup);
  if (column && column->styleRef().hasBackground())
    tableCellPainter.paintContainerBackgroundBehindCell(
        paintInfoForCells, cellPoint, *column,
        DisplayItem::kTableCellBackgroundFromColumn);

  // Paint the row group next.
  if (m_layoutTableSection.styleRef().hasBackground())
    tableCellPainter.paintContainerBackgroundBehindCell(
        paintInfoForCells, cellPoint, m_layoutTableSection,
        DisplayItem::kTableCellBackgroundFromSection);
}

void TableSectionPainter::paintCell(const LayoutTableCell& cell,
                                    const PaintInfo& paintInfoForCells,
                                    const LayoutPoint& paintOffset) {
  if (!cell.hasSelfPaintingLayer() && !cell.row()->hasSelfPaintingLayer()) {
    LayoutPoint cellPoint =
        m_layoutTableSection.flipForWritingModeForChild(&cell, paintOffset);
    cell.paint(paintInfoForCells, cellPoint);
  }
}

void TableSectionPainter::paintBoxShadow(const PaintInfo& paintInfo,
                                         const LayoutPoint& paintOffset,
                                         ShadowStyle shadowStyle) {
  DCHECK(shouldPaintSelfBlockBackground(paintInfo.phase));
  if (!m_layoutTableSection.styleRef().boxShadow())
    return;

  DisplayItem::Type type = shadowStyle == Normal
                               ? DisplayItem::kTableSectionBoxShadowNormal
                               : DisplayItem::kTableSectionBoxShadowInset;
  if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
          paintInfo.context, m_layoutTableSection, type))
    return;

  LayoutRect bounds = BoxPainter(m_layoutTableSection)
                          .boundsForDrawingRecorder(paintInfo, paintOffset);
  LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableSection,
                                       type, bounds);
  BoxPainter::paintBoxShadow(
      paintInfo, LayoutRect(paintOffset, m_layoutTableSection.size()),
      m_layoutTableSection.styleRef(), shadowStyle);
}

}  // namespace blink
