Chromium Code Reviews| 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()); |
|
Stephen Chennney
2015/02/04 19:18:59
Do we have tests covering this assert? I believe i
| |
| 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(); |
|
Stephen Chennney
2015/02/04 19:18:59
Yippee. Getting rid of a call to GraphicsContext::
| |
| 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 canvasElementElement::createImageBuffer()! |
|
Stephen Chennney
2015/02/04 19:18:59
Typo?
| |
| 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)) |
| 270 , m_fillStyle(CanvasStyle::createFromRGBA(Color::black)) | 268 , m_fillStyle(CanvasStyle::createFromRGBA(Color::black)) |
| 271 , m_lineWidth(1) | 269 , m_lineWidth(1) |
| 272 , m_lineCap(ButtCap) | 270 , m_lineCap(ButtCap) |
| 273 , m_lineJoin(MiterJoin) | 271 , m_lineJoin(MiterJoin) |
| 274 , m_miterLimit(10) | 272 , m_miterLimit(10) |
| 275 , m_shadowBlur(0) | 273 , m_shadowBlur(0) |
| 276 , m_shadowColor(Color::transparent) | 274 , m_shadowColor(Color::transparent) |
| (...skipping 104 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 | |
|
chrishtr
2015/02/04 07:17:49
How do you plan to get rid of this code later?
dshwang
2015/02/04 13:50:03
I guess @junov will remove GraphicsContext in Imag
| |
| 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 / 3.14159265f)); |
|
dshwang
2015/02/04 13:50:03
how about using piFloat in MathExtras.h
Justin Novosad
2015/02/04 18:37:47
Acknowledged.
| |
| 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(); |
|
dshwang
2015/02/04 13:50:03
why this method use GraphicsContext?
Justin Novosad
2015/02/04 18:37:47
One step at a time. For now I am still relying on
| |
| 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((WindRule)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 = const_cast<SkPath&>(path.skPath()); |
| 1117 // Note: we destructivetly alter the fillType of path | |
| 1118 SkPath::FillType oldFillType = skPath.getFillType(); | |
| 1119 skPath.setFillType(parseWinding(windingRuleString)); | |
| 1100 ImageBuffer* buffer = canvas()->buffer(); | 1120 ImageBuffer* buffer = canvas()->buffer(); |
| 1101 if (buffer && buffer->needsClipTracking()) { | 1121 if (buffer && buffer->needsClipTracking()) { |
| 1102 modifiableState().m_clipList.clipPath(path, windRule, m_clipAntialiasing , state().m_transform); | 1122 modifiableState().m_clipList.clipPath(skPath, m_clipAntialiasing, affine TransformToSkMatrix(state().m_transform)); |
| 1103 } | 1123 } |
| 1104 c->clipPath(path, windRule, m_clipAntialiasing); | 1124 |
| 1125 c->clipPath(skPath, SkRegion::kIntersect_Op, m_clipAntialiasing == AntiAlias ed); | |
| 1126 skPath.setFillType(oldFillType); | |
| 1105 modifiableState().m_hasClip = true; | 1127 modifiableState().m_hasClip = true; |
| 1106 } | 1128 } |
| 1107 | 1129 |
| 1108 void CanvasRenderingContext2D::clip(const String& windingRuleString) | 1130 void CanvasRenderingContext2D::clip(const String& windingRuleString) |
| 1109 { | 1131 { |
| 1110 clipInternal(m_path, windingRuleString); | 1132 clipInternal(m_path, windingRuleString); |
| 1111 } | 1133 } |
| 1112 | 1134 |
| 1113 void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleSt ring) | 1135 void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleSt ring) |
| 1114 { | 1136 { |
| 1115 clipInternal(domPath->path(), windingRuleString); | 1137 clipInternal(domPath->path(), windingRuleString); |
| 1116 } | 1138 } |
| 1117 | 1139 |
| 1118 bool CanvasRenderingContext2D::isPointInPath(const float x, const float y, const String& windingRuleString) | 1140 bool CanvasRenderingContext2D::isPointInPath(const float x, const float y, const String& windingRuleString) |
| 1119 { | 1141 { |
| 1120 return isPointInPathInternal(m_path, x, y, windingRuleString); | 1142 return isPointInPathInternal(m_path, x, y, windingRuleString); |
| 1121 } | 1143 } |
| 1122 | 1144 |
| 1123 bool CanvasRenderingContext2D::isPointInPath(Path2D* domPath, const float x, con st float y, const String& windingRuleString) | 1145 bool CanvasRenderingContext2D::isPointInPath(Path2D* domPath, const float x, con st float y, const String& windingRuleString) |
| 1124 { | 1146 { |
| 1125 return isPointInPathInternal(domPath->path(), x, y, windingRuleString); | 1147 return isPointInPathInternal(domPath->path(), x, y, windingRuleString); |
| 1126 } | 1148 } |
| 1127 | 1149 |
| 1128 bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, const flo at x, const float y, const String& windingRuleString) | 1150 bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, const flo at x, const float y, const String& windingRuleString) |
| 1129 { | 1151 { |
| 1130 GraphicsContext* c = drawingContext(); | 1152 SkCanvas* c = drawingCanvas(); |
| 1131 if (!c) | 1153 if (!c) |
| 1132 return false; | 1154 return false; |
| 1133 if (!state().m_invertibleCTM) | 1155 if (!state().m_invertibleCTM) |
| 1134 return false; | 1156 return false; |
| 1135 | 1157 |
| 1136 FloatPoint point(x, y); | 1158 FloatPoint point(x, y); |
| 1137 if (!std::isfinite(point.x()) || !std::isfinite(point.y())) | 1159 if (!std::isfinite(point.x()) || !std::isfinite(point.y())) |
| 1138 return false; | 1160 return false; |
| 1139 AffineTransform ctm = state().m_transform; | 1161 AffineTransform ctm = state().m_transform; |
| 1140 FloatPoint transformedPoint = ctm.inverse().mapPoint(point); | 1162 FloatPoint transformedPoint = ctm.inverse().mapPoint(point); |
| 1141 | 1163 |
| 1142 return path.contains(transformedPoint, parseWinding(windingRuleString)); | 1164 return path.contains(transformedPoint, (WindRule)parseWinding(windingRuleStr ing)); |
|
dshwang
2015/02/04 13:50:03
could you make converting inline function for Wind
Justin Novosad
2015/02/04 18:37:47
Acknowledged.
| |
| 1143 } | 1165 } |
| 1144 | 1166 |
| 1145 bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y) | 1167 bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y) |
| 1146 { | 1168 { |
| 1147 return isPointInStrokeInternal(m_path, x, y); | 1169 return isPointInStrokeInternal(m_path, x, y); |
| 1148 } | 1170 } |
| 1149 | 1171 |
| 1150 bool CanvasRenderingContext2D::isPointInStroke(Path2D* domPath, const float x, c onst float y) | 1172 bool CanvasRenderingContext2D::isPointInStroke(Path2D* domPath, const float x, c onst float y) |
| 1151 { | 1173 { |
| 1152 return isPointInStrokeInternal(domPath->path(), x, y); | 1174 return isPointInStrokeInternal(domPath->path(), x, y); |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1666 } | 1688 } |
| 1667 | 1689 |
| 1668 void CanvasRenderingContext2D::didDraw(const FloatRect& dirtyRect) | 1690 void CanvasRenderingContext2D::didDraw(const FloatRect& dirtyRect) |
| 1669 { | 1691 { |
| 1670 if (dirtyRect.isEmpty()) | 1692 if (dirtyRect.isEmpty()) |
| 1671 return; | 1693 return; |
| 1672 | 1694 |
| 1673 canvas()->didDraw(dirtyRect); | 1695 canvas()->didDraw(dirtyRect); |
| 1674 } | 1696 } |
| 1675 | 1697 |
| 1698 SkCanvas* CanvasRenderingContext2D::drawingCanvas() const | |
| 1699 { | |
| 1700 if (isContextLost()) | |
| 1701 return nullptr; | |
| 1702 return canvas()->drawingCanvas(); | |
| 1703 } | |
| 1704 | |
| 1676 GraphicsContext* CanvasRenderingContext2D::drawingContext() const | 1705 GraphicsContext* CanvasRenderingContext2D::drawingContext() const |
| 1677 { | 1706 { |
| 1678 if (isContextLost()) | 1707 if (isContextLost()) |
| 1679 return nullptr; | 1708 return nullptr; |
| 1680 return canvas()->drawingContext(); | 1709 return canvas()->drawingContext(); |
| 1681 } | 1710 } |
| 1682 | 1711 |
| 1683 PassRefPtrWillBeRawPtr<ImageData> CanvasRenderingContext2D::createImageData(Pass RefPtrWillBeRawPtr<ImageData> imageData) const | 1712 PassRefPtrWillBeRawPtr<ImageData> CanvasRenderingContext2D::createImageData(Pass RefPtrWillBeRawPtr<ImageData> imageData) const |
| 1684 { | 1713 { |
| 1685 return ImageData::create(imageData->size()); | 1714 return ImageData::create(imageData->size()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1726 | 1755 |
| 1727 FloatRect logicalRect(sx, sy, sw, sh); | 1756 FloatRect logicalRect(sx, sy, sw, sh); |
| 1728 if (logicalRect.width() < 1) | 1757 if (logicalRect.width() < 1) |
| 1729 logicalRect.setWidth(1); | 1758 logicalRect.setWidth(1); |
| 1730 if (logicalRect.height() < 1) | 1759 if (logicalRect.height() < 1) |
| 1731 logicalRect.setHeight(1); | 1760 logicalRect.setHeight(1); |
| 1732 if (!logicalRect.isExpressibleAsIntRect()) | 1761 if (!logicalRect.isExpressibleAsIntRect()) |
| 1733 return nullptr; | 1762 return nullptr; |
| 1734 | 1763 |
| 1735 IntRect imageDataRect = enclosingIntRect(logicalRect); | 1764 IntRect imageDataRect = enclosingIntRect(logicalRect); |
| 1736 ImageBuffer* buffer = canvas()->buffer(); | 1765 ImageBuffer* buffer =canvas()->buffer(); |
|
Stephen Chennney
2015/02/04 19:18:59
typo?
| |
| 1737 if (!buffer || isContextLost()) | 1766 if (!buffer || isContextLost()) |
| 1738 return ImageData::create(imageDataRect.size()); | 1767 return ImageData::create(imageDataRect.size()); |
| 1739 | 1768 |
| 1740 WTF::ArrayBufferContents contents; | 1769 WTF::ArrayBufferContents contents; |
| 1741 if (!buffer->getImageData(Unmultiplied, imageDataRect, contents)) | 1770 if (!buffer->getImageData(Unmultiplied, imageDataRect, contents)) |
| 1742 return nullptr; | 1771 return nullptr; |
| 1743 | 1772 |
| 1744 RefPtr<DOMArrayBuffer> arrayBuffer = DOMArrayBuffer::create(contents); | 1773 RefPtr<DOMArrayBuffer> arrayBuffer = DOMArrayBuffer::create(contents); |
| 1745 return ImageData::create( | 1774 return ImageData::create( |
| 1746 imageDataRect.size(), | 1775 imageDataRect.size(), |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2217 bool CanvasRenderingContext2D::imageSmoothingEnabled() const | 2246 bool CanvasRenderingContext2D::imageSmoothingEnabled() const |
| 2218 { | 2247 { |
| 2219 return state().m_imageSmoothingEnabled; | 2248 return state().m_imageSmoothingEnabled; |
| 2220 } | 2249 } |
| 2221 | 2250 |
| 2222 void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled) | 2251 void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled) |
| 2223 { | 2252 { |
| 2224 if (enabled == state().m_imageSmoothingEnabled) | 2253 if (enabled == state().m_imageSmoothingEnabled) |
| 2225 return; | 2254 return; |
| 2226 | 2255 |
| 2227 GraphicsContext* c = drawingContext(); | 2256 SkCanvas* c = drawingCanvas(); |
| 2228 realizeSaves(c); | 2257 realizeSaves(c); |
| 2229 modifiableState().m_imageSmoothingEnabled = enabled; | 2258 modifiableState().m_imageSmoothingEnabled = enabled; |
| 2230 if (c) | 2259 if (c) |
| 2231 c->setImageInterpolationQuality(enabled ? CanvasDefaultInterpolationQual ity : InterpolationNone); | 2260 drawingContext()->setImageInterpolationQuality(enabled ? CanvasDefaultIn terpolationQuality : InterpolationNone); |
|
dshwang
2015/02/04 13:50:03
Is it safe to mix to use SkCanvas and GraphicsCont
Justin Novosad
2015/02/04 18:37:47
This CL brings us into an intermediate state where
| |
| 2232 } | 2261 } |
| 2233 | 2262 |
| 2234 void CanvasRenderingContext2D::getContextAttributes(Canvas2DContextAttributes& a ttrs) const | 2263 void CanvasRenderingContext2D::getContextAttributes(Canvas2DContextAttributes& a ttrs) const |
| 2235 { | 2264 { |
| 2236 attrs.setAlpha(m_hasAlpha); | 2265 attrs.setAlpha(m_hasAlpha); |
| 2237 } | 2266 } |
| 2238 | 2267 |
| 2239 void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element) | 2268 void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element) |
| 2240 { | 2269 { |
| 2241 drawFocusIfNeededInternal(m_path, element); | 2270 drawFocusIfNeededInternal(m_path, element); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2362 | 2391 |
| 2363 unsigned CanvasRenderingContext2D::hitRegionsCount() const | 2392 unsigned CanvasRenderingContext2D::hitRegionsCount() const |
| 2364 { | 2393 { |
| 2365 if (m_hitRegionManager) | 2394 if (m_hitRegionManager) |
| 2366 return m_hitRegionManager->getHitRegionsCount(); | 2395 return m_hitRegionManager->getHitRegionsCount(); |
| 2367 | 2396 |
| 2368 return 0; | 2397 return 0; |
| 2369 } | 2398 } |
| 2370 | 2399 |
| 2371 } // namespace blink | 2400 } // namespace blink |
| OLD | NEW |