| 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 | 114 |
| 115 // Copy the last stop to 1.0 if needed. See comment above about this float | 115 // Copy the last stop to 1.0 if needed. See comment above about this float |
| 116 // comparison. | 116 // comparison. |
| 117 DCHECK(!pos.IsEmpty()); | 117 DCHECK(!pos.IsEmpty()); |
| 118 if (pos.back() < 1) { | 118 if (pos.back() < 1) { |
| 119 pos.push_back(WebCoreFloatToSkScalar(1)); | 119 pos.push_back(WebCoreFloatToSkScalar(1)); |
| 120 colors.push_back(colors.back()); | 120 colors.push_back(colors.back()); |
| 121 } | 121 } |
| 122 } | 122 } |
| 123 | 123 |
| 124 sk_sp<PaintShader> Gradient::CreateShaderInternal( | 124 std::unique_ptr<PaintShader> Gradient::CreateShaderInternal( |
| 125 const SkMatrix& local_matrix) { | 125 const SkMatrix& local_matrix) { |
| 126 SortStopsIfNecessary(); | 126 SortStopsIfNecessary(); |
| 127 DCHECK(stops_sorted_); | 127 DCHECK(stops_sorted_); |
| 128 | 128 |
| 129 ColorBuffer colors; | 129 ColorBuffer colors; |
| 130 colors.ReserveCapacity(stops_.size()); | 130 colors.ReserveCapacity(stops_.size()); |
| 131 OffsetBuffer pos; | 131 OffsetBuffer pos; |
| 132 pos.ReserveCapacity(stops_.size()); | 132 pos.ReserveCapacity(stops_.size()); |
| 133 | 133 |
| 134 FillSkiaStops(colors, pos); | 134 FillSkiaStops(colors, pos); |
| 135 DCHECK_GE(colors.size(), 2ul); | 135 DCHECK_GE(colors.size(), 2ul); |
| 136 DCHECK_EQ(pos.size(), colors.size()); | 136 DCHECK_EQ(pos.size(), colors.size()); |
| 137 | 137 |
| 138 SkShader::TileMode tile = SkShader::kClamp_TileMode; | 138 SkShader::TileMode tile = SkShader::kClamp_TileMode; |
| 139 switch (spread_method_) { | 139 switch (spread_method_) { |
| 140 case kSpreadMethodReflect: | 140 case kSpreadMethodReflect: |
| 141 tile = SkShader::kMirror_TileMode; | 141 tile = SkShader::kMirror_TileMode; |
| 142 break; | 142 break; |
| 143 case kSpreadMethodRepeat: | 143 case kSpreadMethodRepeat: |
| 144 tile = SkShader::kRepeat_TileMode; | 144 tile = SkShader::kRepeat_TileMode; |
| 145 break; | 145 break; |
| 146 case kSpreadMethodPad: | 146 case kSpreadMethodPad: |
| 147 tile = SkShader::kClamp_TileMode; | 147 tile = SkShader::kClamp_TileMode; |
| 148 break; | 148 break; |
| 149 } | 149 } |
| 150 | 150 |
| 151 uint32_t flags = color_interpolation_ == ColorInterpolation::kPremultiplied | 151 uint32_t flags = color_interpolation_ == ColorInterpolation::kPremultiplied |
| 152 ? SkGradientShader::kInterpolateColorsInPremul_Flag | 152 ? SkGradientShader::kInterpolateColorsInPremul_Flag |
| 153 : 0; | 153 : 0; |
| 154 sk_sp<SkShader> shader = CreateShader(colors, pos, tile, flags, local_matrix); | 154 std::unique_ptr<PaintShader> shader = |
| 155 if (!shader) { | 155 CreateShader(colors, pos, tile, flags, local_matrix, colors.back()); |
| 156 // use last color, since our "geometry" was degenerate (e.g. radius==0) | 156 DCHECK(shader); |
| 157 shader = SkShader::MakeColorShader(colors.back()); | |
| 158 } | |
| 159 | 157 |
| 160 return WrapSkShader(std::move(shader)); | 158 return shader; |
| 161 } | 159 } |
| 162 | 160 |
| 163 void Gradient::ApplyToFlags(PaintFlags& flags, const SkMatrix& local_matrix) { | 161 void Gradient::ApplyToFlags(PaintFlags& flags, const SkMatrix& local_matrix) { |
| 164 if (!cached_shader_ || local_matrix != cached_shader_->getLocalMatrix()) | 162 if (!cached_shader_ || |
| 163 local_matrix != cached_shader_->sk_shader()->getLocalMatrix()) { |
| 165 cached_shader_ = CreateShaderInternal(local_matrix); | 164 cached_shader_ = CreateShaderInternal(local_matrix); |
| 165 } |
| 166 | 166 |
| 167 flags.setShader(cached_shader_); | 167 flags.setShader(WTF::MakeUnique<PaintShader>(*cached_shader_)); |
| 168 | 168 |
| 169 // Legacy behavior: gradients are always dithered. | 169 // Legacy behavior: gradients are always dithered. |
| 170 flags.setDither(true); | 170 flags.setDither(true); |
| 171 } | 171 } |
| 172 | 172 |
| 173 namespace { | 173 namespace { |
| 174 | 174 |
| 175 class LinearGradient final : public Gradient { | 175 class LinearGradient final : public Gradient { |
| 176 public: | 176 public: |
| 177 LinearGradient(const FloatPoint& p0, | 177 LinearGradient(const FloatPoint& p0, |
| 178 const FloatPoint& p1, | 178 const FloatPoint& p1, |
| 179 GradientSpreadMethod spread_method, | 179 GradientSpreadMethod spread_method, |
| 180 ColorInterpolation interpolation) | 180 ColorInterpolation interpolation) |
| 181 : Gradient(Type::kLinear, spread_method, interpolation), | 181 : Gradient(Type::kLinear, spread_method, interpolation), |
| 182 p0_(p0), | 182 p0_(p0), |
| 183 p1_(p1) {} | 183 p1_(p1) {} |
| 184 | 184 |
| 185 protected: | 185 protected: |
| 186 sk_sp<SkShader> CreateShader(const ColorBuffer& colors, | 186 std::unique_ptr<PaintShader> CreateShader( |
| 187 const OffsetBuffer& pos, | 187 const ColorBuffer& colors, |
| 188 SkShader::TileMode tile_mode, | 188 const OffsetBuffer& pos, |
| 189 uint32_t flags, | 189 SkShader::TileMode tile_mode, |
| 190 const SkMatrix& local_matrix) const override { | 190 uint32_t flags, |
| 191 const SkMatrix& local_matrix, |
| 192 SkColor fallback_color) const override { |
| 191 SkPoint pts[2] = {p0_.Data(), p1_.Data()}; | 193 SkPoint pts[2] = {p0_.Data(), p1_.Data()}; |
| 192 return SkGradientShader::MakeLinear(pts, colors.data(), pos.data(), | 194 return WTF::MakeUnique<PaintShader>( |
| 193 static_cast<int>(colors.size()), | 195 pts, colors.data(), pos.data(), static_cast<int>(colors.size()), |
| 194 tile_mode, flags, &local_matrix); | 196 tile_mode, flags, &local_matrix, fallback_color); |
| 195 } | 197 } |
| 196 | 198 |
| 197 private: | 199 private: |
| 198 const FloatPoint p0_; | 200 const FloatPoint p0_; |
| 199 const FloatPoint p1_; | 201 const FloatPoint p1_; |
| 200 }; | 202 }; |
| 201 | 203 |
| 202 class RadialGradient final : public Gradient { | 204 class RadialGradient final : public Gradient { |
| 203 public: | 205 public: |
| 204 RadialGradient(const FloatPoint& p0, | 206 RadialGradient(const FloatPoint& p0, |
| 205 float r0, | 207 float r0, |
| 206 const FloatPoint& p1, | 208 const FloatPoint& p1, |
| 207 float r1, | 209 float r1, |
| 208 float aspect_ratio, | 210 float aspect_ratio, |
| 209 GradientSpreadMethod spread_method, | 211 GradientSpreadMethod spread_method, |
| 210 ColorInterpolation interpolation) | 212 ColorInterpolation interpolation) |
| 211 : Gradient(Type::kRadial, spread_method, interpolation), | 213 : Gradient(Type::kRadial, spread_method, interpolation), |
| 212 p0_(p0), | 214 p0_(p0), |
| 213 p1_(p1), | 215 p1_(p1), |
| 214 r0_(r0), | 216 r0_(r0), |
| 215 r1_(r1), | 217 r1_(r1), |
| 216 aspect_ratio_(aspect_ratio) {} | 218 aspect_ratio_(aspect_ratio) {} |
| 217 | 219 |
| 218 protected: | 220 protected: |
| 219 sk_sp<SkShader> CreateShader(const ColorBuffer& colors, | 221 std::unique_ptr<PaintShader> CreateShader( |
| 220 const OffsetBuffer& pos, | 222 const ColorBuffer& colors, |
| 221 SkShader::TileMode tile_mode, | 223 const OffsetBuffer& pos, |
| 222 uint32_t flags, | 224 SkShader::TileMode tile_mode, |
| 223 const SkMatrix& local_matrix) const override { | 225 uint32_t flags, |
| 226 const SkMatrix& local_matrix, |
| 227 SkColor fallback_color) const override { |
| 224 SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix); | 228 SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix); |
| 225 if (aspect_ratio_ != 1) { | 229 if (aspect_ratio_ != 1) { |
| 226 // CSS3 elliptical gradients: apply the elliptical scaling at the | 230 // CSS3 elliptical gradients: apply the elliptical scaling at the |
| 227 // gradient center point. | 231 // gradient center point. |
| 228 DCHECK(p0_ == p1_); | 232 DCHECK(p0_ == p1_); |
| 229 adjusted_local_matrix.writable()->preScale(1, 1 / aspect_ratio_, p0_.X(), | 233 adjusted_local_matrix.writable()->preScale(1, 1 / aspect_ratio_, p0_.X(), |
| 230 p0_.Y()); | 234 p0_.Y()); |
| 231 } | 235 } |
| 232 | 236 |
| 233 // Since the two-point radial gradient is slower than the plain radial, | 237 // Since the two-point radial gradient is slower than the plain radial, |
| 234 // only use it if we have to. | 238 // only use it if we have to. |
| 235 if (p0_ == p1_ && r0_ <= 0.0f) { | 239 if (p0_ == p1_ && r0_ <= 0.0f) { |
| 236 return SkGradientShader::MakeRadial( | 240 return WTF::MakeUnique<PaintShader>( |
| 237 p1_.Data(), r1_, colors.data(), pos.data(), | 241 p1_.Data(), r1_, colors.data(), pos.data(), |
| 238 static_cast<int>(colors.size()), tile_mode, flags, | 242 static_cast<int>(colors.size()), tile_mode, flags, |
| 239 adjusted_local_matrix); | 243 adjusted_local_matrix); |
| 240 } | 244 } |
| 241 | 245 |
| 242 // The radii we give to Skia must be positive. If we're given a | 246 // The radii we give to Skia must be positive. If we're given a |
| 243 // negative radius, ask for zero instead. | 247 // negative radius, ask for zero instead. |
| 244 const SkScalar radius0 = std::max(WebCoreFloatToSkScalar(r0_), 0.0f); | 248 const SkScalar radius0 = std::max(WebCoreFloatToSkScalar(r0_), 0.0f); |
| 245 const SkScalar radius1 = std::max(WebCoreFloatToSkScalar(r1_), 0.0f); | 249 const SkScalar radius1 = std::max(WebCoreFloatToSkScalar(r1_), 0.0f); |
| 246 return SkGradientShader::MakeTwoPointConical( | 250 return WTF::MakeUnique<PaintShader>( |
| 247 p0_.Data(), radius0, p1_.Data(), radius1, colors.data(), pos.data(), | 251 p0_.Data(), radius0, p1_.Data(), radius1, colors.data(), pos.data(), |
| 248 static_cast<int>(colors.size()), tile_mode, flags, | 252 static_cast<int>(colors.size()), tile_mode, flags, |
| 249 adjusted_local_matrix); | 253 adjusted_local_matrix, fallback_color); |
| 250 } | 254 } |
| 251 | 255 |
| 252 private: | 256 private: |
| 253 const FloatPoint p0_; | 257 const FloatPoint p0_; |
| 254 const FloatPoint p1_; | 258 const FloatPoint p1_; |
| 255 const float r0_; | 259 const float r0_; |
| 256 const float r1_; | 260 const float r1_; |
| 257 const float aspect_ratio_; // For elliptical gradient, width / height. | 261 const float aspect_ratio_; // For elliptical gradient, width / height. |
| 258 }; | 262 }; |
| 259 | 263 |
| 260 class ConicGradient final : public Gradient { | 264 class ConicGradient final : public Gradient { |
| 261 public: | 265 public: |
| 262 ConicGradient(const FloatPoint& position, | 266 ConicGradient(const FloatPoint& position, |
| 263 float angle, | 267 float angle, |
| 264 ColorInterpolation interpolation) | 268 ColorInterpolation interpolation) |
| 265 : Gradient(Type::kConic, kSpreadMethodPad, interpolation), | 269 : Gradient(Type::kConic, kSpreadMethodPad, interpolation), |
| 266 position_(position), | 270 position_(position), |
| 267 angle_(angle) {} | 271 angle_(angle) {} |
| 268 | 272 |
| 269 protected: | 273 protected: |
| 270 sk_sp<SkShader> CreateShader(const ColorBuffer& colors, | 274 std::unique_ptr<PaintShader> CreateShader( |
| 271 const OffsetBuffer& pos, | 275 const ColorBuffer& colors, |
| 272 SkShader::TileMode tile_mode, | 276 const OffsetBuffer& pos, |
| 273 uint32_t flags, | 277 SkShader::TileMode tile_mode, |
| 274 const SkMatrix& local_matrix) const override { | 278 uint32_t flags, |
| 279 const SkMatrix& local_matrix, |
| 280 SkColor fallback_color) const override { |
| 275 DCHECK_NE(tile_mode, SkShader::kMirror_TileMode); | 281 DCHECK_NE(tile_mode, SkShader::kMirror_TileMode); |
| 276 | 282 |
| 277 // Skia's sweep gradient angles are relative to the x-axis, not the y-axis. | 283 // Skia's sweep gradient angles are relative to the x-axis, not the y-axis. |
| 278 const float skia_angle = angle_ - 90; | 284 const float skia_angle = angle_ - 90; |
| 279 SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix); | 285 SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix); |
| 280 if (skia_angle) { | 286 if (skia_angle) { |
| 281 adjusted_local_matrix.writable()->preRotate(skia_angle, position_.X(), | 287 adjusted_local_matrix.writable()->preRotate(skia_angle, position_.X(), |
| 282 position_.Y()); | 288 position_.Y()); |
| 283 } | 289 } |
| 284 | 290 |
| 285 return SkGradientShader::MakeSweep( | 291 return WTF::MakeUnique<PaintShader>(position_.X(), position_.Y(), |
| 286 position_.X(), position_.Y(), colors.data(), pos.data(), | 292 colors.data(), pos.data(), |
| 287 static_cast<int>(colors.size()), flags, adjusted_local_matrix); | 293 static_cast<int>(colors.size()), flags, |
| 294 adjusted_local_matrix, fallback_color); |
| 288 } | 295 } |
| 289 | 296 |
| 290 private: | 297 private: |
| 291 const FloatPoint position_; | 298 const FloatPoint position_; |
| 292 const float angle_; | 299 const float angle_; |
| 293 }; | 300 }; |
| 294 | 301 |
| 295 } // anonymous ns | 302 } // anonymous ns |
| 296 | 303 |
| 297 PassRefPtr<Gradient> Gradient::CreateLinear(const FloatPoint& p0, | 304 PassRefPtr<Gradient> Gradient::CreateLinear(const FloatPoint& p0, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 312 spread_method, interpolation)); | 319 spread_method, interpolation)); |
| 313 } | 320 } |
| 314 | 321 |
| 315 PassRefPtr<Gradient> Gradient::CreateConic(const FloatPoint& position, | 322 PassRefPtr<Gradient> Gradient::CreateConic(const FloatPoint& position, |
| 316 float angle, | 323 float angle, |
| 317 ColorInterpolation interpolation) { | 324 ColorInterpolation interpolation) { |
| 318 return AdoptRef(new ConicGradient(position, angle, interpolation)); | 325 return AdoptRef(new ConicGradient(position, angle, interpolation)); |
| 319 } | 326 } |
| 320 | 327 |
| 321 } // namespace blink | 328 } // namespace blink |
| OLD | NEW |