1/* 2 * Copyright (c) 2009, Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32#include "core/rendering/svg/RenderSVGModelObject.h" 33 34#include "core/rendering/RenderLayer.h" 35#include "core/rendering/RenderView.h" 36#include "core/rendering/svg/RenderSVGRoot.h" 37#include "core/rendering/svg/SVGRenderSupport.h" 38#include "core/rendering/svg/SVGResourcesCache.h" 39#include "core/svg/SVGGraphicsElement.h" 40 41namespace WebCore { 42 43RenderSVGModelObject::RenderSVGModelObject(SVGElement* node) 44 : RenderObject(node) 45{ 46} 47 48bool RenderSVGModelObject::isChildAllowed(RenderObject* child, RenderStyle*) const 49{ 50 return child->isSVG() && !(child->isSVGInline() || child->isSVGInlineText()); 51} 52 53LayoutRect RenderSVGModelObject::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const 54{ 55 return SVGRenderSupport::clippedOverflowRectForRepaint(this, paintInvalidationContainer); 56} 57 58void RenderSVGModelObject::computeFloatRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, FloatRect& paintInvalidationRect, bool fixed) const 59{ 60 SVGRenderSupport::computeFloatRectForRepaint(this, paintInvalidationContainer, paintInvalidationRect, fixed); 61} 62 63void RenderSVGModelObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const 64{ 65 SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, wasFixed); 66} 67 68const RenderObject* RenderSVGModelObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const 69{ 70 return SVGRenderSupport::pushMappingToContainer(this, ancestorToStopAt, geometryMap); 71} 72 73void RenderSVGModelObject::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const 74{ 75 IntRect rect = enclosingIntRect(strokeBoundingBox()); 76 rect.moveBy(roundedIntPoint(accumulatedOffset)); 77 rects.append(rect); 78} 79 80void RenderSVGModelObject::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const 81{ 82 quads.append(localToAbsoluteQuad(strokeBoundingBox(), 0 /* mode */, wasFixed)); 83} 84 85void RenderSVGModelObject::willBeDestroyed() 86{ 87 SVGResourcesCache::clientDestroyed(this); 88 RenderObject::willBeDestroyed(); 89} 90 91void RenderSVGModelObject::computeLayerHitTestRects(LayerHitTestRects& rects) const 92{ 93 // Using just the rect for the SVGRoot is good enough for now. 94 SVGRenderSupport::findTreeRootObject(this)->computeLayerHitTestRects(rects); 95} 96 97void RenderSVGModelObject::addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const 98{ 99 // We don't walk into SVG trees at all - just report their container. 100} 101 102void RenderSVGModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 103{ 104 if (diff.needsFullLayout()) { 105 setNeedsBoundariesUpdate(); 106 if (style()->hasTransform()) 107 setNeedsTransformUpdate(); 108 } 109 110 RenderObject::styleDidChange(diff, oldStyle); 111 SVGResourcesCache::clientStyleChanged(this, diff, style()); 112} 113 114bool RenderSVGModelObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction) 115{ 116 ASSERT_NOT_REACHED(); 117 return false; 118} 119 120// The SVG addFocusRingRects() method adds rects in local coordinates so the default absoluteFocusRingQuads 121// returns incorrect values for SVG objects. Overriding this method provides access to the absolute bounds. 122void RenderSVGModelObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads) 123{ 124 quads.append(localToAbsoluteQuad(FloatQuad(paintInvalidationRectInLocalCoordinates()))); 125} 126 127void RenderSVGModelObject::invalidateTreeAfterLayout(const RenderLayerModelObject& paintInvalidationContainer) 128{ 129 // Note: This is a reduced version of RenderBox::invalidateTreeAfterLayout(). 130 // FIXME: Should share code with RenderBox::invalidateTreeAfterLayout(). 131 ASSERT(RuntimeEnabledFeatures::repaintAfterLayoutEnabled()); 132 ASSERT(!needsLayout()); 133 134 if (!shouldCheckForPaintInvalidationAfterLayout()) 135 return; 136 137 ForceHorriblySlowRectMapping slowRectMapping(*this); 138 139 const LayoutRect oldPaintInvalidationRect = previousPaintInvalidationRect(); 140 const LayoutPoint oldPositionFromPaintInvalidationContainer = previousPositionFromPaintInvalidationContainer(); 141 const RenderLayerModelObject& newPaintInvalidationContainer = *containerForPaintInvalidation(); 142 setPreviousPaintInvalidationRect(clippedOverflowRectForPaintInvalidation(&newPaintInvalidationContainer)); 143 setPreviousPositionFromPaintInvalidationContainer(RenderLayer::positionFromPaintInvalidationContainer(this, &newPaintInvalidationContainer)); 144 145 // If an ancestor container had its transform changed, then we just 146 // need to update the RenderSVGModelObject's repaint rect above. The invalidation 147 // will be handled by the container where the transform changed. This essentially 148 // means that we prune the entire branch for performance. 149 if (!SVGRenderSupport::parentTransformDidChange(this)) 150 return; 151 152 // If we are set to do a full paint invalidation that means the RenderView will be 153 // issue paint invalidations. We can then skip issuing of paint invalidations for the child 154 // renderers as they'll be covered by the RenderView. 155 if (view()->doingFullRepaint()) { 156 RenderObject::invalidateTreeAfterLayout(newPaintInvalidationContainer); 157 return; 158 } 159 160 const LayoutRect& newPaintInvalidationRect = previousPaintInvalidationRect(); 161 const LayoutPoint& newPositionFromPaintInvalidationContainer = previousPositionFromPaintInvalidationContainer(); 162 invalidatePaintAfterLayoutIfNeeded(containerForPaintInvalidation(), 163 shouldDoFullPaintInvalidationAfterLayout(), oldPaintInvalidationRect, oldPositionFromPaintInvalidationContainer, 164 &newPaintInvalidationRect, &newPositionFromPaintInvalidationContainer); 165 166 RenderObject::invalidateTreeAfterLayout(newPaintInvalidationContainer); 167} 168 169} // namespace WebCore 170