Commit 20511984 authored by pdr@chromium.org's avatar pdr@chromium.org

Refactor ObjectPainter::paintOutline to take a paintOffset

This patch refactors ObjectPainter::paintOutline to take a visual
overflow rect and layout size (w/o paint offset), plus a paint offset.
This cleans up the callsites so each doesn't need to compute a moved
visual overflow rect, and prepares the paint code for paint offset
caching. This has been split off from https://codereview.chromium.org/1315993004.

A TODO has been added above outlineRectForSVG because the function
should not exist. paintInvalidationRectInLocalCoordinates should be
fixed to contain the outline extent.

BUG=508383

Review URL: https://codereview.chromium.org/1321613002

git-svn-id: svn://svn.chromium.org/blink/trunk@201326 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent feeacbab
......@@ -142,4 +142,12 @@ void LayoutSVGModelObject::invalidateTreeIfNeeded(PaintInvalidationState& paintI
invalidatePaintOfSubtreesIfNeeded(childPaintInvalidationState);
}
LayoutRect LayoutSVGModelObject::outlineVisualOverflowRect() const
{
LayoutRect outlineBounds(FloatPoint(), m_paintInvalidationBoundingBox.size());
if (int outlineOutset = styleRef().outlineOutsetExtent())
outlineBounds.inflate(outlineOutset);
return outlineBounds;
}
} // namespace blink
......@@ -64,6 +64,10 @@ public:
bool isOfType(LayoutObjectType type) const override { return type == LayoutObjectSVG || LayoutObject::isOfType(type); }
// TODO(pdr): The outline extent should be included in paintInvalidationRectInLocalCoordinates.
// Returns the paint invalidation size inflated for the outline extent.
LayoutRect outlineVisualOverflowRect() const;
protected:
void addLayerHitTestRects(LayerHitTestRects&, const DeprecatedPaintLayer* currentCompositedLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const final;
void willBeDestroyed() override;
......
......@@ -146,15 +146,6 @@ void BlockPainter::paintAsInlineBlock(LayoutObject& layoutObject, const PaintInf
}
}
static inline LayoutRect visualOverflowRectWithPaintOffset(const LayoutBlock& layoutBox, const LayoutPoint& paintOffset)
{
if (!RuntimeEnabledFeatures::slimmingPaintEnabled())
return LayoutRect();
LayoutRect bounds = layoutBox.visualOverflowRect();
bounds.moveBy(paintOffset);
return bounds;
}
void BlockPainter::paintObject(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
const PaintPhase paintPhase = paintInfo.phase;
......@@ -211,7 +202,7 @@ void BlockPainter::paintObject(const PaintInfo& paintInfo, const LayoutPoint& pa
// Don't paint focus ring for anonymous block continuation because the
// inline element having outline-style:auto paints the whole focus ring.
if (!m_layoutBlock.style()->outlineStyleIsAuto() || !m_layoutBlock.isAnonymousBlockContinuation())
ObjectPainter(m_layoutBlock).paintOutline(paintInfo, LayoutRect(paintOffset, m_layoutBlock.size()), visualOverflowRectWithPaintOffset(m_layoutBlock, paintOffset));
ObjectPainter(m_layoutBlock).paintOutline(paintInfo, m_layoutBlock.visualOverflowRect(), m_layoutBlock.size(), paintOffset);
}
if (paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)
......@@ -220,7 +211,9 @@ void BlockPainter::paintObject(const PaintInfo& paintInfo, const LayoutPoint& pa
// If the caret's node's layout object's containing block is this block, and the paint action is PaintPhaseForeground,
// then paint the caret.
if (paintPhase == PaintPhaseForeground && hasCaret() && !LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*paintInfo.context, m_layoutBlock, DisplayItem::Caret)) {
LayoutObjectDrawingRecorder recorder(*paintInfo.context, m_layoutBlock, DisplayItem::Caret, visualOverflowRectWithPaintOffset(m_layoutBlock, paintOffset));
LayoutRect bounds = m_layoutBlock.visualOverflowRect();
bounds.moveBy(paintOffset);
LayoutObjectDrawingRecorder recorder(*paintInfo.context, m_layoutBlock, DisplayItem::Caret, bounds);
paintCarets(paintInfo, paintOffset);
}
}
......
......@@ -16,13 +16,6 @@
namespace blink {
LayoutRect ObjectPainter::outlineBounds(const LayoutRect& objectBounds, const ComputedStyle& style)
{
LayoutRect outlineBounds(objectBounds);
outlineBounds.inflate(style.outlineOutsetExtent());
return outlineBounds;
}
void ObjectPainter::paintFocusRing(const PaintInfo& paintInfo, const ComputedStyle& style, const Vector<LayoutRect>& focusRingRects)
{
ASSERT(style.outlineStyleIsAuto());
......@@ -32,7 +25,7 @@ void ObjectPainter::paintFocusRing(const PaintInfo& paintInfo, const ComputedSty
paintInfo.context->drawFocusRing(focusRingIntRects, style.outlineWidth(), style.outlineOffset(), m_layoutObject.resolveColor(style, CSSPropertyOutlineColor));
}
void ObjectPainter::paintOutline(const PaintInfo& paintInfo, const LayoutRect& objectBounds, const LayoutRect& visualOverflowBounds)
void ObjectPainter::paintOutline(const PaintInfo& paintInfo, const LayoutRect& visualOverflowRect, const LayoutSize& objectSize, const LayoutPoint& paintOffset)
{
const ComputedStyle& styleToUse = m_layoutObject.styleRef();
if (!styleToUse.hasOutline())
......@@ -41,13 +34,15 @@ void ObjectPainter::paintOutline(const PaintInfo& paintInfo, const LayoutRect& o
if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*paintInfo.context, m_layoutObject, paintInfo.phase))
return;
LayoutRect visualOverflowBounds(visualOverflowRect);
visualOverflowBounds.moveBy(paintOffset);
LayoutObjectDrawingRecorder recorder(*paintInfo.context, m_layoutObject, paintInfo.phase, visualOverflowBounds);
if (styleToUse.outlineStyleIsAuto()) {
if (LayoutTheme::theme().shouldDrawDefaultFocusRing(&m_layoutObject)) {
// Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
Vector<LayoutRect> focusRingRects;
m_layoutObject.addOutlineRects(focusRingRects, objectBounds.location());
m_layoutObject.addOutlineRects(focusRingRects, paintOffset);
paintFocusRing(paintInfo, styleToUse, focusRingRects);
}
return;
......@@ -56,7 +51,8 @@ void ObjectPainter::paintOutline(const PaintInfo& paintInfo, const LayoutRect& o
if (styleToUse.outlineStyle() == BNONE)
return;
LayoutRect inner(pixelSnappedIntRect(objectBounds));
LayoutRect inner(paintOffset, objectSize);
inner = LayoutRect(pixelSnappedIntRect(inner));
inner.inflate(styleToUse.outlineOffset());
LayoutRect outer(inner);
......
......@@ -14,6 +14,7 @@ class Color;
class GraphicsContext;
class LayoutPoint;
class LayoutRect;
class LayoutSize;
struct PaintInfo;
class LayoutObject;
class ComputedStyle;
......@@ -22,14 +23,12 @@ class ObjectPainter {
public:
ObjectPainter(LayoutObject& layoutObject) : m_layoutObject(layoutObject) { }
void paintOutline(const PaintInfo&, const LayoutRect& objectBounds, const LayoutRect& visualOverflowBounds);
void paintOutline(const PaintInfo&, const LayoutRect& visualOverflowRect, const LayoutSize& objectSize, const LayoutPoint& paintOffset);
void paintFocusRing(const PaintInfo&, const ComputedStyle&, const Vector<LayoutRect>& focusRingRects);
void addPDFURLRectIfNeeded(const PaintInfo&, const LayoutPoint& paintOffset);
static void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide, Color, EBorderStyle, int adjbw1, int adjbw2, bool antialias = false);
static LayoutRect outlineBounds(const LayoutRect& objectBounds, const ComputedStyle&);
private:
static void drawDashedOrDottedBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2,
BoxSide, Color, int thickness, EBorderStyle, bool antialias);
......
......@@ -33,11 +33,8 @@ void PartPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffs
return;
}
LayoutRect visualOverflowRect(m_layoutPart.visualOverflowRect());
visualOverflowRect.moveBy(adjustedPaintOffset);
if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && m_layoutPart.style()->hasOutline())
ObjectPainter(m_layoutPart).paintOutline(paintInfo, borderRect, visualOverflowRect);
ObjectPainter(m_layoutPart).paintOutline(paintInfo, m_layoutPart.visualOverflowRect(), borderRect.size(), adjustedPaintOffset);
if (paintInfo.phase != PaintPhaseForeground)
return;
......
......@@ -23,10 +23,7 @@ void ReplacedPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paint
return;
LayoutPoint adjustedPaintOffset = paintOffset + m_layoutReplaced.location();
LayoutRect paintRect(adjustedPaintOffset, m_layoutReplaced.size());
LayoutRect visualOverflowRect(m_layoutReplaced.visualOverflowRect());
visualOverflowRect.moveBy(adjustedPaintOffset);
LayoutRect borderRect(adjustedPaintOffset, m_layoutReplaced.size());
if (m_layoutReplaced.hasBoxDecorationBackground() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
m_layoutReplaced.paintBoxDecorationBackground(paintInfo, adjustedPaintOffset);
......@@ -41,7 +38,7 @@ void ReplacedPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paint
if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) {
if (m_layoutReplaced.styleRef().outlineWidth())
ObjectPainter(m_layoutReplaced).paintOutline(paintInfo, paintRect, visualOverflowRect);
ObjectPainter(m_layoutReplaced).paintOutline(paintInfo, m_layoutReplaced.visualOverflowRect(), borderRect.size(), adjustedPaintOffset);
return;
}
......@@ -59,13 +56,11 @@ void ReplacedPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paint
Optional<RoundedInnerRectClipper> clipper;
bool completelyClippedOut = false;
if (m_layoutReplaced.style()->hasBorderRadius()) {
LayoutRect borderRect = LayoutRect(adjustedPaintOffset, m_layoutReplaced.size());
if (borderRect.isEmpty()) {
completelyClippedOut = true;
} else {
// Push a clip if we have a border radius, since we want to round the foreground content that gets painted.
FloatRoundedRect roundedInnerRect = m_layoutReplaced.style()->getRoundedInnerBorderFor(paintRect,
FloatRoundedRect roundedInnerRect = m_layoutReplaced.style()->getRoundedInnerBorderFor(borderRect,
LayoutRectOutsets(
-(m_layoutReplaced.paddingTop() + m_layoutReplaced.borderTop()),
-(m_layoutReplaced.paddingRight() + m_layoutReplaced.borderRight()),
......@@ -73,7 +68,7 @@ void ReplacedPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paint
-(m_layoutReplaced.paddingLeft() + m_layoutReplaced.borderLeft())),
true, true);
clipper.emplace(m_layoutReplaced, paintInfo, paintRect, roundedInnerRect, ApplyToDisplayListIfEnabled);
clipper.emplace(m_layoutReplaced, paintInfo, borderRect, roundedInnerRect, ApplyToDisplayListIfEnabled);
}
}
......
......@@ -59,9 +59,10 @@ void SVGContainerPainter::paint(const PaintInfo& paintInfo)
return;
if (m_layoutSVGContainer.style()->outlineWidth() && m_layoutSVGContainer.style()->visibility() == VISIBLE) {
PaintInfo outlinePaintInfo(paintInfoBeforeFiltering);
outlinePaintInfo.phase = PaintPhaseSelfOutline;
LayoutRect layoutBoundingBox(boundingBox);
LayoutRect visualOverflowRect = ObjectPainter::outlineBounds(layoutBoundingBox, m_layoutSVGContainer.styleRef());
ObjectPainter(m_layoutSVGContainer).paintOutline(paintInfoBeforeFiltering, layoutBoundingBox, visualOverflowRect);
ObjectPainter(m_layoutSVGContainer).paintOutline(outlinePaintInfo, m_layoutSVGContainer.outlineVisualOverflowRect(), layoutBoundingBox.size(), layoutBoundingBox.location());
}
if (paintInfoBeforeFiltering.isPrinting())
......
......@@ -59,8 +59,7 @@ void SVGImagePainter::paint(const PaintInfo& paintInfo)
PaintInfo outlinePaintInfo(paintInfoBeforeFiltering);
outlinePaintInfo.phase = PaintPhaseSelfOutline;
LayoutRect layoutBoundingBox(boundingBox);
LayoutRect visualOverflowRect = ObjectPainter::outlineBounds(layoutBoundingBox, m_layoutSVGImage.styleRef());
ObjectPainter(m_layoutSVGImage).paintOutline(outlinePaintInfo, layoutBoundingBox, visualOverflowRect);
ObjectPainter(m_layoutSVGImage).paintOutline(outlinePaintInfo, m_layoutSVGImage.outlineVisualOverflowRect(), layoutBoundingBox.size(), layoutBoundingBox.location());
}
}
......
......@@ -116,9 +116,8 @@ void SVGShapePainter::paint(const PaintInfo& paintInfo)
if (m_layoutSVGShape.style()->outlineWidth()) {
PaintInfo outlinePaintInfo(paintInfoBeforeFiltering);
outlinePaintInfo.phase = PaintPhaseSelfOutline;
LayoutRect layoutObjectBounds(boundingBox);
LayoutRect visualOverflowRect = ObjectPainter::outlineBounds(layoutObjectBounds, m_layoutSVGShape.styleRef());
ObjectPainter(m_layoutSVGShape).paintOutline(outlinePaintInfo, layoutObjectBounds, visualOverflowRect);
LayoutRect layoutBoundingBox(boundingBox);
ObjectPainter(m_layoutSVGShape).paintOutline(outlinePaintInfo, m_layoutSVGShape.outlineVisualOverflowRect(), layoutBoundingBox.size(), layoutBoundingBox.location());
}
}
......
......@@ -65,11 +65,8 @@ void TablePainter::paintObject(const PaintInfo& paintInfo, const LayoutPoint& pa
}
// Paint outline.
if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && m_layoutTable.style()->hasOutline() && m_layoutTable.style()->visibility() == VISIBLE) {
LayoutRect overflowRect(m_layoutTable.visualOverflowRect());
overflowRect.moveBy(paintOffset);
ObjectPainter(m_layoutTable).paintOutline(paintInfo, LayoutRect(paintOffset, m_layoutTable.size()), overflowRect);
}
if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && m_layoutTable.style()->hasOutline() && m_layoutTable.style()->visibility() == VISIBLE)
ObjectPainter(m_layoutTable).paintOutline(paintInfo, m_layoutTable.visualOverflowRect(), m_layoutTable.size(), paintOffset);
}
void TablePainter::paintBoxDecorationBackground(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
......
......@@ -38,12 +38,10 @@ void TableRowPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paint
void TableRowPainter::paintOutlineForRowIfNeeded(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
LayoutPoint adjustedPaintOffset = paintOffset + m_layoutTableRow.location();
PaintPhase paintPhase = paintInfo.phase;
if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && m_layoutTableRow.style()->visibility() == VISIBLE) {
LayoutRect visualOverflowRect(m_layoutTableRow.visualOverflowRect());
visualOverflowRect.moveBy(adjustedPaintOffset);
ObjectPainter(m_layoutTableRow).paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, m_layoutTableRow.size()), visualOverflowRect);
LayoutPoint adjustedPaintOffset = paintOffset + m_layoutTableRow.location();
ObjectPainter(m_layoutTableRow).paintOutline(paintInfo, m_layoutTableRow.visualOverflowRect(), m_layoutTableRow.size(), adjustedPaintOffset);
}
}
......
......@@ -37,11 +37,8 @@ void TableSectionPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& p
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);
}
if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && m_layoutTableSection.style()->visibility() == VISIBLE)
ObjectPainter(m_layoutTableSection).paintOutline(paintInfo, m_layoutTableSection.visualOverflowRect(), m_layoutTableSection.size(), adjustedPaintOffset);
}
static inline bool compareCellPositions(LayoutTableCell* elem1, LayoutTableCell* elem2)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment