• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007, 2008 Rob Buis <buis@kde.org>
3  *           (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
4  *           (C) 2007 Eric Seidel <eric@webkit.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "config.h"
24 
25 #if ENABLE(SVG)
26 #include "SVGRenderSupport.h"
27 
28 #include "TransformationMatrix.h"
29 #include "ImageBuffer.h"
30 #include "RenderObject.h"
31 #include "RenderSVGContainer.h"
32 #include "RenderView.h"
33 #include "SVGResourceClipper.h"
34 #include "SVGResourceFilter.h"
35 #include "SVGResourceMasker.h"
36 #include "SVGStyledElement.h"
37 #include "SVGURIReference.h"
38 #include <wtf/UnusedParam.h>
39 
40 namespace WebCore {
41 
prepareToRenderSVGContent(RenderObject * object,RenderObject::PaintInfo & paintInfo,const FloatRect & boundingBox,SVGResourceFilter * & filter,SVGResourceFilter * rootFilter)42 void prepareToRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, const FloatRect& boundingBox, SVGResourceFilter*& filter, SVGResourceFilter* rootFilter)
43 {
44 #if !ENABLE(SVG_FILTERS)
45     UNUSED_PARAM(filter);
46     UNUSED_PARAM(rootFilter);
47 #endif
48 
49     SVGElement* svgElement = static_cast<SVGElement*>(object->element());
50     ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
51     ASSERT(object);
52 
53     SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
54     const RenderStyle* style = object->style();
55     ASSERT(style);
56 
57     const SVGRenderStyle* svgStyle = style->svgStyle();
58     ASSERT(svgStyle);
59 
60     // Setup transparency layers before setting up filters!
61     float opacity = style->opacity();
62     if (opacity < 1.0f) {
63         paintInfo.context->clip(enclosingIntRect(boundingBox));
64         paintInfo.context->beginTransparencyLayer(opacity);
65     }
66 
67 #if ENABLE(SVG_FILTERS)
68     AtomicString filterId(svgStyle->filter());
69 #endif
70 
71     AtomicString clipperId(svgStyle->clipPath());
72     AtomicString maskerId(svgStyle->maskElement());
73 
74     Document* document = object->document();
75 
76 #if ENABLE(SVG_FILTERS)
77     SVGResourceFilter* newFilter = getFilterById(document, filterId);
78     if (newFilter == rootFilter) {
79         // Catch <text filter="url(#foo)">Test<tspan filter="url(#foo)">123</tspan></text>.
80         // The filter is NOT meant to be applied twice in that case!
81         filter = 0;
82         filterId = String();
83     } else
84         filter = newFilter;
85 #endif
86 
87     SVGResourceClipper* clipper = getClipperById(document, clipperId);
88     SVGResourceMasker* masker = getMaskerById(document, maskerId);
89 
90 #if ENABLE(SVG_FILTERS)
91     if (filter) {
92         filter->addClient(styledElement);
93         filter->prepareFilter(paintInfo.context, boundingBox);
94     } else if (!filterId.isEmpty())
95         svgElement->document()->accessSVGExtensions()->addPendingResource(filterId, styledElement);
96 #endif
97 
98     if (clipper) {
99         clipper->addClient(styledElement);
100         clipper->applyClip(paintInfo.context, boundingBox);
101     } else if (!clipperId.isEmpty())
102         svgElement->document()->accessSVGExtensions()->addPendingResource(clipperId, styledElement);
103 
104     if (masker) {
105         masker->addClient(styledElement);
106         masker->applyMask(paintInfo.context, boundingBox);
107     } else if (!maskerId.isEmpty())
108         svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);
109 }
110 
finishRenderSVGContent(RenderObject * object,RenderObject::PaintInfo & paintInfo,const FloatRect & boundingBox,SVGResourceFilter * & filter,GraphicsContext * savedContext)111 void finishRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, const FloatRect& boundingBox, SVGResourceFilter*& filter, GraphicsContext* savedContext)
112 {
113 #if !ENABLE(SVG_FILTERS)
114     UNUSED_PARAM(boundingBox);
115     UNUSED_PARAM(filter);
116     UNUSED_PARAM(savedContext);
117 #endif
118 
119     ASSERT(object);
120 
121     const RenderStyle* style = object->style();
122     ASSERT(style);
123 
124 #if ENABLE(SVG_FILTERS)
125     if (filter) {
126         filter->applyFilter(paintInfo.context, boundingBox);
127         paintInfo.context = savedContext;
128     }
129 #endif
130 
131     float opacity = style->opacity();
132     if (opacity < 1.0f)
133         paintInfo.context->endTransparencyLayer();
134 }
135 
renderSubtreeToImage(ImageBuffer * image,RenderObject * item)136 void renderSubtreeToImage(ImageBuffer* image, RenderObject* item)
137 {
138     ASSERT(item);
139     ASSERT(image);
140     ASSERT(image->context());
141     RenderObject::PaintInfo info(image->context(), IntRect(), PaintPhaseForeground, 0, 0, 0);
142 
143     RenderSVGContainer* svgContainer = 0;
144     if (item && item->isSVGContainer())
145         svgContainer = static_cast<RenderSVGContainer*>(item);
146 
147     bool drawsContents = svgContainer ? svgContainer->drawsContents() : false;
148     if (svgContainer && !drawsContents)
149         svgContainer->setDrawsContents(true);
150 
151     item->layoutIfNeeded();
152     item->paint(info, 0, 0);
153 
154     if (svgContainer && !drawsContents)
155         svgContainer->setDrawsContents(false);
156 }
157 
clampImageBufferSizeToViewport(RenderObject * object,IntSize & size)158 void clampImageBufferSizeToViewport(RenderObject* object, IntSize& size)
159 {
160     if (!object || !object->isRenderView())
161         return;
162 
163     RenderView* view = static_cast<RenderView*>(object);
164     if (!view->frameView())
165         return;
166 
167     int viewWidth = view->frameView()->visibleWidth();
168     int viewHeight = view->frameView()->visibleHeight();
169 
170     if (size.width() > viewWidth)
171         size.setWidth(viewWidth);
172 
173     if (size.height() > viewHeight)
174         size.setHeight(viewHeight);
175 }
176 
177 } // namespace WebCore
178 
179 #endif // ENABLE(SVG)
180