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

Side by Side Diff: Source/core/html/canvas/CanvasRenderingContext2DState.cpp

Issue 1194733002: Adding the 'filter' context attribute to 2D canvas (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: applied corrections Created 5 years, 6 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
OLDNEW
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
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
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
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::getFilter(Element* styleResolution Host, 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
336 StyleResolverState resolverState(styleResolutionHost->document(), styleR esolutionHost, filterStyle.get());
337 resolverState.setStyle(filterStyle);
338
339 // TODO(junov): crbug.com/502877 Feed m_fillStyle and m_strokeStyle into FillPaint and
340 // StrokePaint respectively for filters that reference SVG.
341 StyleBuilder::applyProperty(CSSPropertyWebkitFilter, resolverState, m_fi lterValue.get());
342 RefPtrWillBeRawPtr<FilterEffectBuilder> filterEffectBuilder = FilterEffe ctBuilder::create();
343 const float effectiveZoom = 1.0f; // Deliberately ignore zoom on the can vas element
344 filterEffectBuilder->build(styleResolutionHost, filterStyle->filter(), e ffectiveZoom);
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
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
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
OLDNEW
« no previous file with comments | « Source/core/html/canvas/CanvasRenderingContext2DState.h ('k') | Source/core/layout/svg/ReferenceFilterBuilder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698