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 | |
106 // is cleared before destruction, to avoid assertions in the | |
107 // GraphicsContext dtor. | |
108 if (size_t stackSize = m_stateStack.size()) { | 105 if (size_t stackSize = m_stateStack.size()) { |
109 if (GraphicsContext* context = canvas()->existingDrawingContext()) { | 106 if (GraphicsContext* context = canvas()->existingDrawingContext()) { |
110 while (--stackSize) | 107 while (--stackSize) |
111 context->restore(); | 108 context->restore(); |
112 } | 109 } |
113 } | 110 } |
114 } | 111 } |
115 | 112 |
116 CanvasRenderingContext2D::~CanvasRenderingContext2D() | 113 CanvasRenderingContext2D::~CanvasRenderingContext2D() |
117 { | 114 { |
118 #if !ENABLE(OILPAN) | 115 } |
| 116 |
| 117 void CanvasRenderingContext2D::validateStateStack() |
| 118 { |
119 #if !ASSERT_DISABLED | 119 #if !ASSERT_DISABLED |
120 unwindStateStack(); | 120 GraphicsContext* context = canvas()->existingDrawingContext(); |
121 #endif | 121 if (context && !context->contextDisabled()) |
| 122 ASSERT(context->saveCount() == m_stateStack.size()); |
122 #endif | 123 #endif |
123 } | 124 } |
124 | 125 |
125 bool CanvasRenderingContext2D::isAccelerated() const | 126 bool CanvasRenderingContext2D::isAccelerated() const |
126 { | 127 { |
127 if (!canvas()->hasImageBuffer()) | 128 if (!canvas()->hasImageBuffer()) |
128 return false; | 129 return false; |
129 GraphicsContext* context = drawingContext(); | 130 GraphicsContext* context = drawingContext(); |
130 return context && context->isAccelerated(); | 131 return context && context->isAccelerated(); |
131 } | 132 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 reset(); | 220 reset(); |
220 m_isContextLost = false; | 221 m_isContextLost = false; |
221 if (contextLostRestoredEventsEnabled()) { | 222 if (contextLostRestoredEventsEnabled()) { |
222 RefPtrWillBeRawPtr<Event> event(Event::create(EventTypeNames::contextres
tored)); | 223 RefPtrWillBeRawPtr<Event> event(Event::create(EventTypeNames::contextres
tored)); |
223 canvas()->dispatchEvent(event); | 224 canvas()->dispatchEvent(event); |
224 } | 225 } |
225 } | 226 } |
226 | 227 |
227 void CanvasRenderingContext2D::reset() | 228 void CanvasRenderingContext2D::reset() |
228 { | 229 { |
| 230 validateStateStack(); |
229 unwindStateStack(); | 231 unwindStateStack(); |
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 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2380 FloatRect dirtyRect; | 2390 FloatRect dirtyRect; |
2381 if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect)) | 2391 if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect)) |
2382 return; | 2392 return; |
2383 | 2393 |
2384 c->save(); | 2394 c->save(); |
2385 c->setAlphaAsFloat(1.0); | 2395 c->setAlphaAsFloat(1.0); |
2386 c->clearShadow(); | 2396 c->clearShadow(); |
2387 c->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal); | 2397 c->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal); |
2388 c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor); | 2398 c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor); |
2389 c->restore(); | 2399 c->restore(); |
2390 | 2400 validateStateStack(); |
2391 didDraw(dirtyRect); | 2401 didDraw(dirtyRect); |
2392 } | 2402 } |
2393 | 2403 |
2394 } // namespace WebCore | 2404 } // namespace WebCore |
OLD | NEW |