| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |