void TableSectionPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    ANNOTATE_GRAPHICS_CONTEXT(paintInfo, &m_layoutTableSection);

    ASSERT(!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()->columns().size();

    if (!totalRows || !totalCols)
        return;

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

    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && m_layoutTableSection.style()->visibility() == VISIBLE) {
        LayoutRect visualOverflowRect(m_layoutTableSection.visualOverflowRect());
        visualOverflowRect.moveBy(adjustedPaintOffset);
        ObjectPainter(m_layoutTableSection).paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, m_layoutTableSection.size()), visualOverflowRect);
    }
}
void TableSectionPainter::paintCollapsedBorders(const PaintInfo& paintInfo, const LayoutPoint& paintOffset, const CollapsedBorderValue& currentBorderValue)
{
    if (!m_layoutTableSection.numRows() || !m_layoutTableSection.table()->columns().size())
        return;

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

    LayoutRect localPaintInvalidationRect = LayoutRect(paintInfo.rect);
    localPaintInvalidationRect.moveBy(-adjustedPaintOffset);

    LayoutRect tableAlignedRect = m_layoutTableSection.logicalRectForWritingModeAndDirection(localPaintInvalidationRect);

    CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect);
    CellSpan dirtiedColumns = m_layoutTableSection.dirtiedColumns(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 BlockPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    Optional<SubtreeRecorder> subtreeRecorder;
    if (needsSubtreeRecorder(m_layoutBlock)) {
        subtreeRecorder.emplace(*paintInfo.context, m_layoutBlock, paintInfo.phase);
        if (subtreeRecorder->canUseCache())
            return;
    }

    PaintInfo localPaintInfo(paintInfo);

    LayoutPoint adjustedPaintOffset = paintOffset + m_layoutBlock.location();

    PaintPhase originalPhase = localPaintInfo.phase;

    // Check if we need to do anything at all.
    LayoutRect overflowBox = overflowRectForPaintRejection();
    m_layoutBlock.flipForWritingMode(overflowBox);
    overflowBox.moveBy(adjustedPaintOffset);
    if (!overflowBox.intersects(LayoutRect(localPaintInfo.rect)))
        return;

    // There are some cases where not all clipped visual overflow is accounted for.
    // FIXME: reduce the number of such cases.
    ContentsClipBehavior contentsClipBehavior = ForceContentsClip;
    if (m_layoutBlock.hasOverflowClip() && !m_layoutBlock.hasControlClip() && !(m_layoutBlock.shouldPaintSelectionGaps() && originalPhase == PaintPhaseForeground) && !hasCaret())
        contentsClipBehavior = SkipContentsClipIfPossible;

    if (localPaintInfo.phase == PaintPhaseOutline) {
        localPaintInfo.phase = PaintPhaseChildOutlines;
    } else if (localPaintInfo.phase == PaintPhaseChildBlockBackground) {
        localPaintInfo.phase = PaintPhaseBlockBackground;
        m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
        localPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
    }

    {
        BoxClipper boxClipper(m_layoutBlock, localPaintInfo, adjustedPaintOffset, contentsClipBehavior);
        m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
    }

    if (originalPhase == PaintPhaseOutline) {
        localPaintInfo.phase = PaintPhaseSelfOutline;
        m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
        localPaintInfo.phase = originalPhase;
    } else if (originalPhase == PaintPhaseChildBlockBackground) {
        localPaintInfo.phase = originalPhase;
    }

    // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
    // z-index. We paint after we painted the background/border, so that the scrollbars will
    // sit above the background/border.
    paintOverflowControlsIfNeeded(localPaintInfo, adjustedPaintOffset);
}
Example #4
0
void BlockPainter::paint(const PaintInfo& paintInfo,
                         const LayoutPoint& paintOffset) {
  LayoutPoint adjustedPaintOffset = paintOffset + m_layoutBlock.location();
  if (!intersectsPaintRect(paintInfo, adjustedPaintOffset))
    return;

  PaintInfo localPaintInfo(paintInfo);
  PaintPhase originalPhase = localPaintInfo.phase;

  // There are some cases where not all clipped visual overflow is accounted
  // for.
  // FIXME: reduce the number of such cases.
  ContentsClipBehavior contentsClipBehavior = ForceContentsClip;
  if (m_layoutBlock.hasOverflowClip() && !m_layoutBlock.hasControlClip() &&
      !m_layoutBlock.hasCaret())
    contentsClipBehavior = SkipContentsClipIfPossible;

  if (originalPhase == PaintPhaseOutline) {
    localPaintInfo.phase = PaintPhaseDescendantOutlinesOnly;
  } else if (shouldPaintSelfBlockBackground(originalPhase)) {
    localPaintInfo.phase = PaintPhaseSelfBlockBackgroundOnly;
    m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
    if (shouldPaintDescendantBlockBackgrounds(originalPhase))
      localPaintInfo.phase = PaintPhaseDescendantBlockBackgroundsOnly;
  }

  if (originalPhase != PaintPhaseSelfBlockBackgroundOnly &&
      originalPhase != PaintPhaseSelfOutlineOnly) {
    BoxClipper boxClipper(m_layoutBlock, localPaintInfo, adjustedPaintOffset,
                          contentsClipBehavior);
    m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
  }

  if (shouldPaintSelfOutline(originalPhase)) {
    localPaintInfo.phase = PaintPhaseSelfOutlineOnly;
    m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
  }

  // Our scrollbar widgets paint exactly when we tell them to, so that they work
  // properly with z-index. We paint after we painted the background/border, so
  // that the scrollbars will sit above the background/border.
  localPaintInfo.phase = originalPhase;
  paintOverflowControlsIfNeeded(localPaintInfo, adjustedPaintOffset);
}
Example #5
0
void BlockPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    if (!intersectsPaintRect(paintInfo, paintOffset))
        return;

    LayoutPoint adjustedPaintOffset = paintOffset + m_layoutBlock.location();
    PaintInfo localPaintInfo(paintInfo);
    PaintPhase originalPhase = localPaintInfo.phase;

    // There are some cases where not all clipped visual overflow is accounted for.
    // FIXME: reduce the number of such cases.
    ContentsClipBehavior contentsClipBehavior = ForceContentsClip;
    if (m_layoutBlock.hasOverflowClip() && !m_layoutBlock.hasControlClip() && !(m_layoutBlock.shouldPaintSelectionGaps() && originalPhase == PaintPhaseForeground) && !m_layoutBlock.hasCaret())
        contentsClipBehavior = SkipContentsClipIfPossible;

    if (localPaintInfo.phase == PaintPhaseOutline) {
        localPaintInfo.phase = PaintPhaseChildOutlines;
    } else if (localPaintInfo.phase == PaintPhaseChildBlockBackground) {
        localPaintInfo.phase = PaintPhaseBlockBackground;
        m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
        localPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
    }

    {
        BoxClipper boxClipper(m_layoutBlock, localPaintInfo, adjustedPaintOffset, contentsClipBehavior);
        m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
    }

    if (originalPhase == PaintPhaseOutline) {
        localPaintInfo.phase = PaintPhaseSelfOutline;
        m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
        localPaintInfo.phase = originalPhase;
    } else if (originalPhase == PaintPhaseChildBlockBackground) {
        localPaintInfo.phase = originalPhase;
    }

    // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
    // z-index. We paint after we painted the background/border, so that the scrollbars will
    // sit above the background/border.
    paintOverflowControlsIfNeeded(localPaintInfo, adjustedPaintOffset);
}