Commit bae48d0a authored by eric@webkit.org's avatar eric@webkit.org

Reviewed by Antti Koivisto.

        Move RenderPath and RenderSVGContainer onto a unified clippedOverflowRectForRepaint
        https://bugs.webkit.org/show_bug.cgi?id=25268

        Lots of minus lines.  Now we're sharing more sane code
        (which will respect -webkit-transforms! and scroll offsets correctly)

        Which means this fixes:
        https://bugs.webkit.org/show_bug.cgi?id=20769 too!

        We're no longer expanding the paint rect "for anti-aliasing", since
        I can't find a case where that's required.  If it is, repaintRectInLocalCoordinates()
        should be fixed to handle those cases instead of here.

        This fixes svg/custom/scroll-hit-test (now that we respect scroll offsets when repainting)
        as well as improves our focus ring drawing seen in svg/custom/focus-ring
        focus rings are now closer to transformed content by a couple pixels (they were needlessly outset by the antialiasing hack)
        Also, it fixes the dumped rects for markers, causing a progression in svg/custom/marker-overflow-clip

        * rendering/RenderPath.cpp:
        (WebCore::RenderPath::repaintRectInLocalCoordinates):
        (WebCore::RenderPath::setPath):
        * rendering/RenderPath.h:
        * rendering/RenderSVGContainer.cpp:
        (WebCore::RenderSVGContainer::repaintRectInLocalCoordinates):
        * rendering/RenderSVGContainer.h:
        * rendering/RenderSVGModelObject.cpp:
        (WebCore::RenderSVGModelObject::clippedOverflowRectForRepaint):
        (WebCore::RenderSVGModelObject::computeRectForRepaint):
        * rendering/RenderSVGModelObject.h:
        * rendering/RenderSVGRoot.cpp:
        (WebCore::RenderSVGRoot::computeRectForRepaint):
        * rendering/RenderSVGRoot.h:

