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

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

Issue 895153002: Make CanvasRenderingContext2D use SkCanvas directly (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: fix issue with the copy composite operator Created 5 years, 10 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
« no previous file with comments | « Source/core/html/canvas/CanvasRenderingContext2D.h ('k') | Source/core/html/canvas/ClipList.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 , m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreC ontextEvent) 103 , m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreC ontextEvent)
104 { 104 {
105 if (document.settings() && document.settings()->antialiasedClips2dCanvasEnab led()) 105 if (document.settings() && document.settings()->antialiasedClips2dCanvasEnab led())
106 m_clipAntialiasing = AntiAliased; 106 m_clipAntialiasing = AntiAliased;
107 m_stateStack.append(adoptPtrWillBeNoop(new State())); 107 m_stateStack.append(adoptPtrWillBeNoop(new State()));
108 } 108 }
109 109
110 void CanvasRenderingContext2D::unwindStateStack() 110 void CanvasRenderingContext2D::unwindStateStack()
111 { 111 {
112 if (size_t stackSize = m_stateStack.size()) { 112 if (size_t stackSize = m_stateStack.size()) {
113 if (GraphicsContext* context = canvas()->existingDrawingContext()) { 113 if (SkCanvas* skCanvas = canvas()->existingDrawingCanvas()) {
114 while (--stackSize) 114 while (--stackSize)
115 context->restore(); 115 skCanvas->restore();
116 } 116 }
117 } 117 }
118 } 118 }
119 119
120 CanvasRenderingContext2D::~CanvasRenderingContext2D() 120 CanvasRenderingContext2D::~CanvasRenderingContext2D()
121 { 121 {
122 } 122 }
123 123
124 void CanvasRenderingContext2D::validateStateStack() 124 void CanvasRenderingContext2D::validateStateStack()
125 { 125 {
126 #if ENABLE(ASSERT) 126 #if ENABLE(ASSERT)
127 GraphicsContext* context = canvas()->existingDrawingContext(); 127 SkCanvas* skCanvas = canvas()->existingDrawingCanvas();
128 if (context && !context->contextDisabled() && !m_isContextLost) 128 if (skCanvas && !m_isContextLost) {
129 ASSERT(context->saveCount() == m_stateStack.size()); 129 ASSERT(static_cast<size_t>(skCanvas->getSaveCount() - 1) == m_stateStack .size());
130 }
130 #endif 131 #endif
131 } 132 }
132 133
133 bool CanvasRenderingContext2D::isAccelerated() const 134 bool CanvasRenderingContext2D::isAccelerated() const
134 { 135 {
135 if (!canvas()->hasImageBuffer()) 136 if (!canvas()->hasImageBuffer())
136 return false; 137 return false;
137 GraphicsContext* context = drawingContext(); 138 return canvas()->buffer()->isAccelerated();
138 return context && context->isAccelerated();
139 } 139 }
140 140
141 bool CanvasRenderingContext2D::isContextLost() const 141 bool CanvasRenderingContext2D::isContextLost() const
142 { 142 {
143 return m_isContextLost; 143 return m_isContextLost;
144 } 144 }
145 145
146 void CanvasRenderingContext2D::loseContext() 146 void CanvasRenderingContext2D::loseContext()
147 { 147 {
148 if (m_isContextLost) 148 if (m_isContextLost)
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 validateStateStack(); 238 validateStateStack();
239 unwindStateStack(); 239 unwindStateStack();
240 m_stateStack.resize(1); 240 m_stateStack.resize(1);
241 m_stateStack.first() = adoptPtrWillBeNoop(new State()); 241 m_stateStack.first() = adoptPtrWillBeNoop(new State());
242 m_path.clear(); 242 m_path.clear();
243 validateStateStack(); 243 validateStateStack();
244 } 244 }
245 245
246 void CanvasRenderingContext2D::restoreCanvasMatrixClipStack() 246 void CanvasRenderingContext2D::restoreCanvasMatrixClipStack()
247 { 247 {
248 GraphicsContext* c = drawingContext(); 248 SkCanvas* c = drawingCanvas();
249 if (!c) 249 if (!c)
250 return; 250 return;
251 WillBeHeapVector<OwnPtrWillBeMember<State>>::iterator currState; 251 WillBeHeapVector<OwnPtrWillBeMember<State>>::iterator currState;
252 for (currState = m_stateStack.begin(); currState < m_stateStack.end(); currS tate++) { 252 for (currState = m_stateStack.begin(); currState < m_stateStack.end(); currS tate++) {
253 // We are only restoring state stored in the SkCanvas, and not 253 // The initial save accounts for the save installed by canvasElementElem ent::m_contextStateSaver
254 // state stored in the graphics context, so we call save() only on the c anvas. 254 c->save();
255 // The initial save accounts for the save installed by HTMLCanvasElement ::m_contextStateSaver
256 c->canvas()->save();
257 c->setMatrix(SkMatrix::I()); 255 c->setMatrix(SkMatrix::I());
258 currState->get()->m_clipList.playback(c); 256 currState->get()->m_clipList.playback(c);
259 c->setCTM(currState->get()->m_transform); 257 c->setMatrix(affineTransformToSkMatrix(currState->get()->m_transform));
260 } 258 }
261 } 259 }
262 260
263 // Important: Several of these properties are also stored in GraphicsContext's 261 // Important: Several of these properties are also stored in GraphicsContext's
264 // StrokeData. The default values that StrokeData uses may not the same values 262 // StrokeData. The default values that StrokeData uses may not the same values
265 // that the canvas 2d spec specifies. Make sure to sync the initial state of the 263 // that the canvas 2d spec specifies. Make sure to sync the initial state of the
266 // GraphicsContext in HTMLCanvasElement::createImageBuffer()! 264 // GraphicsContext in HTMLCanvasElement::createImageBuffer()!
267 CanvasRenderingContext2D::State::State() 265 CanvasRenderingContext2D::State::State()
268 : m_unrealizedSaveCount(0) 266 : m_unrealizedSaveCount(0)
269 , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black)) 267 , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black))
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 m_font.update(fontSelector); 379 m_font.update(fontSelector);
382 } 380 }
383 381
384 void CanvasRenderingContext2D::State::trace(Visitor* visitor) 382 void CanvasRenderingContext2D::State::trace(Visitor* visitor)
385 { 383 {
386 visitor->trace(m_strokeStyle); 384 visitor->trace(m_strokeStyle);
387 visitor->trace(m_fillStyle); 385 visitor->trace(m_fillStyle);
388 CSSFontSelectorClient::trace(visitor); 386 CSSFontSelectorClient::trace(visitor);
389 } 387 }
390 388
391 void CanvasRenderingContext2D::realizeSaves(GraphicsContext* context) 389 void CanvasRenderingContext2D::realizeSaves(SkCanvas* canvas)
392 { 390 {
393 validateStateStack(); 391 validateStateStack();
394 if (state().m_unrealizedSaveCount) { 392 if (state().m_unrealizedSaveCount) {
395 ASSERT(m_stateStack.size() >= 1); 393 ASSERT(m_stateStack.size() >= 1);
396 // Reduce the current state's unrealized count by one now, 394 // Reduce the current state's unrealized count by one now,
397 // to reflect the fact we are saving one state. 395 // to reflect the fact we are saving one state.
398 m_stateStack.last()->m_unrealizedSaveCount--; 396 m_stateStack.last()->m_unrealizedSaveCount--;
399 m_stateStack.append(adoptPtrWillBeNoop(new State(state(), DontCopyClipLi st))); 397 m_stateStack.append(adoptPtrWillBeNoop(new State(state(), DontCopyClipLi st)));
400 // Set the new state's unrealized count to 0, because it has no outstand ing saves. 398 // Set the new state's unrealized count to 0, because it has no outstand ing saves.
401 // We need to do this explicitly because the copy constructor and operat or= used 399 // We need to do this explicitly because the copy constructor and operat or= used
402 // by the Vector operations copy the unrealized count from the previous state (in 400 // by the Vector operations copy the unrealized count from the previous state (in
403 // turn necessary to support correct resizing and unwinding of the stack ). 401 // turn necessary to support correct resizing and unwinding of the stack ).
404 m_stateStack.last()->m_unrealizedSaveCount = 0; 402 m_stateStack.last()->m_unrealizedSaveCount = 0;
405 if (!context) 403 if (!canvas)
406 context = drawingContext(); 404 canvas = drawingCanvas();
407 if (context) 405 if (canvas)
408 context->save(); 406 canvas->save();
409 validateStateStack(); 407 validateStateStack();
410 } 408 }
411 } 409 }
412 410
413 void CanvasRenderingContext2D::restore() 411 void CanvasRenderingContext2D::restore()
414 { 412 {
415 validateStateStack(); 413 validateStateStack();
416 if (state().m_unrealizedSaveCount) { 414 if (state().m_unrealizedSaveCount) {
417 // We never realized the save, so just record that it was unnecessary. 415 // We never realized the save, so just record that it was unnecessary.
418 --m_stateStack.last()->m_unrealizedSaveCount; 416 --m_stateStack.last()->m_unrealizedSaveCount;
419 return; 417 return;
420 } 418 }
421 ASSERT(m_stateStack.size() >= 1); 419 ASSERT(m_stateStack.size() >= 1);
422 if (m_stateStack.size() <= 1) 420 if (m_stateStack.size() <= 1)
423 return; 421 return;
424 m_path.transform(state().m_transform); 422 m_path.transform(state().m_transform);
425 m_stateStack.removeLast(); 423 m_stateStack.removeLast();
426 m_path.transform(state().m_transform.inverse()); 424 m_path.transform(state().m_transform.inverse());
427 GraphicsContext* c = drawingContext(); 425 SkCanvas* c = drawingCanvas();
428 if (c) 426 if (c)
429 c->restore(); 427 c->restore();
428
429 // Temporary code while crbug.com/453113 is a WIP: GraphicsContext state sta ck
430 // is no longer exercised so state stored still stored in GC must be re-inst alled
431 // after a restore.
432 GraphicsContext* gc = drawingContext();
433 if (gc) {
434 state().m_fillStyle->applyFillColor(gc);
435 state().m_strokeStyle->applyStrokeColor(gc);
436 gc->setStrokeThickness(state().m_lineWidth);
437 gc->setLineCap(state().m_lineCap);
438 gc->setLineJoin(state().m_lineJoin);
439 gc->setMiterLimit(state().m_miterLimit);
440 applyLineDash();
441 gc->setAlphaAsFloat(state().m_globalAlpha);
442 gc->setCompositeOperation(state().m_globalComposite);
443 gc->setImageInterpolationQuality(state().m_imageSmoothingEnabled ? Canva sDefaultInterpolationQuality : InterpolationNone);
444 applyShadow();
445 }
446
430 validateStateStack(); 447 validateStateStack();
431 } 448 }
432 449
433 static inline void convertCanvasStyleToUnionType(CanvasStyle* style, StringOrCan vasGradientOrCanvasPattern& returnValue) 450 static inline void convertCanvasStyleToUnionType(CanvasStyle* style, StringOrCan vasGradientOrCanvasPattern& returnValue)
434 { 451 {
435 if (CanvasGradient* gradient = style->canvasGradient()) { 452 if (CanvasGradient* gradient = style->canvasGradient()) {
436 returnValue.setCanvasGradient(gradient); 453 returnValue.setCanvasGradient(gradient);
437 return; 454 return;
438 } 455 }
439 if (CanvasPattern* pattern = style->canvasPattern()) { 456 if (CanvasPattern* pattern = style->canvasPattern()) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 RefPtrWillBeRawPtr<CanvasPattern> canvasPattern = style.getAsCanvasPatte rn(); 490 RefPtrWillBeRawPtr<CanvasPattern> canvasPattern = style.getAsCanvasPatte rn();
474 491
475 if (canvas()->originClean() && !canvasPattern->originClean()) 492 if (canvas()->originClean() && !canvasPattern->originClean())
476 canvas()->setOriginTainted(); 493 canvas()->setOriginTainted();
477 494
478 canvasStyle = CanvasStyle::createFromPattern(canvasPattern); 495 canvasStyle = CanvasStyle::createFromPattern(canvasPattern);
479 } 496 }
480 497
481 ASSERT(canvasStyle); 498 ASSERT(canvasStyle);
482 499
483 GraphicsContext* c = drawingContext(); 500 SkCanvas* c = drawingCanvas();
484 realizeSaves(c); 501 realizeSaves(c);
485 modifiableState().m_strokeStyle = canvasStyle.release(); 502 modifiableState().m_strokeStyle = canvasStyle.release();
486 if (!c) 503 if (!c)
487 return; 504 return;
488 state().m_strokeStyle->applyStrokeColor(c); 505 state().m_strokeStyle->applyStrokeColor(drawingContext());
489 modifiableState().m_unparsedStrokeColor = colorString; 506 modifiableState().m_unparsedStrokeColor = colorString;
490 } 507 }
491 508
492 void CanvasRenderingContext2D::fillStyle(StringOrCanvasGradientOrCanvasPattern& returnValue) const 509 void CanvasRenderingContext2D::fillStyle(StringOrCanvasGradientOrCanvasPattern& returnValue) const
493 { 510 {
494 convertCanvasStyleToUnionType(state().m_fillStyle.get(), returnValue); 511 convertCanvasStyleToUnionType(state().m_fillStyle.get(), returnValue);
495 } 512 }
496 513
497 void CanvasRenderingContext2D::setFillStyle(const StringOrCanvasGradientOrCanvas Pattern& style) 514 void CanvasRenderingContext2D::setFillStyle(const StringOrCanvasGradientOrCanvas Pattern& style)
498 { 515 {
499 ASSERT(!style.isNull()); 516 ASSERT(!style.isNull());
500 517 validateStateStack();
501 String colorString; 518 String colorString;
502 RefPtrWillBeRawPtr<CanvasStyle> canvasStyle; 519 RefPtrWillBeRawPtr<CanvasStyle> canvasStyle;
503 if (style.isString()) { 520 if (style.isString()) {
504 colorString = style.getAsString(); 521 colorString = style.getAsString();
505 if (colorString == state().m_unparsedFillColor) 522 if (colorString == state().m_unparsedFillColor)
506 return; 523 return;
507 RGBA32 parsedColor = 0; 524 RGBA32 parsedColor = 0;
508 if (!parseColorOrCurrentColor(parsedColor, colorString, canvas())) 525 if (!parseColorOrCurrentColor(parsedColor, colorString, canvas()))
509 return; 526 return;
510 if (state().m_fillStyle->isEquivalentRGBA(parsedColor)) { 527 if (state().m_fillStyle->isEquivalentRGBA(parsedColor)) {
511 realizeSaves(nullptr); 528 realizeSaves(nullptr);
512 modifiableState().m_unparsedFillColor = colorString; 529 modifiableState().m_unparsedFillColor = colorString;
513 return; 530 return;
514 } 531 }
515 canvasStyle = CanvasStyle::createFromRGBA(parsedColor); 532 canvasStyle = CanvasStyle::createFromRGBA(parsedColor);
516 } else if (style.isCanvasGradient()) { 533 } else if (style.isCanvasGradient()) {
517 canvasStyle = CanvasStyle::createFromGradient(style.getAsCanvasGradient( )); 534 canvasStyle = CanvasStyle::createFromGradient(style.getAsCanvasGradient( ));
518 } else if (style.isCanvasPattern()) { 535 } else if (style.isCanvasPattern()) {
519 RefPtrWillBeRawPtr<CanvasPattern> canvasPattern = style.getAsCanvasPatte rn(); 536 RefPtrWillBeRawPtr<CanvasPattern> canvasPattern = style.getAsCanvasPatte rn();
520 537
521 if (canvas()->originClean() && !canvasPattern->originClean()) 538 if (canvas()->originClean() && !canvasPattern->originClean())
522 canvas()->setOriginTainted(); 539 canvas()->setOriginTainted();
523 540
524 canvasStyle = CanvasStyle::createFromPattern(canvasPattern); 541 canvasStyle = CanvasStyle::createFromPattern(canvasPattern);
525 } 542 }
526 543
527 ASSERT(canvasStyle); 544 ASSERT(canvasStyle);
528 545
529 GraphicsContext* c = drawingContext(); 546 SkCanvas* c = drawingCanvas();
530 realizeSaves(c); 547 realizeSaves(c);
531 modifiableState().m_fillStyle = canvasStyle.release(); 548 modifiableState().m_fillStyle = canvasStyle.release();
532 if (!c) 549 if (!c)
533 return; 550 return;
534 state().m_fillStyle->applyFillColor(c); 551 state().m_fillStyle->applyFillColor(drawingContext());
535 modifiableState().m_unparsedFillColor = colorString; 552 modifiableState().m_unparsedFillColor = colorString;
536 } 553 }
537 554
538 float CanvasRenderingContext2D::lineWidth() const 555 float CanvasRenderingContext2D::lineWidth() const
539 { 556 {
540 return state().m_lineWidth; 557 return state().m_lineWidth;
541 } 558 }
542 559
543 void CanvasRenderingContext2D::setLineWidth(float width) 560 void CanvasRenderingContext2D::setLineWidth(float width)
544 { 561 {
545 if (!std::isfinite(width) || width <= 0) 562 if (!std::isfinite(width) || width <= 0)
546 return; 563 return;
547 if (state().m_lineWidth == width) 564 if (state().m_lineWidth == width)
548 return; 565 return;
549 GraphicsContext* c = drawingContext(); 566 SkCanvas* c = drawingCanvas();
550 realizeSaves(c); 567 realizeSaves(c);
551 modifiableState().m_lineWidth = width; 568 modifiableState().m_lineWidth = width;
552 if (!c) 569 if (!c)
553 return; 570 return;
554 c->setStrokeThickness(width); 571 drawingContext()->setStrokeThickness(width);
555 } 572 }
556 573
557 String CanvasRenderingContext2D::lineCap() const 574 String CanvasRenderingContext2D::lineCap() const
558 { 575 {
559 return lineCapName(state().m_lineCap); 576 return lineCapName(state().m_lineCap);
560 } 577 }
561 578
562 void CanvasRenderingContext2D::setLineCap(const String& s) 579 void CanvasRenderingContext2D::setLineCap(const String& s)
563 { 580 {
564 LineCap cap; 581 LineCap cap;
565 if (!parseLineCap(s, cap)) 582 if (!parseLineCap(s, cap))
566 return; 583 return;
567 if (state().m_lineCap == cap) 584 if (state().m_lineCap == cap)
568 return; 585 return;
569 GraphicsContext* c = drawingContext(); 586 SkCanvas* c = drawingCanvas();
570 realizeSaves(c); 587 realizeSaves(c);
571 modifiableState().m_lineCap = cap; 588 modifiableState().m_lineCap = cap;
572 if (!c) 589 if (!c)
573 return; 590 return;
574 c->setLineCap(cap); 591 drawingContext()->setLineCap(cap);
575 } 592 }
576 593
577 String CanvasRenderingContext2D::lineJoin() const 594 String CanvasRenderingContext2D::lineJoin() const
578 { 595 {
579 return lineJoinName(state().m_lineJoin); 596 return lineJoinName(state().m_lineJoin);
580 } 597 }
581 598
582 void CanvasRenderingContext2D::setLineJoin(const String& s) 599 void CanvasRenderingContext2D::setLineJoin(const String& s)
583 { 600 {
584 LineJoin join; 601 LineJoin join;
585 if (!parseLineJoin(s, join)) 602 if (!parseLineJoin(s, join))
586 return; 603 return;
587 if (state().m_lineJoin == join) 604 if (state().m_lineJoin == join)
588 return; 605 return;
589 GraphicsContext* c = drawingContext(); 606 SkCanvas* c = drawingCanvas();
590 realizeSaves(c); 607 realizeSaves(c);
591 modifiableState().m_lineJoin = join; 608 modifiableState().m_lineJoin = join;
592 if (!c) 609 if (!c)
593 return; 610 return;
594 c->setLineJoin(join); 611 drawingContext()->setLineJoin(join);
595 } 612 }
596 613
597 float CanvasRenderingContext2D::miterLimit() const 614 float CanvasRenderingContext2D::miterLimit() const
598 { 615 {
599 return state().m_miterLimit; 616 return state().m_miterLimit;
600 } 617 }
601 618
602 void CanvasRenderingContext2D::setMiterLimit(float limit) 619 void CanvasRenderingContext2D::setMiterLimit(float limit)
603 { 620 {
604 if (!std::isfinite(limit) || limit <= 0) 621 if (!std::isfinite(limit) || limit <= 0)
605 return; 622 return;
606 if (state().m_miterLimit == limit) 623 if (state().m_miterLimit == limit)
607 return; 624 return;
608 GraphicsContext* c = drawingContext(); 625 SkCanvas* c = drawingCanvas();
609 realizeSaves(c); 626 realizeSaves(c);
610 modifiableState().m_miterLimit = limit; 627 modifiableState().m_miterLimit = limit;
611 if (!c) 628 if (!c)
612 return; 629 return;
613 c->setMiterLimit(limit); 630 drawingContext()->setMiterLimit(limit);
614 } 631 }
615 632
616 float CanvasRenderingContext2D::shadowOffsetX() const 633 float CanvasRenderingContext2D::shadowOffsetX() const
617 { 634 {
618 return state().m_shadowOffset.width(); 635 return state().m_shadowOffset.width();
619 } 636 }
620 637
621 void CanvasRenderingContext2D::setShadowOffsetX(float x) 638 void CanvasRenderingContext2D::setShadowOffsetX(float x)
622 { 639 {
623 if (!std::isfinite(x)) 640 if (!std::isfinite(x))
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 { 754 {
738 return state().m_globalAlpha; 755 return state().m_globalAlpha;
739 } 756 }
740 757
741 void CanvasRenderingContext2D::setGlobalAlpha(float alpha) 758 void CanvasRenderingContext2D::setGlobalAlpha(float alpha)
742 { 759 {
743 if (!(alpha >= 0 && alpha <= 1)) 760 if (!(alpha >= 0 && alpha <= 1))
744 return; 761 return;
745 if (state().m_globalAlpha == alpha) 762 if (state().m_globalAlpha == alpha)
746 return; 763 return;
747 GraphicsContext* c = drawingContext(); 764 SkCanvas* c = drawingCanvas();
748 realizeSaves(c); 765 realizeSaves(c);
749 modifiableState().m_globalAlpha = alpha; 766 modifiableState().m_globalAlpha = alpha;
750 if (!c) 767 if (!c)
751 return; 768 return;
752 c->setAlphaAsFloat(alpha); 769 drawingContext()->setAlphaAsFloat(alpha);
753 } 770 }
754 771
755 String CanvasRenderingContext2D::globalCompositeOperation() const 772 String CanvasRenderingContext2D::globalCompositeOperation() const
756 { 773 {
757 return compositeOperatorName(compositeOperatorFromSkia(state().m_globalCompo site), blendModeFromSkia(state().m_globalComposite)); 774 return compositeOperatorName(compositeOperatorFromSkia(state().m_globalCompo site), blendModeFromSkia(state().m_globalComposite));
758 } 775 }
759 776
760 void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati on) 777 void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati on)
761 { 778 {
762 CompositeOperator op = CompositeSourceOver; 779 CompositeOperator op = CompositeSourceOver;
763 WebBlendMode blendMode = WebBlendModeNormal; 780 WebBlendMode blendMode = WebBlendModeNormal;
764 if (!parseCompositeAndBlendOperator(operation, op, blendMode)) 781 if (!parseCompositeAndBlendOperator(operation, op, blendMode))
765 return; 782 return;
766 SkXfermode::Mode xfermode = WebCoreCompositeToSkiaComposite(op, blendMode); 783 SkXfermode::Mode xfermode = WebCoreCompositeToSkiaComposite(op, blendMode);
767 if (state().m_globalComposite == xfermode) 784 if (state().m_globalComposite == xfermode)
768 return; 785 return;
769 GraphicsContext* c = drawingContext(); 786 SkCanvas* c = drawingCanvas();
770 realizeSaves(c); 787 realizeSaves(c);
771 modifiableState().m_globalComposite = xfermode; 788 modifiableState().m_globalComposite = xfermode;
772 if (!c) 789 if (!c)
773 return; 790 return;
774 c->setCompositeOperation(xfermode); 791 drawingContext()->setCompositeOperation(xfermode);
775 } 792 }
776 793
777 void CanvasRenderingContext2D::setCurrentTransform(PassRefPtrWillBeRawPtr<SVGMat rixTearOff> passMatrixTearOff) 794 void CanvasRenderingContext2D::setCurrentTransform(PassRefPtrWillBeRawPtr<SVGMat rixTearOff> passMatrixTearOff)
778 { 795 {
779 RefPtrWillBeRawPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff; 796 RefPtrWillBeRawPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff;
780 const AffineTransform& transform = matrixTearOff->value(); 797 const AffineTransform& transform = matrixTearOff->value();
781 setTransform(transform.a(), transform.b(), transform.c(), transform.d(), tra nsform.e(), transform.f()); 798 setTransform(transform.a(), transform.b(), transform.c(), transform.d(), tra nsform.e(), transform.f());
782 } 799 }
783 800
784 void CanvasRenderingContext2D::scale(float sx, float sy) 801 void CanvasRenderingContext2D::scale(float sx, float sy)
785 { 802 {
786 GraphicsContext* c = drawingContext(); 803 SkCanvas* c = drawingCanvas();
787 if (!c) 804 if (!c)
788 return; 805 return;
789 if (!state().m_invertibleCTM) 806 if (!state().m_invertibleCTM)
790 return; 807 return;
791 808
792 if (!std::isfinite(sx) || !std::isfinite(sy)) 809 if (!std::isfinite(sx) || !std::isfinite(sy))
793 return; 810 return;
794 811
795 AffineTransform newTransform = state().m_transform; 812 AffineTransform newTransform = state().m_transform;
796 newTransform.scaleNonUniform(sx, sy); 813 newTransform.scaleNonUniform(sx, sy);
797 if (state().m_transform == newTransform) 814 if (state().m_transform == newTransform)
798 return; 815 return;
799 816
800 realizeSaves(c); 817 realizeSaves(c);
801 818
802 if (!newTransform.isInvertible()) { 819 if (!newTransform.isInvertible()) {
803 modifiableState().m_invertibleCTM = false; 820 modifiableState().m_invertibleCTM = false;
804 return; 821 return;
805 } 822 }
806 823
807 modifiableState().m_transform = newTransform; 824 modifiableState().m_transform = newTransform;
808 c->scale(sx, sy); 825 c->scale(sx, sy);
809 m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy)); 826 m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy));
810 } 827 }
811 828
812 void CanvasRenderingContext2D::rotate(float angleInRadians) 829 void CanvasRenderingContext2D::rotate(float angleInRadians)
813 { 830 {
814 GraphicsContext* c = drawingContext(); 831 SkCanvas* c = drawingCanvas();
815 if (!c) 832 if (!c)
816 return; 833 return;
817 if (!state().m_invertibleCTM) 834 if (!state().m_invertibleCTM)
818 return; 835 return;
819 836
820 if (!std::isfinite(angleInRadians)) 837 if (!std::isfinite(angleInRadians))
821 return; 838 return;
822 839
823 AffineTransform newTransform = state().m_transform; 840 AffineTransform newTransform = state().m_transform;
824 newTransform.rotateRadians(angleInRadians); 841 newTransform.rotateRadians(angleInRadians);
825 if (state().m_transform == newTransform) 842 if (state().m_transform == newTransform)
826 return; 843 return;
827 844
828 realizeSaves(c); 845 realizeSaves(c);
829 846
830 if (!newTransform.isInvertible()) { 847 if (!newTransform.isInvertible()) {
831 modifiableState().m_invertibleCTM = false; 848 modifiableState().m_invertibleCTM = false;
832 return; 849 return;
833 } 850 }
834 851
835 modifiableState().m_transform = newTransform; 852 modifiableState().m_transform = newTransform;
836 c->rotate(angleInRadians); 853 c->rotate(angleInRadians * (180.0f / piFloat));
837 m_path.transform(AffineTransform().rotateRadians(-angleInRadians)); 854 m_path.transform(AffineTransform().rotateRadians(-angleInRadians));
838 } 855 }
839 856
840 void CanvasRenderingContext2D::translate(float tx, float ty) 857 void CanvasRenderingContext2D::translate(float tx, float ty)
841 { 858 {
842 GraphicsContext* c = drawingContext(); 859 SkCanvas* c = drawingCanvas();
843 if (!c) 860 if (!c)
844 return; 861 return;
845 if (!state().m_invertibleCTM) 862 if (!state().m_invertibleCTM)
846 return; 863 return;
847 864
848 if (!std::isfinite(tx) || !std::isfinite(ty)) 865 if (!std::isfinite(tx) || !std::isfinite(ty))
849 return; 866 return;
850 867
851 AffineTransform newTransform = state().m_transform; 868 AffineTransform newTransform = state().m_transform;
852 newTransform.translate(tx, ty); 869 newTransform.translate(tx, ty);
853 if (state().m_transform == newTransform) 870 if (state().m_transform == newTransform)
854 return; 871 return;
855 872
856 realizeSaves(c); 873 realizeSaves(c);
857 874
858 if (!newTransform.isInvertible()) { 875 if (!newTransform.isInvertible()) {
859 modifiableState().m_invertibleCTM = false; 876 modifiableState().m_invertibleCTM = false;
860 return; 877 return;
861 } 878 }
862 879
863 modifiableState().m_transform = newTransform; 880 modifiableState().m_transform = newTransform;
864 c->translate(tx, ty); 881 c->translate(tx, ty);
865 m_path.transform(AffineTransform().translate(-tx, -ty)); 882 m_path.transform(AffineTransform().translate(-tx, -ty));
866 } 883 }
867 884
868 void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float m22, float dx, float dy) 885 void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float m22, float dx, float dy)
869 { 886 {
870 GraphicsContext* c = drawingContext(); 887 SkCanvas* c = drawingCanvas();
871 if (!c) 888 if (!c)
872 return; 889 return;
873 if (!state().m_invertibleCTM) 890 if (!state().m_invertibleCTM)
874 return; 891 return;
875 892
876 if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || !std ::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy)) 893 if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || !std ::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy))
877 return; 894 return;
878 895
879 AffineTransform transform(m11, m12, m21, m22, dx, dy); 896 AffineTransform transform(m11, m12, m21, m22, dx, dy);
880 AffineTransform newTransform = state().m_transform * transform; 897 AffineTransform newTransform = state().m_transform * transform;
881 if (state().m_transform == newTransform) 898 if (state().m_transform == newTransform)
882 return; 899 return;
883 900
884 realizeSaves(c); 901 realizeSaves(c);
885 902
886 modifiableState().m_transform = newTransform; 903 modifiableState().m_transform = newTransform;
887 if (!newTransform.isInvertible()) { 904 if (!newTransform.isInvertible()) {
888 modifiableState().m_invertibleCTM = false; 905 modifiableState().m_invertibleCTM = false;
889 return; 906 return;
890 } 907 }
891 908
892 c->concatCTM(transform); 909 c->concat(affineTransformToSkMatrix(transform));
893 m_path.transform(transform.inverse()); 910 m_path.transform(transform.inverse());
894 } 911 }
895 912
896 void CanvasRenderingContext2D::resetTransform() 913 void CanvasRenderingContext2D::resetTransform()
897 { 914 {
898 GraphicsContext* c = drawingContext(); 915 SkCanvas* c = drawingCanvas();
899 if (!c) 916 if (!c)
900 return; 917 return;
901 918
902 AffineTransform ctm = state().m_transform; 919 AffineTransform ctm = state().m_transform;
903 bool invertibleCTM = state().m_invertibleCTM; 920 bool invertibleCTM = state().m_invertibleCTM;
904 // It is possible that CTM is identity while CTM is not invertible. 921 // It is possible that CTM is identity while CTM is not invertible.
905 // When CTM becomes non-invertible, realizeSaves() can make CTM identity. 922 // When CTM becomes non-invertible, realizeSaves() can make CTM identity.
906 if (ctm.isIdentity() && invertibleCTM) 923 if (ctm.isIdentity() && invertibleCTM)
907 return; 924 return;
908 925
909 realizeSaves(c); 926 realizeSaves(c);
910 // resetTransform() resolves the non-invertible CTM state. 927 // resetTransform() resolves the non-invertible CTM state.
911 modifiableState().m_transform.makeIdentity(); 928 modifiableState().m_transform.makeIdentity();
912 modifiableState().m_invertibleCTM = true; 929 modifiableState().m_invertibleCTM = true;
913 c->setCTM(canvas()->baseTransform()); 930 c->setMatrix(affineTransformToSkMatrix(canvas()->baseTransform()));
914 931
915 if (invertibleCTM) 932 if (invertibleCTM)
916 m_path.transform(ctm); 933 m_path.transform(ctm);
917 // When else, do nothing because all transform methods didn't update m_path when CTM became non-invertible. 934 // When else, do nothing because all transform methods didn't update m_path when CTM became non-invertible.
918 // It means that resetTransform() restores m_path just before CTM became non -invertible. 935 // It means that resetTransform() restores m_path just before CTM became non -invertible.
919 } 936 }
920 937
921 void CanvasRenderingContext2D::setTransform(float m11, float m12, float m21, flo at m22, float dx, float dy) 938 void CanvasRenderingContext2D::setTransform(float m11, float m12, float m21, flo at m22, float dx, float dy)
922 { 939 {
923 GraphicsContext* c = drawingContext(); 940 SkCanvas* c = drawingCanvas();
924 if (!c) 941 if (!c)
925 return; 942 return;
926 943
927 if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || !std ::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy)) 944 if (!std::isfinite(m11) || !std::isfinite(m21) || !std::isfinite(dx) || !std ::isfinite(m12) || !std::isfinite(m22) || !std::isfinite(dy))
928 return; 945 return;
929 946
930 resetTransform(); 947 resetTransform();
931 transform(m11, m12, m21, m22, dx, dy); 948 transform(m11, m12, m21, m22, dx, dy);
932 } 949 }
933 950
(...skipping 24 matching lines...) Expand all
958 } 975 }
959 976
960 static bool isFullCanvasCompositeMode(SkXfermode::Mode op) 977 static bool isFullCanvasCompositeMode(SkXfermode::Mode op)
961 { 978 {
962 // See 4.8.11.1.3 Compositing 979 // See 4.8.11.1.3 Compositing
963 // CompositeSourceAtop and CompositeDestinationOut are not listed here as th e platforms already 980 // CompositeSourceAtop and CompositeDestinationOut are not listed here as th e platforms already
964 // implement the specification's behavior. 981 // implement the specification's behavior.
965 return op == SkXfermode::kSrcIn_Mode || op == SkXfermode::kSrcOut_Mode || op == SkXfermode::kDstIn_Mode || op == SkXfermode::kDstATop_Mode; 982 return op == SkXfermode::kSrcIn_Mode || op == SkXfermode::kSrcOut_Mode || op == SkXfermode::kDstIn_Mode || op == SkXfermode::kDstATop_Mode;
966 } 983 }
967 984
968 static WindRule parseWinding(const String& windingRuleString) 985 static SkPath::FillType parseWinding(const String& windingRuleString)
969 { 986 {
970 if (windingRuleString == "nonzero") 987 if (windingRuleString == "nonzero")
971 return RULE_NONZERO; 988 return SkPath::kWinding_FillType;
972 if (windingRuleString == "evenodd") 989 if (windingRuleString == "evenodd")
973 return RULE_EVENODD; 990 return SkPath::kEvenOdd_FillType;
974 991
975 ASSERT_NOT_REACHED(); 992 ASSERT_NOT_REACHED();
976 return RULE_EVENODD; 993 return SkPath::kEvenOdd_FillType;
977 } 994 }
978 995
979 void CanvasRenderingContext2D::fillInternal(const Path& path, const String& wind ingRuleString) 996 void CanvasRenderingContext2D::fillInternal(const Path& path, const String& wind ingRuleString)
980 { 997 {
981 if (path.isEmpty()) { 998 if (path.isEmpty()) {
982 return; 999 return;
983 } 1000 }
984 GraphicsContext* c = drawingContext(); 1001 GraphicsContext* c = drawingContext();
985 if (!c) { 1002 if (!c) {
986 return; 1003 return;
987 } 1004 }
988 if (!state().m_invertibleCTM) { 1005 if (!state().m_invertibleCTM) {
989 return; 1006 return;
990 } 1007 }
991 FloatRect clipBounds; 1008 FloatRect clipBounds;
992 if (!c->getTransformedClipBounds(&clipBounds)) { 1009 if (!c->getTransformedClipBounds(&clipBounds)) {
993 return; 1010 return;
994 } 1011 }
995 1012
996 // If gradient size is zero, then paint nothing. 1013 // If gradient size is zero, then paint nothing.
997 Gradient* gradient = c->fillGradient(); 1014 Gradient* gradient = c->fillGradient();
998 if (gradient && gradient->isZeroSize()) { 1015 if (gradient && gradient->isZeroSize()) {
999 return; 1016 return;
1000 } 1017 }
1001 1018
1002 WindRule windRule = c->fillRule(); 1019 WindRule windRule = c->fillRule();
1003 c->setFillRule(parseWinding(windingRuleString)); 1020 c->setFillRule(SkFillTypeToWindRule(parseWinding(windingRuleString)));
1004 1021
1005 if (isFullCanvasCompositeMode(state().m_globalComposite)) { 1022 if (isFullCanvasCompositeMode(state().m_globalComposite)) {
1006 fullCanvasCompositedDraw(bind(&GraphicsContext::fillPath, c, path)); 1023 fullCanvasCompositedDraw(bind(&GraphicsContext::fillPath, c, path));
1007 didDraw(clipBounds); 1024 didDraw(clipBounds);
1008 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) { 1025 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) {
1009 clearCanvas(); 1026 clearCanvas();
1010 c->clearShadow(); 1027 c->clearShadow();
1011 c->fillPath(path); 1028 c->fillPath(path);
1012 applyShadow(DrawShadowAndForeground); 1029 applyShadow(DrawShadowAndForeground);
1013 didDraw(clipBounds); 1030 didDraw(clipBounds);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 strokeInternal(m_path); 1096 strokeInternal(m_path);
1080 } 1097 }
1081 1098
1082 void CanvasRenderingContext2D::stroke(Path2D* domPath) 1099 void CanvasRenderingContext2D::stroke(Path2D* domPath)
1083 { 1100 {
1084 strokeInternal(domPath->path()); 1101 strokeInternal(domPath->path());
1085 } 1102 }
1086 1103
1087 void CanvasRenderingContext2D::clipInternal(const Path& path, const String& wind ingRuleString) 1104 void CanvasRenderingContext2D::clipInternal(const Path& path, const String& wind ingRuleString)
1088 { 1105 {
1089 GraphicsContext* c = drawingContext(); 1106 SkCanvas* c = drawingCanvas();
1090 if (!c) { 1107 if (!c) {
1091 return; 1108 return;
1092 } 1109 }
1093 if (!state().m_invertibleCTM) { 1110 if (!state().m_invertibleCTM) {
1094 return; 1111 return;
1095 } 1112 }
1096 1113
1097 realizeSaves(c); 1114 realizeSaves(c);
1098 1115
1099 WindRule windRule = parseWinding(windingRuleString); 1116 SkPath skPath = path.skPath();
1117 skPath.setFillType(parseWinding(windingRuleString));
1100 ImageBuffer* buffer = canvas()->buffer(); 1118 ImageBuffer* buffer = canvas()->buffer();
1101 if (buffer && buffer->needsClipTracking()) { 1119 if (buffer && buffer->needsClipTracking()) {
1102 modifiableState().m_clipList.clipPath(path, windRule, m_clipAntialiasing , state().m_transform); 1120 modifiableState().m_clipList.clipPath(skPath, m_clipAntialiasing, affine TransformToSkMatrix(state().m_transform));
1103 } 1121 }
1104 c->clipPath(path, windRule, m_clipAntialiasing); 1122
1123 c->clipPath(skPath, SkRegion::kIntersect_Op, m_clipAntialiasing == AntiAlias ed);
1124 if (!skPath.isRect(0))
1125 drawingContext()->setHasComplexClip();
1105 modifiableState().m_hasClip = true; 1126 modifiableState().m_hasClip = true;
1106 } 1127 }
1107 1128
1108 void CanvasRenderingContext2D::clip(const String& windingRuleString) 1129 void CanvasRenderingContext2D::clip(const String& windingRuleString)
1109 { 1130 {
1110 clipInternal(m_path, windingRuleString); 1131 clipInternal(m_path, windingRuleString);
1111 } 1132 }
1112 1133
1113 void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleSt ring) 1134 void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleSt ring)
1114 { 1135 {
1115 clipInternal(domPath->path(), windingRuleString); 1136 clipInternal(domPath->path(), windingRuleString);
1116 } 1137 }
1117 1138
1118 bool CanvasRenderingContext2D::isPointInPath(const float x, const float y, const String& windingRuleString) 1139 bool CanvasRenderingContext2D::isPointInPath(const float x, const float y, const String& windingRuleString)
1119 { 1140 {
1120 return isPointInPathInternal(m_path, x, y, windingRuleString); 1141 return isPointInPathInternal(m_path, x, y, windingRuleString);
1121 } 1142 }
1122 1143
1123 bool CanvasRenderingContext2D::isPointInPath(Path2D* domPath, const float x, con st float y, const String& windingRuleString) 1144 bool CanvasRenderingContext2D::isPointInPath(Path2D* domPath, const float x, con st float y, const String& windingRuleString)
1124 { 1145 {
1125 return isPointInPathInternal(domPath->path(), x, y, windingRuleString); 1146 return isPointInPathInternal(domPath->path(), x, y, windingRuleString);
1126 } 1147 }
1127 1148
1128 bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, const flo at x, const float y, const String& windingRuleString) 1149 bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, const flo at x, const float y, const String& windingRuleString)
1129 { 1150 {
1130 GraphicsContext* c = drawingContext(); 1151 SkCanvas* c = drawingCanvas();
1131 if (!c) 1152 if (!c)
1132 return false; 1153 return false;
1133 if (!state().m_invertibleCTM) 1154 if (!state().m_invertibleCTM)
1134 return false; 1155 return false;
1135 1156
1136 FloatPoint point(x, y); 1157 FloatPoint point(x, y);
1137 if (!std::isfinite(point.x()) || !std::isfinite(point.y())) 1158 if (!std::isfinite(point.x()) || !std::isfinite(point.y()))
1138 return false; 1159 return false;
1139 AffineTransform ctm = state().m_transform; 1160 AffineTransform ctm = state().m_transform;
1140 FloatPoint transformedPoint = ctm.inverse().mapPoint(point); 1161 FloatPoint transformedPoint = ctm.inverse().mapPoint(point);
1141 1162
1142 return path.contains(transformedPoint, parseWinding(windingRuleString)); 1163 return path.contains(transformedPoint, SkFillTypeToWindRule(parseWinding(win dingRuleString)));
1143 } 1164 }
1144 1165
1145 bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y) 1166 bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y)
1146 { 1167 {
1147 return isPointInStrokeInternal(m_path, x, y); 1168 return isPointInStrokeInternal(m_path, x, y);
1148 } 1169 }
1149 1170
1150 bool CanvasRenderingContext2D::isPointInStroke(Path2D* domPath, const float x, c onst float y) 1171 bool CanvasRenderingContext2D::isPointInStroke(Path2D* domPath, const float x, c onst float y)
1151 { 1172 {
1152 return isPointInStrokeInternal(domPath->path(), x, y); 1173 return isPointInStrokeInternal(domPath->path(), x, y);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 if (!context) 1240 if (!context)
1220 return; 1241 return;
1221 if (!state().m_invertibleCTM) 1242 if (!state().m_invertibleCTM)
1222 return; 1243 return;
1223 FloatRect rect(x, y, width, height); 1244 FloatRect rect(x, y, width, height);
1224 1245
1225 FloatRect dirtyRect; 1246 FloatRect dirtyRect;
1226 if (!computeDirtyRect(rect, &dirtyRect)) 1247 if (!computeDirtyRect(rect, &dirtyRect))
1227 return; 1248 return;
1228 1249
1229 bool saved = false; 1250 context->clearShadow();
1230 if (shouldDrawShadows()) { 1251 context->setAlphaAsFloat(1);
1231 context->save(); 1252 context->setCompositeOperation(SkXfermode::kSrcOver_Mode);
1232 saved = true; 1253
1233 context->clearShadow();
1234 }
1235 if (state().m_globalAlpha != 1) {
1236 if (!saved) {
1237 context->save();
1238 saved = true;
1239 }
1240 context->setAlphaAsFloat(1);
1241 }
1242 if (state().m_globalComposite != SkXfermode::kSrcOver_Mode) {
1243 if (!saved) {
1244 context->save();
1245 saved = true;
1246 }
1247 context->setCompositeOperation(SkXfermode::kSrcOver_Mode);
1248 }
1249 context->clearRect(rect); 1254 context->clearRect(rect);
1250 if (m_hitRegionManager) 1255 if (m_hitRegionManager)
1251 m_hitRegionManager->removeHitRegionsInRect(rect, state().m_transform); 1256 m_hitRegionManager->removeHitRegionsInRect(rect, state().m_transform);
1252 if (saved) 1257
1253 context->restore(); 1258 applyShadow(DrawShadowAndForeground);
1259 context->setAlphaAsFloat(state().m_globalAlpha);
1260 context->setCompositeOperation(state().m_globalComposite);
1254 1261
1255 validateStateStack(); 1262 validateStateStack();
1256 didDraw(dirtyRect); 1263 didDraw(dirtyRect);
1257 } 1264 }
1258 1265
1259 // FIXME(crbug.com/425531): Funtional.h cannot handle override function signatur e. 1266 // FIXME(crbug.com/425531): Funtional.h cannot handle override function signatur e.
1260 static void fillRectOnContext(GraphicsContext* context, const FloatRect& rect) 1267 static void fillRectOnContext(GraphicsContext* context, const FloatRect& rect)
1261 { 1268 {
1262 context->fillRect(rect); 1269 context->fillRect(rect);
1263 } 1270 }
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 } 1437 }
1431 1438
1432 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, 1439 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce,
1433 float sx, float sy, float sw, float sh, 1440 float sx, float sy, float sw, float sh,
1434 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) 1441 float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
1435 { 1442 {
1436 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource); 1443 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource);
1437 drawImageInternal(imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, dh, excep tionState); 1444 drawImageInternal(imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, dh, excep tionState);
1438 } 1445 }
1439 1446
1440 static void drawVideo(GraphicsContext* c, CanvasImageSource* imageSource, FloatR ect srcRect, FloatRect dstRect) 1447 static void drawVideo(SkCanvas* c, GraphicsContext* gc, CanvasImageSource* image Source, FloatRect srcRect, FloatRect dstRect)
1441 { 1448 {
1442 HTMLVideoElement* video = static_cast<HTMLVideoElement*>(imageSource); 1449 HTMLVideoElement* video = static_cast<HTMLVideoElement*>(imageSource);
1443 GraphicsContextStateSaver stateSaver(*c); 1450 c->save();
1444 c->clip(dstRect); 1451 c->clipRect(WebCoreFloatRectToSKRect(dstRect));
1445 c->translate(dstRect.x(), dstRect.y()); 1452 c->translate(dstRect.x(), dstRect.y());
1446 c->scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.heigh t()); 1453 c->scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.heigh t());
1447 c->translate(-srcRect.x(), -srcRect.y()); 1454 c->translate(-srcRect.x(), -srcRect.y());
1448 video->paintCurrentFrameInContext(c, IntRect(IntPoint(), IntSize(video->vide oWidth(), video->videoHeight()))); 1455 video->paintCurrentFrameInContext(gc, IntRect(IntPoint(), IntSize(video->vid eoWidth(), video->videoHeight())));
1449 stateSaver.restore(); 1456 c->restore();
1450 } 1457 }
1451 1458
1452 static void drawImageOnContext(GraphicsContext* c, CanvasImageSource* imageSourc e, Image* image, const FloatRect& srcRect, const FloatRect& dstRect) 1459 static void drawImageOnContext(SkCanvas* c, GraphicsContext* gc, CanvasImageSour ce* imageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRec t)
1453 { 1460 {
1454 if (!imageSource->isVideoElement()) { 1461 if (!imageSource->isVideoElement()) {
1455 c->drawImage(image, dstRect, srcRect, c->compositeOperation()); 1462 gc->drawImage(image, dstRect, srcRect, gc->compositeOperation());
1456 } else { 1463 } else {
1457 drawVideo(c, static_cast<HTMLVideoElement*>(imageSource), srcRect, dstRe ct); 1464 drawVideo(c, gc, static_cast<HTMLVideoElement*>(imageSource), srcRect, d stRect);
1458 } 1465 }
1459 } 1466 }
1460 1467
1461 void CanvasRenderingContext2D::drawImageInternal(CanvasImageSource* imageSource, 1468 void CanvasRenderingContext2D::drawImageInternal(CanvasImageSource* imageSource,
1462 float sx, float sy, float sw, float sh, 1469 float sx, float sy, float sw, float sh,
1463 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) 1470 float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
1464 { 1471 {
1465 RefPtr<Image> image; 1472 RefPtr<Image> image;
1466 SourceImageStatus sourceImageStatus = InvalidSourceImageStatus; 1473 SourceImageStatus sourceImageStatus = InvalidSourceImageStatus;
1467 if (!imageSource->isVideoElement()) { 1474 if (!imageSource->isVideoElement()) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 1511
1505 // FIXME: crbug.com/447218 1512 // FIXME: crbug.com/447218
1506 // We make the destination canvas fall out of display list mode by calling 1513 // We make the destination canvas fall out of display list mode by calling
1507 // willAccessPixels. This is to prevent run-away memory consumption caused b y SkSurface 1514 // willAccessPixels. This is to prevent run-away memory consumption caused b y SkSurface
1508 // copyOnWrite when the source canvas is animated and consumed at a rate hig her than the 1515 // copyOnWrite when the source canvas is animated and consumed at a rate hig her than the
1509 // presentation frame rate of the destination canvas. 1516 // presentation frame rate of the destination canvas.
1510 if (imageSource->isCanvasElement()) 1517 if (imageSource->isCanvasElement())
1511 canvas()->buffer()->willAccessPixels(); 1518 canvas()->buffer()->willAccessPixels();
1512 1519
1513 if (rectContainsTransformedRect(dstRect, clipBounds)) { 1520 if (rectContainsTransformedRect(dstRect, clipBounds)) {
1514 drawImageOnContext(c, imageSource, image.get(), srcRect, dstRect); 1521 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), srcRect , dstRect);
1515 didDraw(clipBounds); 1522 didDraw(clipBounds);
1516 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { 1523 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
1517 fullCanvasCompositedDraw(bind(&drawImageOnContext, c, imageSource, image .get(), srcRect, dstRect)); 1524 fullCanvasCompositedDraw(bind(&drawImageOnContext, drawingCanvas(), c, i mageSource, image.get(), srcRect, dstRect));
1518 didDraw(clipBounds); 1525 didDraw(clipBounds);
1519 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) { 1526 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) {
1520 clearCanvas(); 1527 clearCanvas();
1521 drawImageOnContext(c, imageSource, image.get(), srcRect, dstRect); 1528 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), srcRect , dstRect);
1522 didDraw(clipBounds); 1529 didDraw(clipBounds);
1523 } else { 1530 } else {
1524 FloatRect dirtyRect; 1531 FloatRect dirtyRect;
1525 if (computeDirtyRect(dstRect, clipBounds, &dirtyRect)) { 1532 if (computeDirtyRect(dstRect, clipBounds, &dirtyRect)) {
1526 drawImageOnContext(c, imageSource, image.get(), srcRect, dstRect); 1533 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), src Rect, dstRect);
1527 didDraw(dirtyRect); 1534 didDraw(dirtyRect);
1528 } 1535 }
1529 } 1536 }
1537
1530 validateStateStack(); 1538 validateStateStack();
1531 1539
1532 if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && can vas()->buffer()) 1540 if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && can vas()->buffer())
1533 canvas()->buffer()->flush(); 1541 canvas()->buffer()->flush();
1534 1542
1535 if (canvas()->originClean() && wouldTaintOrigin(imageSource)) 1543 if (canvas()->originClean() && wouldTaintOrigin(imageSource))
1536 canvas()->setOriginTainted(); 1544 canvas()->setOriginTainted();
1537 } 1545 }
1538 1546
1539 void CanvasRenderingContext2D::clearCanvas() 1547 void CanvasRenderingContext2D::clearCanvas()
1540 { 1548 {
1541 FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height()); 1549 FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height());
1542 GraphicsContext* c = drawingContext(); 1550 SkCanvas* c = drawingCanvas();
1543 if (!c) 1551 if (!c)
1544 return; 1552 return;
1545 1553
1546 c->save(); 1554 c->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK);
1547 c->setCTM(canvas()->baseTransform());
1548 c->clearRect(canvasRect);
1549 c->restore();
1550 } 1555 }
1551 1556
1552 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect , const FloatRect& transformedRect) const 1557 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect , const FloatRect& transformedRect) const
1553 { 1558 {
1554 FloatQuad quad(rect); 1559 FloatQuad quad(rect);
1555 FloatQuad transformedQuad(transformedRect); 1560 FloatQuad transformedQuad(transformedRect);
1556 return state().m_transform.mapQuad(quad).containsQuad(transformedQuad); 1561 return state().m_transform.mapQuad(quad).containsQuad(transformedQuad);
1557 } 1562 }
1558 1563
1559 void CanvasRenderingContext2D::fullCanvasCompositedDraw(PassOwnPtr<Closure> draw ) 1564 void CanvasRenderingContext2D::fullCanvasCompositedDraw(PassOwnPtr<Closure> draw )
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1666 } 1671 }
1667 1672
1668 void CanvasRenderingContext2D::didDraw(const FloatRect& dirtyRect) 1673 void CanvasRenderingContext2D::didDraw(const FloatRect& dirtyRect)
1669 { 1674 {
1670 if (dirtyRect.isEmpty()) 1675 if (dirtyRect.isEmpty())
1671 return; 1676 return;
1672 1677
1673 canvas()->didDraw(dirtyRect); 1678 canvas()->didDraw(dirtyRect);
1674 } 1679 }
1675 1680
1681 SkCanvas* CanvasRenderingContext2D::drawingCanvas() const
1682 {
1683 if (isContextLost())
1684 return nullptr;
1685 return canvas()->drawingCanvas();
1686 }
1687
1676 GraphicsContext* CanvasRenderingContext2D::drawingContext() const 1688 GraphicsContext* CanvasRenderingContext2D::drawingContext() const
1677 { 1689 {
1678 if (isContextLost()) 1690 if (isContextLost())
1679 return nullptr; 1691 return nullptr;
1680 return canvas()->drawingContext(); 1692 return canvas()->drawingContext();
1681 } 1693 }
1682 1694
1683 PassRefPtrWillBeRawPtr<ImageData> CanvasRenderingContext2D::createImageData(Pass RefPtrWillBeRawPtr<ImageData> imageData) const 1695 PassRefPtrWillBeRawPtr<ImageData> CanvasRenderingContext2D::createImageData(Pass RefPtrWillBeRawPtr<ImageData> imageData) const
1684 { 1696 {
1685 return ImageData::create(imageData->size()); 1697 return ImageData::create(imageData->size());
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 bool CanvasRenderingContext2D::imageSmoothingEnabled() const 2229 bool CanvasRenderingContext2D::imageSmoothingEnabled() const
2218 { 2230 {
2219 return state().m_imageSmoothingEnabled; 2231 return state().m_imageSmoothingEnabled;
2220 } 2232 }
2221 2233
2222 void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled) 2234 void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled)
2223 { 2235 {
2224 if (enabled == state().m_imageSmoothingEnabled) 2236 if (enabled == state().m_imageSmoothingEnabled)
2225 return; 2237 return;
2226 2238
2227 GraphicsContext* c = drawingContext(); 2239 SkCanvas* c = drawingCanvas();
2228 realizeSaves(c); 2240 realizeSaves(c);
2229 modifiableState().m_imageSmoothingEnabled = enabled; 2241 modifiableState().m_imageSmoothingEnabled = enabled;
2230 if (c) 2242 if (c)
2231 c->setImageInterpolationQuality(enabled ? CanvasDefaultInterpolationQual ity : InterpolationNone); 2243 drawingContext()->setImageInterpolationQuality(enabled ? CanvasDefaultIn terpolationQuality : InterpolationNone);
2232 } 2244 }
2233 2245
2234 void CanvasRenderingContext2D::getContextAttributes(Canvas2DContextAttributes& a ttrs) const 2246 void CanvasRenderingContext2D::getContextAttributes(Canvas2DContextAttributes& a ttrs) const
2235 { 2247 {
2236 attrs.setAlpha(m_hasAlpha); 2248 attrs.setAlpha(m_hasAlpha);
2237 } 2249 }
2238 2250
2239 void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element) 2251 void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element)
2240 { 2252 {
2241 drawFocusIfNeededInternal(m_path, element); 2253 drawFocusIfNeededInternal(m_path, element);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2283 const int focusRingOutline = 0; 2295 const int focusRingOutline = 0;
2284 2296
2285 // We need to add focusRingWidth to dirtyRect. 2297 // We need to add focusRingWidth to dirtyRect.
2286 StrokeData strokeData; 2298 StrokeData strokeData;
2287 strokeData.setThickness(focusRingWidth); 2299 strokeData.setThickness(focusRingWidth);
2288 2300
2289 FloatRect dirtyRect; 2301 FloatRect dirtyRect;
2290 if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect)) 2302 if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect))
2291 return; 2303 return;
2292 2304
2293 c->save();
2294 c->setAlphaAsFloat(1.0); 2305 c->setAlphaAsFloat(1.0);
2295 c->clearShadow(); 2306 c->clearShadow();
2296 c->setCompositeOperation(SkXfermode::kSrcOver_Mode); 2307 c->setCompositeOperation(SkXfermode::kSrcOver_Mode);
2297 c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor); 2308 c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor);
2298 c->restore(); 2309 applyShadow(DrawShadowAndForeground);
2310 c->setAlphaAsFloat(state().m_globalAlpha);
2311 c->setCompositeOperation(state().m_globalComposite);
2312
2299 validateStateStack(); 2313 validateStateStack();
2300 didDraw(dirtyRect); 2314 didDraw(dirtyRect);
2301 } 2315 }
2302 2316
2303 void CanvasRenderingContext2D::addHitRegion(const HitRegionOptions& options, Exc eptionState& exceptionState) 2317 void CanvasRenderingContext2D::addHitRegion(const HitRegionOptions& options, Exc eptionState& exceptionState)
2304 { 2318 {
2305 if (options.id().isEmpty() && !options.control()) { 2319 if (options.id().isEmpty() && !options.control()) {
2306 exceptionState.throwDOMException(NotSupportedError, "Both id and control are null."); 2320 exceptionState.throwDOMException(NotSupportedError, "Both id and control are null.");
2307 return; 2321 return;
2308 } 2322 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2362 2376
2363 unsigned CanvasRenderingContext2D::hitRegionsCount() const 2377 unsigned CanvasRenderingContext2D::hitRegionsCount() const
2364 { 2378 {
2365 if (m_hitRegionManager) 2379 if (m_hitRegionManager)
2366 return m_hitRegionManager->getHitRegionsCount(); 2380 return m_hitRegionManager->getHitRegionsCount();
2367 2381
2368 return 0; 2382 return 0;
2369 } 2383 }
2370 2384
2371 } // namespace blink 2385 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/html/canvas/CanvasRenderingContext2D.h ('k') | Source/core/html/canvas/ClipList.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698