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); }
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); }
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); }