OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 | 6 |
7 #include "core/html/canvas/CanvasRenderingContext2DState.h" | 7 #include "core/html/canvas/CanvasRenderingContext2DState.h" |
8 | 8 |
9 #include "core/css/CSSFontSelector.h" | 9 #include "core/css/CSSFontSelector.h" |
10 #include "core/css/resolver/FilterOperationResolver.h" | |
11 #include "core/css/resolver/StyleBuilder.h" | |
12 #include "core/css/resolver/StyleResolverState.h" | |
10 #include "core/html/canvas/CanvasGradient.h" | 13 #include "core/html/canvas/CanvasGradient.h" |
11 #include "core/html/canvas/CanvasPattern.h" | 14 #include "core/html/canvas/CanvasPattern.h" |
12 #include "core/html/canvas/CanvasStyle.h" | 15 #include "core/html/canvas/CanvasStyle.h" |
16 #include "core/paint/FilterEffectBuilder.h" | |
17 #include "core/style/ComputedStyle.h" | |
13 #include "platform/graphics/DrawLooperBuilder.h" | 18 #include "platform/graphics/DrawLooperBuilder.h" |
19 #include "platform/graphics/filters/SkiaImageFilterBuilder.h" | |
14 #include "platform/graphics/skia/SkiaUtils.h" | 20 #include "platform/graphics/skia/SkiaUtils.h" |
15 #include "third_party/skia/include/effects/SkDashPathEffect.h" | 21 #include "third_party/skia/include/effects/SkDashPathEffect.h" |
16 #include "third_party/skia/include/effects/SkDropShadowImageFilter.h" | 22 #include "third_party/skia/include/effects/SkDropShadowImageFilter.h" |
17 | 23 |
18 static const char defaultFont[] = "10px sans-serif"; | 24 static const char defaultFont[] = "10px sans-serif"; |
25 static const char defaultFilter[] = "none"; | |
19 | 26 |
20 namespace blink { | 27 namespace blink { |
21 | 28 |
22 CanvasRenderingContext2DState::CanvasRenderingContext2DState() | 29 CanvasRenderingContext2DState::CanvasRenderingContext2DState() |
23 : m_unrealizedSaveCount(0) | 30 : m_unrealizedSaveCount(0) |
24 , m_strokeStyle(CanvasStyle::createFromRGBA(SK_ColorBLACK)) | 31 , m_strokeStyle(CanvasStyle::createFromRGBA(SK_ColorBLACK)) |
25 , m_fillStyle(CanvasStyle::createFromRGBA(SK_ColorBLACK)) | 32 , m_fillStyle(CanvasStyle::createFromRGBA(SK_ColorBLACK)) |
26 , m_shadowBlur(0) | 33 , m_shadowBlur(0) |
27 , m_shadowColor(Color::transparent) | 34 , m_shadowColor(Color::transparent) |
28 , m_globalAlpha(1) | 35 , m_globalAlpha(1) |
29 , m_lineDashOffset(0) | 36 , m_lineDashOffset(0) |
30 , m_unparsedFont(defaultFont) | 37 , m_unparsedFont(defaultFont) |
38 , m_unparsedFilter(defaultFilter) | |
31 , m_textAlign(StartTextAlign) | 39 , m_textAlign(StartTextAlign) |
32 , m_textBaseline(AlphabeticTextBaseline) | 40 , m_textBaseline(AlphabeticTextBaseline) |
33 , m_direction(DirectionInherit) | 41 , m_direction(DirectionInherit) |
34 , m_realizedFont(false) | 42 , m_realizedFont(false) |
35 , m_isTransformInvertible(true) | 43 , m_isTransformInvertible(true) |
36 , m_hasClip(false) | 44 , m_hasClip(false) |
37 , m_hasComplexClip(false) | 45 , m_hasComplexClip(false) |
38 , m_fillStyleDirty(true) | 46 , m_fillStyleDirty(true) |
39 , m_strokeStyleDirty(true) | 47 , m_strokeStyleDirty(true) |
40 , m_lineDashDirty(false) | 48 , m_lineDashDirty(false) |
(...skipping 27 matching lines...) Expand all Loading... | |
68 , m_emptyDrawLooper(other.m_emptyDrawLooper) | 76 , m_emptyDrawLooper(other.m_emptyDrawLooper) |
69 , m_shadowOnlyDrawLooper(other.m_shadowOnlyDrawLooper) | 77 , m_shadowOnlyDrawLooper(other.m_shadowOnlyDrawLooper) |
70 , m_shadowAndForegroundDrawLooper(other.m_shadowAndForegroundDrawLooper) | 78 , m_shadowAndForegroundDrawLooper(other.m_shadowAndForegroundDrawLooper) |
71 , m_shadowOnlyImageFilter(other.m_shadowOnlyImageFilter) | 79 , m_shadowOnlyImageFilter(other.m_shadowOnlyImageFilter) |
72 , m_shadowAndForegroundImageFilter(other.m_shadowAndForegroundImageFilter) | 80 , m_shadowAndForegroundImageFilter(other.m_shadowAndForegroundImageFilter) |
73 , m_globalAlpha(other.m_globalAlpha) | 81 , m_globalAlpha(other.m_globalAlpha) |
74 , m_transform(other.m_transform) | 82 , m_transform(other.m_transform) |
75 , m_lineDashOffset(other.m_lineDashOffset) | 83 , m_lineDashOffset(other.m_lineDashOffset) |
76 , m_unparsedFont(other.m_unparsedFont) | 84 , m_unparsedFont(other.m_unparsedFont) |
77 , m_font(other.m_font) | 85 , m_font(other.m_font) |
86 , m_unparsedFilter(other.m_unparsedFilter) | |
87 , m_filterValue(other.m_filterValue) | |
88 , m_resolvedFilter(other.m_resolvedFilter) | |
78 , m_textAlign(other.m_textAlign) | 89 , m_textAlign(other.m_textAlign) |
79 , m_textBaseline(other.m_textBaseline) | 90 , m_textBaseline(other.m_textBaseline) |
80 , m_direction(other.m_direction) | 91 , m_direction(other.m_direction) |
81 , m_realizedFont(other.m_realizedFont) | 92 , m_realizedFont(other.m_realizedFont) |
82 , m_isTransformInvertible(other.m_isTransformInvertible) | 93 , m_isTransformInvertible(other.m_isTransformInvertible) |
83 , m_hasClip(other.m_hasClip) | 94 , m_hasClip(other.m_hasClip) |
84 , m_hasComplexClip(other.m_hasComplexClip) | 95 , m_hasComplexClip(other.m_hasComplexClip) |
85 , m_fillStyleDirty(other.m_fillStyleDirty) | 96 , m_fillStyleDirty(other.m_fillStyleDirty) |
86 , m_strokeStyleDirty(other.m_strokeStyleDirty) | 97 , m_strokeStyleDirty(other.m_strokeStyleDirty) |
87 , m_lineDashDirty(other.m_lineDashDirty) | 98 , m_lineDashDirty(other.m_lineDashDirty) |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInval idationCallbacks(this); | 160 static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInval idationCallbacks(this); |
150 #endif | 161 #endif |
151 } | 162 } |
152 | 163 |
153 void CanvasRenderingContext2DState::fontsNeedUpdate(CSSFontSelector* fontSelecto r) | 164 void CanvasRenderingContext2DState::fontsNeedUpdate(CSSFontSelector* fontSelecto r) |
154 { | 165 { |
155 ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector()); | 166 ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector()); |
156 ASSERT(m_realizedFont); | 167 ASSERT(m_realizedFont); |
157 | 168 |
158 m_font.update(fontSelector); | 169 m_font.update(fontSelector); |
170 // FIXME: We only really need to invalidate the resolved filter if the font | |
171 // update above changed anything and the filter uses font-dependent units. | |
172 m_resolvedFilter.clear(); | |
159 } | 173 } |
160 | 174 |
161 DEFINE_TRACE(CanvasRenderingContext2DState) | 175 DEFINE_TRACE(CanvasRenderingContext2DState) |
162 { | 176 { |
163 visitor->trace(m_strokeStyle); | 177 visitor->trace(m_strokeStyle); |
164 visitor->trace(m_fillStyle); | 178 visitor->trace(m_fillStyle); |
165 CSSFontSelectorClient::trace(visitor); | 179 CSSFontSelectorClient::trace(visitor); |
166 } | 180 } |
167 | 181 |
168 void CanvasRenderingContext2DState::setLineDashOffset(float offset) | 182 void CanvasRenderingContext2DState::setLineDashOffset(float offset) |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
279 void CanvasRenderingContext2DState::setFont(const Font& font, CSSFontSelector* s elector) | 293 void CanvasRenderingContext2DState::setFont(const Font& font, CSSFontSelector* s elector) |
280 { | 294 { |
281 #if !ENABLE(OILPAN) | 295 #if !ENABLE(OILPAN) |
282 if (m_realizedFont) | 296 if (m_realizedFont) |
283 static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInval idationCallbacks(this); | 297 static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInval idationCallbacks(this); |
284 #endif | 298 #endif |
285 m_font = font; | 299 m_font = font; |
286 m_font.update(selector); | 300 m_font.update(selector); |
287 m_realizedFont = true; | 301 m_realizedFont = true; |
288 selector->registerForInvalidationCallbacks(this); | 302 selector->registerForInvalidationCallbacks(this); |
303 // FIXME: We only really need to invalidate the resolved filter if it | |
304 // uses font-relative units. | |
305 m_resolvedFilter.clear(); | |
289 } | 306 } |
290 | 307 |
291 const Font& CanvasRenderingContext2DState::font() const | 308 const Font& CanvasRenderingContext2DState::font() const |
292 { | 309 { |
293 ASSERT(m_realizedFont); | 310 ASSERT(m_realizedFont); |
294 return m_font; | 311 return m_font; |
295 } | 312 } |
296 | 313 |
297 void CanvasRenderingContext2DState::setTransform(const AffineTransform& transfor m) | 314 void CanvasRenderingContext2DState::setTransform(const AffineTransform& transfor m) |
298 { | 315 { |
299 m_isTransformInvertible = transform.isInvertible(); | 316 m_isTransformInvertible = transform.isInvertible(); |
300 m_transform = transform; | 317 m_transform = transform; |
301 } | 318 } |
302 | 319 |
303 void CanvasRenderingContext2DState::resetTransform() | 320 void CanvasRenderingContext2DState::resetTransform() |
304 { | 321 { |
305 m_transform.makeIdentity(); | 322 m_transform.makeIdentity(); |
306 m_isTransformInvertible = true; | 323 m_isTransformInvertible = true; |
307 } | 324 } |
308 | 325 |
326 SkImageFilter* CanvasRenderingContext2DState::filter(Element* styleResolutionHos t, const Font& font) const | |
327 { | |
328 if (!m_filterValue) | |
329 return nullptr; | |
330 | |
331 if (!m_resolvedFilter) { | |
332 RefPtr<ComputedStyle> filterStyle = ComputedStyle::create(); | |
333 // Must set font in case the filter uses any font-relative units (em, ex ) | |
334 filterStyle->setFont(font); | |
335 SVGComputedStyle& svgStyle = filterStyle->accessSVGStyle(); | |
336 | |
337 StyleResolverState resolverState(styleResolutionHost->document(), styleR esolutionHost, filterStyle.get()); | |
338 resolverState.setStyle(filterStyle); | |
339 | |
340 // TODO(junov): crbug.com/502877 Feed m_fillStyle and m_strokeStyle into FillPaint and | |
341 // StrokePaint respectively for filters that refernece SVG. | |
Stephen White
2015/06/22 15:28:54
Nit: reference
| |
342 StyleBuilder::applyProperty(CSSPropertyWebkitFilter, resolverState, m_fi lterValue.get()); | |
343 RefPtrWillBeRawPtr<FilterEffectBuilder> filterEffectBuilder = FilterEffe ctBuilder::create(); | |
344 filterEffectBuilder->build(styleResolutionHost, filterStyle->filter(), F ilterEffectBuilder::IgnoreScale); | |
345 | |
346 SkiaImageFilterBuilder imageFilterBuilder; | |
347 RefPtrWillBeRawPtr<FilterEffect> lastEffect = filterEffectBuilder->lastE ffect(); | |
348 m_resolvedFilter = imageFilterBuilder.build(lastEffect.get(), ColorSpace DeviceRGB); | |
349 } | |
350 | |
351 return m_resolvedFilter.get(); | |
352 } | |
353 | |
309 SkDrawLooper* CanvasRenderingContext2DState::emptyDrawLooper() const | 354 SkDrawLooper* CanvasRenderingContext2DState::emptyDrawLooper() const |
310 { | 355 { |
311 if (!m_emptyDrawLooper) { | 356 if (!m_emptyDrawLooper) { |
312 OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create( ); | 357 OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create( ); |
313 m_emptyDrawLooper = drawLooperBuilder->detachDrawLooper(); | 358 m_emptyDrawLooper = drawLooperBuilder->detachDrawLooper(); |
314 } | 359 } |
315 return m_emptyDrawLooper.get(); | 360 return m_emptyDrawLooper.get(); |
316 } | 361 } |
317 | 362 |
318 SkDrawLooper* CanvasRenderingContext2DState::shadowOnlyDrawLooper() const | 363 SkDrawLooper* CanvasRenderingContext2DState::shadowOnlyDrawLooper() const |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
379 m_shadowBlur = shadowBlur; | 424 m_shadowBlur = shadowBlur; |
380 shadowParameterChanged(); | 425 shadowParameterChanged(); |
381 } | 426 } |
382 | 427 |
383 void CanvasRenderingContext2DState::setShadowColor(SkColor shadowColor) | 428 void CanvasRenderingContext2DState::setShadowColor(SkColor shadowColor) |
384 { | 429 { |
385 m_shadowColor = shadowColor; | 430 m_shadowColor = shadowColor; |
386 shadowParameterChanged(); | 431 shadowParameterChanged(); |
387 } | 432 } |
388 | 433 |
434 void CanvasRenderingContext2DState::setFilter(PassRefPtrWillBeRawPtr<CSSValue> f ilterValue) | |
435 { | |
436 m_filterValue = filterValue; | |
437 m_resolvedFilter.clear(); | |
438 } | |
439 | |
389 void CanvasRenderingContext2DState::setGlobalComposite(SkXfermode::Mode mode) | 440 void CanvasRenderingContext2DState::setGlobalComposite(SkXfermode::Mode mode) |
390 { | 441 { |
391 m_strokePaint.setXfermodeMode(mode); | 442 m_strokePaint.setXfermodeMode(mode); |
392 m_fillPaint.setXfermodeMode(mode); | 443 m_fillPaint.setXfermodeMode(mode); |
393 m_imagePaint.setXfermodeMode(mode); | 444 m_imagePaint.setXfermodeMode(mode); |
394 } | 445 } |
395 | 446 |
396 SkXfermode::Mode CanvasRenderingContext2DState::globalComposite() const | 447 SkXfermode::Mode CanvasRenderingContext2DState::globalComposite() const |
397 { | 448 { |
398 SkXfermode* xferMode = m_strokePaint.getXfermode(); | 449 SkXfermode* xferMode = m_strokePaint.getXfermode(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 return paint; | 498 return paint; |
448 } | 499 } |
449 | 500 |
450 if (!shouldDrawShadows() && shadowMode == DrawShadowOnly) { | 501 if (!shouldDrawShadows() && shadowMode == DrawShadowOnly) { |
451 paint->setLooper(emptyDrawLooper()); // draw nothing | 502 paint->setLooper(emptyDrawLooper()); // draw nothing |
452 paint->setImageFilter(0); | 503 paint->setImageFilter(0); |
453 return paint; | 504 return paint; |
454 } | 505 } |
455 | 506 |
456 if (shadowMode == DrawShadowOnly) { | 507 if (shadowMode == DrawShadowOnly) { |
457 if (imageType == NonOpaqueImage) { | 508 if (imageType == NonOpaqueImage || m_filterValue) { |
458 paint->setLooper(0); | 509 paint->setLooper(0); |
459 paint->setImageFilter(shadowOnlyImageFilter()); | 510 paint->setImageFilter(shadowOnlyImageFilter()); |
460 return paint; | 511 return paint; |
461 } | 512 } |
462 paint->setLooper(shadowOnlyDrawLooper()); | 513 paint->setLooper(shadowOnlyDrawLooper()); |
463 paint->setImageFilter(0); | 514 paint->setImageFilter(0); |
464 return paint; | 515 return paint; |
465 } | 516 } |
466 | 517 |
467 ASSERT(shadowMode == DrawShadowAndForeground); | 518 ASSERT(shadowMode == DrawShadowAndForeground); |
468 if (imageType == NonOpaqueImage) { | 519 if (imageType == NonOpaqueImage) { |
469 paint->setLooper(0); | 520 paint->setLooper(0); |
470 paint->setImageFilter(shadowAndForegroundImageFilter()); | 521 paint->setImageFilter(shadowAndForegroundImageFilter()); |
471 return paint; | 522 return paint; |
472 } | 523 } |
473 paint->setLooper(shadowAndForegroundDrawLooper()); | 524 paint->setLooper(shadowAndForegroundDrawLooper()); |
474 paint->setImageFilter(0); | 525 paint->setImageFilter(0); |
475 return paint; | 526 return paint; |
476 } | 527 } |
477 | 528 |
478 } // blink | 529 } // blink |
OLD | NEW |