git-svn-id: svn://svn.chromium.org/blink/trunk@42613 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 163bad48
2009-04-17 Eric Seidel <eric@webkit.org>
Reviewed by Antti Koivisto.
Move RenderPath and RenderSVGContainer onto a unified clippedOverflowRectForRepaint
https://bugs.webkit.org/show_bug.cgi?id=25268
* platform/mac/svg/custom/focus-ring-expected.checksum:
* platform/mac/svg/custom/focus-ring-expected.png:
* platform/mac/svg/custom/marker-overflow-clip-expected.txt:
* platform/mac/svg/custom/scroll-hit-test-expected.checksum:
* platform/mac/svg/custom/scroll-hit-test-expected.png:
2009-04-17 Dan Bernstein <mitz@apple.com> 2009-04-17 Dan Bernstein <mitz@apple.com>
Rubber-stamped by Anders Carlsson. Rubber-stamped by Anders Carlsson.
......
bc4d2cc849d81a1db68fae1ac7e9f2fe b0271ba362746668aa698b1dc12d3393
\ No newline at end of file \ No newline at end of file
...@@ -2,12 +2,12 @@ KCanvasResource {id="marker" [type=MARKER] [angle=auto] [ref x=50.00 y=50.00]} ...@@ -2,12 +2,12 @@ KCanvasResource {id="marker" [type=MARKER] [angle=auto] [ref x=50.00 y=50.00]}
layer at (0,0) size 800x600 layer at (0,0) size 800x600
RenderView at (0,0) size 800x600 RenderView at (0,0) size 800x600
layer at (0,0) size 800x600 layer at (0,0) size 800x600
RenderSVGRoot {svg} at (-25,-25) size 353x100 RenderSVGRoot {svg} at (-50,-50) size 378x300
RenderSVGViewportContainer {marker} at (-25,-25) size 100x100 RenderSVGViewportContainer {marker} at (-25,-25) size 100x100
RenderPath {rect} at (-25,-25) size 100x100 [fill={[type=SOLID] [color=#FF0000]}] [data="M-50.00,-50.00 L150.00,-50.00 L150.00,150.00 L-50.00,150.00 Z"] RenderPath {rect} at (-25,-25) size 100x100 [fill={[type=SOLID] [color=#FF0000]}] [data="M-50.00,-50.00 L150.00,-50.00 L150.00,150.00 L-50.00,150.00 Z"]
RenderPath {rect} at (0,0) size 50x50 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"] RenderPath {rect} at (0,0) size 50x50 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
RenderPath {rect} at (0,0) size 25x25 [fill={[type=SOLID] [color=#000000]}] [data="M0.00,0.00 L25.00,0.00 L25.00,25.00 L0.00,25.00 Z"] RenderPath {rect} at (0,0) size 25x25 [fill={[type=SOLID] [color=#000000]}] [data="M0.00,0.00 L25.00,0.00 L25.00,25.00 L0.00,25.00 Z"]
RenderPath {path} at (100,100) size 0x0 [start marker=marker] [data="M100.00,100.00 L100.00,100.00"] RenderPath {path} at (-50,-50) size 300x300 [start marker=marker] [data="M100.00,100.00 L100.00,100.00"]
RenderSVGText {text} at (30,20) size 298x18 contains 1 chunk(s) RenderSVGText {text} at (30,20) size 298x18 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-14) size 298x18 RenderSVGInlineText {#text} at (0,-14) size 298x18
chunk 1 text run 1 at (30.00,20.00) startOffset 0 endOffset 45 width 298.00: "There should be a 150x150 green rect at 25x25" chunk 1 text run 1 at (30.00,20.00) startOffset 0 endOffset 45 width 298.00: "There should be a 150x150 green rect at 25x25"
ef9de3f943272ed530ce5762716b8284 778803df0a824ed8f2c7dfa07c56832e
\ No newline at end of file \ No newline at end of file
2009-04-17 Eric Seidel <eric@webkit.org>
Reviewed by Antti Koivisto.
Move RenderPath and RenderSVGContainer onto a unified clippedOverflowRectForRepaint
https://bugs.webkit.org/show_bug.cgi?id=25268
Lots of minus lines. Now we're sharing more sane code
(which will respect -webkit-transforms! and scroll offsets correctly)
Which means this fixes:
https://bugs.webkit.org/show_bug.cgi?id=20769 and
https://bugs.webkit.org/show_bug.cgi?id=21968 too!
We're no longer expanding the paint rect "for anti-aliasing", since
I can't find a case where that's required. If it is, repaintRectInLocalCoordinates()
should be fixed to handle those cases instead of here.
This fixes svg/custom/scroll-hit-test (now that we respect scroll offsets when repainting)
as well as improves our focus ring drawing seen in svg/custom/focus-ring
focus rings are now closer to transformed content by a couple pixels (they were needlessly outset by the antialiasing hack)
Also, it fixes the dumped rects for markers, causing a progression in svg/custom/marker-overflow-clip
* rendering/RenderPath.cpp:
(WebCore::RenderPath::repaintRectInLocalCoordinates):
(WebCore::RenderPath::setPath):
* rendering/RenderPath.h:
* rendering/RenderSVGContainer.cpp:
(WebCore::RenderSVGContainer::repaintRectInLocalCoordinates):
* rendering/RenderSVGContainer.h:
* rendering/RenderSVGModelObject.cpp:
(WebCore::RenderSVGModelObject::clippedOverflowRectForRepaint):
(WebCore::RenderSVGModelObject::computeRectForRepaint):
* rendering/RenderSVGModelObject.h:
* rendering/RenderSVGRoot.cpp:
(WebCore::RenderSVGRoot::computeRectForRepaint):
* rendering/RenderSVGRoot.h:
2009-04-17 Chris Fleizach <cfleizach@apple.com> 2009-04-17 Chris Fleizach <cfleizach@apple.com>
Reviewed by Darin Adler. Reviewed by Darin Adler.
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005, 2008 Rob Buis <buis@kde.org> 2004, 2005, 2008 Rob Buis <buis@kde.org>
2005, 2007 Eric Seidel <eric@webkit.org> 2005, 2007 Eric Seidel <eric@webkit.org>
2009 Google, Inc.
This file is part of the KDE project
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
...@@ -112,10 +111,10 @@ FloatRect RenderPath::objectBoundingBox() const ...@@ -112,10 +111,10 @@ FloatRect RenderPath::objectBoundingBox() const
if (m_path.isEmpty()) if (m_path.isEmpty())
return FloatRect(); return FloatRect();
if (m_fillBBox.isEmpty()) if (m_cachedLocalFillBBox.isEmpty())
m_fillBBox = m_path.boundingRect(); m_cachedLocalFillBBox = m_path.boundingRect();
return m_fillBBox; return m_cachedLocalFillBBox;
} }
FloatRect RenderPath::repaintRectInLocalCoordinates() const FloatRect RenderPath::repaintRectInLocalCoordinates() const
...@@ -123,23 +122,29 @@ FloatRect RenderPath::repaintRectInLocalCoordinates() const ...@@ -123,23 +122,29 @@ FloatRect RenderPath::repaintRectInLocalCoordinates() const
if (m_path.isEmpty()) if (m_path.isEmpty())
return FloatRect(); return FloatRect();
if (m_strokeBbox.isEmpty()) { // If we already have a cached repaint rect, return that
if (!style()->svgStyle()->hasStroke()) if (!m_cachedLocalRepaintRect.isEmpty())
return objectBoundingBox(); return m_cachedLocalRepaintRect;
if (!style()->svgStyle()->hasStroke())
m_cachedLocalRepaintRect = objectBoundingBox();
else {
BoundingRectStrokeStyleApplier strokeStyle(this, style()); BoundingRectStrokeStyleApplier strokeStyle(this, style());
m_strokeBbox = m_path.strokeBoundingRect(&strokeStyle); m_cachedLocalRepaintRect = m_path.strokeBoundingRect(&strokeStyle);
} }
// FIXME: This should include filter and marker content too.
return m_strokeBbox; // Markers and filters can paint outside of the stroke path
m_cachedLocalRepaintRect.unite(m_markerBounds);
m_cachedLocalRepaintRect.unite(filterBoundingBox());
return m_cachedLocalRepaintRect;
} }
void RenderPath::setPath(const Path& newPath) void RenderPath::setPath(const Path& newPath)
{ {
m_path = newPath; m_path = newPath;
m_strokeBbox = FloatRect(); m_cachedLocalRepaintRect = FloatRect();
m_fillBBox = FloatRect(); m_cachedLocalFillBBox = FloatRect();
} }
const Path& RenderPath::path() const const Path& RenderPath::path() const
...@@ -170,23 +175,6 @@ void RenderPath::layout() ...@@ -170,23 +175,6 @@ void RenderPath::layout()
setNeedsLayout(false); setNeedsLayout(false);
} }
IntRect RenderPath::clippedOverflowRectForRepaint(RenderBoxModelObject* /*repaintContainer*/)
{
// FIXME: handle non-root repaintContainer
FloatRect repaintRect = absoluteTransform().mapRect(repaintRectInLocalCoordinates());
// Markers can expand the bounding box
repaintRect.unite(m_markerBounds);
// Filters can paint anywhere. If we have one, expand our rect so we are sure to repaint it.
repaintRect.unite(filterBoundingBox());
if (!repaintRect.isEmpty())
repaintRect.inflate(1); // inflate 1 pixel for antialiasing
return enclosingIntRect(repaintRect);
}
int RenderPath::lineHeight(bool, bool) const int RenderPath::lineHeight(bool, bool) const
{ {
return repaintRectInLocalCoordinates().height(); return repaintRectInLocalCoordinates().height();
......
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
2004, 2005 Rob Buis <buis@kde.org> 2004, 2005 Rob Buis <buis@kde.org>
2005 Eric Seidel <eric@webkit.org> 2005 Eric Seidel <eric@webkit.org>
2006 Apple Computer, Inc 2006 Apple Computer, Inc
2009 Google, Inc.
This file is part of the KDE project
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
...@@ -58,7 +57,6 @@ public: ...@@ -58,7 +57,6 @@ public:
virtual TransformationMatrix localTransform() const; virtual TransformationMatrix localTransform() const;
virtual void layout(); virtual void layout();
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual bool requiresLayer() const { return false; } virtual bool requiresLayer() const { return false; }
virtual int lineHeight(bool b, bool isRootLineBox = false) const; virtual int lineHeight(bool b, bool isRootLineBox = false) const;
virtual int baselinePosition(bool b, bool isRootLineBox = false) const; virtual int baselinePosition(bool b, bool isRootLineBox = false) const;
...@@ -77,8 +75,8 @@ private: ...@@ -77,8 +75,8 @@ private:
virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer) const; virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer) const;
mutable Path m_path; mutable Path m_path;
mutable FloatRect m_fillBBox; mutable FloatRect m_cachedLocalFillBBox;
mutable FloatRect m_strokeBbox; mutable FloatRect m_cachedLocalRepaintRect;
FloatRect m_markerBounds; FloatRect m_markerBounds;
TransformationMatrix m_localTransform; TransformationMatrix m_localTransform;
IntRect m_absoluteBounds; IntRect m_absoluteBounds;
......
...@@ -152,22 +152,6 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int, int) ...@@ -152,22 +152,6 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int, int)
paintOutline(paintInfo.context, m_absoluteBounds.x(), m_absoluteBounds.y(), m_absoluteBounds.width(), m_absoluteBounds.height(), style()); paintOutline(paintInfo.context, m_absoluteBounds.x(), m_absoluteBounds.y(), m_absoluteBounds.width(), m_absoluteBounds.height(), style());
} }
IntRect RenderSVGContainer::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
FloatRect repaintRect;
for (RenderObject* current = firstChild(); current != 0; current = current->nextSibling())
repaintRect.unite(current->clippedOverflowRectForRepaint(repaintContainer));
// Filters can paint anywhere. If we have one, expand our rect so we are sure to repaint it.
repaintRect.unite(filterBoundingBox());
if (!repaintRect.isEmpty())
repaintRect.inflate(1); // inflate 1 pixel for antialiasing
return enclosingIntRect(repaintRect);
}
void RenderSVGContainer::addFocusRingRects(GraphicsContext* graphicsContext, int, int) void RenderSVGContainer::addFocusRingRects(GraphicsContext* graphicsContext, int, int)
{ {
graphicsContext->addFocusRingRect(m_absoluteBounds); graphicsContext->addFocusRingRect(m_absoluteBounds);
...@@ -192,7 +176,12 @@ FloatRect RenderSVGContainer::objectBoundingBox() const ...@@ -192,7 +176,12 @@ FloatRect RenderSVGContainer::objectBoundingBox() const
// width or height, so we union all of our child rects as our repaint rect. // width or height, so we union all of our child rects as our repaint rect.
FloatRect RenderSVGContainer::repaintRectInLocalCoordinates() const FloatRect RenderSVGContainer::repaintRectInLocalCoordinates() const
{ {
return computeContainerBoundingBox(this, true); FloatRect repaintRect = computeContainerBoundingBox(this, true);
// A filter on this container can paint outside of the union of the child repaint rects
repaintRect.unite(filterBoundingBox());
return repaintRect;
} }
bool RenderSVGContainer::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction) bool RenderSVGContainer::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
......
...@@ -52,7 +52,6 @@ public: ...@@ -52,7 +52,6 @@ public:
virtual void layout(); virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY); virtual void paint(PaintInfo&, int parentX, int parentY);
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel = true); virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel = true);
virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true); virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true);
virtual void addFocusRingRects(GraphicsContext*, int tx, int ty); virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
......
...@@ -33,10 +33,12 @@ ...@@ -33,10 +33,12 @@
#if ENABLE(SVG) #if ENABLE(SVG)
#include "RenderSVGModelObject.h" #include "RenderSVGModelObject.h"
#include "RenderLayer.h"
#include "SVGStyledElement.h"
#if ENABLE(SVG_FILTERS) #if ENABLE(SVG_FILTERS)
#include "SVGResourceFilter.h" #include "SVGResourceFilter.h"
#endif #endif
#include "SVGStyledElement.h"
namespace WebCore { namespace WebCore {
...@@ -45,6 +47,26 @@ RenderSVGModelObject::RenderSVGModelObject(SVGStyledElement* node) ...@@ -45,6 +47,26 @@ RenderSVGModelObject::RenderSVGModelObject(SVGStyledElement* node)
{ {
} }
IntRect RenderSVGModelObject::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
// Return early for any cases where we don't actually paint
if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
return IntRect();
// Pass our local paint rect to computeRectForRepaint() which will
// map to parent coords and recurse up the parent chain.
IntRect repaintRect = enclosingIntRect(repaintRectInLocalCoordinates());
computeRectForRepaint(repaintContainer, repaintRect);
return repaintRect;
}
void RenderSVGModelObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
// Translate to coords in our parent renderer, and then call computeRectForRepaint on our parent
repaintRect = localToParentTransform().mapRect(repaintRect);
parent()->computeRectForRepaint(repaintContainer, repaintRect, fixed);
}
FloatRect RenderSVGModelObject::filterBoundingBox() const FloatRect RenderSVGModelObject::filterBoundingBox() const
{ {
#if ENABLE(SVG_FILTERS) #if ENABLE(SVG_FILTERS)
......
...@@ -50,6 +50,9 @@ public: ...@@ -50,6 +50,9 @@ public:
virtual bool requiresLayer() const { return false; } virtual bool requiresLayer() const { return false; }
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
protected: protected:
// Returns the bounding box for the filter associated with this object (if any) // Returns the bounding box for the filter associated with this object (if any)
FloatRect filterBoundingBox() const; FloatRect filterBoundingBox() const;
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005, 2007, 2008, 2009 Rob Buis <buis@kde.org> 2004, 2005, 2007, 2008, 2009 Rob Buis <buis@kde.org>
2007 Eric Seidel <eric@webkit.org> 2007 Eric Seidel <eric@webkit.org>
2009 Google, Inc.
This file is part of the KDE project
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
...@@ -253,6 +252,20 @@ TransformationMatrix RenderSVGRoot::localTransform() const ...@@ -253,6 +252,20 @@ TransformationMatrix RenderSVGRoot::localTransform() const
return TransformationMatrix(); return TransformationMatrix();
} }
void RenderSVGRoot::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
// Apply our viewbox transform, and then call RenderBox's method to handle all the normal CSS Box model bits
TransformationMatrix localToParent = localToParentTransform();
// Undo the x(),y() translation included in localToParentTransform() because
// RenderBox::computeRectForRepaint() expects it to be included in repaintRect
localToParent.translateRight(-x(), -y());
// Apply our localToParent transform and pass the rect off to our RenderBox
repaintRect = localToParent.mapRect(repaintRect);
RenderBox::computeRectForRepaint(repaintContainer, repaintRect, fixed);
}
bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction) bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
{ {
TransformationMatrix ctm = RenderBox::absoluteTransform(); TransformationMatrix ctm = RenderBox::absoluteTransform();
......
...@@ -47,7 +47,7 @@ public: ...@@ -47,7 +47,7 @@ public:
virtual int lineHeight(bool b, bool isRootLineBox = false) const; virtual int lineHeight(bool b, bool isRootLineBox = false) const;
virtual int baselinePosition(bool b, bool isRootLineBox = false) const; virtual int baselinePosition(bool b, bool isRootLineBox = false) const;
virtual void calcPrefWidths(); virtual void calcPrefWidths();
virtual void layout(); virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY); virtual void paint(PaintInfo&, int parentX, int parentY);
...@@ -66,7 +66,9 @@ public: ...@@ -66,7 +66,9 @@ public:
FloatRect viewport() const; FloatRect viewport() const;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed);
private: private:
void calcViewport(); void calcViewport();
void applyContentTransforms(PaintInfo&, int parentX, int parentY); void applyContentTransforms(PaintInfo&, int parentX, int parentY);
......
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