diff options
author | Steve Block <steveblock@google.com> | 2010-04-27 16:31:00 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-05-11 14:42:12 +0100 |
commit | dcc8cf2e65d1aa555cce12431a16547e66b469ee (patch) | |
tree | 92a8d65cd5383bca9749f5327fb5e440563926e6 /WebCore/rendering/RenderPath.cpp | |
parent | ccac38a6b48843126402088a309597e682f40fe6 (diff) | |
download | external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.zip external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.gz external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.bz2 |
Merge webkit.org at r58033 : Initial merge by git
Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1
Diffstat (limited to 'WebCore/rendering/RenderPath.cpp')
-rw-r--r-- | WebCore/rendering/RenderPath.cpp | 129 |
1 files changed, 76 insertions, 53 deletions
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp index bcedd38..b1e2a8f 100644 --- a/WebCore/rendering/RenderPath.cpp +++ b/WebCore/rendering/RenderPath.cpp @@ -31,10 +31,11 @@ #include "GraphicsContext.h" #include "PointerEventsHitRules.h" #include "RenderSVGContainer.h" +#include "RenderSVGResourceFilter.h" +#include "RenderSVGResourceMarker.h" #include "StrokeStyleApplier.h" #include "SVGPaintServer.h" #include "SVGRenderSupport.h" -#include "SVGResourceMarker.h" #include "SVGStyledTransformableElement.h" #include "SVGTransformList.h" #include "SVGURIReference.h" @@ -64,19 +65,12 @@ private: RenderPath::RenderPath(SVGStyledTransformableElement* node) : RenderSVGModelObject(node) + , m_needsBoundariesUpdate(false) // default is false, as this is only used when a RenderSVGResource tells us that the boundaries need to be recached + , m_needsPathUpdate(true) // default is true, so we grab a Path object once from SVGStyledTransformableElement + , m_needsTransformUpdate(true) // default is true, so we grab a AffineTransform object once from SVGStyledTransformableElement { } -const AffineTransform& RenderPath::localToParentTransform() const -{ - return m_localTransform; -} - -AffineTransform RenderPath::localTransform() const -{ - return m_localTransform; -} - bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill) const { if (m_path.isEmpty()) @@ -171,22 +165,34 @@ FloatRect RenderPath::repaintRectInLocalCoordinates() const return m_cachedLocalRepaintRect; } -void RenderPath::setPath(const Path& newPath) -{ - m_path = newPath; - m_cachedLocalRepaintRect = FloatRect(); - m_cachedLocalStrokeBBox = FloatRect(); - m_cachedLocalFillBBox = FloatRect(); - m_cachedLocalMarkerBBox = FloatRect(); -} - void RenderPath::layout() { LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout()); - SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node()); - m_localTransform = element->animatedLocalTransform(); - setPath(element->toPathData()); + + // We need to update the Path object whenever the underlying SVGStyledTransformableElement uses relative values + // as the viewport size may have changed. It would be nice to optimize this to detect these changes, and only + // update when needed, even when using relative values. + if (!m_needsPathUpdate && element->hasRelativeValues()) + m_needsPathUpdate = true; + + bool needsUpdate = m_needsPathUpdate || m_needsTransformUpdate || m_needsBoundariesUpdate; + + if (m_needsBoundariesUpdate) + m_needsBoundariesUpdate = false; + + if (m_needsPathUpdate) { + m_path = element->toPathData(); + m_needsPathUpdate = false; + } + + if (m_needsTransformUpdate) { + m_localTransform = element->animatedLocalTransform(); + m_needsTransformUpdate = false; + } + + if (needsUpdate) + invalidateCachedBoundaries(); repainter.repaintAfterLayout(); setNeedsLayout(false); @@ -223,29 +229,32 @@ void RenderPath::paint(PaintInfo& paintInfo, int, int) return; PaintInfo childPaintInfo(paintInfo); - childPaintInfo.context->save(); - applyTransformToPaintInfo(childPaintInfo, m_localTransform); - SVGResourceFilter* filter = 0; - - if (childPaintInfo.phase == PaintPhaseForeground) { - PaintInfo savedInfo(childPaintInfo); - - if (prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter)) { - if (style()->svgStyle()->shapeRendering() == SR_CRISPEDGES) - childPaintInfo.context->setShouldAntialias(false); - fillAndStrokePath(m_path, childPaintInfo.context, style(), this); - - if (static_cast<SVGStyledElement*>(node())->supportsMarkers()) - m_markerLayoutInfo.drawMarkers(childPaintInfo); + bool drawsOutline = style()->outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline); + if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) { + childPaintInfo.context->save(); + applyTransformToPaintInfo(childPaintInfo, m_localTransform); + RenderSVGResourceFilter* filter = 0; + + if (childPaintInfo.phase == PaintPhaseForeground) { + PaintInfo savedInfo(childPaintInfo); + + if (prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter)) { + if (style()->svgStyle()->shapeRendering() == SR_CRISPEDGES) + childPaintInfo.context->setShouldAntialias(false); + fillAndStrokePath(m_path, childPaintInfo.context, style(), this); + + if (static_cast<SVGStyledElement*>(node())->supportsMarkers()) + m_markerLayoutInfo.drawMarkers(childPaintInfo); + } + finishRenderSVGContent(this, childPaintInfo, filter, savedInfo.context); } - finishRenderSVGContent(this, childPaintInfo, filter, savedInfo.context); - } - if ((childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth()) - paintOutline(childPaintInfo.context, static_cast<int>(boundingBox.x()), static_cast<int>(boundingBox.y()), - static_cast<int>(boundingBox.width()), static_cast<int>(boundingBox.height()), style()); - - childPaintInfo.context->restore(); + if (drawsOutline) + paintOutline(childPaintInfo.context, static_cast<int>(boundingBox.x()), static_cast<int>(boundingBox.y()), + static_cast<int>(boundingBox.width()), static_cast<int>(boundingBox.height())); + + childPaintInfo.context->restore(); + } } // This method is called from inside paintOutline() since we call paintOutline() @@ -293,28 +302,28 @@ void RenderPath::calculateMarkerBoundsIfNeeded() const return; const SVGRenderStyle* svgStyle = style()->svgStyle(); - AtomicString startMarkerId(svgStyle->startMarker()); - AtomicString midMarkerId(svgStyle->midMarker()); - AtomicString endMarkerId(svgStyle->endMarker()); + AtomicString startMarkerId(svgStyle->markerStartResource()); + AtomicString midMarkerId(svgStyle->markerMidResource()); + AtomicString endMarkerId(svgStyle->markerEndResource()); - SVGResourceMarker* startMarker = getMarkerById(doc, startMarkerId, this); - SVGResourceMarker* midMarker = getMarkerById(doc, midMarkerId, this); - SVGResourceMarker* endMarker = getMarkerById(doc, endMarkerId, this); + RenderSVGResourceMarker* startMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, startMarkerId); + RenderSVGResourceMarker* midMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, midMarkerId); + RenderSVGResourceMarker* endMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, endMarkerId); if (!startMarker && !startMarkerId.isEmpty()) svgElement->document()->accessSVGExtensions()->addPendingResource(startMarkerId, styledElement); else if (startMarker) - startMarker->addClient(styledElement); + startMarker->addClient(this); if (!midMarker && !midMarkerId.isEmpty()) svgElement->document()->accessSVGExtensions()->addPendingResource(midMarkerId, styledElement); else if (midMarker) - midMarker->addClient(styledElement); + midMarker->addClient(this); if (!endMarker && !endMarkerId.isEmpty()) svgElement->document()->accessSVGExtensions()->addPendingResource(endMarkerId, styledElement); else if (endMarker) - endMarker->addClient(styledElement); + endMarker->addClient(this); if (!startMarker && !midMarker && !endMarker) return; @@ -323,6 +332,20 @@ void RenderPath::calculateMarkerBoundsIfNeeded() const m_cachedLocalMarkerBBox = m_markerLayoutInfo.calculateBoundaries(startMarker, midMarker, endMarker, strokeWidth, m_path); } +void RenderPath::invalidateCachedBoundaries() +{ + m_cachedLocalRepaintRect = FloatRect(); + m_cachedLocalStrokeBBox = FloatRect(); + m_cachedLocalFillBBox = FloatRect(); + m_cachedLocalMarkerBBox = FloatRect(); +} + +void RenderPath::styleWillChange(StyleDifference diff, const RenderStyle* newStyle) +{ + invalidateCachedBoundaries(); + RenderSVGModelObject::styleWillChange(diff, newStyle); +} + } #endif // ENABLE(SVG) |