2 * Copyright (C) 2007, 2008 Rob Buis <buis@kde.org>
3 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
5 * Copyright (C) 2009 Google, Inc. All rights reserved.
6 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
7 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
28 #include "SVGRenderingContext.h"
31 #include "FrameView.h"
32 #include "RenderSVGResource.h"
33 #include "RenderSVGResourceClipper.h"
34 #include "RenderSVGResourceFilter.h"
35 #include "RenderSVGResourceMasker.h"
36 #include "SVGImageBufferTools.h"
37 #include "SVGResources.h"
38 #include "SVGResourcesCache.h"
42 static inline bool isRenderingMaskImage(RenderObject* object)
44 if (object->frame() && object->frame()->view())
45 return object->frame()->view()->paintBehavior() & PaintBehaviorRenderingSVGMask;
49 SVGRenderingContext::~SVGRenderingContext()
51 // Fast path if we don't need to restore anything.
52 if (!(m_renderingFlags & ActionsNeeded))
55 ASSERT(m_object && m_paintInfo);
58 if (m_renderingFlags & EndFilterLayer) {
60 m_filter->postApplyResource(static_cast<RenderSVGShape*>(m_object), m_paintInfo->context, ApplyToDefaultMode, 0, 0);
61 m_paintInfo->context = m_savedContext;
65 if (m_renderingFlags & EndOpacityLayer)
66 m_paintInfo->context->endTransparencyLayer();
68 if (m_renderingFlags & EndShadowLayer)
69 m_paintInfo->context->endTransparencyLayer();
71 if (m_renderingFlags & RestoreGraphicsContext)
72 m_paintInfo->context->restore();
75 void SVGRenderingContext::prepareToRenderSVGContent(RenderObject* object, PaintInfo& paintInfo, NeedsGraphicsContextSave needsGraphicsContextSave)
80 // This function must not be called twice!
81 ASSERT(!(m_renderingFlags & PrepareToRenderSVGContentWasCalled));
82 m_renderingFlags |= PrepareToRenderSVGContentWasCalled;
86 m_paintInfo = &paintInfo;
91 // We need to save / restore the context even if the initialization failed.
92 if (needsGraphicsContextSave == SaveGraphicsContext) {
93 m_paintInfo->context->save();
94 m_renderingFlags |= RestoreGraphicsContext;
97 RenderStyle* style = m_object->style();
100 const SVGRenderStyle* svgStyle = style->svgStyle();
103 // Setup transparency layers before setting up SVG resources!
104 bool isRenderingMask = isRenderingMaskImage(m_object);
105 float opacity = isRenderingMask ? 1 : style->opacity();
106 const ShadowData* shadow = svgStyle->shadow();
107 if (opacity < 1 || shadow) {
108 FloatRect repaintRect = m_object->repaintRectInLocalCoordinates();
111 m_paintInfo->context->clip(repaintRect);
112 m_paintInfo->context->beginTransparencyLayer(opacity);
113 m_renderingFlags |= EndOpacityLayer;
117 m_paintInfo->context->clip(repaintRect);
118 m_paintInfo->context->setShadow(IntSize(roundToInt(shadow->x()), roundToInt(shadow->y())), shadow->blur(), shadow->color(), style->colorSpace());
119 m_paintInfo->context->beginTransparencyLayer(1);
120 m_renderingFlags |= EndShadowLayer;
124 SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(m_object);
127 if (svgStyle->hasFilter())
130 m_renderingFlags |= RenderingPrepared;
134 if (!isRenderingMask) {
135 if (RenderSVGResourceMasker* masker = resources->masker()) {
136 if (!masker->applyResource(m_object, style, m_paintInfo->context, ApplyToDefaultMode))
141 if (RenderSVGResourceClipper* clipper = resources->clipper()) {
142 if (!clipper->applyResource(m_object, style, m_paintInfo->context, ApplyToDefaultMode))
147 if (!isRenderingMask) {
148 m_filter = resources->filter();
150 m_savedContext = m_paintInfo->context;
151 // Return with false here may mean that we don't need to draw the content
152 // (because it was either drawn before or empty) but we still need to apply the filter.
153 m_renderingFlags |= EndFilterLayer;
154 if (!m_filter->applyResource(m_object, style, m_paintInfo->context, ApplyToDefaultMode))
160 m_renderingFlags |= RenderingPrepared;