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

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

Issue 1093673002: Removing the dependency on GraphicsContext for drawing images in 2D canvas (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: pdr corrections + needsrebaselines Created 5 years, 7 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved. 8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved.
9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
10 * 10 *
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 #include "core/html/canvas/CanvasRenderingContext2DState.h" 54 #include "core/html/canvas/CanvasRenderingContext2DState.h"
55 #include "core/html/canvas/CanvasStyle.h" 55 #include "core/html/canvas/CanvasStyle.h"
56 #include "core/html/canvas/HitRegion.h" 56 #include "core/html/canvas/HitRegion.h"
57 #include "core/html/canvas/Path2D.h" 57 #include "core/html/canvas/Path2D.h"
58 #include "core/layout/LayoutBox.h" 58 #include "core/layout/LayoutBox.h"
59 #include "core/layout/LayoutTheme.h" 59 #include "core/layout/LayoutTheme.h"
60 #include "platform/fonts/FontCache.h" 60 #include "platform/fonts/FontCache.h"
61 #include "platform/geometry/FloatQuad.h" 61 #include "platform/geometry/FloatQuad.h"
62 #include "platform/graphics/DrawLooperBuilder.h" 62 #include "platform/graphics/DrawLooperBuilder.h"
63 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" 63 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h"
64 #include "platform/graphics/GraphicsContext.h"
65 #include "platform/graphics/ImageBuffer.h" 64 #include "platform/graphics/ImageBuffer.h"
65 #include "platform/graphics/StrokeData.h"
66 #include "platform/graphics/skia/SkiaUtils.h"
66 #include "platform/text/BidiTextRun.h" 67 #include "platform/text/BidiTextRun.h"
67 #include "third_party/skia/include/core/SkCanvas.h" 68 #include "third_party/skia/include/core/SkCanvas.h"
69 #include "third_party/skia/include/core/SkImageFilter.h"
70 #include "third_party/skia/include/effects/SkCornerPathEffect.h"
68 #include "wtf/ArrayBufferContents.h" 71 #include "wtf/ArrayBufferContents.h"
69 #include "wtf/CheckedArithmetic.h" 72 #include "wtf/CheckedArithmetic.h"
70 #include "wtf/MathExtras.h" 73 #include "wtf/MathExtras.h"
71 #include "wtf/OwnPtr.h" 74 #include "wtf/OwnPtr.h"
72 #include "wtf/text/StringBuilder.h" 75 #include "wtf/text/StringBuilder.h"
73 76
74 namespace blink { 77 namespace blink {
75 78
76 static const int defaultFontSize = 10; 79 static const int defaultFontSize = 10;
77 static const char defaultFontFamily[] = "sans-serif"; 80 static const char defaultFontFamily[] = "sans-serif";
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 #if ENABLE(ASSERT) 154 #if ENABLE(ASSERT)
152 SkCanvas* skCanvas = canvas()->existingDrawingCanvas(); 155 SkCanvas* skCanvas = canvas()->existingDrawingCanvas();
153 if (skCanvas && m_contextLostMode == NotLostContext) { 156 if (skCanvas && m_contextLostMode == NotLostContext) {
154 ASSERT(static_cast<size_t>(skCanvas->getSaveCount() - 1) == m_stateStack .size()); 157 ASSERT(static_cast<size_t>(skCanvas->getSaveCount() - 1) == m_stateStack .size());
155 } 158 }
156 #endif 159 #endif
157 } 160 }
158 161
159 CanvasRenderingContext2DState& CanvasRenderingContext2D::modifiableState() 162 CanvasRenderingContext2DState& CanvasRenderingContext2D::modifiableState()
160 { 163 {
161 ASSERT(!state().hasUnrealizedSaves()); 164 realizeSaves();
162 return *m_stateStack.last(); 165 return *m_stateStack.last();
163 } 166 }
164 167
165 bool CanvasRenderingContext2D::isAccelerated() const 168 bool CanvasRenderingContext2D::isAccelerated() const
166 { 169 {
167 if (!canvas()->hasImageBuffer()) 170 if (!canvas()->hasImageBuffer())
168 return false; 171 return false;
169 return canvas()->buffer()->isAccelerated(); 172 return canvas()->buffer()->isAccelerated();
170 } 173 }
171 174
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 WillBeHeapVector<OwnPtrWillBeMember<CanvasRenderingContext2DState>>::iterato r currState; 296 WillBeHeapVector<OwnPtrWillBeMember<CanvasRenderingContext2DState>>::iterato r currState;
294 for (currState = m_stateStack.begin(); currState < m_stateStack.end(); currS tate++) { 297 for (currState = m_stateStack.begin(); currState < m_stateStack.end(); currS tate++) {
295 // The initial save accounts for the save installed by canvasElementElem ent::m_contextStateSaver 298 // The initial save accounts for the save installed by canvasElementElem ent::m_contextStateSaver
296 c->save(); 299 c->save();
297 c->setMatrix(SkMatrix::I()); 300 c->setMatrix(SkMatrix::I());
298 currState->get()->playbackClips(c); 301 currState->get()->playbackClips(c);
299 c->setMatrix(affineTransformToSkMatrix(currState->get()->transform())); 302 c->setMatrix(affineTransformToSkMatrix(currState->get()->transform()));
300 } 303 }
301 } 304 }
302 305
303 void CanvasRenderingContext2D::realizeSaves(SkCanvas* canvas) 306 void CanvasRenderingContext2D::realizeSaves()
304 { 307 {
305 validateStateStack(); 308 validateStateStack();
306 if (state().hasUnrealizedSaves()) { 309 if (state().hasUnrealizedSaves()) {
307 ASSERT(m_stateStack.size() >= 1); 310 ASSERT(m_stateStack.size() >= 1);
308 // Reduce the current state's unrealized count by one now, 311 // Reduce the current state's unrealized count by one now,
309 // to reflect the fact we are saving one state. 312 // to reflect the fact we are saving one state.
310 m_stateStack.last()->restore(); 313 m_stateStack.last()->restore();
311 m_stateStack.append(adoptPtrWillBeNoop(new CanvasRenderingContext2DState (state(), CanvasRenderingContext2DState::DontCopyClipList))); 314 m_stateStack.append(adoptPtrWillBeNoop(new CanvasRenderingContext2DState (state(), CanvasRenderingContext2DState::DontCopyClipList)));
312 // Set the new state's unrealized count to 0, because it has no outstand ing saves. 315 // Set the new state's unrealized count to 0, because it has no outstand ing saves.
313 // We need to do this explicitly because the copy constructor and operat or= used 316 // We need to do this explicitly because the copy constructor and operat or= used
314 // by the Vector operations copy the unrealized count from the previous state (in 317 // by the Vector operations copy the unrealized count from the previous state (in
315 // turn necessary to support correct resizing and unwinding of the stack ). 318 // turn necessary to support correct resizing and unwinding of the stack ).
316 m_stateStack.last()->resetUnrealizedSaveCount(); 319 m_stateStack.last()->resetUnrealizedSaveCount();
317 if (!canvas) 320 SkCanvas* canvas = drawingCanvas();
318 canvas = drawingCanvas();
319 if (canvas) 321 if (canvas)
320 canvas->save(); 322 canvas->save();
321 validateStateStack(); 323 validateStateStack();
322 } 324 }
323 } 325 }
324 326
325 void CanvasRenderingContext2D::save() 327 void CanvasRenderingContext2D::save()
326 { 328 {
327 m_stateStack.last()->save(); 329 m_stateStack.last()->save();
328 } 330 }
329 331
330 void CanvasRenderingContext2D::restore() 332 void CanvasRenderingContext2D::restore()
331 { 333 {
332 validateStateStack(); 334 validateStateStack();
333 if (state().hasUnrealizedSaves()) { 335 if (state().hasUnrealizedSaves()) {
334 // We never realized the save, so just record that it was unnecessary. 336 // We never realized the save, so just record that it was unnecessary.
335 m_stateStack.last()->restore(); 337 m_stateStack.last()->restore();
336 return; 338 return;
337 } 339 }
338 ASSERT(m_stateStack.size() >= 1); 340 ASSERT(m_stateStack.size() >= 1);
339 if (m_stateStack.size() <= 1) 341 if (m_stateStack.size() <= 1)
340 return; 342 return;
341 m_path.transform(state().transform()); 343 m_path.transform(state().transform());
342 m_stateStack.removeLast(); 344 m_stateStack.removeLast();
343 m_path.transform(state().transform().inverse()); 345 m_path.transform(state().transform().inverse());
344 SkCanvas* c = drawingCanvas(); 346 SkCanvas* c = drawingCanvas();
345 if (c) 347 if (c)
346 c->restore(); 348 c->restore();
347 349
348 // Temporary code while crbug.com/453113 is a WIP: GraphicsContext state sta ck
349 // is no longer exercised so state stored still stored in GC must be re-inst alled
350 // after a restore.
351 GraphicsContext* gc = drawingContext();
352 if (gc) {
353 gc->setAlphaAsFloat(state().globalAlpha());
354 gc->setCompositeOperation(state().globalComposite());
355 gc->setImageInterpolationQuality(state().imageSmoothingEnabled() ? Canva sDefaultInterpolationQuality : InterpolationNone);
356 }
357
358 validateStateStack(); 350 validateStateStack();
359 } 351 }
360 352
361 static inline void convertCanvasStyleToUnionType(CanvasStyle* style, StringOrCan vasGradientOrCanvasPattern& returnValue) 353 static inline void convertCanvasStyleToUnionType(CanvasStyle* style, StringOrCan vasGradientOrCanvasPattern& returnValue)
362 { 354 {
363 if (CanvasGradient* gradient = style->canvasGradient()) { 355 if (CanvasGradient* gradient = style->canvasGradient()) {
364 returnValue.setCanvasGradient(gradient); 356 returnValue.setCanvasGradient(gradient);
365 return; 357 return;
366 } 358 }
367 if (CanvasPattern* pattern = style->canvasPattern()) { 359 if (CanvasPattern* pattern = style->canvasPattern()) {
(...skipping 15 matching lines...) Expand all
383 String colorString; 375 String colorString;
384 RefPtrWillBeRawPtr<CanvasStyle> canvasStyle = nullptr; 376 RefPtrWillBeRawPtr<CanvasStyle> canvasStyle = nullptr;
385 if (style.isString()) { 377 if (style.isString()) {
386 colorString = style.getAsString(); 378 colorString = style.getAsString();
387 if (colorString == state().unparsedStrokeColor()) 379 if (colorString == state().unparsedStrokeColor())
388 return; 380 return;
389 RGBA32 parsedColor = 0; 381 RGBA32 parsedColor = 0;
390 if (!parseColorOrCurrentColor(parsedColor, colorString, canvas())) 382 if (!parseColorOrCurrentColor(parsedColor, colorString, canvas()))
391 return; 383 return;
392 if (state().strokeStyle()->isEquivalentRGBA(parsedColor)) { 384 if (state().strokeStyle()->isEquivalentRGBA(parsedColor)) {
393 realizeSaves(nullptr);
394 modifiableState().setUnparsedStrokeColor(colorString); 385 modifiableState().setUnparsedStrokeColor(colorString);
395 return; 386 return;
396 } 387 }
397 canvasStyle = CanvasStyle::createFromRGBA(parsedColor); 388 canvasStyle = CanvasStyle::createFromRGBA(parsedColor);
398 } else if (style.isCanvasGradient()) { 389 } else if (style.isCanvasGradient()) {
399 canvasStyle = CanvasStyle::createFromGradient(style.getAsCanvasGradient( )); 390 canvasStyle = CanvasStyle::createFromGradient(style.getAsCanvasGradient( ));
400 } else if (style.isCanvasPattern()) { 391 } else if (style.isCanvasPattern()) {
401 RefPtrWillBeRawPtr<CanvasPattern> canvasPattern = style.getAsCanvasPatte rn(); 392 RefPtrWillBeRawPtr<CanvasPattern> canvasPattern = style.getAsCanvasPatte rn();
402 393
403 if (canvas()->originClean() && !canvasPattern->originClean()) 394 if (canvas()->originClean() && !canvasPattern->originClean())
404 canvas()->setOriginTainted(); 395 canvas()->setOriginTainted();
405 396
406 canvasStyle = CanvasStyle::createFromPattern(canvasPattern); 397 canvasStyle = CanvasStyle::createFromPattern(canvasPattern);
407 } 398 }
408 399
409 ASSERT(canvasStyle); 400 ASSERT(canvasStyle);
410 401
411 SkCanvas* c = drawingCanvas();
412 realizeSaves(c);
413 modifiableState().setStrokeStyle(canvasStyle.release()); 402 modifiableState().setStrokeStyle(canvasStyle.release());
414 if (!c)
415 return;
416 modifiableState().setUnparsedStrokeColor(colorString); 403 modifiableState().setUnparsedStrokeColor(colorString);
417 } 404 }
418 405
419 void CanvasRenderingContext2D::fillStyle(StringOrCanvasGradientOrCanvasPattern& returnValue) const 406 void CanvasRenderingContext2D::fillStyle(StringOrCanvasGradientOrCanvasPattern& returnValue) const
420 { 407 {
421 convertCanvasStyleToUnionType(state().fillStyle(), returnValue); 408 convertCanvasStyleToUnionType(state().fillStyle(), returnValue);
422 } 409 }
423 410
424 void CanvasRenderingContext2D::setFillStyle(const StringOrCanvasGradientOrCanvas Pattern& style) 411 void CanvasRenderingContext2D::setFillStyle(const StringOrCanvasGradientOrCanvas Pattern& style)
425 { 412 {
426 ASSERT(!style.isNull()); 413 ASSERT(!style.isNull());
427 validateStateStack(); 414 validateStateStack();
428 String colorString; 415 String colorString;
429 RefPtrWillBeRawPtr<CanvasStyle> canvasStyle = nullptr; 416 RefPtrWillBeRawPtr<CanvasStyle> canvasStyle = nullptr;
430 if (style.isString()) { 417 if (style.isString()) {
431 colorString = style.getAsString(); 418 colorString = style.getAsString();
432 if (colorString == state().unparsedFillColor()) 419 if (colorString == state().unparsedFillColor())
433 return; 420 return;
434 RGBA32 parsedColor = 0; 421 RGBA32 parsedColor = 0;
435 if (!parseColorOrCurrentColor(parsedColor, colorString, canvas())) 422 if (!parseColorOrCurrentColor(parsedColor, colorString, canvas()))
436 return; 423 return;
437 if (state().fillStyle()->isEquivalentRGBA(parsedColor)) { 424 if (state().fillStyle()->isEquivalentRGBA(parsedColor)) {
438 realizeSaves(nullptr);
439 modifiableState().setUnparsedFillColor(colorString); 425 modifiableState().setUnparsedFillColor(colorString);
440 return; 426 return;
441 } 427 }
442 canvasStyle = CanvasStyle::createFromRGBA(parsedColor); 428 canvasStyle = CanvasStyle::createFromRGBA(parsedColor);
443 } else if (style.isCanvasGradient()) { 429 } else if (style.isCanvasGradient()) {
444 canvasStyle = CanvasStyle::createFromGradient(style.getAsCanvasGradient( )); 430 canvasStyle = CanvasStyle::createFromGradient(style.getAsCanvasGradient( ));
445 } else if (style.isCanvasPattern()) { 431 } else if (style.isCanvasPattern()) {
446 RefPtrWillBeRawPtr<CanvasPattern> canvasPattern = style.getAsCanvasPatte rn(); 432 RefPtrWillBeRawPtr<CanvasPattern> canvasPattern = style.getAsCanvasPatte rn();
447 433
448 if (canvas()->originClean() && !canvasPattern->originClean()) 434 if (canvas()->originClean() && !canvasPattern->originClean())
449 canvas()->setOriginTainted(); 435 canvas()->setOriginTainted();
450 436
451 canvasStyle = CanvasStyle::createFromPattern(canvasPattern); 437 canvasStyle = CanvasStyle::createFromPattern(canvasPattern);
452 } 438 }
453 439
454 ASSERT(canvasStyle); 440 ASSERT(canvasStyle);
455 SkCanvas* c = drawingCanvas();
456 if (!c)
457 return;
458 realizeSaves(c);
459
460 modifiableState().setFillStyle(canvasStyle.release()); 441 modifiableState().setFillStyle(canvasStyle.release());
461 modifiableState().setUnparsedFillColor(colorString); 442 modifiableState().setUnparsedFillColor(colorString);
462 } 443 }
463 444
464 float CanvasRenderingContext2D::lineWidth() const 445 float CanvasRenderingContext2D::lineWidth() const
465 { 446 {
466 return state().lineWidth(); 447 return state().lineWidth();
467 } 448 }
468 449
469 void CanvasRenderingContext2D::setLineWidth(float width) 450 void CanvasRenderingContext2D::setLineWidth(float width)
470 { 451 {
471 if (!std::isfinite(width) || width <= 0) 452 if (!std::isfinite(width) || width <= 0)
472 return; 453 return;
473 if (state().lineWidth() == width) 454 if (state().lineWidth() == width)
474 return; 455 return;
475 SkCanvas* c = drawingCanvas();
476 realizeSaves(c);
477 modifiableState().setLineWidth(width); 456 modifiableState().setLineWidth(width);
478 if (!c)
479 return;
480 } 457 }
481 458
482 String CanvasRenderingContext2D::lineCap() const 459 String CanvasRenderingContext2D::lineCap() const
483 { 460 {
484 return lineCapName(state().lineCap()); 461 return lineCapName(state().lineCap());
485 } 462 }
486 463
487 void CanvasRenderingContext2D::setLineCap(const String& s) 464 void CanvasRenderingContext2D::setLineCap(const String& s)
488 { 465 {
489 LineCap cap; 466 LineCap cap;
490 if (!parseLineCap(s, cap)) 467 if (!parseLineCap(s, cap))
491 return; 468 return;
492 if (state().lineCap() == cap) 469 if (state().lineCap() == cap)
493 return; 470 return;
494 SkCanvas* c = drawingCanvas();
495 realizeSaves(c);
496 modifiableState().setLineCap(cap); 471 modifiableState().setLineCap(cap);
497 if (!c)
498 return;
499 } 472 }
500 473
501 String CanvasRenderingContext2D::lineJoin() const 474 String CanvasRenderingContext2D::lineJoin() const
502 { 475 {
503 return lineJoinName(state().lineJoin()); 476 return lineJoinName(state().lineJoin());
504 } 477 }
505 478
506 void CanvasRenderingContext2D::setLineJoin(const String& s) 479 void CanvasRenderingContext2D::setLineJoin(const String& s)
507 { 480 {
508 LineJoin join; 481 LineJoin join;
509 if (!parseLineJoin(s, join)) 482 if (!parseLineJoin(s, join))
510 return; 483 return;
511 if (state().lineJoin() == join) 484 if (state().lineJoin() == join)
512 return; 485 return;
513 SkCanvas* c = drawingCanvas();
514 realizeSaves(c);
515 modifiableState().setLineJoin(join); 486 modifiableState().setLineJoin(join);
516 if (!c)
517 return;
518 } 487 }
519 488
520 float CanvasRenderingContext2D::miterLimit() const 489 float CanvasRenderingContext2D::miterLimit() const
521 { 490 {
522 return state().miterLimit(); 491 return state().miterLimit();
523 } 492 }
524 493
525 void CanvasRenderingContext2D::setMiterLimit(float limit) 494 void CanvasRenderingContext2D::setMiterLimit(float limit)
526 { 495 {
527 if (!std::isfinite(limit) || limit <= 0) 496 if (!std::isfinite(limit) || limit <= 0)
528 return; 497 return;
529 if (state().miterLimit() == limit) 498 if (state().miterLimit() == limit)
530 return; 499 return;
531 SkCanvas* c = drawingCanvas();
532 realizeSaves(c);
533 modifiableState().setMiterLimit(limit); 500 modifiableState().setMiterLimit(limit);
534 if (!c)
535 return;
536 } 501 }
537 502
538 float CanvasRenderingContext2D::shadowOffsetX() const 503 float CanvasRenderingContext2D::shadowOffsetX() const
539 { 504 {
540 return state().shadowOffset().width(); 505 return state().shadowOffset().width();
541 } 506 }
542 507
543 void CanvasRenderingContext2D::setShadowOffsetX(float x) 508 void CanvasRenderingContext2D::setShadowOffsetX(float x)
544 { 509 {
545 if (!std::isfinite(x)) 510 if (!std::isfinite(x))
546 return; 511 return;
547 if (state().shadowOffset().width() == x) 512 if (state().shadowOffset().width() == x)
548 return; 513 return;
549 realizeSaves(nullptr);
550 modifiableState().setShadowOffsetX(x); 514 modifiableState().setShadowOffsetX(x);
551 } 515 }
552 516
553 float CanvasRenderingContext2D::shadowOffsetY() const 517 float CanvasRenderingContext2D::shadowOffsetY() const
554 { 518 {
555 return state().shadowOffset().height(); 519 return state().shadowOffset().height();
556 } 520 }
557 521
558 void CanvasRenderingContext2D::setShadowOffsetY(float y) 522 void CanvasRenderingContext2D::setShadowOffsetY(float y)
559 { 523 {
560 if (!std::isfinite(y)) 524 if (!std::isfinite(y))
561 return; 525 return;
562 if (state().shadowOffset().height() == y) 526 if (state().shadowOffset().height() == y)
563 return; 527 return;
564 realizeSaves(nullptr);
565 modifiableState().setShadowOffsetY(y); 528 modifiableState().setShadowOffsetY(y);
566 } 529 }
567 530
568 float CanvasRenderingContext2D::shadowBlur() const 531 float CanvasRenderingContext2D::shadowBlur() const
569 { 532 {
570 return state().shadowBlur(); 533 return state().shadowBlur();
571 } 534 }
572 535
573 void CanvasRenderingContext2D::setShadowBlur(float blur) 536 void CanvasRenderingContext2D::setShadowBlur(float blur)
574 { 537 {
575 if (!std::isfinite(blur) || blur < 0) 538 if (!std::isfinite(blur) || blur < 0)
576 return; 539 return;
577 if (state().shadowBlur() == blur) 540 if (state().shadowBlur() == blur)
578 return; 541 return;
579 realizeSaves(nullptr);
580 modifiableState().setShadowBlur(blur); 542 modifiableState().setShadowBlur(blur);
581 } 543 }
582 544
583 String CanvasRenderingContext2D::shadowColor() const 545 String CanvasRenderingContext2D::shadowColor() const
584 { 546 {
585 return Color(state().shadowColor()).serialized(); 547 return Color(state().shadowColor()).serialized();
586 } 548 }
587 549
588 void CanvasRenderingContext2D::setShadowColor(const String& color) 550 void CanvasRenderingContext2D::setShadowColor(const String& color)
589 { 551 {
590 RGBA32 rgba; 552 RGBA32 rgba;
591 if (!parseColorOrCurrentColor(rgba, color, canvas())) 553 if (!parseColorOrCurrentColor(rgba, color, canvas()))
592 return; 554 return;
593 if (state().shadowColor() == rgba) 555 if (state().shadowColor() == rgba)
594 return; 556 return;
595 realizeSaves(nullptr);
596 modifiableState().setShadowColor(rgba); 557 modifiableState().setShadowColor(rgba);
597 } 558 }
598 559
599 const Vector<float>& CanvasRenderingContext2D::getLineDash() const 560 const Vector<float>& CanvasRenderingContext2D::getLineDash() const
600 { 561 {
601 return state().lineDash(); 562 return state().lineDash();
602 } 563 }
603 564
604 static bool lineDashSequenceIsValid(const Vector<float>& dash) 565 static bool lineDashSequenceIsValid(const Vector<float>& dash)
605 { 566 {
606 for (size_t i = 0; i < dash.size(); i++) { 567 for (size_t i = 0; i < dash.size(); i++) {
607 if (!std::isfinite(dash[i]) || dash[i] < 0) 568 if (!std::isfinite(dash[i]) || dash[i] < 0)
608 return false; 569 return false;
609 } 570 }
610 return true; 571 return true;
611 } 572 }
612 573
613 void CanvasRenderingContext2D::setLineDash(const Vector<float>& dash) 574 void CanvasRenderingContext2D::setLineDash(const Vector<float>& dash)
614 { 575 {
615 if (!lineDashSequenceIsValid(dash)) 576 if (!lineDashSequenceIsValid(dash))
616 return; 577 return;
617
618 realizeSaves(nullptr);
619 modifiableState().setLineDash(dash); 578 modifiableState().setLineDash(dash);
620 } 579 }
621 580
622 float CanvasRenderingContext2D::lineDashOffset() const 581 float CanvasRenderingContext2D::lineDashOffset() const
623 { 582 {
624 return state().lineDashOffset(); 583 return state().lineDashOffset();
625 } 584 }
626 585
627 void CanvasRenderingContext2D::setLineDashOffset(float offset) 586 void CanvasRenderingContext2D::setLineDashOffset(float offset)
628 { 587 {
629 if (!std::isfinite(offset) || state().lineDashOffset() == offset) 588 if (!std::isfinite(offset) || state().lineDashOffset() == offset)
630 return; 589 return;
631
632 realizeSaves(nullptr);
633 modifiableState().setLineDashOffset(offset); 590 modifiableState().setLineDashOffset(offset);
634 } 591 }
635 592
636 float CanvasRenderingContext2D::globalAlpha() const 593 float CanvasRenderingContext2D::globalAlpha() const
637 { 594 {
638 return state().globalAlpha(); 595 return state().globalAlpha();
639 } 596 }
640 597
641 void CanvasRenderingContext2D::setGlobalAlpha(float alpha) 598 void CanvasRenderingContext2D::setGlobalAlpha(float alpha)
642 { 599 {
643 if (!(alpha >= 0 && alpha <= 1)) 600 if (!(alpha >= 0 && alpha <= 1))
644 return; 601 return;
645 if (state().globalAlpha() == alpha) 602 if (state().globalAlpha() == alpha)
646 return; 603 return;
647 SkCanvas* c = drawingCanvas();
648 realizeSaves(c);
649 modifiableState().setGlobalAlpha(alpha); 604 modifiableState().setGlobalAlpha(alpha);
650 if (!c)
651 return;
652 drawingContext()->setAlphaAsFloat(alpha);
653 } 605 }
654 606
655 String CanvasRenderingContext2D::globalCompositeOperation() const 607 String CanvasRenderingContext2D::globalCompositeOperation() const
656 { 608 {
657 return compositeOperatorName(compositeOperatorFromSkia(state().globalComposi te()), blendModeFromSkia(state().globalComposite())); 609 return compositeOperatorName(compositeOperatorFromSkia(state().globalComposi te()), blendModeFromSkia(state().globalComposite()));
658 } 610 }
659 611
660 void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati on) 612 void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati on)
661 { 613 {
662 CompositeOperator op = CompositeSourceOver; 614 CompositeOperator op = CompositeSourceOver;
663 WebBlendMode blendMode = WebBlendModeNormal; 615 WebBlendMode blendMode = WebBlendModeNormal;
664 // TODO(dshwang): Support nonstandard "darker" until M43. crbug.com/425628 616 // TODO(dshwang): Support nonstandard "darker" until M43. crbug.com/425628
665 String operationName = operation; 617 String operationName = operation;
666 if (operation == "darker") { 618 if (operation == "darker") {
667 operationName = "darken"; 619 operationName = "darken";
668 if (canvas()) 620 if (canvas())
669 UseCounter::countDeprecation(canvas()->document(), UseCounter::Canva sRenderingContext2DCompositeOperationDarker); 621 UseCounter::countDeprecation(canvas()->document(), UseCounter::Canva sRenderingContext2DCompositeOperationDarker);
670 } 622 }
671 if (!parseCompositeAndBlendOperator(operationName, op, blendMode)) 623 if (!parseCompositeAndBlendOperator(operationName, op, blendMode))
672 return; 624 return;
673 SkXfermode::Mode xfermode = WebCoreCompositeToSkiaComposite(op, blendMode); 625 SkXfermode::Mode xfermode = WebCoreCompositeToSkiaComposite(op, blendMode);
674 if (state().globalComposite() == xfermode) 626 if (state().globalComposite() == xfermode)
675 return; 627 return;
676 SkCanvas* c = drawingCanvas();
677 realizeSaves(c);
678 modifiableState().setGlobalComposite(xfermode); 628 modifiableState().setGlobalComposite(xfermode);
679 if (!c)
680 return;
681 drawingContext()->setCompositeOperation(xfermode);
682 } 629 }
683 630
684 PassRefPtrWillBeRawPtr<SVGMatrixTearOff> CanvasRenderingContext2D::currentTransf orm() const 631 PassRefPtrWillBeRawPtr<SVGMatrixTearOff> CanvasRenderingContext2D::currentTransf orm() const
685 { 632 {
686 return SVGMatrixTearOff::create(state().transform()); 633 return SVGMatrixTearOff::create(state().transform());
687 } 634 }
688 635
689 void CanvasRenderingContext2D::setCurrentTransform(PassRefPtrWillBeRawPtr<SVGMat rixTearOff> passMatrixTearOff) 636 void CanvasRenderingContext2D::setCurrentTransform(PassRefPtrWillBeRawPtr<SVGMat rixTearOff> passMatrixTearOff)
690 { 637 {
691 RefPtrWillBeRawPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff; 638 RefPtrWillBeRawPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff;
692 const AffineTransform& transform = matrixTearOff->value(); 639 const AffineTransform& transform = matrixTearOff->value();
693 setTransform(transform.a(), transform.b(), transform.c(), transform.d(), tra nsform.e(), transform.f()); 640 setTransform(transform.a(), transform.b(), transform.c(), transform.d(), tra nsform.e(), transform.f());
694 } 641 }
695 642
696 void CanvasRenderingContext2D::scale(float sx, float sy) 643 void CanvasRenderingContext2D::scale(float sx, float sy)
697 { 644 {
698 SkCanvas* c = drawingCanvas(); 645 SkCanvas* c = drawingCanvas();
699 if (!c) 646 if (!c)
700 return; 647 return;
701 648
702 if (!std::isfinite(sx) || !std::isfinite(sy)) 649 if (!std::isfinite(sx) || !std::isfinite(sy))
703 return; 650 return;
704 651
705 AffineTransform newTransform = state().transform(); 652 AffineTransform newTransform = state().transform();
706 newTransform.scaleNonUniform(sx, sy); 653 newTransform.scaleNonUniform(sx, sy);
707 if (state().transform() == newTransform) 654 if (state().transform() == newTransform)
708 return; 655 return;
709 656
710 realizeSaves(c);
711
712 modifiableState().setTransform(newTransform); 657 modifiableState().setTransform(newTransform);
713 if (!state().isTransformInvertible()) 658 if (!state().isTransformInvertible())
714 return; 659 return;
715 660
716 c->scale(sx, sy); 661 c->scale(sx, sy);
717 m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy)); 662 m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy));
718 } 663 }
719 664
720 void CanvasRenderingContext2D::rotate(float angleInRadians) 665 void CanvasRenderingContext2D::rotate(float angleInRadians)
721 { 666 {
722 SkCanvas* c = drawingCanvas(); 667 SkCanvas* c = drawingCanvas();
723 if (!c) 668 if (!c)
724 return; 669 return;
725 670
726 if (!std::isfinite(angleInRadians)) 671 if (!std::isfinite(angleInRadians))
727 return; 672 return;
728 673
729 AffineTransform newTransform = state().transform(); 674 AffineTransform newTransform = state().transform();
730 newTransform.rotateRadians(angleInRadians); 675 newTransform.rotateRadians(angleInRadians);
731 if (state().transform() == newTransform) 676 if (state().transform() == newTransform)
732 return; 677 return;
733 678
734 realizeSaves(c);
735
736 modifiableState().setTransform(newTransform); 679 modifiableState().setTransform(newTransform);
737 if (!state().isTransformInvertible()) 680 if (!state().isTransformInvertible())
738 return; 681 return;
739 c->rotate(angleInRadians * (180.0f / piFloat)); 682 c->rotate(angleInRadians * (180.0f / piFloat));
740 m_path.transform(AffineTransform().rotateRadians(-angleInRadians)); 683 m_path.transform(AffineTransform().rotateRadians(-angleInRadians));
741 } 684 }
742 685
743 void CanvasRenderingContext2D::translate(float tx, float ty) 686 void CanvasRenderingContext2D::translate(float tx, float ty)
744 { 687 {
745 SkCanvas* c = drawingCanvas(); 688 SkCanvas* c = drawingCanvas();
746 if (!c) 689 if (!c)
747 return; 690 return;
748 if (!state().isTransformInvertible()) 691 if (!state().isTransformInvertible())
749 return; 692 return;
750 693
751 if (!std::isfinite(tx) || !std::isfinite(ty)) 694 if (!std::isfinite(tx) || !std::isfinite(ty))
752 return; 695 return;
753 696
754 AffineTransform newTransform = state().transform(); 697 AffineTransform newTransform = state().transform();
755 newTransform.translate(tx, ty); 698 newTransform.translate(tx, ty);
756 if (state().transform() == newTransform) 699 if (state().transform() == newTransform)
757 return; 700 return;
758 701
759 realizeSaves(c);
760
761 modifiableState().setTransform(newTransform); 702 modifiableState().setTransform(newTransform);
762 if (!state().isTransformInvertible()) 703 if (!state().isTransformInvertible())
763 return; 704 return;
764 c->translate(tx, ty); 705 c->translate(tx, ty);
765 m_path.transform(AffineTransform().translate(-tx, -ty)); 706 m_path.transform(AffineTransform().translate(-tx, -ty));
766 } 707 }
767 708
768 void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float m22, float dx, float dy) 709 void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float m22, float dx, float dy)
769 { 710 {
770 SkCanvas* c = drawingCanvas(); 711 SkCanvas* c = drawingCanvas();
771 if (!c) 712 if (!c)
772 return; 713 return;
773 714
774 if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || !std ::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy)) 715 if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || !std ::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy))
775 return; 716 return;
776 717
777 AffineTransform transform(m11, m12, m21, m22, dx, dy); 718 AffineTransform transform(m11, m12, m21, m22, dx, dy);
778 AffineTransform newTransform = state().transform() * transform; 719 AffineTransform newTransform = state().transform() * transform;
779 if (state().transform() == newTransform) 720 if (state().transform() == newTransform)
780 return; 721 return;
781 722
782 realizeSaves(c);
783
784 modifiableState().setTransform(newTransform); 723 modifiableState().setTransform(newTransform);
785 if (!state().isTransformInvertible()) 724 if (!state().isTransformInvertible())
786 return; 725 return;
787 726
788 c->concat(affineTransformToSkMatrix(transform)); 727 c->concat(affineTransformToSkMatrix(transform));
789 m_path.transform(transform.inverse()); 728 m_path.transform(transform.inverse());
790 } 729 }
791 730
792 void CanvasRenderingContext2D::resetTransform() 731 void CanvasRenderingContext2D::resetTransform()
793 { 732 {
794 SkCanvas* c = drawingCanvas(); 733 SkCanvas* c = drawingCanvas();
795 if (!c) 734 if (!c)
796 return; 735 return;
797 736
798 AffineTransform ctm = state().transform(); 737 AffineTransform ctm = state().transform();
799 bool invertibleCTM = state().isTransformInvertible(); 738 bool invertibleCTM = state().isTransformInvertible();
800 // It is possible that CTM is identity while CTM is not invertible. 739 // It is possible that CTM is identity while CTM is not invertible.
801 // When CTM becomes non-invertible, realizeSaves() can make CTM identity. 740 // When CTM becomes non-invertible, realizeSaves() can make CTM identity.
802 if (ctm.isIdentity() && invertibleCTM) 741 if (ctm.isIdentity() && invertibleCTM)
803 return; 742 return;
804 743
805 realizeSaves(c);
806 // resetTransform() resolves the non-invertible CTM state. 744 // resetTransform() resolves the non-invertible CTM state.
807 modifiableState().resetTransform(); 745 modifiableState().resetTransform();
808 c->setMatrix(affineTransformToSkMatrix(canvas()->baseTransform())); 746 c->setMatrix(affineTransformToSkMatrix(canvas()->baseTransform()));
809 747
810 if (invertibleCTM) 748 if (invertibleCTM)
811 m_path.transform(ctm); 749 m_path.transform(ctm);
812 // When else, do nothing because all transform methods didn't update m_path when CTM became non-invertible. 750 // When else, do nothing because all transform methods didn't update m_path when CTM became non-invertible.
813 // It means that resetTransform() restores m_path just before CTM became non -invertible. 751 // It means that resetTransform() restores m_path just before CTM became non -invertible.
814 } 752 }
815 753
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc & drawCoversClipBounds, const SkRect& bounds, CanvasRenderingContext2DState::Pai ntType paintType, CanvasRenderingContext2DState::ImageType imageType) 830 bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc & drawCoversClipBounds, const SkRect& bounds, CanvasRenderingContext2DState::Pai ntType paintType, CanvasRenderingContext2DState::ImageType imageType)
893 { 831 {
894 if (!state().isTransformInvertible()) 832 if (!state().isTransformInvertible())
895 return false; 833 return false;
896 834
897 SkIRect clipBounds; 835 SkIRect clipBounds;
898 if (!drawingCanvas() || !drawingCanvas()->getClipDeviceBounds(&clipBounds)) 836 if (!drawingCanvas() || !drawingCanvas()->getClipDeviceBounds(&clipBounds))
899 return false; 837 return false;
900 838
901 // If gradient size is zero, then paint nothing. 839 // If gradient size is zero, then paint nothing.
902 CanvasGradient* gradient = state().style(paintType)->canvasGradient(); 840 CanvasStyle* style = state().style(paintType);
903 if (gradient && gradient->gradient()->isZeroSize()) 841 if (style) {
904 return false; 842 CanvasGradient* gradient = style->canvasGradient();
843 if (gradient && gradient->gradient()->isZeroSize())
844 return false;
845 }
905 846
906 if (isFullCanvasCompositeMode(state().globalComposite())) { 847 if (isFullCanvasCompositeMode(state().globalComposite())) {
907 fullCanvasCompositedDraw(drawFunc, paintType, imageType); 848 fullCanvasCompositedDraw(drawFunc, paintType, imageType);
908 didDraw(clipBounds); 849 didDraw(clipBounds);
909 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) { 850 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) {
910 clearCanvas(); // takes care of checkOvewrdraw() 851 clearCanvas(); // takes care of checkOvewrdraw()
911 const SkPaint* paint = state().getPaint(paintType, DrawForegroundOnly, i mageType); 852 const SkPaint* paint = state().getPaint(paintType, DrawForegroundOnly, i mageType);
912 drawFunc(paint); 853 drawFunc(paint);
913 didDraw(clipBounds); 854 didDraw(clipBounds);
914 } else { 855 } else {
915 SkIRect dirtyRect; 856 SkIRect dirtyRect;
916 if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) { 857 if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) {
917 const SkPaint* paint = state().getPaint(paintType, DrawShadowAndFore ground, imageType); 858 const SkPaint* paint = state().getPaint(paintType, DrawShadowAndFore ground, imageType);
918 if (paintType == CanvasRenderingContext2DState::FillPaintType && dra wCoversClipBounds(clipBounds)) 859 if (paintType != CanvasRenderingContext2DState::StrokePaintType && d rawCoversClipBounds(clipBounds))
919 checkOverdraw(bounds, paint, imageType, ClipFill); 860 checkOverdraw(bounds, paint, imageType, ClipFill);
920 drawFunc(paint); 861 drawFunc(paint);
921 didDraw(dirtyRect); 862 didDraw(dirtyRect);
922 } 863 }
923 } 864 }
924 return true; 865 return true;
925 } 866 }
926 867
927 static bool isPathExpensive(const Path& path) 868 static bool isPathExpensive(const Path& path)
928 { 869 {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 void CanvasRenderingContext2D::clipInternal(const Path& path, const String& wind ingRuleString) 998 void CanvasRenderingContext2D::clipInternal(const Path& path, const String& wind ingRuleString)
1058 { 999 {
1059 SkCanvas* c = drawingCanvas(); 1000 SkCanvas* c = drawingCanvas();
1060 if (!c) { 1001 if (!c) {
1061 return; 1002 return;
1062 } 1003 }
1063 if (!state().isTransformInvertible()) { 1004 if (!state().isTransformInvertible()) {
1064 return; 1005 return;
1065 } 1006 }
1066 1007
1067 realizeSaves(c);
1068
1069 SkPath skPath = path.skPath(); 1008 SkPath skPath = path.skPath();
1070 skPath.setFillType(parseWinding(windingRuleString)); 1009 skPath.setFillType(parseWinding(windingRuleString));
1071 modifiableState().clipPath(skPath, m_clipAntialiasing); 1010 modifiableState().clipPath(skPath, m_clipAntialiasing);
1072 c->clipPath(skPath, SkRegion::kIntersect_Op, m_clipAntialiasing == AntiAlias ed); 1011 c->clipPath(skPath, SkRegion::kIntersect_Op, m_clipAntialiasing == AntiAlias ed);
1073 if (ExpensiveCanvasHeuristicParameters::ComplexClipsAreExpensive && !skPath. isRect(0) && canvas()->hasImageBuffer()) { 1012 if (ExpensiveCanvasHeuristicParameters::ComplexClipsAreExpensive && !skPath. isRect(0) && canvas()->hasImageBuffer()) {
1074 canvas()->buffer()->setHasExpensiveOp(); 1013 canvas()->buffer()->setHasExpensiveOp();
1075 } 1014 }
1076 } 1015 }
1077 1016
1078 void CanvasRenderingContext2D::clip(const String& windingRuleString) 1017 void CanvasRenderingContext2D::clip(const String& windingRuleString)
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 c->drawRect(rect, clearPaint); 1154 c->drawRect(rect, clearPaint);
1216 didDraw(dirtyRect); 1155 didDraw(dirtyRect);
1217 } 1156 }
1218 } 1157 }
1219 1158
1220 if (m_hitRegionManager) { 1159 if (m_hitRegionManager) {
1221 m_hitRegionManager->removeHitRegionsInRect(rect, state().transform()); 1160 m_hitRegionManager->removeHitRegionsInRect(rect, state().transform());
1222 } 1161 }
1223 } 1162 }
1224 1163
1225 void CanvasRenderingContext2D::applyShadow(ShadowMode shadowMode)
1226 {
1227 GraphicsContext* c = drawingContext();
1228 if (!c)
1229 return;
1230
1231 if (state().shouldDrawShadows()) {
1232 c->setShadow(state().shadowOffset(), state().shadowBlur(), state().shado wColor(),
1233 DrawLooperBuilder::ShadowIgnoresTransforms, DrawLooperBuilder::Shado wRespectsAlpha, shadowMode);
1234 } else {
1235 c->clearShadow();
1236 }
1237 }
1238
1239 static inline FloatRect normalizeRect(const FloatRect& rect) 1164 static inline FloatRect normalizeRect(const FloatRect& rect)
1240 { 1165 {
1241 return FloatRect(std::min(rect.x(), rect.maxX()), 1166 return FloatRect(std::min(rect.x(), rect.maxX()),
1242 std::min(rect.y(), rect.maxY()), 1167 std::min(rect.y(), rect.maxY()),
1243 std::max(rect.width(), -rect.width()), 1168 std::max(rect.width(), -rect.width()),
1244 std::max(rect.height(), -rect.height())); 1169 std::max(rect.height(), -rect.height()));
1245 } 1170 }
1246 1171
1247 static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* s rcRect, FloatRect* dstRect) 1172 static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* s rcRect, FloatRect* dstRect)
1248 { 1173 {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 } 1219 }
1295 1220
1296 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, 1221 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce,
1297 float sx, float sy, float sw, float sh, 1222 float sx, float sy, float sw, float sh,
1298 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) 1223 float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
1299 { 1224 {
1300 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource); 1225 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource);
1301 drawImage(imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, dh, exceptionStat e); 1226 drawImage(imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, dh, exceptionStat e);
1302 } 1227 }
1303 1228
1304 void CanvasRenderingContext2D::drawVideo(CanvasImageSource* imageSource, const F loatRect& srcRect, const FloatRect& dstRect) 1229 class Canvas2DImageFilterQualityHelper : public ImageFilterQualityHelper {
1230 public:
1231 Canvas2DImageFilterQualityHelper(const SkMatrix& ctm, SkFilterQuality filter Quality)
1232 : m_filterQuality(filterQuality)
1233 , m_ctm(ctm) { }
1234 SkFilterQuality computeFilterQuality(Image*, const FloatRect& dest, const Fl oatRect& src) const override { return m_filterQuality; }
1235 bool shouldClampToSourceRect() const override { return false; }
1236 bool shouldDrawAntiAliased(const FloatRect& destRect) const override;
1237 virtual ~Canvas2DImageFilterQualityHelper() { }
1238 private:
1239 SkFilterQuality m_filterQuality;
1240 SkMatrix m_ctm;
1241 };
1242
1243 bool Canvas2DImageFilterQualityHelper::shouldDrawAntiAliased(const FloatRect& de stRect) const
1305 { 1244 {
1306 HTMLVideoElement* video = static_cast<HTMLVideoElement*>(imageSource); 1245 // Don't disable anti-aliasing if we're rotated or skewed.
1307 ASSERT(video); 1246 if (!m_ctm.rectStaysRect())
1308 SkCanvas* c = drawingCanvas(); 1247 return true;
1309 if (!c) 1248 // Check if the dimensions of the destination are "small" (less than one
1310 return; 1249 // device pixel). To prevent sudden drop-outs. Since we know that
1311 c->save(); 1250 // kRectStaysRect_Mask is set, the matrix either has scale and no skew or
1312 c->clipRect(WebCoreFloatRectToSKRect(dstRect)); 1251 // vice versa. We can query the kAffine_Mask flag to determine which case
1313 c->translate(dstRect.x(), dstRect.y()); 1252 // it is.
1314 c->scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.heigh t()); 1253 // FIXME: This queries the CTM while drawing, which is generally
1315 c->translate(-srcRect.x(), -srcRect.y()); 1254 // discouraged. Always drawing with AA can negatively impact performance
1316 video->paintCurrentFrameInContext(drawingContext(), IntRect(IntPoint(), IntS ize(video->videoWidth(), video->videoHeight()))); 1255 // though - that's why it's not always on.
1317 // In case the paint propagated a queued context loss signal 1256 SkScalar widthExpansion, heightExpansion;
1318 if (drawingCanvas()) 1257 if (m_ctm.getType() & SkMatrix::kAffine_Mask)
1319 drawingCanvas()->restore(); 1258 widthExpansion = m_ctm[SkMatrix::kMSkewY], heightExpansion = m_ctm[SkMat rix::kMSkewX];
1259 else
1260 widthExpansion = m_ctm[SkMatrix::kMScaleX], heightExpansion = m_ctm[SkMa trix::kMScaleY];
1261 return destRect.width() * fabs(widthExpansion) < 1 || destRect.height() * fa bs(heightExpansion) < 1;
1320 } 1262 }
1321 1263
1322 void CanvasRenderingContext2D::drawImageOnContext(CanvasImageSource* imageSource , Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const SkPain t* paint) 1264 void CanvasRenderingContext2D::drawImageInternal(CanvasImageSource* imageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const SkPaint * paint)
1323 { 1265 {
1324 SkXfermode::Mode mode; 1266 SkCanvas* c = drawingCanvas();
1325 if (!SkXfermode::AsMode(paint->getXfermode(), &mode)) 1267 ASSERT(c);
1326 mode = SkXfermode::kSrcOver_Mode;
1327 1268
1328 RefPtr<SkImageFilter> imageFilter(paint->getImageFilter()); 1269 int initialSaveCount = c->getSaveCount();
1329 drawingContext()->setDropShadowImageFilter(imageFilter.release()); 1270 SkPaint imagePaint = *paint;
1330 RefPtr<SkDrawLooper> drawLooper(paint->getLooper()); 1271
1331 drawingContext()->setDrawLooper(drawLooper.release()); 1272 if (paint->getImageFilter()) {
1273 SkMatrix ctm = c->getTotalMatrix();
1274 SkMatrix invCtm;
1275 if (!ctm.invert(&invCtm)) {
1276 ASSERT_NOT_REACHED(); // There is an earlier check for invertibility
1277 }
1278 c->save();
1279 c->concat(invCtm);
1280 SkRect bounds = dstRect;
1281 ctm.mapRect(&bounds);
1282 SkRect filteredBounds;
1283 paint->getImageFilter()->computeFastBounds(bounds, &filteredBounds);
1284 SkPaint layerPaint;
1285 layerPaint.setXfermode(paint->getXfermode());
1286 layerPaint.setImageFilter(paint->getImageFilter());
1287 c->saveLayer(&filteredBounds, &layerPaint);
1288 c->concat(ctm);
1289 imagePaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
1290 imagePaint.setImageFilter(nullptr);
1291 }
1332 1292
1333 if (!imageSource->isVideoElement()) { 1293 if (!imageSource->isVideoElement()) {
1334 drawingContext()->drawImage(image, dstRect, srcRect, mode); 1294 // TODO: Find a way to pass SkCanvas::kBleed_DrawBitmapRectFlag
1295 Canvas2DImageFilterQualityHelper filterHelper(c->getTotalMatrix(), image Paint.getFilterQuality());
1296 image->draw(c, imagePaint, dstRect, srcRect, DoNotRespectImageOrientatio n, &filterHelper);
1335 } else { 1297 } else {
1336 SkXfermode::Mode oldMode = drawingContext()->compositeOperation(); 1298 c->save();
1337 drawingContext()->setCompositeOperation(mode); 1299 c->clipRect(WebCoreFloatRectToSKRect(dstRect));
1338 drawVideo(imageSource, srcRect, dstRect); 1300 c->translate(dstRect.x(), dstRect.y());
1339 // Must re-check drawingContext() in case drawVideo propagated a pending context loss signal 1301 c->scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.h eight());
1340 if (drawingContext()) 1302 c->translate(-srcRect.x(), -srcRect.y());
1341 drawingContext()->setCompositeOperation(oldMode); 1303 HTMLVideoElement* video = static_cast<HTMLVideoElement*>(imageSource);
1304 video->paintCurrentFrame(c, IntRect(IntPoint(), IntSize(video->videoWidt h(), video->videoHeight())), &imagePaint);
1342 } 1305 }
1306
1307 c->restoreToCount(initialSaveCount);
1343 } 1308 }
1344 1309
1345 void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource, 1310 void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
1346 float sx, float sy, float sw, float sh, 1311 float sx, float sy, float sw, float sh,
1347 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) 1312 float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
1348 { 1313 {
1349 if (!drawingCanvas()) 1314 if (!drawingCanvas())
1350 return; 1315 return;
1351 1316
1352 RefPtr<Image> image; 1317 RefPtr<Image> image;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 // We make the destination canvas fall out of display list mode by calling 1350 // We make the destination canvas fall out of display list mode by calling
1386 // willAccessPixels. This is to prevent run-away memory consumption caused b y SkSurface 1351 // willAccessPixels. This is to prevent run-away memory consumption caused b y SkSurface
1387 // copyOnWrite when the source canvas is animated and consumed at a rate hig her than the 1352 // copyOnWrite when the source canvas is animated and consumed at a rate hig her than the
1388 // presentation frame rate of the destination canvas. 1353 // presentation frame rate of the destination canvas.
1389 if (imageSource->isCanvasElement()) 1354 if (imageSource->isCanvasElement())
1390 canvas()->buffer()->willAccessPixels(); 1355 canvas()->buffer()->willAccessPixels();
1391 1356
1392 draw( 1357 draw(
1393 [this, &imageSource, &image, &srcRect, dstRect](const SkPaint* paint) // draw lambda 1358 [this, &imageSource, &image, &srcRect, dstRect](const SkPaint* paint) // draw lambda
1394 { 1359 {
1395 if (drawingCanvas()) 1360 drawImageInternal(imageSource, image.get(), srcRect, dstRect, paint) ;
1396 drawImageOnContext(imageSource, image.get(), srcRect, dstRect, p aint);
1397 }, 1361 },
1398 [this, &dstRect](const SkIRect& clipBounds) // overdraw test lambda 1362 [this, &dstRect](const SkIRect& clipBounds) // overdraw test lambda
1399 { 1363 {
1400 return rectContainsTransformedRect(dstRect, clipBounds); 1364 return rectContainsTransformedRect(dstRect, clipBounds);
1401 }, 1365 },
1402 dstRect, 1366 dstRect,
1403 CanvasRenderingContext2DState::FillPaintType, 1367 CanvasRenderingContext2DState::ImagePaintType,
1404 imageSource->isOpaque() ? CanvasRenderingContext2DState::OpaqueImage : C anvasRenderingContext2DState::NonOpaqueImage); 1368 imageSource->isOpaque() ? CanvasRenderingContext2DState::OpaqueImage : C anvasRenderingContext2DState::NonOpaqueImage);
1405 1369
1406 validateStateStack(); 1370 validateStateStack();
1407 1371
1408 bool isExpensive = false; 1372 bool isExpensive = false;
1409 1373
1410 if (ExpensiveCanvasHeuristicParameters::SVGImageSourcesAreExpensive && image && image->isSVGImage()) 1374 if (ExpensiveCanvasHeuristicParameters::SVGImageSourcesAreExpensive && image && image->isSVGImage())
1411 isExpensive = true; 1375 isExpensive = true;
1412 1376
1413 if (imageSource->elementSize().width() * imageSource->elementSize().height() > canvas()->width() * canvas()->height() * ExpensiveCanvasHeuristicParameters:: ExpensiveImageSizeRatio) 1377 if (imageSource->elementSize().width() * imageSource->elementSize().height() > canvas()->width() * canvas()->height() * ExpensiveCanvasHeuristicParameters:: ExpensiveImageSizeRatio)
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1539 canvas()->didDraw(SkRect::Make(dirtyRect)); 1503 canvas()->didDraw(SkRect::Make(dirtyRect));
1540 } 1504 }
1541 1505
1542 SkCanvas* CanvasRenderingContext2D::drawingCanvas() const 1506 SkCanvas* CanvasRenderingContext2D::drawingCanvas() const
1543 { 1507 {
1544 if (isContextLost()) 1508 if (isContextLost())
1545 return nullptr; 1509 return nullptr;
1546 return canvas()->drawingCanvas(); 1510 return canvas()->drawingCanvas();
1547 } 1511 }
1548 1512
1549 GraphicsContext* CanvasRenderingContext2D::drawingContext() const
1550 {
1551 if (isContextLost())
1552 return nullptr;
1553 return canvas()->drawingContext();
1554 }
1555
1556 ImageData* CanvasRenderingContext2D::createImageData(ImageData* imageData) const 1513 ImageData* CanvasRenderingContext2D::createImageData(ImageData* imageData) const
1557 { 1514 {
1558 return ImageData::create(imageData->size()); 1515 return ImageData::create(imageData->size());
1559 } 1516 }
1560 1517
1561 ImageData* CanvasRenderingContext2D::createImageData(float sw, float sh, Excepti onState& exceptionState) const 1518 ImageData* CanvasRenderingContext2D::createImageData(float sw, float sh, Excepti onState& exceptionState) const
1562 { 1519 {
1563 if (!sw || !sh) { 1520 if (!sw || !sh) {
1564 exceptionState.throwDOMException(IndexSizeError, String::format("The sou rce %s is 0.", sw ? "height" : "width")); 1521 exceptionState.throwDOMException(IndexSizeError, String::format("The sou rce %s is 0.", sw ? "height" : "width"));
1565 return nullptr; 1522 return nullptr;
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 1680
1724 String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont); 1681 String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont);
1725 1682
1726 // According to http://lists.w3.org/Archives/Public/public-html/2009Jul/0947 .html, 1683 // According to http://lists.w3.org/Archives/Public/public-html/2009Jul/0947 .html,
1727 // the "inherit" and "initial" values must be ignored. 1684 // the "inherit" and "initial" values must be ignored.
1728 if (fontValue == "inherit" || fontValue == "initial") 1685 if (fontValue == "inherit" || fontValue == "initial")
1729 return; 1686 return;
1730 1687
1731 // The parse succeeded. 1688 // The parse succeeded.
1732 String newFontSafeCopy(newFont); // Create a string copy since newFont can b e deleted inside realizeSaves. 1689 String newFontSafeCopy(newFont); // Create a string copy since newFont can b e deleted inside realizeSaves.
1733 realizeSaves(nullptr);
1734 modifiableState().setUnparsedFont(newFontSafeCopy); 1690 modifiableState().setUnparsedFont(newFontSafeCopy);
1735 1691
1736 // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work 1692 // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
1737 // relative to the canvas. 1693 // relative to the canvas.
1738 RefPtr<ComputedStyle> newStyle = ComputedStyle::create(); 1694 RefPtr<ComputedStyle> newStyle = ComputedStyle::create();
1739 canvas()->document().updateLayoutTreeIfNeeded(); 1695 canvas()->document().updateLayoutTreeIfNeeded();
1740 if (const ComputedStyle* computedStyle = canvas()->ensureComputedStyle()) { 1696 if (const ComputedStyle* computedStyle = canvas()->ensureComputedStyle()) {
1741 FontDescription elementFontDescription(computedStyle->fontDescription()) ; 1697 FontDescription elementFontDescription(computedStyle->fontDescription()) ;
1742 // Reset the computed size to avoid inheriting the zoom factor from the <canvas> element. 1698 // Reset the computed size to avoid inheriting the zoom factor from the <canvas> element.
1743 elementFontDescription.setComputedSize(elementFontDescription.specifiedS ize()); 1699 elementFontDescription.setComputedSize(elementFontDescription.specifiedS ize());
(...skipping 22 matching lines...) Expand all
1766 return textAlignName(state().textAlign()); 1722 return textAlignName(state().textAlign());
1767 } 1723 }
1768 1724
1769 void CanvasRenderingContext2D::setTextAlign(const String& s) 1725 void CanvasRenderingContext2D::setTextAlign(const String& s)
1770 { 1726 {
1771 TextAlign align; 1727 TextAlign align;
1772 if (!parseTextAlign(s, align)) 1728 if (!parseTextAlign(s, align))
1773 return; 1729 return;
1774 if (state().textAlign() == align) 1730 if (state().textAlign() == align)
1775 return; 1731 return;
1776 realizeSaves(nullptr);
1777 modifiableState().setTextAlign(align); 1732 modifiableState().setTextAlign(align);
1778 } 1733 }
1779 1734
1780 String CanvasRenderingContext2D::textBaseline() const 1735 String CanvasRenderingContext2D::textBaseline() const
1781 { 1736 {
1782 return textBaselineName(state().textBaseline()); 1737 return textBaselineName(state().textBaseline());
1783 } 1738 }
1784 1739
1785 void CanvasRenderingContext2D::setTextBaseline(const String& s) 1740 void CanvasRenderingContext2D::setTextBaseline(const String& s)
1786 { 1741 {
1787 TextBaseline baseline; 1742 TextBaseline baseline;
1788 if (!parseTextBaseline(s, baseline)) 1743 if (!parseTextBaseline(s, baseline))
1789 return; 1744 return;
1790 if (state().textBaseline() == baseline) 1745 if (state().textBaseline() == baseline)
1791 return; 1746 return;
1792 realizeSaves(nullptr);
1793 modifiableState().setTextBaseline(baseline); 1747 modifiableState().setTextBaseline(baseline);
1794 } 1748 }
1795 1749
1796 static inline TextDirection toTextDirection(CanvasRenderingContext2DState::Direc tion direction, HTMLCanvasElement* canvas, const ComputedStyle** computedStyle = 0) 1750 static inline TextDirection toTextDirection(CanvasRenderingContext2DState::Direc tion direction, HTMLCanvasElement* canvas, const ComputedStyle** computedStyle = 0)
1797 { 1751 {
1798 const ComputedStyle* style = (computedStyle || direction == CanvasRenderingC ontext2DState::DirectionInherit) ? canvas->ensureComputedStyle() : nullptr; 1752 const ComputedStyle* style = (computedStyle || direction == CanvasRenderingC ontext2DState::DirectionInherit) ? canvas->ensureComputedStyle() : nullptr;
1799 if (computedStyle) 1753 if (computedStyle)
1800 *computedStyle = style; 1754 *computedStyle = style;
1801 switch (direction) { 1755 switch (direction) {
1802 case CanvasRenderingContext2DState::DirectionInherit: 1756 case CanvasRenderingContext2DState::DirectionInherit:
(...skipping 22 matching lines...) Expand all
1825 else if (directionString == rtl) 1779 else if (directionString == rtl)
1826 direction = CanvasRenderingContext2DState::DirectionRTL; 1780 direction = CanvasRenderingContext2DState::DirectionRTL;
1827 else if (directionString == ltr) 1781 else if (directionString == ltr)
1828 direction = CanvasRenderingContext2DState::DirectionLTR; 1782 direction = CanvasRenderingContext2DState::DirectionLTR;
1829 else 1783 else
1830 return; 1784 return;
1831 1785
1832 if (state().direction() == direction) 1786 if (state().direction() == direction)
1833 return; 1787 return;
1834 1788
1835 realizeSaves(nullptr);
1836 modifiableState().setDirection(direction); 1789 modifiableState().setDirection(direction);
1837 } 1790 }
1838 1791
1839 void CanvasRenderingContext2D::fillText(const String& text, float x, float y) 1792 void CanvasRenderingContext2D::fillText(const String& text, float x, float y)
1840 { 1793 {
1841 drawTextInternal(text, x, y, CanvasRenderingContext2DState::FillPaintType); 1794 drawTextInternal(text, x, y, CanvasRenderingContext2DState::FillPaintType);
1842 } 1795 }
1843 1796
1844 void CanvasRenderingContext2D::fillText(const String& text, float x, float y, fl oat maxWidth) 1797 void CanvasRenderingContext2D::fillText(const String& text, float x, float y, fl oat maxWidth)
1845 { 1798 {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1999 if (state().lineJoin() == MiterJoin) 1952 if (state().lineJoin() == MiterJoin)
2000 delta *= state().miterLimit(); 1953 delta *= state().miterLimit();
2001 else if (state().lineCap() == SquareCap) 1954 else if (state().lineCap() == SquareCap)
2002 delta *= root2; 1955 delta *= root2;
2003 1956
2004 rect.inflate(delta); 1957 rect.inflate(delta);
2005 } 1958 }
2006 1959
2007 const Font& CanvasRenderingContext2D::accessFont() 1960 const Font& CanvasRenderingContext2D::accessFont()
2008 { 1961 {
2009 // This needs style to be up to date, but can't assert so because drawTextIn ternal
2010 // can invalidate style before this is called (e.g. drawingContext invalidat es style).
2011 if (!state().hasRealizedFont()) 1962 if (!state().hasRealizedFont())
2012 setFont(state().unparsedFont()); 1963 setFont(state().unparsedFont());
2013 return state().font(); 1964 return state().font();
2014 } 1965 }
2015 1966
2016 int CanvasRenderingContext2D::getFontBaseline(const FontMetrics& fontMetrics) co nst 1967 int CanvasRenderingContext2D::getFontBaseline(const FontMetrics& fontMetrics) co nst
2017 { 1968 {
2018 switch (state().textBaseline()) { 1969 switch (state().textBaseline()) {
2019 case TopTextBaseline: 1970 case TopTextBaseline:
2020 return fontMetrics.ascent(); 1971 return fontMetrics.ascent();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2054 bool CanvasRenderingContext2D::imageSmoothingEnabled() const 2005 bool CanvasRenderingContext2D::imageSmoothingEnabled() const
2055 { 2006 {
2056 return state().imageSmoothingEnabled(); 2007 return state().imageSmoothingEnabled();
2057 } 2008 }
2058 2009
2059 void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled) 2010 void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled)
2060 { 2011 {
2061 if (enabled == state().imageSmoothingEnabled()) 2012 if (enabled == state().imageSmoothingEnabled())
2062 return; 2013 return;
2063 2014
2064 SkCanvas* c = drawingCanvas();
2065 realizeSaves(c);
2066 modifiableState().setImageSmoothingEnabled(enabled); 2015 modifiableState().setImageSmoothingEnabled(enabled);
2067 if (c)
2068 drawingContext()->setImageInterpolationQuality(enabled ? CanvasDefaultIn terpolationQuality : InterpolationNone);
2069 } 2016 }
2070 2017
2071 void CanvasRenderingContext2D::getContextAttributes(Canvas2DContextAttributes& a ttrs) const 2018 void CanvasRenderingContext2D::getContextAttributes(Canvas2DContextAttributes& a ttrs) const
2072 { 2019 {
2073 attrs.setAlpha(m_hasAlpha); 2020 attrs.setAlpha(m_hasAlpha);
2074 } 2021 }
2075 2022
2076 void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element) 2023 void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element)
2077 { 2024 {
2078 drawFocusIfNeededInternal(m_path, element); 2025 drawFocusIfNeededInternal(m_path, element);
(...skipping 29 matching lines...) Expand all
2108 if (path.isEmpty()) 2055 if (path.isEmpty())
2109 return false; 2056 return false;
2110 if (!element->isDescendantOf(canvas())) 2057 if (!element->isDescendantOf(canvas()))
2111 return false; 2058 return false;
2112 2059
2113 return true; 2060 return true;
2114 } 2061 }
2115 2062
2116 void CanvasRenderingContext2D::drawFocusRing(const Path& path) 2063 void CanvasRenderingContext2D::drawFocusRing(const Path& path)
2117 { 2064 {
2118 GraphicsContext* c = drawingContext(); 2065 if (!drawingCanvas())
2119 if (!c)
2120 return; 2066 return;
2121 2067
2122 // These should match the style defined in html.css. 2068 // These should match the style defined in html.css.
2123 Color focusRingColor = LayoutTheme::theme().focusRingColor(); 2069 Color focusRingColor = LayoutTheme::theme().focusRingColor();
2124 const int focusRingWidth = 5; 2070 const int focusRingWidth = 5;
2125 const int focusRingOutline = 0;
2126 2071
2127 // We need to add focusRingWidth to dirtyRect. 2072 // We need to add focusRingWidth to dirtyRect.
2128 StrokeData strokeData; 2073 StrokeData strokeData;
2129 strokeData.setThickness(focusRingWidth); 2074 strokeData.setThickness(focusRingWidth);
2130 2075
2131 SkIRect dirtyRect; 2076 SkIRect dirtyRect;
2132 if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect)) 2077 if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect))
2133 return; 2078 return;
2134 2079
2135 c->setAlphaAsFloat(1.0); 2080 SkPaint paint;
2136 c->clearShadow(); 2081 paint.setAntiAlias(true);
2137 c->setCompositeOperation(SkXfermode::kSrcOver_Mode); 2082 paint.setStyle(SkPaint::kStroke_Style);
2138 c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor); 2083 paint.setColor(focusRingColor.rgb());
2139 c->setAlphaAsFloat(state().globalAlpha()); 2084 paint.setStrokeWidth(focusRingWidth);
2140 c->setCompositeOperation(state().globalComposite());
2141 2085
2142 validateStateStack(); 2086 #if OS(MACOSX)
Stephen White 2015/05/27 15:46:02 Nit: IWBN to relocate these platform-specific diff
Justin Novosad 2015/05/27 20:08:16 Looking at the GC counterpart of this code... I sm
2087 paint.setAlpha(64);
2088 float cornerRadius = (focusRingWidth - 1) * 0.5f;
2089 #else
2090 const float cornerRadius = 1;
2091 #endif
2092
2093 paint.setPathEffect(SkCornerPathEffect::Create(SkFloatToScalar(cornerRadius) ))->unref();
2094
2095 // Outer path
2096 drawingCanvas()->drawPath(path.skPath(), paint);
2097
2098 #if OS(MACOSX)
2099 // Inner path
2100 paint.setAlpha(128);
2101 paint.setStrokeWidth(paint.getStrokeWidth() * 0.5f);
2102 drawingCanvas()->drawPath(path.skPath(), paint);
2103 #endif
2104
2143 didDraw(dirtyRect); 2105 didDraw(dirtyRect);
2144 } 2106 }
2145 2107
2146 void CanvasRenderingContext2D::updateFocusRingElementAccessibility(const Path& p ath, Element* element) 2108 void CanvasRenderingContext2D::updateFocusRingElementAccessibility(const Path& p ath, Element* element)
2147 { 2109 {
2148 AXObjectCache* axObjectCache = element->document().existingAXObjectCache(); 2110 AXObjectCache* axObjectCache = element->document().existingAXObjectCache();
2149 LayoutBoxModelObject* lbmo = canvas()->layoutBoxModelObject(); 2111 LayoutBoxModelObject* lbmo = canvas()->layoutBoxModelObject();
2150 LayoutObject* renderer = canvas()->layoutObject(); 2112 LayoutObject* renderer = canvas()->layoutObject();
2151 if (!axObjectCache || !lbmo || !renderer) 2113 if (!axObjectCache || !lbmo || !renderer)
2152 return; 2114 return;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
2291 if (imageType == CanvasRenderingContext2DState::NonOpaqueImage) 2253 if (imageType == CanvasRenderingContext2DState::NonOpaqueImage)
2292 return; 2254 return;
2293 if (alpha < 0xFF) 2255 if (alpha < 0xFF)
2294 return; 2256 return;
2295 } 2257 }
2296 2258
2297 canvas()->buffer()->willOverwriteCanvas(); 2259 canvas()->buffer()->willOverwriteCanvas();
2298 } 2260 }
2299 2261
2300 } // namespace blink 2262 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698