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); |
156 if (!shader || !shader->is_valid()) { | |
156 // use last color, since our "geometry" was degenerate (e.g. radius==0) | 157 // use last color, since our "geometry" was degenerate (e.g. radius==0) |
157 shader = SkShader::MakeColorShader(colors.back()); | 158 shader = WTF::MakeUnique<PaintShader>(colors.back()); |
158 } | 159 } |
159 | 160 |
160 return WrapSkShader(std::move(shader)); | 161 return shader; |
161 } | 162 } |
162 | 163 |
163 void Gradient::ApplyToFlags(PaintFlags& flags, const SkMatrix& local_matrix) { | 164 void Gradient::ApplyToFlags(PaintFlags& flags, const SkMatrix& local_matrix) { |
164 if (!cached_shader_ || local_matrix != cached_shader_->getLocalMatrix()) | 165 if (!cached_shader_ || |
166 local_matrix != cached_shader_->sk_shader()->getLocalMatrix()) { | |
165 cached_shader_ = CreateShaderInternal(local_matrix); | 167 cached_shader_ = CreateShaderInternal(local_matrix); |
168 } | |
166 | 169 |
167 flags.setShader(cached_shader_); | 170 flags.setShader(WTF::MakeUnique<PaintShader>(*cached_shader_)); |
enne (OOO)
2017/05/23 18:55:02
This line is probably the one that's most concerni
| |
168 | 171 |
169 // Legacy behavior: gradients are always dithered. | 172 // Legacy behavior: gradients are always dithered. |
170 flags.setDither(true); | 173 flags.setDither(true); |
171 } | 174 } |
172 | 175 |
173 namespace { | 176 namespace { |
174 | 177 |
175 class LinearGradient final : public Gradient { | 178 class LinearGradient final : public Gradient { |
176 public: | 179 public: |
177 LinearGradient(const FloatPoint& p0, | 180 LinearGradient(const FloatPoint& p0, |
178 const FloatPoint& p1, | 181 const FloatPoint& p1, |
179 GradientSpreadMethod spread_method, | 182 GradientSpreadMethod spread_method, |
180 ColorInterpolation interpolation) | 183 ColorInterpolation interpolation) |
181 : Gradient(Type::kLinear, spread_method, interpolation), | 184 : Gradient(Type::kLinear, spread_method, interpolation), |
182 p0_(p0), | 185 p0_(p0), |
183 p1_(p1) {} | 186 p1_(p1) {} |
184 | 187 |
185 protected: | 188 protected: |
186 sk_sp<SkShader> CreateShader(const ColorBuffer& colors, | 189 std::unique_ptr<PaintShader> CreateShader( |
187 const OffsetBuffer& pos, | 190 const ColorBuffer& colors, |
188 SkShader::TileMode tile_mode, | 191 const OffsetBuffer& pos, |
189 uint32_t flags, | 192 SkShader::TileMode tile_mode, |
190 const SkMatrix& local_matrix) const override { | 193 uint32_t flags, |
194 const SkMatrix& local_matrix) const override { | |
191 SkPoint pts[2] = {p0_.Data(), p1_.Data()}; | 195 SkPoint pts[2] = {p0_.Data(), p1_.Data()}; |
192 return SkGradientShader::MakeLinear(pts, colors.data(), pos.data(), | 196 return WTF::MakeUnique<PaintShader>(pts, colors.data(), pos.data(), |
193 static_cast<int>(colors.size()), | 197 static_cast<int>(colors.size()), |
194 tile_mode, flags, &local_matrix); | 198 tile_mode, flags, &local_matrix); |
195 } | 199 } |
196 | 200 |
197 private: | 201 private: |
198 const FloatPoint p0_; | 202 const FloatPoint p0_; |
199 const FloatPoint p1_; | 203 const FloatPoint p1_; |
200 }; | 204 }; |
201 | 205 |
202 class RadialGradient final : public Gradient { | 206 class RadialGradient final : public Gradient { |
203 public: | 207 public: |
204 RadialGradient(const FloatPoint& p0, | 208 RadialGradient(const FloatPoint& p0, |
205 float r0, | 209 float r0, |
206 const FloatPoint& p1, | 210 const FloatPoint& p1, |
207 float r1, | 211 float r1, |
208 float aspect_ratio, | 212 float aspect_ratio, |
209 GradientSpreadMethod spread_method, | 213 GradientSpreadMethod spread_method, |
210 ColorInterpolation interpolation) | 214 ColorInterpolation interpolation) |
211 : Gradient(Type::kRadial, spread_method, interpolation), | 215 : Gradient(Type::kRadial, spread_method, interpolation), |
212 p0_(p0), | 216 p0_(p0), |
213 p1_(p1), | 217 p1_(p1), |
214 r0_(r0), | 218 r0_(r0), |
215 r1_(r1), | 219 r1_(r1), |
216 aspect_ratio_(aspect_ratio) {} | 220 aspect_ratio_(aspect_ratio) {} |
217 | 221 |
218 protected: | 222 protected: |
219 sk_sp<SkShader> CreateShader(const ColorBuffer& colors, | 223 std::unique_ptr<PaintShader> CreateShader( |
220 const OffsetBuffer& pos, | 224 const ColorBuffer& colors, |
221 SkShader::TileMode tile_mode, | 225 const OffsetBuffer& pos, |
222 uint32_t flags, | 226 SkShader::TileMode tile_mode, |
223 const SkMatrix& local_matrix) const override { | 227 uint32_t flags, |
228 const SkMatrix& local_matrix) const override { | |
224 SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix); | 229 SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix); |
225 if (aspect_ratio_ != 1) { | 230 if (aspect_ratio_ != 1) { |
226 // CSS3 elliptical gradients: apply the elliptical scaling at the | 231 // CSS3 elliptical gradients: apply the elliptical scaling at the |
227 // gradient center point. | 232 // gradient center point. |
228 DCHECK(p0_ == p1_); | 233 DCHECK(p0_ == p1_); |
229 adjusted_local_matrix.writable()->preScale(1, 1 / aspect_ratio_, p0_.X(), | 234 adjusted_local_matrix.writable()->preScale(1, 1 / aspect_ratio_, p0_.X(), |
230 p0_.Y()); | 235 p0_.Y()); |
231 } | 236 } |
232 | 237 |
233 // Since the two-point radial gradient is slower than the plain radial, | 238 // Since the two-point radial gradient is slower than the plain radial, |
234 // only use it if we have to. | 239 // only use it if we have to. |
235 if (p0_ == p1_ && r0_ <= 0.0f) { | 240 if (p0_ == p1_ && r0_ <= 0.0f) { |
236 return SkGradientShader::MakeRadial( | 241 return WTF::MakeUnique<PaintShader>( |
237 p1_.Data(), r1_, colors.data(), pos.data(), | 242 p1_.Data(), r1_, colors.data(), pos.data(), |
238 static_cast<int>(colors.size()), tile_mode, flags, | 243 static_cast<int>(colors.size()), tile_mode, flags, |
239 adjusted_local_matrix); | 244 adjusted_local_matrix); |
240 } | 245 } |
241 | 246 |
242 // The radii we give to Skia must be positive. If we're given a | 247 // The radii we give to Skia must be positive. If we're given a |
243 // negative radius, ask for zero instead. | 248 // negative radius, ask for zero instead. |
244 const SkScalar radius0 = std::max(WebCoreFloatToSkScalar(r0_), 0.0f); | 249 const SkScalar radius0 = std::max(WebCoreFloatToSkScalar(r0_), 0.0f); |
245 const SkScalar radius1 = std::max(WebCoreFloatToSkScalar(r1_), 0.0f); | 250 const SkScalar radius1 = std::max(WebCoreFloatToSkScalar(r1_), 0.0f); |
246 return SkGradientShader::MakeTwoPointConical( | 251 return WTF::MakeUnique<PaintShader>( |
247 p0_.Data(), radius0, p1_.Data(), radius1, colors.data(), pos.data(), | 252 p0_.Data(), radius0, p1_.Data(), radius1, colors.data(), pos.data(), |
248 static_cast<int>(colors.size()), tile_mode, flags, | 253 static_cast<int>(colors.size()), tile_mode, flags, |
249 adjusted_local_matrix); | 254 adjusted_local_matrix); |
250 } | 255 } |
251 | 256 |
252 private: | 257 private: |
253 const FloatPoint p0_; | 258 const FloatPoint p0_; |
254 const FloatPoint p1_; | 259 const FloatPoint p1_; |
255 const float r0_; | 260 const float r0_; |
256 const float r1_; | 261 const float r1_; |
257 const float aspect_ratio_; // For elliptical gradient, width / height. | 262 const float aspect_ratio_; // For elliptical gradient, width / height. |
258 }; | 263 }; |
259 | 264 |
260 class ConicGradient final : public Gradient { | 265 class ConicGradient final : public Gradient { |
261 public: | 266 public: |
262 ConicGradient(const FloatPoint& position, | 267 ConicGradient(const FloatPoint& position, |
263 float angle, | 268 float angle, |
264 ColorInterpolation interpolation) | 269 ColorInterpolation interpolation) |
265 : Gradient(Type::kConic, kSpreadMethodPad, interpolation), | 270 : Gradient(Type::kConic, kSpreadMethodPad, interpolation), |
266 position_(position), | 271 position_(position), |
267 angle_(angle) {} | 272 angle_(angle) {} |
268 | 273 |
269 protected: | 274 protected: |
270 sk_sp<SkShader> CreateShader(const ColorBuffer& colors, | 275 std::unique_ptr<PaintShader> CreateShader( |
271 const OffsetBuffer& pos, | 276 const ColorBuffer& colors, |
272 SkShader::TileMode tile_mode, | 277 const OffsetBuffer& pos, |
273 uint32_t flags, | 278 SkShader::TileMode tile_mode, |
274 const SkMatrix& local_matrix) const override { | 279 uint32_t flags, |
280 const SkMatrix& local_matrix) 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>( |
286 position_.X(), position_.Y(), colors.data(), pos.data(), | 292 position_.X(), position_.Y(), colors.data(), pos.data(), |
287 static_cast<int>(colors.size()), flags, adjusted_local_matrix); | 293 static_cast<int>(colors.size()), flags, adjusted_local_matrix); |
288 } | 294 } |
289 | 295 |
290 private: | 296 private: |
291 const FloatPoint position_; | 297 const FloatPoint position_; |
292 const float angle_; | 298 const float angle_; |
293 }; | 299 }; |
294 | 300 |
295 } // anonymous ns | 301 } // anonymous ns |
(...skipping 16 matching lines...) Expand all Loading... | |
312 spread_method, interpolation)); | 318 spread_method, interpolation)); |
313 } | 319 } |
314 | 320 |
315 PassRefPtr<Gradient> Gradient::CreateConic(const FloatPoint& position, | 321 PassRefPtr<Gradient> Gradient::CreateConic(const FloatPoint& position, |
316 float angle, | 322 float angle, |
317 ColorInterpolation interpolation) { | 323 ColorInterpolation interpolation) { |
318 return AdoptRef(new ConicGradient(position, angle, interpolation)); | 324 return AdoptRef(new ConicGradient(position, angle, interpolation)); |
319 } | 325 } |
320 | 326 |
321 } // namespace blink | 327 } // namespace blink |
OLD | NEW |