OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |