void TableCellPainter::paintCollapsedBorders(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) { ASSERT(paintInfo.phase == PaintPhaseCollapsedTableBorders); if (!paintInfo.shouldPaintWithinRoot(&m_layoutTableCell) || m_layoutTableCell.style()->visibility() != VISIBLE) return; LayoutRect paintRect = paintBounds(paintOffset, AddOffsetFromParent); LayoutRect drawingCullRect(paintRect); drawingCullRect.expandEdges(m_layoutTableCell.table()->outerBorderTop(), m_layoutTableCell.table()->outerBorderRight(), m_layoutTableCell.table()->outerBorderBottom(), m_layoutTableCell.table()->outerBorderLeft()); if (drawingCullRect.y() >= paintInfo.rect.maxY()) return; if (drawingCullRect.maxY() <= paintInfo.rect.y()) return; const CollapsedBorderValue* tableCurrentBorderValue = m_layoutTableCell.table()->currentBorderValue(); if (!tableCurrentBorderValue) return; const ComputedStyle& styleForCellFlow = m_layoutTableCell.styleForCellFlow(); const CollapsedBorderValue& leftBorderValue = cachedCollapsedLeftBorder(styleForCellFlow); const CollapsedBorderValue& rightBorderValue = cachedCollapsedRightBorder(styleForCellFlow); const CollapsedBorderValue& topBorderValue = cachedCollapsedTopBorder(styleForCellFlow); const CollapsedBorderValue& bottomBorderValue = cachedCollapsedBottomBorder(styleForCellFlow); bool shouldPaintTop = topBorderValue.shouldPaint(*tableCurrentBorderValue); bool shouldPaintBottom = bottomBorderValue.shouldPaint(*tableCurrentBorderValue); bool shouldPaintLeft = leftBorderValue.shouldPaint(*tableCurrentBorderValue); bool shouldPaintRight = rightBorderValue.shouldPaint(*tableCurrentBorderValue); if (!shouldPaintTop && !shouldPaintBottom && !shouldPaintLeft && !shouldPaintRight) return; GraphicsContext* graphicsContext = paintInfo.context; LayoutObjectDrawingRecorder recorder(*graphicsContext, m_layoutTableCell, paintInfo.phase, drawingCullRect); if (recorder.canUseCachedDrawing()) return; bool antialias = BoxPainter::shouldAntialiasLines(graphicsContext); // Adjust our x/y/width/height so that we paint the collapsed borders at the correct location. int topWidth = topBorderValue.width(); int bottomWidth = bottomBorderValue.width(); int leftWidth = leftBorderValue.width(); int rightWidth = rightBorderValue.width(); IntRect borderRect = pixelSnappedIntRect(paintRect.x() - leftWidth / 2, paintRect.y() - topWidth / 2, paintRect.width() + leftWidth / 2 + (rightWidth + 1) / 2, paintRect.height() + topWidth / 2 + (bottomWidth + 1) / 2); Color cellColor = m_layoutTableCell.resolveColor(CSSPropertyColor); // We never paint diagonals at the joins. We simply let the border with the highest // precedence paint on top of borders with lower precedence. if (shouldPaintTop) { ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.x(), borderRect.y(), borderRect.maxX(), borderRect.y() + topWidth, BSTop, topBorderValue.color().resolve(cellColor), collapsedBorderStyle(topBorderValue.style()), 0, 0, antialias); } if (shouldPaintBottom) { ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.x(), borderRect.maxY() - bottomWidth, borderRect.maxX(), borderRect.maxY(), BSBottom, bottomBorderValue.color().resolve(cellColor), collapsedBorderStyle(bottomBorderValue.style()), 0, 0, antialias); } if (shouldPaintLeft) { ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.x(), borderRect.y(), borderRect.x() + leftWidth, borderRect.maxY(), BSLeft, leftBorderValue.color().resolve(cellColor), collapsedBorderStyle(leftBorderValue.style()), 0, 0, antialias); } if (shouldPaintRight) { ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.maxX() - rightWidth, borderRect.y(), borderRect.maxX(), borderRect.maxY(), BSRight, rightBorderValue.color().resolve(cellColor), collapsedBorderStyle(rightBorderValue.style()), 0, 0, antialias); } }
void TableCellPainter::paintCollapsedBorders(const PaintInfo& paintInfo, const LayoutPoint& paintOffset, const CollapsedBorderValue& currentBorderValue) { if (m_layoutTableCell.style()->visibility() != VISIBLE) return; const ComputedStyle& styleForCellFlow = m_layoutTableCell.styleForCellFlow(); const CollapsedBorderValue* leftBorderValue = cachedCollapsedLeftBorder(styleForCellFlow); const CollapsedBorderValue* rightBorderValue = cachedCollapsedRightBorder(styleForCellFlow); const CollapsedBorderValue* topBorderValue = cachedCollapsedTopBorder(styleForCellFlow); const CollapsedBorderValue* bottomBorderValue = cachedCollapsedBottomBorder(styleForCellFlow); int displayItemType = DisplayItem::TableCollapsedBorderBase; int topWidth = 0; int bottomWidth = 0; int leftWidth = 0; int rightWidth = 0; if (topBorderValue) { if (topBorderValue->shouldPaint(currentBorderValue)) displayItemType |= DisplayItem::TableCollapsedBorderTop; topWidth = topBorderValue->width(); } if (bottomBorderValue) { if (bottomBorderValue->shouldPaint(currentBorderValue)) displayItemType |= DisplayItem::TableCollapsedBorderBottom; bottomWidth = bottomBorderValue->width(); } if (leftBorderValue) { if (leftBorderValue->shouldPaint(currentBorderValue)) displayItemType |= DisplayItem::TableCollapsedBorderLeft; leftWidth = leftBorderValue->width(); } if (rightBorderValue) { if (rightBorderValue->shouldPaint(currentBorderValue)) displayItemType |= DisplayItem::TableCollapsedBorderRight; rightWidth = rightBorderValue->width(); } if (displayItemType == DisplayItem::TableCollapsedBorderBase) return; // Adjust our x/y/width/height so that we paint the collapsed borders at the correct location. LayoutRect paintRect = paintBounds(paintOffset, AddOffsetFromParent); IntRect borderRect = pixelSnappedIntRect(paintRect.x() - leftWidth / 2, paintRect.y() - topWidth / 2, paintRect.width() + leftWidth / 2 + (rightWidth + 1) / 2, paintRect.height() + topWidth / 2 + (bottomWidth + 1) / 2); if (!paintInfo.cullRect().intersectsCullRect(borderRect)) return; GraphicsContext& graphicsContext = paintInfo.context; if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(graphicsContext, m_layoutTableCell, static_cast<DisplayItem::Type>(displayItemType))) return; LayoutObjectDrawingRecorder recorder(graphicsContext, m_layoutTableCell, static_cast<DisplayItem::Type>(displayItemType), borderRect); Color cellColor = m_layoutTableCell.resolveColor(CSSPropertyColor); // We never paint diagonals at the joins. We simply let the border with the highest // precedence paint on top of borders with lower precedence. if (displayItemType & DisplayItem::TableCollapsedBorderTop) { ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.x(), borderRect.y(), borderRect.maxX(), borderRect.y() + topWidth, BSTop, topBorderValue->color().resolve(cellColor), collapsedBorderStyle(topBorderValue->style()), 0, 0, true); } if (displayItemType & DisplayItem::TableCollapsedBorderBottom) { ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.x(), borderRect.maxY() - bottomWidth, borderRect.maxX(), borderRect.maxY(), BSBottom, bottomBorderValue->color().resolve(cellColor), collapsedBorderStyle(bottomBorderValue->style()), 0, 0, true); } if (displayItemType & DisplayItem::TableCollapsedBorderLeft) { ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.x(), borderRect.y(), borderRect.x() + leftWidth, borderRect.maxY(), BSLeft, leftBorderValue->color().resolve(cellColor), collapsedBorderStyle(leftBorderValue->style()), 0, 0, true); } if (displayItemType & DisplayItem::TableCollapsedBorderRight) { ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.maxX() - rightWidth, borderRect.y(), borderRect.maxX(), borderRect.maxY(), BSRight, rightBorderValue->color().resolve(cellColor), collapsedBorderStyle(rightBorderValue->style()), 0, 0, true); } }
void TableCellPainter::paintCollapsedBorders(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) { ASSERT(paintInfo.phase == PaintPhaseCollapsedTableBorders); if (!paintInfo.shouldPaintWithinRoot(&m_renderTableCell) || m_renderTableCell.style()->visibility() != VISIBLE) return; LayoutRect paintRect = paintBounds(paintOffset, AddOffsetFromParent); if (paintRect.y() - m_renderTableCell.table()->outerBorderTop() >= paintInfo.rect.maxY()) return; if (paintRect.maxY() + m_renderTableCell.table()->outerBorderBottom() <= paintInfo.rect.y()) return; if (!m_renderTableCell.table()->currentBorderValue()) return; RenderDrawingRecorder recorder(paintInfo.context, m_renderTableCell, paintInfo.phase, paintRect); if (recorder.canUseCachedDrawing()) return; const RenderStyle* styleForCellFlow = m_renderTableCell.styleForCellFlow(); CollapsedBorderValue leftVal = cachedCollapsedLeftBorder(styleForCellFlow); CollapsedBorderValue rightVal = cachedCollapsedRightBorder(styleForCellFlow); CollapsedBorderValue topVal = cachedCollapsedTopBorder(styleForCellFlow); CollapsedBorderValue bottomVal = cachedCollapsedBottomBorder(styleForCellFlow); // Adjust our x/y/width/height so that we paint the collapsed borders at the correct location. int topWidth = topVal.width(); int bottomWidth = bottomVal.width(); int leftWidth = leftVal.width(); int rightWidth = rightVal.width(); IntRect borderRect = pixelSnappedIntRect(paintRect.x() - leftWidth / 2, paintRect.y() - topWidth / 2, paintRect.width() + leftWidth / 2 + (rightWidth + 1) / 2, paintRect.height() + topWidth / 2 + (bottomWidth + 1) / 2); EBorderStyle topStyle = collapsedBorderStyle(topVal.style()); EBorderStyle bottomStyle = collapsedBorderStyle(bottomVal.style()); EBorderStyle leftStyle = collapsedBorderStyle(leftVal.style()); EBorderStyle rightStyle = collapsedBorderStyle(rightVal.style()); bool renderTop = topStyle > BHIDDEN && !topVal.isTransparent(); bool renderBottom = bottomStyle > BHIDDEN && !bottomVal.isTransparent(); bool renderLeft = leftStyle > BHIDDEN && !leftVal.isTransparent(); bool renderRight = rightStyle > BHIDDEN && !rightVal.isTransparent(); // We never paint diagonals at the joins. We simply let the border with the highest // precedence paint on top of borders with lower precedence. CollapsedBorders borders; borders.addBorder(topVal, BSTop, renderTop, borderRect.x(), borderRect.y(), borderRect.maxX(), borderRect.y() + topWidth, topStyle); borders.addBorder(bottomVal, BSBottom, renderBottom, borderRect.x(), borderRect.maxY() - bottomWidth, borderRect.maxX(), borderRect.maxY(), bottomStyle); borders.addBorder(leftVal, BSLeft, renderLeft, borderRect.x(), borderRect.y(), borderRect.x() + leftWidth, borderRect.maxY(), leftStyle); borders.addBorder(rightVal, BSRight, renderRight, borderRect.maxX() - rightWidth, borderRect.y(), borderRect.maxX(), borderRect.maxY(), rightStyle); GraphicsContext* graphicsContext = paintInfo.context; bool antialias = BoxPainter::shouldAntialiasLines(graphicsContext); for (CollapsedBorder* border = borders.nextBorder(); border; border = borders.nextBorder()) { if (border->borderValue.isSameIgnoringColor(*m_renderTableCell.table()->currentBorderValue())) { ObjectPainter::drawLineForBoxSide(graphicsContext, border->x1, border->y1, border->x2, border->y2, border->side, border->borderValue.color().resolve(m_renderTableCell.resolveColor(CSSPropertyColor)), border->style, 0, 0, antialias); } } }