Chromium Code Reviews| 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 |