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

Side by Side Diff: Source/platform/graphics/Gradient.cpp

Issue 201523002: Replace manual pointer arithmetic with WTF:Vector in Gradient::shader() (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 9 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4 * Copyright (C) 2013 Google Inc. All rights reserved. 4 * Copyright (C) 2013 Google Inc. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 18 matching lines...) Expand all
29 #include "platform/graphics/Gradient.h" 29 #include "platform/graphics/Gradient.h"
30 30
31 #include "platform/geometry/FloatRect.h" 31 #include "platform/geometry/FloatRect.h"
32 #include "platform/graphics/Color.h" 32 #include "platform/graphics/Color.h"
33 #include "platform/graphics/GraphicsContext.h" 33 #include "platform/graphics/GraphicsContext.h"
34 #include "platform/graphics/skia/SkiaUtils.h" 34 #include "platform/graphics/skia/SkiaUtils.h"
35 #include "third_party/skia/include/core/SkColorShader.h" 35 #include "third_party/skia/include/core/SkColorShader.h"
36 #include "third_party/skia/include/core/SkShader.h" 36 #include "third_party/skia/include/core/SkShader.h"
37 #include "third_party/skia/include/effects/SkGradientShader.h" 37 #include "third_party/skia/include/effects/SkGradientShader.h"
38 38
39 typedef Vector<SkScalar, 8> ColorStopOffsetVector;
40 typedef Vector<SkColor, 8> ColorStopColorVector;
41
39 namespace WebCore { 42 namespace WebCore {
40 43
41 Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1) 44 Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1)
42 : m_p0(p0) 45 : m_p0(p0)
43 , m_p1(p1) 46 , m_p1(p1)
44 , m_r0(0) 47 , m_r0(0)
45 , m_r1(0) 48 , m_r1(0)
46 , m_aspectRatio(1) 49 , m_aspectRatio(1)
47 , m_radial(false) 50 , m_radial(false)
48 , m_stopsSorted(false) 51 , m_stopsSorted(false)
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 if (count < 1 || stop->stop < 1.0) 174 if (count < 1 || stop->stop < 1.0)
172 countUsed++; 175 countUsed++;
173 return countUsed; 176 return countUsed;
174 } 177 }
175 178
176 // Collect sorted stop position and color information into the pos and colors 179 // Collect sorted stop position and color information into the pos and colors
177 // buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large 180 // buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large
178 // enough to hold information for all stops, including the new endpoints if 181 // enough to hold information for all stops, including the new endpoints if
179 // stops at 0.0 and 1.0 aren't already included. 182 // stops at 0.0 and 1.0 aren't already included.
180 static void fillStops(const Gradient::ColorStop* stopData, 183 static void fillStops(const Gradient::ColorStop* stopData,
181 size_t count, SkScalar* pos, SkColor* colors) 184 size_t count, ColorStopOffsetVector& pos, ColorStopColorVector& colors)
182 { 185 {
183 const Gradient::ColorStop* stop = stopData; 186 const Gradient::ColorStop* stop = stopData;
184 size_t start = 0; 187 size_t start = 0;
185 if (count < 1) { 188 if (count < 1) {
186 // A gradient with no stops must be transparent black. 189 // A gradient with no stops must be transparent black.
187 pos[0] = WebCoreFloatToSkScalar(0.0); 190 pos[0] = WebCoreFloatToSkScalar(0.0);
188 colors[0] = makeSkColor(0.0, 0.0, 0.0, 0.0); 191 colors[0] = makeSkColor(0.0, 0.0, 0.0, 0.0);
189 start = 1; 192 start = 1;
190 } else if (stop->stop > 0.0) { 193 } else if (stop->stop > 0.0) {
191 // Copy the first stop to 0.0. The first stop position may have a slight 194 // Copy the first stop to 0.0. The first stop position may have a slight
(...skipping 24 matching lines...) Expand all
216 if (m_gradient) 219 if (m_gradient)
217 return m_gradient.get(); 220 return m_gradient.get();
218 221
219 sortStopsIfNecessary(); 222 sortStopsIfNecessary();
220 ASSERT(m_stopsSorted); 223 ASSERT(m_stopsSorted);
221 224
222 size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size()); 225 size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size());
223 ASSERT(countUsed >= 2); 226 ASSERT(countUsed >= 2);
224 ASSERT(countUsed >= m_stops.size()); 227 ASSERT(countUsed >= m_stops.size());
225 228
226 // FIXME: Why is all this manual pointer math needed?! 229 ColorStopOffsetVector pos(countUsed);
227 SkAutoMalloc storage(countUsed * (sizeof(SkColor) + sizeof(SkScalar))); 230 ColorStopColorVector colors(countUsed);
228 SkColor* colors = (SkColor*)storage.get();
229 SkScalar* pos = (SkScalar*)(colors + countUsed);
230
231 fillStops(m_stops.data(), m_stops.size(), pos, colors); 231 fillStops(m_stops.data(), m_stops.size(), pos, colors);
232 232
233 SkShader::TileMode tile = SkShader::kClamp_TileMode; 233 SkShader::TileMode tile = SkShader::kClamp_TileMode;
234 switch (m_spreadMethod) { 234 switch (m_spreadMethod) {
235 case SpreadMethodReflect: 235 case SpreadMethodReflect:
236 tile = SkShader::kMirror_TileMode; 236 tile = SkShader::kMirror_TileMode;
237 break; 237 break;
238 case SpreadMethodRepeat: 238 case SpreadMethodRepeat:
239 tile = SkShader::kRepeat_TileMode; 239 tile = SkShader::kRepeat_TileMode;
240 break; 240 break;
241 case SpreadMethodPad: 241 case SpreadMethodPad:
242 tile = SkShader::kClamp_TileMode; 242 tile = SkShader::kClamp_TileMode;
243 break; 243 break;
244 } 244 }
245 245
246 uint32_t shouldDrawInPMColorSpace = m_drawInPMColorSpace ? SkGradientShader: :kInterpolateColorsInPremul_Flag : 0; 246 uint32_t shouldDrawInPMColorSpace = m_drawInPMColorSpace ? SkGradientShader: :kInterpolateColorsInPremul_Flag : 0;
247 if (m_radial) { 247 if (m_radial) {
248 // Since the two-point radial gradient is slower than the plain radial, 248 // Since the two-point radial gradient is slower than the plain radial,
249 // only use it if we have to. 249 // only use it if we have to.
250 if (m_p0 == m_p1 && m_r0 <= 0.0f) { 250 if (m_p0 == m_p1 && m_r0 <= 0.0f) {
251 m_gradient = adoptRef(SkGradientShader::CreateRadial(m_p1, m_r1, col ors, pos, static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace)); 251 m_gradient = adoptRef(SkGradientShader::CreateRadial(m_p1, m_r1, col ors.data(), pos.data(), static_cast<int>(countUsed), tile, 0, shouldDrawInPMColo rSpace));
252 } else { 252 } else {
253 // The radii we give to Skia must be positive. If we're given a 253 // The radii we give to Skia must be positive. If we're given a
254 // negative radius, ask for zero instead. 254 // negative radius, ask for zero instead.
255 SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0; 255 SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0;
256 SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0; 256 SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0;
257 m_gradient = adoptRef(SkGradientShader::CreateTwoPointConical(m_p0, radius0, m_p1, radius1, colors, pos, static_cast<int>(countUsed), tile, 0, shoul dDrawInPMColorSpace)); 257 m_gradient = adoptRef(SkGradientShader::CreateTwoPointConical(m_p0, radius0, m_p1, radius1, colors.data(), pos.data(), static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace));
258 } 258 }
259 259
260 if (aspectRatio() != 1) { 260 if (aspectRatio() != 1) {
261 // CSS3 elliptical gradients: apply the elliptical scaling at the 261 // CSS3 elliptical gradients: apply the elliptical scaling at the
262 // gradient center point. 262 // gradient center point.
263 m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y()); 263 m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y());
264 m_gradientSpaceTransformation.scale(1, 1 / aspectRatio()); 264 m_gradientSpaceTransformation.scale(1, 1 / aspectRatio());
265 m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y()); 265 m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y());
266 ASSERT(m_p0 == m_p1); 266 ASSERT(m_p0 == m_p1);
267 } 267 }
268 } else { 268 } else {
269 SkPoint pts[2] = { m_p0, m_p1 }; 269 SkPoint pts[2] = { m_p0, m_p1 };
270 m_gradient = adoptRef(SkGradientShader::CreateLinear(pts, colors, pos, s tatic_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace)); 270 m_gradient = adoptRef(SkGradientShader::CreateLinear(pts, colors.data(), pos.data(), static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace));
271 } 271 }
272 272
273 if (!m_gradient) { 273 if (!m_gradient) {
274 // use last color, since our "geometry" was degenerate (e.g. radius==0) 274 // use last color, since our "geometry" was degenerate (e.g. radius==0)
275 m_gradient = adoptRef(new SkColorShader(colors[countUsed - 1])); 275 m_gradient = adoptRef(new SkColorShader(colors[countUsed - 1]));
276 } else { 276 } else {
277 m_gradient->setLocalMatrix(affineTransformToSkMatrix(m_gradientSpaceTran sformation)); 277 m_gradient->setLocalMatrix(affineTransformToSkMatrix(m_gradientSpaceTran sformation));
278 } 278 }
279 return m_gradient.get(); 279 return m_gradient.get();
280 } 280 }
281 281
282 } //namespace 282 } //namespace
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698