diff options
author | Ben Murdoch <benm@google.com> | 2011-05-13 16:23:25 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-16 11:35:02 +0100 |
commit | 65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch) | |
tree | f478babb801e720de7bfaee23443ffe029f58731 /Source/WebCore/rendering/SVGRenderSupport.cpp | |
parent | 47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff) | |
download | external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2 |
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebCore/rendering/SVGRenderSupport.cpp')
-rw-r--r-- | Source/WebCore/rendering/SVGRenderSupport.cpp | 352 |
1 files changed, 0 insertions, 352 deletions
diff --git a/Source/WebCore/rendering/SVGRenderSupport.cpp b/Source/WebCore/rendering/SVGRenderSupport.cpp deleted file mode 100644 index cbde49b..0000000 --- a/Source/WebCore/rendering/SVGRenderSupport.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Rob Buis <buis@kde.org> - * (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> - * (C) 2007 Eric Seidel <eric@webkit.org> - * (C) 2009 Google, Inc. All rights reserved. - * (C) 2009 Dirk Schulze <krit@webkit.org> - * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#if ENABLE(SVG) -#include "SVGRenderSupport.h" - -#include "FrameView.h" -#include "ImageBuffer.h" -#include "NodeRenderStyle.h" -#include "RenderLayer.h" -#include "RenderSVGPath.h" -#include "RenderSVGResource.h" -#include "RenderSVGResourceClipper.h" -#include "RenderSVGResourceFilter.h" -#include "RenderSVGResourceMarker.h" -#include "RenderSVGResourceMasker.h" -#include "RenderSVGRoot.h" -#include "SVGResources.h" -#include "SVGStyledElement.h" -#include "TransformState.h" -#include <wtf/UnusedParam.h> - -namespace WebCore { - -IntRect SVGRenderSupport::clippedOverflowRectForRepaint(RenderObject* object, RenderBoxModelObject* repaintContainer) -{ - // Return early for any cases where we don't actually paint - if (object->style()->visibility() != VISIBLE && !object->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(object->repaintRectInLocalCoordinates()); - object->computeRectForRepaint(repaintContainer, repaintRect); - return repaintRect; -} - -void SVGRenderSupport::computeRectForRepaint(RenderObject* object, RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed) -{ - const SVGRenderStyle* svgStyle = object->style()->svgStyle(); - if (const ShadowData* shadow = svgStyle->shadow()) - shadow->adjustRectForShadow(repaintRect); - - // Translate to coords in our parent renderer, and then call computeRectForRepaint on our parent - repaintRect = object->localToParentTransform().mapRect(repaintRect); - object->parent()->computeRectForRepaint(repaintContainer, repaintRect, fixed); -} - -void SVGRenderSupport::mapLocalToContainer(const RenderObject* object, RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState) -{ - ASSERT(!fixed); // We should have no fixed content in the SVG rendering tree. - ASSERT(useTransforms); // Mapping a point through SVG w/o respecting transforms is useless. - transformState.applyTransform(object->localToParentTransform()); - object->parent()->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState); -} - -bool SVGRenderSupport::prepareToRenderSVGContent(RenderObject* object, PaintInfo& paintInfo) -{ - ASSERT(object); - - RenderStyle* style = object->style(); - ASSERT(style); - - const SVGRenderStyle* svgStyle = style->svgStyle(); - ASSERT(svgStyle); - - // Setup transparency layers before setting up SVG resources! - float opacity = style->opacity(); - const ShadowData* shadow = svgStyle->shadow(); - if (opacity < 1 || shadow) { - FloatRect repaintRect = object->repaintRectInLocalCoordinates(); - - if (opacity < 1) { - paintInfo.context->clip(repaintRect); - paintInfo.context->beginTransparencyLayer(opacity); - } - - if (shadow) { - paintInfo.context->clip(repaintRect); - paintInfo.context->setShadow(IntSize(shadow->x(), shadow->y()), shadow->blur(), shadow->color(), style->colorSpace()); - paintInfo.context->beginTransparencyLayer(1); - } - } - - SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object); - if (!resources) - return true; - - if (RenderSVGResourceMasker* masker = resources->masker()) { - if (!masker->applyResource(object, style, paintInfo.context, ApplyToDefaultMode)) - return false; - } - - if (RenderSVGResourceClipper* clipper = resources->clipper()) { - if (!clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode)) - return false; - } - -#if ENABLE(FILTERS) - if (RenderSVGResourceFilter* filter = resources->filter()) { - if (!filter->applyResource(object, style, paintInfo.context, ApplyToDefaultMode)) - return false; - } -#endif - - return true; -} - -void SVGRenderSupport::finishRenderSVGContent(RenderObject* object, PaintInfo& paintInfo, GraphicsContext* savedContext) -{ -#if !ENABLE(FILTERS) - UNUSED_PARAM(savedContext); -#endif - - ASSERT(object); - - const RenderStyle* style = object->style(); - ASSERT(style); - - const SVGRenderStyle* svgStyle = style->svgStyle(); - ASSERT(svgStyle); - -#if ENABLE(FILTERS) - SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object); - if (resources) { - if (RenderSVGResourceFilter* filter = resources->filter()) { - filter->postApplyResource(object, paintInfo.context, ApplyToDefaultMode, /* path */0); - paintInfo.context = savedContext; - } - } -#endif - - if (style->opacity() < 1) - paintInfo.context->endTransparencyLayer(); - - if (svgStyle->shadow()) - paintInfo.context->endTransparencyLayer(); -} - -void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObject* container, FloatRect& objectBoundingBox, FloatRect& strokeBoundingBox, FloatRect& repaintBoundingBox) -{ - for (RenderObject* current = container->firstChild(); current; current = current->nextSibling()) { - if (current->isSVGHiddenContainer()) - continue; - - const AffineTransform& transform = current->localToParentTransform(); - if (transform.isIdentity()) { - objectBoundingBox.unite(current->objectBoundingBox()); - strokeBoundingBox.unite(current->strokeBoundingBox()); - repaintBoundingBox.unite(current->repaintRectInLocalCoordinates()); - } else { - objectBoundingBox.unite(transform.mapRect(current->objectBoundingBox())); - strokeBoundingBox.unite(transform.mapRect(current->strokeBoundingBox())); - repaintBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates())); - } - } -} - -bool SVGRenderSupport::paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo& paintInfo) -{ - if (localTransform.isIdentity()) - return localRepaintRect.intersects(paintInfo.rect); - - return localTransform.mapRect(localRepaintRect).intersects(paintInfo.rect); -} - -const RenderSVGRoot* SVGRenderSupport::findTreeRootObject(const RenderObject* start) -{ - while (start && !start->isSVGRoot()) - start = start->parent(); - - ASSERT(start); - ASSERT(start->isSVGRoot()); - return toRenderSVGRoot(start); -} - -static inline void invalidateResourcesOfChildren(RenderObject* start) -{ - ASSERT(!start->needsLayout()); - if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(start)) - resources->removeClientFromCache(start, false); - - for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) - invalidateResourcesOfChildren(child); -} - -void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout) -{ - bool layoutSizeChanged = findTreeRootObject(start)->isLayoutSizeChanged(); - HashSet<RenderObject*> notlayoutedObjects; - - for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) { - bool needsLayout = selfNeedsLayout; - - if (layoutSizeChanged) { - // When selfNeedsLayout is false and the layout size changed, we have to check whether this child uses relative lengths - if (SVGElement* element = child->node()->isSVGElement() ? static_cast<SVGElement*>(child->node()) : 0) { - if (element->isStyled() && static_cast<SVGStyledElement*>(element)->hasRelativeLengths()) { - // When the layout size changed and when using relative values tell the RenderSVGPath to update its Path object - if (child->isSVGPath()) - toRenderSVGPath(child)->setNeedsPathUpdate(); - - needsLayout = true; - } - } - } - - if (needsLayout) { - child->setNeedsLayout(true, false); - child->layout(); - } else { - if (child->needsLayout()) - child->layout(); - else if (layoutSizeChanged) - notlayoutedObjects.add(child); - } - - ASSERT(!child->needsLayout()); - } - - if (!layoutSizeChanged) { - ASSERT(notlayoutedObjects.isEmpty()); - return; - } - - // If the layout size changed, invalidate all resources of all children that didn't go through the layout() code path. - HashSet<RenderObject*>::iterator end = notlayoutedObjects.end(); - for (HashSet<RenderObject*>::iterator it = notlayoutedObjects.begin(); it != end; ++it) - invalidateResourcesOfChildren(*it); -} - -bool SVGRenderSupport::isOverflowHidden(const RenderObject* object) -{ - // SVG doesn't support independent x/y overflow - ASSERT(object->style()->overflowX() == object->style()->overflowY()); - - // OSCROLL is never set for SVG - see CSSStyleSelector::adjustRenderStyle - ASSERT(object->style()->overflowX() != OSCROLL); - - // RenderSVGRoot should never query for overflow state - it should always clip itself to the initial viewport size. - ASSERT(!object->isRoot()); - - return object->style()->overflowX() == OHIDDEN; -} - -void SVGRenderSupport::intersectRepaintRectWithResources(const RenderObject* object, FloatRect& repaintRect) -{ - ASSERT(object); - - RenderStyle* style = object->style(); - ASSERT(style); - - const SVGRenderStyle* svgStyle = style->svgStyle(); - ASSERT(svgStyle); - - RenderObject* renderer = const_cast<RenderObject*>(object); - SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer); - if (!resources) { - if (const ShadowData* shadow = svgStyle->shadow()) - shadow->adjustRectForShadow(repaintRect); - return; - } - -#if ENABLE(FILTERS) - if (RenderSVGResourceFilter* filter = resources->filter()) - repaintRect = filter->resourceBoundingBox(renderer); -#endif - - if (RenderSVGResourceClipper* clipper = resources->clipper()) - repaintRect.intersect(clipper->resourceBoundingBox(renderer)); - - if (RenderSVGResourceMasker* masker = resources->masker()) - repaintRect.intersect(masker->resourceBoundingBox(renderer)); - - if (const ShadowData* shadow = svgStyle->shadow()) - shadow->adjustRectForShadow(repaintRect); -} - -bool SVGRenderSupport::pointInClippingArea(RenderObject* object, const FloatPoint& point) -{ - ASSERT(object); - - // We just take clippers into account to determine if a point is on the node. The Specification may - // change later and we also need to check maskers. - SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object); - if (!resources) - return true; - - if (RenderSVGResourceClipper* clipper = resources->clipper()) - return clipper->hitTestClipContent(object->objectBoundingBox(), point); - - return true; -} - -void SVGRenderSupport::applyStrokeStyleToContext(GraphicsContext* context, const RenderStyle* style, const RenderObject* object) -{ - ASSERT(context); - ASSERT(style); - ASSERT(object); - ASSERT(object->node()); - ASSERT(object->node()->isSVGElement()); - - const SVGRenderStyle* svgStyle = style->svgStyle(); - ASSERT(svgStyle); - - SVGElement* lengthContext = static_cast<SVGElement*>(object->node()); - context->setStrokeThickness(svgStyle->strokeWidth().value(lengthContext)); - context->setLineCap(svgStyle->capStyle()); - context->setLineJoin(svgStyle->joinStyle()); - if (svgStyle->joinStyle() == MiterJoin) - context->setMiterLimit(svgStyle->strokeMiterLimit()); - - const Vector<SVGLength>& dashes = svgStyle->strokeDashArray(); - if (dashes.isEmpty()) - context->setStrokeStyle(SolidStroke); - else { - DashArray dashArray; - const Vector<SVGLength>::const_iterator end = dashes.end(); - for (Vector<SVGLength>::const_iterator it = dashes.begin(); it != end; ++it) - dashArray.append((*it).value(lengthContext)); - - context->setLineDash(dashArray, svgStyle->strokeDashOffset().value(lengthContext)); - } -} - -} - -#endif |