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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 , m_dispatchContextLostEventTimer(this, &CanvasRenderingContext2D::dispatchC ontextLostEvent) | 95 , m_dispatchContextLostEventTimer(this, &CanvasRenderingContext2D::dispatchC ontextLostEvent) |
96 , m_dispatchContextRestoredEventTimer(this, &CanvasRenderingContext2D::dispa tchContextRestoredEvent) | 96 , m_dispatchContextRestoredEventTimer(this, &CanvasRenderingContext2D::dispa tchContextRestoredEvent) |
97 , m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreC ontextEvent) | 97 , m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreC ontextEvent) |
98 { | 98 { |
99 m_stateStack.append(adoptPtrWillBeNoop(new State())); | 99 m_stateStack.append(adoptPtrWillBeNoop(new State())); |
100 ScriptWrappable::init(this); | 100 ScriptWrappable::init(this); |
101 } | 101 } |
102 | 102 |
103 void CanvasRenderingContext2D::unwindStateStack() | 103 void CanvasRenderingContext2D::unwindStateStack() |
104 { | 104 { |
105 // Ensure that the state stack in the ImageBuffer's context | 105 if (GraphicsContext* context = canvas()->existingDrawingContext()) { |
106 // is cleared before destruction, to avoid assertions in the | 106 context->unwindStateStack(); |
107 // GraphicsContext dtor. | |
108 if (size_t stackSize = m_stateStack.size()) { | |
f(malita)
2014/05/27 20:28:22
Since we're asserting that m_stateStack.size() ==
Justin Novosad
2014/05/27 22:25:25
Good point. GC::unwindStateStack was my fist attem
| |
109 if (GraphicsContext* context = canvas()->existingDrawingContext()) { | |
110 while (--stackSize) | |
111 context->restore(); | |
112 } | |
113 } | 107 } |
114 } | 108 } |
115 | 109 |
116 CanvasRenderingContext2D::~CanvasRenderingContext2D() | 110 CanvasRenderingContext2D::~CanvasRenderingContext2D() |
117 { | 111 { |
118 #if !ENABLE(OILPAN) | 112 } |
113 | |
114 void CanvasRenderingContext2D::validateStateStack() | |
115 { | |
119 #if !ASSERT_DISABLED | 116 #if !ASSERT_DISABLED |
120 unwindStateStack(); | 117 GraphicsContext* context = canvas()->existingDrawingContext(); |
121 #endif | 118 if (context && !context->contextDisabled()) |
119 ASSERT(context->saveCount() == m_stateStack.size()); | |
122 #endif | 120 #endif |
123 } | 121 } |
124 | 122 |
125 bool CanvasRenderingContext2D::isAccelerated() const | 123 bool CanvasRenderingContext2D::isAccelerated() const |
126 { | 124 { |
127 if (!canvas()->hasImageBuffer()) | 125 if (!canvas()->hasImageBuffer()) |
128 return false; | 126 return false; |
129 GraphicsContext* context = drawingContext(); | 127 GraphicsContext* context = drawingContext(); |
130 return context && context->isAccelerated(); | 128 return context && context->isAccelerated(); |
131 } | 129 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 reset(); | 217 reset(); |
220 m_isContextLost = false; | 218 m_isContextLost = false; |
221 if (contextLostRestoredEventsEnabled()) { | 219 if (contextLostRestoredEventsEnabled()) { |
222 RefPtrWillBeRawPtr<Event> event(Event::create(EventTypeNames::contextres tored)); | 220 RefPtrWillBeRawPtr<Event> event(Event::create(EventTypeNames::contextres tored)); |
223 canvas()->dispatchEvent(event); | 221 canvas()->dispatchEvent(event); |
224 } | 222 } |
225 } | 223 } |
226 | 224 |
227 void CanvasRenderingContext2D::reset() | 225 void CanvasRenderingContext2D::reset() |
228 { | 226 { |
227 validateStateStack(); | |
229 unwindStateStack(); | 228 unwindStateStack(); |
229 // Replace the save() held by HTMLCanvasElement::m_contextStateSaver | |
Stephen White
2014/05/27 18:11:32
Maybe it's jetlag, but I don't understand this com
| |
230 if (GraphicsContext* context = canvas()->existingDrawingContext()) | |
231 context->save(); | |
230 m_stateStack.resize(1); | 232 m_stateStack.resize(1); |
231 m_stateStack.first() = adoptPtrWillBeNoop(new State()); | 233 m_stateStack.first() = adoptPtrWillBeNoop(new State()); |
232 m_path.clear(); | 234 m_path.clear(); |
235 validateStateStack(); | |
233 } | 236 } |
234 | 237 |
235 // Important: Several of these properties are also stored in GraphicsContext's | 238 // Important: Several of these properties are also stored in GraphicsContext's |
236 // StrokeData. The default values that StrokeData uses may not the same values | 239 // StrokeData. The default values that StrokeData uses may not the same values |
237 // that the canvas 2d spec specifies. Make sure to sync the initial state of the | 240 // that the canvas 2d spec specifies. Make sure to sync the initial state of the |
238 // GraphicsContext in HTMLCanvasElement::createImageBuffer()! | 241 // GraphicsContext in HTMLCanvasElement::createImageBuffer()! |
239 CanvasRenderingContext2D::State::State() | 242 CanvasRenderingContext2D::State::State() |
240 : m_unrealizedSaveCount(0) | 243 : m_unrealizedSaveCount(0) |
241 , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black)) | 244 , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black)) |
242 , m_fillStyle(CanvasStyle::createFromRGBA(Color::black)) | 245 , m_fillStyle(CanvasStyle::createFromRGBA(Color::black)) |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 void CanvasRenderingContext2D::State::fontsNeedUpdate(CSSFontSelector* fontSelec tor) | 344 void CanvasRenderingContext2D::State::fontsNeedUpdate(CSSFontSelector* fontSelec tor) |
342 { | 345 { |
343 ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector()); | 346 ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector()); |
344 ASSERT(m_realizedFont); | 347 ASSERT(m_realizedFont); |
345 | 348 |
346 m_font.update(fontSelector); | 349 m_font.update(fontSelector); |
347 } | 350 } |
348 | 351 |
349 void CanvasRenderingContext2D::realizeSaves() | 352 void CanvasRenderingContext2D::realizeSaves() |
350 { | 353 { |
354 validateStateStack(); | |
351 if (state().m_unrealizedSaveCount) { | 355 if (state().m_unrealizedSaveCount) { |
352 ASSERT(m_stateStack.size() >= 1); | 356 ASSERT(m_stateStack.size() >= 1); |
353 // Reduce the current state's unrealized count by one now, | 357 // Reduce the current state's unrealized count by one now, |
354 // to reflect the fact we are saving one state. | 358 // to reflect the fact we are saving one state. |
355 m_stateStack.last()->m_unrealizedSaveCount--; | 359 m_stateStack.last()->m_unrealizedSaveCount--; |
356 m_stateStack.append(adoptPtrWillBeNoop(new State(state()))); | 360 m_stateStack.append(adoptPtrWillBeNoop(new State(state()))); |
357 // Set the new state's unrealized count to 0, because it has no outstand ing saves. | 361 // Set the new state's unrealized count to 0, because it has no outstand ing saves. |
358 // We need to do this explicitly because the copy constructor and operat or= used | 362 // We need to do this explicitly because the copy constructor and operat or= used |
359 // by the Vector operations copy the unrealized count from the previous state (in | 363 // by the Vector operations copy the unrealized count from the previous state (in |
360 // turn necessary to support correct resizing and unwinding of the stack ). | 364 // turn necessary to support correct resizing and unwinding of the stack ). |
361 m_stateStack.last()->m_unrealizedSaveCount = 0; | 365 m_stateStack.last()->m_unrealizedSaveCount = 0; |
362 GraphicsContext* context = drawingContext(); | 366 GraphicsContext* context = drawingContext(); |
367 ASSERT(context); | |
363 if (context) | 368 if (context) |
364 context->save(); | 369 context->save(); |
370 validateStateStack(); | |
365 } | 371 } |
366 } | 372 } |
367 | 373 |
368 void CanvasRenderingContext2D::restore() | 374 void CanvasRenderingContext2D::restore() |
369 { | 375 { |
376 validateStateStack(); | |
370 if (state().m_unrealizedSaveCount) { | 377 if (state().m_unrealizedSaveCount) { |
371 // We never realized the save, so just record that it was unnecessary. | 378 // We never realized the save, so just record that it was unnecessary. |
372 --m_stateStack.last()->m_unrealizedSaveCount; | 379 --m_stateStack.last()->m_unrealizedSaveCount; |
373 return; | 380 return; |
374 } | 381 } |
375 ASSERT(m_stateStack.size() >= 1); | 382 ASSERT(m_stateStack.size() >= 1); |
376 if (m_stateStack.size() <= 1) | 383 if (m_stateStack.size() <= 1) |
377 return; | 384 return; |
378 m_path.transform(state().m_transform); | 385 m_path.transform(state().m_transform); |
379 m_stateStack.removeLast(); | 386 m_stateStack.removeLast(); |
380 m_path.transform(state().m_transform.inverse()); | 387 m_path.transform(state().m_transform.inverse()); |
381 GraphicsContext* c = drawingContext(); | 388 GraphicsContext* c = drawingContext(); |
382 if (c) | 389 if (c) |
383 c->restore(); | 390 c->restore(); |
391 validateStateStack(); | |
384 } | 392 } |
385 | 393 |
386 CanvasStyle* CanvasRenderingContext2D::strokeStyle() const | 394 CanvasStyle* CanvasRenderingContext2D::strokeStyle() const |
387 { | 395 { |
388 return state().m_strokeStyle.get(); | 396 return state().m_strokeStyle.get(); |
389 } | 397 } |
390 | 398 |
391 void CanvasRenderingContext2D::setStrokeStyle(PassRefPtr<CanvasStyle> prpStyle) | 399 void CanvasRenderingContext2D::setStrokeStyle(PassRefPtr<CanvasStyle> prpStyle) |
392 { | 400 { |
393 RefPtr<CanvasStyle> style = prpStyle; | 401 RefPtr<CanvasStyle> style = prpStyle; |
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1233 if (!saved) { | 1241 if (!saved) { |
1234 context->save(); | 1242 context->save(); |
1235 saved = true; | 1243 saved = true; |
1236 } | 1244 } |
1237 context->setCompositeOperation(CompositeSourceOver); | 1245 context->setCompositeOperation(CompositeSourceOver); |
1238 } | 1246 } |
1239 context->clearRect(rect); | 1247 context->clearRect(rect); |
1240 if (saved) | 1248 if (saved) |
1241 context->restore(); | 1249 context->restore(); |
1242 | 1250 |
1251 validateStateStack(); | |
1243 didDraw(dirtyRect); | 1252 didDraw(dirtyRect); |
1244 } | 1253 } |
1245 | 1254 |
1246 void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei ght) | 1255 void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei ght) |
1247 { | 1256 { |
1248 if (!validateRectForCanvas(x, y, width, height)) | 1257 if (!validateRectForCanvas(x, y, width, height)) |
1249 return; | 1258 return; |
1250 | 1259 |
1251 GraphicsContext* c = drawingContext(); | 1260 GraphicsContext* c = drawingContext(); |
1252 if (!c) | 1261 if (!c) |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1528 void CanvasRenderingContext2D::drawVideo(HTMLVideoElement* video, FloatRect srcR ect, FloatRect dstRect) | 1537 void CanvasRenderingContext2D::drawVideo(HTMLVideoElement* video, FloatRect srcR ect, FloatRect dstRect) |
1529 { | 1538 { |
1530 GraphicsContext* c = drawingContext(); | 1539 GraphicsContext* c = drawingContext(); |
1531 GraphicsContextStateSaver stateSaver(*c); | 1540 GraphicsContextStateSaver stateSaver(*c); |
1532 c->clip(dstRect); | 1541 c->clip(dstRect); |
1533 c->translate(dstRect.x(), dstRect.y()); | 1542 c->translate(dstRect.x(), dstRect.y()); |
1534 c->scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() / src Rect.height())); | 1543 c->scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() / src Rect.height())); |
1535 c->translate(-srcRect.x(), -srcRect.y()); | 1544 c->translate(-srcRect.x(), -srcRect.y()); |
1536 video->paintCurrentFrameInContext(c, IntRect(IntPoint(), IntSize(video->vide oWidth(), video->videoHeight()))); | 1545 video->paintCurrentFrameInContext(c, IntRect(IntPoint(), IntSize(video->vide oWidth(), video->videoHeight()))); |
1537 stateSaver.restore(); | 1546 stateSaver.restore(); |
1547 validateStateStack(); | |
1538 } | 1548 } |
1539 | 1549 |
1540 void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image, | 1550 void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image, |
1541 float sx, float sy, float sw, float sh, | 1551 float sx, float sy, float sw, float sh, |
1542 float dx, float dy, float dw, float dh, | 1552 float dx, float dy, float dw, float dh, |
1543 const String& compositeOperation) | 1553 const String& compositeOperation) |
1544 { | 1554 { |
1545 if (!image) | 1555 if (!image) |
1546 return; | 1556 return; |
1547 CompositeOperator op; | 1557 CompositeOperator op; |
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2365 FloatRect dirtyRect; | 2375 FloatRect dirtyRect; |
2366 if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect)) | 2376 if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect)) |
2367 return; | 2377 return; |
2368 | 2378 |
2369 c->save(); | 2379 c->save(); |
2370 c->setAlphaAsFloat(1.0); | 2380 c->setAlphaAsFloat(1.0); |
2371 c->clearShadow(); | 2381 c->clearShadow(); |
2372 c->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal); | 2382 c->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal); |
2373 c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor); | 2383 c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor); |
2374 c->restore(); | 2384 c->restore(); |
2375 | 2385 validateStateStack(); |
2376 didDraw(dirtyRect); | 2386 didDraw(dirtyRect); |
2377 } | 2387 } |
2378 | 2388 |
2379 } // namespace WebCore | 2389 } // namespace WebCore |
OLD | NEW |