Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp

Issue 13616008: Remove CG codepaths from SVG (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> 2 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 3 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
4 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> 4 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
5 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 5 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 20 matching lines...) Expand all
31 #include "RenderSVGText.h" 31 #include "RenderSVGText.h"
32 #include "SVGRenderSupport.h" 32 #include "SVGRenderSupport.h"
33 #include "SVGRenderingContext.h" 33 #include "SVGRenderingContext.h"
34 #include <wtf/UnusedParam.h> 34 #include <wtf/UnusedParam.h>
35 35
36 namespace WebCore { 36 namespace WebCore {
37 37
38 RenderSVGResourceGradient::RenderSVGResourceGradient(SVGGradientElement* node) 38 RenderSVGResourceGradient::RenderSVGResourceGradient(SVGGradientElement* node)
39 : RenderSVGResourceContainer(node) 39 : RenderSVGResourceContainer(node)
40 , m_shouldCollectGradientAttributes(true) 40 , m_shouldCollectGradientAttributes(true)
41 #if USE(CG)
42 , m_savedContext(0)
43 #endif
44 { 41 {
45 } 42 }
46 43
47 void RenderSVGResourceGradient::removeAllClientsFromCache(bool markForInvalidati on) 44 void RenderSVGResourceGradient::removeAllClientsFromCache(bool markForInvalidati on)
48 { 45 {
49 m_gradientMap.clear(); 46 m_gradientMap.clear();
50 m_shouldCollectGradientAttributes = true; 47 m_shouldCollectGradientAttributes = true;
51 markAllClientsForInvalidation(markForInvalidation ? RepaintInvalidation : Pa rentOnlyInvalidation); 48 markAllClientsForInvalidation(markForInvalidation ? RepaintInvalidation : Pa rentOnlyInvalidation);
52 } 49 }
53 50
54 void RenderSVGResourceGradient::removeClientFromCache(RenderObject* client, bool markForInvalidation) 51 void RenderSVGResourceGradient::removeClientFromCache(RenderObject* client, bool markForInvalidation)
55 { 52 {
56 ASSERT(client); 53 ASSERT(client);
57 m_gradientMap.remove(client); 54 m_gradientMap.remove(client);
58 markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation); 55 markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
59 } 56 }
60 57
61 #if USE(CG)
62 static inline bool createMaskAndSwapContextForTextGradient(GraphicsContext*& con text,
63 GraphicsContext*& sav edContext,
64 OwnPtr<ImageBuffer>& imageBuffer,
65 RenderObject* object)
66 {
67 RenderObject* textRootBlock = RenderSVGText::locateRenderSVGTextAncestor(obj ect);
68 ASSERT(textRootBlock);
69
70 AffineTransform absoluteTransform;
71 SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(text RootBlock, absoluteTransform);
72
73 FloatRect repaintRect = textRootBlock->repaintRectInLocalCoordinates();
74 OwnPtr<ImageBuffer> maskImage;
75 if (!SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, maskImage, ColorSpaceDeviceRGB, Unaccelerated))
76 return false;
77
78 GraphicsContext* maskImageContext = maskImage->context();
79 ASSERT(maskImageContext);
80 ASSERT(maskImage);
81 savedContext = context;
82 context = maskImageContext;
83 imageBuffer = maskImage.release();
84 return true;
85 }
86
87 static inline AffineTransform clipToTextMask(GraphicsContext* context,
88 OwnPtr<ImageBuffer>& imageBuffer,
89 FloatRect& targetRect,
90 RenderObject* object,
91 bool boundingBoxMode,
92 const AffineTransform& gradientTran sform)
93 {
94 RenderObject* textRootBlock = RenderSVGText::locateRenderSVGTextAncestor(obj ect);
95 ASSERT(textRootBlock);
96
97 AffineTransform absoluteTransform;
98 SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(text RootBlock, absoluteTransform);
99
100 targetRect = textRootBlock->repaintRectInLocalCoordinates();
101 SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, targetRec t, imageBuffer, false);
102
103 AffineTransform matrix;
104 if (boundingBoxMode) {
105 FloatRect maskBoundingBox = textRootBlock->objectBoundingBox();
106 matrix.translate(maskBoundingBox.x(), maskBoundingBox.y());
107 matrix.scaleNonUniform(maskBoundingBox.width(), maskBoundingBox.height() );
108 }
109 matrix *= gradientTransform;
110 return matrix;
111 }
112 #endif
113
114 bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode) 58 bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
115 { 59 {
116 ASSERT(object); 60 ASSERT(object);
117 ASSERT(style); 61 ASSERT(style);
118 ASSERT(context); 62 ASSERT(context);
119 ASSERT(resourceMode != ApplyToDefaultMode); 63 ASSERT(resourceMode != ApplyToDefaultMode);
120 64
121 // Be sure to synchronize all SVG properties on the gradientElement _before_ processing any further. 65 // Be sure to synchronize all SVG properties on the gradientElement _before_ processing any further.
122 // Otherwhise the call to collectGradientAttributes() in createTileImage(), may cause the SVG DOM property 66 // Otherwhise the call to collectGradientAttributes() in createTileImage(), may cause the SVG DOM property
123 // synchronization to kick in, which causes removeAllClientsFromCache() to b e called, which in turn deletes our 67 // synchronization to kick in, which causes removeAllClientsFromCache() to b e called, which in turn deletes our
(...skipping 19 matching lines...) Expand all
143 OwnPtr<GradientData>& gradientData = m_gradientMap.add(object, nullptr).iter ator->value; 87 OwnPtr<GradientData>& gradientData = m_gradientMap.add(object, nullptr).iter ator->value;
144 if (!gradientData) 88 if (!gradientData)
145 gradientData = adoptPtr(new GradientData); 89 gradientData = adoptPtr(new GradientData);
146 90
147 bool isPaintingText = resourceMode & ApplyToTextMode; 91 bool isPaintingText = resourceMode & ApplyToTextMode;
148 92
149 // Create gradient object 93 // Create gradient object
150 if (!gradientData->gradient) { 94 if (!gradientData->gradient) {
151 buildGradient(gradientData.get()); 95 buildGradient(gradientData.get());
152 96
153 // CG platforms will handle the gradient space transform for text after applying the 97 // We want the text bounding box applied to the gradient space transform now, so the gradient shader can use it.
154 // resource, so don't apply it here. For non-CG platforms, we want the t ext bounding
155 // box applied to the gradient space transform now, so the gradient shad er can use it.
156 #if USE(CG)
157 if (gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && !objectBoundingBox.isEmpty() && !isPaintingText) {
158 #else
159 if (gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && !objectBoundingBox.isEmpty()) { 98 if (gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && !objectBoundingBox.isEmpty()) {
160 #endif
161 gradientData->userspaceTransform.translate(objectBoundingBox.x(), ob jectBoundingBox.y()); 99 gradientData->userspaceTransform.translate(objectBoundingBox.x(), ob jectBoundingBox.y());
162 gradientData->userspaceTransform.scaleNonUniform(objectBoundingBox.w idth(), objectBoundingBox.height()); 100 gradientData->userspaceTransform.scaleNonUniform(objectBoundingBox.w idth(), objectBoundingBox.height());
163 } 101 }
164 102
165 AffineTransform gradientTransform; 103 AffineTransform gradientTransform;
166 calculateGradientTransform(gradientTransform); 104 calculateGradientTransform(gradientTransform);
167 105
168 gradientData->userspaceTransform *= gradientTransform; 106 gradientData->userspaceTransform *= gradientTransform;
169 if (isPaintingText) { 107 if (isPaintingText) {
170 // Depending on font scaling factor, we may need to rescale the grad ient here since 108 // Depending on font scaling factor, we may need to rescale the grad ient here since
171 // text painting removes the scale factor from the context. 109 // text painting removes the scale factor from the context.
172 AffineTransform additionalTextTransform; 110 AffineTransform additionalTextTransform;
173 if (shouldTransformOnTextPainting(object, additionalTextTransform)) 111 if (shouldTransformOnTextPainting(object, additionalTextTransform))
174 gradientData->userspaceTransform *= additionalTextTransform; 112 gradientData->userspaceTransform *= additionalTextTransform;
175 } 113 }
176 gradientData->gradient->setGradientSpaceTransform(gradientData->userspac eTransform); 114 gradientData->gradient->setGradientSpaceTransform(gradientData->userspac eTransform);
177 } 115 }
178 116
179 if (!gradientData->gradient) 117 if (!gradientData->gradient)
180 return false; 118 return false;
181 119
182 // Draw gradient 120 // Draw gradient
183 context->save(); 121 context->save();
184 122
185 if (isPaintingText) { 123 if (isPaintingText)
186 #if USE(CG)
187 if (!createMaskAndSwapContextForTextGradient(context, m_savedContext, m_ imageBuffer, object)) {
188 context->restore();
189 return false;
190 }
191 #endif
192
193 context->setTextDrawingMode(resourceMode & ApplyToFillMode ? TextModeFil l : TextModeStroke); 124 context->setTextDrawingMode(resourceMode & ApplyToFillMode ? TextModeFil l : TextModeStroke);
194 }
195 125
196 const SVGRenderStyle* svgStyle = style->svgStyle(); 126 const SVGRenderStyle* svgStyle = style->svgStyle();
197 ASSERT(svgStyle); 127 ASSERT(svgStyle);
198 128
199 if (resourceMode & ApplyToFillMode) { 129 if (resourceMode & ApplyToFillMode) {
200 context->setAlpha(svgStyle->fillOpacity()); 130 context->setAlpha(svgStyle->fillOpacity());
201 context->setFillGradient(gradientData->gradient); 131 context->setFillGradient(gradientData->gradient);
202 context->setFillRule(svgStyle->fillRule()); 132 context->setFillRule(svgStyle->fillRule());
203 } else if (resourceMode & ApplyToStrokeMode) { 133 } else if (resourceMode & ApplyToStrokeMode) {
204 if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE) 134 if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE)
205 gradientData->gradient->setGradientSpaceTransform(transformOnNonScal ingStroke(object, gradientData->userspaceTransform)); 135 gradientData->gradient->setGradientSpaceTransform(transformOnNonScal ingStroke(object, gradientData->userspaceTransform));
206 context->setAlpha(svgStyle->strokeOpacity()); 136 context->setAlpha(svgStyle->strokeOpacity());
207 context->setStrokeGradient(gradientData->gradient); 137 context->setStrokeGradient(gradientData->gradient);
208 SVGRenderSupport::applyStrokeStyleToContext(context, style, object); 138 SVGRenderSupport::applyStrokeStyleToContext(context, style, object);
209 } 139 }
210 140
211 return true; 141 return true;
212 } 142 }
213 143
214 void RenderSVGResourceGradient::postApplyResource(RenderObject* object, Graphics Context*& context, unsigned short resourceMode, const Path* path, const RenderSV GShape* shape) 144 void RenderSVGResourceGradient::postApplyResource(RenderObject* object, Graphics Context*& context, unsigned short resourceMode, const Path* path, const RenderSV GShape* shape)
215 { 145 {
216 ASSERT(context); 146 ASSERT(context);
217 ASSERT(resourceMode != ApplyToDefaultMode); 147 ASSERT(resourceMode != ApplyToDefaultMode);
148 UNUSED_PARAM(object);
218 149
219 if (resourceMode & ApplyToTextMode) { 150 if (resourceMode & ApplyToFillMode) {
220 #if USE(CG) 151 if (path)
221 // CG requires special handling for gradient on text 152 context->fillPath(*path);
222 GradientData* gradientData; 153 else if (shape)
223 if (m_savedContext && (gradientData = m_gradientMap.get(object))) { 154 shape->fillShape(context);
224 // Restore on-screen drawing context 155 }
225 context = m_savedContext; 156 if (resourceMode & ApplyToStrokeMode) {
226 m_savedContext = 0; 157 if (path)
227 158 context->strokePath(*path);
228 AffineTransform gradientTransform; 159 else if (shape)
229 calculateGradientTransform(gradientTransform); 160 shape->strokeShape(context);
230
231 FloatRect targetRect;
232 gradientData->gradient->setGradientSpaceTransform(clipToTextMask(con text, m_imageBuffer, targetRect, object, gradientUnits() == SVGUnitTypes::SVG_UN IT_TYPE_OBJECTBOUNDINGBOX, gradientTransform));
233 context->setFillGradient(gradientData->gradient);
234
235 context->fillRect(targetRect);
236 m_imageBuffer.clear();
237 }
238 #else
239 UNUSED_PARAM(object);
240 #endif
241 } else {
242 if (resourceMode & ApplyToFillMode) {
243 if (path)
244 context->fillPath(*path);
245 else if (shape)
246 shape->fillShape(context);
247 }
248 if (resourceMode & ApplyToStrokeMode) {
249 if (path)
250 context->strokePath(*path);
251 else if (shape)
252 shape->strokeShape(context);
253 }
254 } 161 }
255 162
256 context->restore(); 163 context->restore();
257 } 164 }
258 165
259 void RenderSVGResourceGradient::addStops(GradientData* gradientData, const Vecto r<Gradient::ColorStop>& stops) const 166 void RenderSVGResourceGradient::addStops(GradientData* gradientData, const Vecto r<Gradient::ColorStop>& stops) const
260 { 167 {
261 ASSERT(gradientData->gradient); 168 ASSERT(gradientData->gradient);
262 169
263 const Vector<Gradient::ColorStop>::const_iterator end = stops.end(); 170 const Vector<Gradient::ColorStop>::const_iterator end = stops.end();
(...skipping 13 matching lines...) Expand all
277 return SpreadMethodRepeat; 184 return SpreadMethodRepeat;
278 } 185 }
279 186
280 ASSERT_NOT_REACHED(); 187 ASSERT_NOT_REACHED();
281 return SpreadMethodPad; 188 return SpreadMethodPad;
282 } 189 }
283 190
284 } 191 }
285 192
286 #endif 193 #endif
OLDNEW
« no previous file with comments | « Source/WebCore/rendering/svg/RenderSVGResourceGradient.h ('k') | Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698