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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 , m_globalComposite(SkXfermode::kSrcOver_Mode) | 276 , m_globalComposite(SkXfermode::kSrcOver_Mode) |
| 277 , m_invertibleCTM(true) | 277 , m_invertibleCTM(true) |
| 278 , m_lineDashOffset(0) | 278 , m_lineDashOffset(0) |
| 279 , m_imageSmoothingEnabled(true) | 279 , m_imageSmoothingEnabled(true) |
| 280 , m_textAlign(StartTextAlign) | 280 , m_textAlign(StartTextAlign) |
| 281 , m_textBaseline(AlphabeticTextBaseline) | 281 , m_textBaseline(AlphabeticTextBaseline) |
| 282 , m_direction(DirectionInherit) | 282 , m_direction(DirectionInherit) |
| 283 , m_unparsedFont(defaultFont) | 283 , m_unparsedFont(defaultFont) |
| 284 , m_realizedFont(false) | 284 , m_realizedFont(false) |
| 285 , m_hasClip(false) | 285 , m_hasClip(false) |
| 286 , m_hasComplexClip(false) | |
| 286 { | 287 { |
| 287 } | 288 } |
| 288 | 289 |
| 289 CanvasRenderingContext2D::State::State(const State& other, ClipListCopyMode mode ) | 290 CanvasRenderingContext2D::State::State(const State& other, ClipListCopyMode mode ) |
| 290 : CSSFontSelectorClient() | 291 : CSSFontSelectorClient() |
| 291 , m_unrealizedSaveCount(other.m_unrealizedSaveCount) | 292 , m_unrealizedSaveCount(other.m_unrealizedSaveCount) |
| 292 , m_unparsedStrokeColor(other.m_unparsedStrokeColor) | 293 , m_unparsedStrokeColor(other.m_unparsedStrokeColor) |
| 293 , m_unparsedFillColor(other.m_unparsedFillColor) | 294 , m_unparsedFillColor(other.m_unparsedFillColor) |
| 294 , m_strokeStyle(other.m_strokeStyle) | 295 , m_strokeStyle(other.m_strokeStyle) |
| 295 , m_fillStyle(other.m_fillStyle) | 296 , m_fillStyle(other.m_fillStyle) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 306 , m_invertibleCTM(other.m_invertibleCTM) | 307 , m_invertibleCTM(other.m_invertibleCTM) |
| 307 , m_lineDashOffset(other.m_lineDashOffset) | 308 , m_lineDashOffset(other.m_lineDashOffset) |
| 308 , m_imageSmoothingEnabled(other.m_imageSmoothingEnabled) | 309 , m_imageSmoothingEnabled(other.m_imageSmoothingEnabled) |
| 309 , m_textAlign(other.m_textAlign) | 310 , m_textAlign(other.m_textAlign) |
| 310 , m_textBaseline(other.m_textBaseline) | 311 , m_textBaseline(other.m_textBaseline) |
| 311 , m_direction(other.m_direction) | 312 , m_direction(other.m_direction) |
| 312 , m_unparsedFont(other.m_unparsedFont) | 313 , m_unparsedFont(other.m_unparsedFont) |
| 313 , m_font(other.m_font) | 314 , m_font(other.m_font) |
| 314 , m_realizedFont(other.m_realizedFont) | 315 , m_realizedFont(other.m_realizedFont) |
| 315 , m_hasClip(other.m_hasClip) | 316 , m_hasClip(other.m_hasClip) |
| 317 , m_hasComplexClip(other.m_hasComplexClip) | |
| 316 { | 318 { |
| 317 if (mode == CopyClipList) { | 319 if (mode == CopyClipList) { |
| 318 m_clipList = other.m_clipList; | 320 m_clipList = other.m_clipList; |
| 319 } | 321 } |
| 320 if (m_realizedFont) | 322 if (m_realizedFont) |
| 321 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); | 323 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); |
| 322 } | 324 } |
| 323 | 325 |
| 324 CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons t State& other) | 326 CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons t State& other) |
| 325 { | 327 { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 348 m_transform = other.m_transform; | 350 m_transform = other.m_transform; |
| 349 m_invertibleCTM = other.m_invertibleCTM; | 351 m_invertibleCTM = other.m_invertibleCTM; |
| 350 m_imageSmoothingEnabled = other.m_imageSmoothingEnabled; | 352 m_imageSmoothingEnabled = other.m_imageSmoothingEnabled; |
| 351 m_textAlign = other.m_textAlign; | 353 m_textAlign = other.m_textAlign; |
| 352 m_textBaseline = other.m_textBaseline; | 354 m_textBaseline = other.m_textBaseline; |
| 353 m_direction = other.m_direction; | 355 m_direction = other.m_direction; |
| 354 m_unparsedFont = other.m_unparsedFont; | 356 m_unparsedFont = other.m_unparsedFont; |
| 355 m_font = other.m_font; | 357 m_font = other.m_font; |
| 356 m_realizedFont = other.m_realizedFont; | 358 m_realizedFont = other.m_realizedFont; |
| 357 m_hasClip = other.m_hasClip; | 359 m_hasClip = other.m_hasClip; |
| 360 m_hasComplexClip = other.m_hasComplexClip; | |
| 358 m_clipList = other.m_clipList; | 361 m_clipList = other.m_clipList; |
| 359 | 362 |
| 360 if (m_realizedFont) | 363 if (m_realizedFont) |
| 361 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); | 364 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); |
| 362 | 365 |
| 363 return *this; | 366 return *this; |
| 364 } | 367 } |
| 365 | 368 |
| 366 CanvasRenderingContext2D::State::~State() | 369 CanvasRenderingContext2D::State::~State() |
| 367 { | 370 { |
| (...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1115 | 1118 |
| 1116 SkPath skPath = path.skPath(); | 1119 SkPath skPath = path.skPath(); |
| 1117 skPath.setFillType(parseWinding(windingRuleString)); | 1120 skPath.setFillType(parseWinding(windingRuleString)); |
| 1118 ImageBuffer* buffer = canvas()->buffer(); | 1121 ImageBuffer* buffer = canvas()->buffer(); |
| 1119 if (buffer && buffer->needsClipTracking()) { | 1122 if (buffer && buffer->needsClipTracking()) { |
| 1120 modifiableState().m_clipList.clipPath(skPath, m_clipAntialiasing, affine TransformToSkMatrix(state().m_transform)); | 1123 modifiableState().m_clipList.clipPath(skPath, m_clipAntialiasing, affine TransformToSkMatrix(state().m_transform)); |
| 1121 } | 1124 } |
| 1122 | 1125 |
| 1123 c->clipPath(skPath, SkRegion::kIntersect_Op, m_clipAntialiasing == AntiAlias ed); | 1126 c->clipPath(skPath, SkRegion::kIntersect_Op, m_clipAntialiasing == AntiAlias ed); |
| 1124 if (!skPath.isRect(0)) | 1127 if (!skPath.isRect(0)) |
| 1125 drawingContext()->setHasComplexClip(); | 1128 modifiableState().m_hasComplexClip = true; |
| 1126 modifiableState().m_hasClip = true; | 1129 modifiableState().m_hasClip = true; |
| 1127 } | 1130 } |
| 1128 | 1131 |
| 1129 void CanvasRenderingContext2D::clip(const String& windingRuleString) | 1132 void CanvasRenderingContext2D::clip(const String& windingRuleString) |
| 1130 { | 1133 { |
| 1131 clipInternal(m_path, windingRuleString); | 1134 clipInternal(m_path, windingRuleString); |
| 1132 } | 1135 } |
| 1133 | 1136 |
| 1134 void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleSt ring) | 1137 void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleSt ring) |
| 1135 { | 1138 { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1229 pathRect, ScrollAlignment::alignCenterAlways, ScrollAlignment::alignTopA lways); | 1232 pathRect, ScrollAlignment::alignCenterAlways, ScrollAlignment::alignTopA lways); |
| 1230 | 1233 |
| 1231 // TODO: should implement "inform the user" that the caret and/or | 1234 // TODO: should implement "inform the user" that the caret and/or |
| 1232 // selection the specified rectangle of the canvas. See http://crbug.com/357 987 | 1235 // selection the specified rectangle of the canvas. See http://crbug.com/357 987 |
| 1233 } | 1236 } |
| 1234 | 1237 |
| 1235 void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he ight) | 1238 void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he ight) |
| 1236 { | 1239 { |
| 1237 if (!validateRectForCanvas(x, y, width, height)) | 1240 if (!validateRectForCanvas(x, y, width, height)) |
| 1238 return; | 1241 return; |
| 1239 GraphicsContext* context = drawingContext(); | |
| 1240 if (!context) | |
| 1241 return; | |
| 1242 if (!state().m_invertibleCTM) | |
| 1243 return; | |
| 1244 FloatRect rect(x, y, width, height); | |
| 1245 | 1242 |
| 1246 FloatRect dirtyRect; | 1243 GraphicsContext* c = drawingContext(); |
| 1247 if (!computeDirtyRect(rect, &dirtyRect)) | 1244 if (!c) |
| 1248 return; | 1245 return; |
| 1249 | 1246 |
| 1250 context->clearShadow(); | 1247 c->clearShadow(); |
| 1251 context->setAlphaAsFloat(1); | 1248 c->setAlphaAsFloat(1); |
| 1252 context->setCompositeOperation(SkXfermode::kSrcOver_Mode); | 1249 c->setCompositeOperation(SkXfermode::kClear_Mode); |
| 1253 | 1250 |
| 1254 context->clearRect(rect); | 1251 fillRect(x, y, width, height); |
| 1255 if (m_hitRegionManager) | |
| 1256 m_hitRegionManager->removeHitRegionsInRect(rect, state().m_transform); | |
| 1257 | 1252 |
| 1258 applyShadow(DrawShadowAndForeground); | 1253 applyShadow(DrawShadowAndForeground); |
| 1259 context->setAlphaAsFloat(state().m_globalAlpha); | 1254 c->setAlphaAsFloat(state().m_globalAlpha); |
| 1260 context->setCompositeOperation(state().m_globalComposite); | 1255 c->setCompositeOperation(state().m_globalComposite); |
| 1261 | 1256 |
| 1262 validateStateStack(); | 1257 if (m_hitRegionManager) { |
| 1263 didDraw(dirtyRect); | 1258 FloatRect rect(x, y, width, height); |
| 1259 m_hitRegionManager->removeHitRegionsInRect(rect, state().m_transform); | |
|
Ken Russell (switch to Gerrit)
2015/02/11 10:11:44
Why was the check removed above of whether the sta
Justin Novosad
2015/02/11 18:59:54
Good catch, my thinking was that we already check
| |
| 1260 } | |
|
dshwang
2015/02/11 08:37:52
why didDraw is removed?
Justin Novosad
2015/02/11 18:59:54
didDraw is taken care of by fillRect now. I'll add
| |
| 1264 } | 1261 } |
| 1265 | 1262 |
| 1266 // FIXME(crbug.com/425531): Funtional.h cannot handle override function signatur e. | 1263 // FIXME(crbug.com/425531): Funtional.h cannot handle override function signatur e. |
| 1267 static void fillRectOnContext(GraphicsContext* context, const FloatRect& rect) | 1264 static void fillRectOnContext(GraphicsContext* context, const FloatRect& rect) |
| 1268 { | 1265 { |
| 1269 context->fillRect(rect); | 1266 context->fillRect(rect); |
| 1270 } | 1267 } |
| 1271 | 1268 |
| 1272 static void strokeRectOnContext(GraphicsContext* context, const FloatRect& rect) | 1269 static void strokeRectOnContext(GraphicsContext* context, const FloatRect& rect) |
| 1273 { | 1270 { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1290 | 1287 |
| 1291 // from the HTML5 Canvas spec: | 1288 // from the HTML5 Canvas spec: |
| 1292 // If x0 = x1 and y0 = y1, then the linear gradient must paint nothing | 1289 // If x0 = x1 and y0 = y1, then the linear gradient must paint nothing |
| 1293 // If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint n othing | 1290 // If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint n othing |
| 1294 Gradient* gradient = c->fillGradient(); | 1291 Gradient* gradient = c->fillGradient(); |
| 1295 if (gradient && gradient->isZeroSize()) | 1292 if (gradient && gradient->isZeroSize()) |
| 1296 return; | 1293 return; |
| 1297 | 1294 |
| 1298 FloatRect rect(x, y, width, height); | 1295 FloatRect rect(x, y, width, height); |
| 1299 if (rectContainsTransformedRect(rect, clipBounds)) { | 1296 if (rectContainsTransformedRect(rect, clipBounds)) { |
| 1297 checkOverdraw(rect, &c->fillPaint(), NoImage, ClipFill); | |
| 1300 c->fillRect(rect); | 1298 c->fillRect(rect); |
| 1301 didDraw(clipBounds); | 1299 didDraw(clipBounds); |
| 1302 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { | 1300 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { |
| 1303 fullCanvasCompositedDraw(bind(&fillRectOnContext, c, rect)); | 1301 fullCanvasCompositedDraw(bind(&fillRectOnContext, c, rect)); |
| 1304 didDraw(clipBounds); | 1302 didDraw(clipBounds); |
| 1305 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) { | 1303 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) { |
| 1306 clearCanvas(); | 1304 clearCanvas(); |
| 1307 c->clearShadow(); | 1305 c->clearShadow(); // Takes care of signaling the overdraw |
| 1308 c->fillRect(rect); | 1306 c->fillRect(rect); |
| 1309 applyShadow(DrawShadowAndForeground); | 1307 applyShadow(DrawShadowAndForeground); |
| 1310 didDraw(clipBounds); | 1308 didDraw(clipBounds); |
| 1311 } else { | 1309 } else { |
| 1312 FloatRect dirtyRect; | 1310 FloatRect dirtyRect; |
| 1313 if (computeDirtyRect(rect, clipBounds, &dirtyRect)) { | 1311 if (computeDirtyRect(rect, clipBounds, &dirtyRect)) { |
| 1314 c->fillRect(rect); | 1312 c->fillRect(rect); |
| 1315 didDraw(dirtyRect); | 1313 didDraw(dirtyRect); |
| 1316 } | 1314 } |
| 1317 } | 1315 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1418 return value.getAsImageBitmap().get(); | 1416 return value.getAsImageBitmap().get(); |
| 1419 ASSERT_NOT_REACHED(); | 1417 ASSERT_NOT_REACHED(); |
| 1420 return nullptr; | 1418 return nullptr; |
| 1421 } | 1419 } |
| 1422 | 1420 |
| 1423 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, float x, float y, ExceptionState& exceptionState) | 1421 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, float x, float y, ExceptionState& exceptionState) |
| 1424 { | 1422 { |
| 1425 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource); | 1423 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource); |
| 1426 FloatSize sourceRectSize = imageSourceInternal->sourceSize(); | 1424 FloatSize sourceRectSize = imageSourceInternal->sourceSize(); |
| 1427 FloatSize destRectSize = imageSourceInternal->defaultDestinationSize(); | 1425 FloatSize destRectSize = imageSourceInternal->defaultDestinationSize(); |
| 1428 drawImageInternal(imageSourceInternal, 0, 0, sourceRectSize.width(), sourceR ectSize.height(), x, y, destRectSize.width(), destRectSize.height(), exceptionSt ate); | 1426 drawImage(imageSourceInternal, 0, 0, sourceRectSize.width(), sourceRectSize. height(), x, y, destRectSize.width(), destRectSize.height(), exceptionState); |
| 1429 } | 1427 } |
| 1430 | 1428 |
| 1431 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, | 1429 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, |
| 1432 float x, float y, float width, float height, ExceptionState& exceptionState) | 1430 float x, float y, float width, float height, ExceptionState& exceptionState) |
| 1433 { | 1431 { |
| 1434 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource); | 1432 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource); |
| 1435 FloatSize sourceRectSize = imageSourceInternal->sourceSize(); | 1433 FloatSize sourceRectSize = imageSourceInternal->sourceSize(); |
| 1436 drawImageInternal(imageSourceInternal, 0, 0, sourceRectSize.width(), sourceR ectSize.height(), x, y, width, height, exceptionState); | 1434 drawImage(imageSourceInternal, 0, 0, sourceRectSize.width(), sourceRectSize. height(), x, y, width, height, exceptionState); |
| 1437 } | 1435 } |
| 1438 | 1436 |
| 1439 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, | 1437 void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour ce, |
| 1440 float sx, float sy, float sw, float sh, | 1438 float sx, float sy, float sw, float sh, |
| 1441 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) | 1439 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) |
| 1442 { | 1440 { |
| 1443 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource); | 1441 CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource); |
| 1444 drawImageInternal(imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, dh, excep tionState); | 1442 drawImage(imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, dh, exceptionStat e); |
| 1445 } | 1443 } |
| 1446 | 1444 |
| 1447 static void drawVideo(SkCanvas* c, GraphicsContext* gc, CanvasImageSource* image Source, FloatRect srcRect, FloatRect dstRect) | 1445 static void drawVideo(SkCanvas* c, GraphicsContext* gc, CanvasImageSource* image Source, FloatRect srcRect, FloatRect dstRect) |
| 1448 { | 1446 { |
| 1449 HTMLVideoElement* video = static_cast<HTMLVideoElement*>(imageSource); | 1447 HTMLVideoElement* video = static_cast<HTMLVideoElement*>(imageSource); |
| 1450 c->save(); | 1448 c->save(); |
| 1451 c->clipRect(WebCoreFloatRectToSKRect(dstRect)); | 1449 c->clipRect(WebCoreFloatRectToSKRect(dstRect)); |
| 1452 c->translate(dstRect.x(), dstRect.y()); | 1450 c->translate(dstRect.x(), dstRect.y()); |
| 1453 c->scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.heigh t()); | 1451 c->scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.heigh t()); |
| 1454 c->translate(-srcRect.x(), -srcRect.y()); | 1452 c->translate(-srcRect.x(), -srcRect.y()); |
| 1455 video->paintCurrentFrameInContext(gc, IntRect(IntPoint(), IntSize(video->vid eoWidth(), video->videoHeight()))); | 1453 video->paintCurrentFrameInContext(gc, IntRect(IntPoint(), IntSize(video->vid eoWidth(), video->videoHeight()))); |
| 1456 c->restore(); | 1454 c->restore(); |
| 1457 } | 1455 } |
| 1458 | 1456 |
| 1459 static void drawImageOnContext(SkCanvas* c, GraphicsContext* gc, CanvasImageSour ce* imageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRec t) | 1457 static void drawImageOnContext(SkCanvas* c, GraphicsContext* gc, CanvasImageSour ce* imageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRec t) |
| 1460 { | 1458 { |
| 1461 if (!imageSource->isVideoElement()) { | 1459 if (!imageSource->isVideoElement()) { |
| 1462 gc->drawImage(image, dstRect, srcRect, gc->compositeOperation()); | 1460 gc->drawImage(image, dstRect, srcRect, gc->compositeOperation()); |
| 1463 } else { | 1461 } else { |
| 1464 drawVideo(c, gc, static_cast<HTMLVideoElement*>(imageSource), srcRect, d stRect); | 1462 drawVideo(c, gc, static_cast<HTMLVideoElement*>(imageSource), srcRect, d stRect); |
| 1465 } | 1463 } |
| 1466 } | 1464 } |
| 1467 | 1465 |
| 1468 void CanvasRenderingContext2D::drawImageInternal(CanvasImageSource* imageSource, | 1466 void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource, |
| 1469 float sx, float sy, float sw, float sh, | 1467 float sx, float sy, float sw, float sh, |
| 1470 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) | 1468 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) |
| 1471 { | 1469 { |
| 1472 RefPtr<Image> image; | 1470 RefPtr<Image> image; |
| 1473 SourceImageStatus sourceImageStatus = InvalidSourceImageStatus; | 1471 SourceImageStatus sourceImageStatus = InvalidSourceImageStatus; |
| 1474 if (!imageSource->isVideoElement()) { | 1472 if (!imageSource->isVideoElement()) { |
| 1475 SourceImageMode mode = canvas() == imageSource ? CopySourceImageIfVolati le : DontCopySourceImage; // Thunking for == | 1473 SourceImageMode mode = canvas() == imageSource ? CopySourceImageIfVolati le : DontCopySourceImage; // Thunking for == |
| 1476 image = imageSource->getSourceImageForCanvas(mode, &sourceImageStatus); | 1474 image = imageSource->getSourceImageForCanvas(mode, &sourceImageStatus); |
| 1477 if (sourceImageStatus == UndecodableSourceImageStatus) | 1475 if (sourceImageStatus == UndecodableSourceImageStatus) |
| 1478 exceptionState.throwDOMException(InvalidStateError, "The HTMLImageEl ement provided is in the 'broken' state."); | 1476 exceptionState.throwDOMException(InvalidStateError, "The HTMLImageEl ement provided is in the 'broken' state."); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1511 | 1509 |
| 1512 // FIXME: crbug.com/447218 | 1510 // FIXME: crbug.com/447218 |
| 1513 // We make the destination canvas fall out of display list mode by calling | 1511 // We make the destination canvas fall out of display list mode by calling |
| 1514 // willAccessPixels. This is to prevent run-away memory consumption caused b y SkSurface | 1512 // willAccessPixels. This is to prevent run-away memory consumption caused b y SkSurface |
| 1515 // copyOnWrite when the source canvas is animated and consumed at a rate hig her than the | 1513 // copyOnWrite when the source canvas is animated and consumed at a rate hig her than the |
| 1516 // presentation frame rate of the destination canvas. | 1514 // presentation frame rate of the destination canvas. |
| 1517 if (imageSource->isCanvasElement()) | 1515 if (imageSource->isCanvasElement()) |
| 1518 canvas()->buffer()->willAccessPixels(); | 1516 canvas()->buffer()->willAccessPixels(); |
| 1519 | 1517 |
| 1520 if (rectContainsTransformedRect(dstRect, clipBounds)) { | 1518 if (rectContainsTransformedRect(dstRect, clipBounds)) { |
| 1519 checkOverdraw(dstRect, &c->fillPaint(), imageSource->isOpaque() ? Opaque Image : NonOpaqueImage, ClipFill); | |
| 1521 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), srcRect , dstRect); | 1520 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), srcRect , dstRect); |
| 1522 didDraw(clipBounds); | 1521 didDraw(clipBounds); |
| 1523 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { | 1522 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { |
| 1524 fullCanvasCompositedDraw(bind(&drawImageOnContext, drawingCanvas(), c, i mageSource, image.get(), srcRect, dstRect)); | 1523 fullCanvasCompositedDraw(bind(&drawImageOnContext, drawingCanvas(), c, i mageSource, image.get(), srcRect, dstRect)); |
| 1525 didDraw(clipBounds); | 1524 didDraw(clipBounds); |
| 1526 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) { | 1525 } else if (state().m_globalComposite == SkXfermode::kSrc_Mode) { |
| 1527 clearCanvas(); | 1526 clearCanvas(); // takes care of signaling an overdraw |
| 1528 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), srcRect , dstRect); | 1527 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), srcRect , dstRect); |
| 1529 didDraw(clipBounds); | 1528 didDraw(clipBounds); |
| 1530 } else { | 1529 } else { |
| 1531 FloatRect dirtyRect; | 1530 FloatRect dirtyRect; |
| 1532 if (computeDirtyRect(dstRect, clipBounds, &dirtyRect)) { | 1531 if (computeDirtyRect(dstRect, clipBounds, &dirtyRect)) { |
| 1533 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), src Rect, dstRect); | 1532 drawImageOnContext(drawingCanvas(), c, imageSource, image.get(), src Rect, dstRect); |
| 1534 didDraw(dirtyRect); | 1533 didDraw(dirtyRect); |
| 1535 } | 1534 } |
| 1536 } | 1535 } |
| 1537 | 1536 |
| 1538 validateStateStack(); | 1537 validateStateStack(); |
| 1539 | 1538 |
| 1540 if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && can vas()->buffer()) | 1539 if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && can vas()->buffer()) |
| 1541 canvas()->buffer()->flush(); | 1540 canvas()->buffer()->flush(); |
| 1542 | 1541 |
| 1543 if (canvas()->originClean() && wouldTaintOrigin(imageSource)) | 1542 if (canvas()->originClean() && wouldTaintOrigin(imageSource)) |
| 1544 canvas()->setOriginTainted(); | 1543 canvas()->setOriginTainted(); |
| 1545 } | 1544 } |
| 1546 | 1545 |
| 1547 void CanvasRenderingContext2D::clearCanvas() | 1546 void CanvasRenderingContext2D::clearCanvas() |
| 1548 { | 1547 { |
| 1549 FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height()); | 1548 FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height()); |
| 1550 SkCanvas* c = drawingCanvas(); | 1549 SkCanvas* c = drawingCanvas(); |
| 1551 if (!c) | 1550 if (!c) |
| 1552 return; | 1551 return; |
| 1553 | 1552 |
| 1553 checkOverdraw(canvasRect, 0, NoImage, ClipFill); | |
| 1554 c->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK); | 1554 c->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK); |
| 1555 } | 1555 } |
| 1556 | 1556 |
| 1557 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect , const FloatRect& transformedRect) const | 1557 bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect , const FloatRect& transformedRect) const |
| 1558 { | 1558 { |
| 1559 FloatQuad quad(rect); | 1559 FloatQuad quad(rect); |
| 1560 FloatQuad transformedQuad(transformedRect); | 1560 FloatQuad transformedQuad(transformedRect); |
| 1561 return state().m_transform.mapQuad(quad).containsQuad(transformedQuad); | 1561 return state().m_transform.mapQuad(quad).containsQuad(transformedQuad); |
| 1562 } | 1562 } |
| 1563 | 1563 |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1784 clipRect.intersect(IntRect(0, 0, data->width(), data->height())); | 1784 clipRect.intersect(IntRect(0, 0, data->width(), data->height())); |
| 1785 IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy)); | 1785 IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy)); |
| 1786 IntRect destRect = enclosingIntRect(clipRect); | 1786 IntRect destRect = enclosingIntRect(clipRect); |
| 1787 destRect.move(destOffset); | 1787 destRect.move(destOffset); |
| 1788 destRect.intersect(IntRect(IntPoint(), buffer->size())); | 1788 destRect.intersect(IntRect(IntPoint(), buffer->size())); |
| 1789 if (destRect.isEmpty()) | 1789 if (destRect.isEmpty()) |
| 1790 return; | 1790 return; |
| 1791 IntRect sourceRect(destRect); | 1791 IntRect sourceRect(destRect); |
| 1792 sourceRect.move(-destOffset); | 1792 sourceRect.move(-destOffset); |
| 1793 | 1793 |
| 1794 checkOverdraw(destRect, 0, NoImage, UntransformedUnclippedFill); | |
| 1795 | |
| 1794 buffer->putByteArray(Unmultiplied, data->data()->data(), IntSize(data->width (), data->height()), sourceRect, IntPoint(destOffset)); | 1796 buffer->putByteArray(Unmultiplied, data->data()->data(), IntSize(data->width (), data->height()), sourceRect, IntPoint(destOffset)); |
| 1795 | 1797 |
| 1796 didDraw(destRect); | 1798 didDraw(destRect); |
| 1797 } | 1799 } |
| 1798 | 1800 |
| 1799 String CanvasRenderingContext2D::font() const | 1801 String CanvasRenderingContext2D::font() const |
| 1800 { | 1802 { |
| 1801 if (!state().m_realizedFont) | 1803 if (!state().m_realizedFont) |
| 1802 return defaultFont; | 1804 return defaultFont; |
| 1803 | 1805 |
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2375 } | 2377 } |
| 2376 | 2378 |
| 2377 unsigned CanvasRenderingContext2D::hitRegionsCount() const | 2379 unsigned CanvasRenderingContext2D::hitRegionsCount() const |
| 2378 { | 2380 { |
| 2379 if (m_hitRegionManager) | 2381 if (m_hitRegionManager) |
| 2380 return m_hitRegionManager->getHitRegionsCount(); | 2382 return m_hitRegionManager->getHitRegionsCount(); |
| 2381 | 2383 |
| 2382 return 0; | 2384 return 0; |
| 2383 } | 2385 } |
| 2384 | 2386 |
| 2387 void CanvasRenderingContext2D::checkOverdraw(const SkRect& rect, const SkPaint* paint, ImageType imageType, DrawType drawType) | |
| 2388 { | |
| 2389 SkCanvas* c = drawingCanvas(); | |
| 2390 if (!c || !canvas()->buffer()->isRecording()) | |
|
Stephen Chennney
2015/02/11 14:33:20
There's a lot of implicit non-null here. As writte
Justin Novosad
2015/02/11 18:59:54
Those checks are taken care of in drawingCanvas().
Stephen Chennney
2015/02/11 19:29:47
OK.
| |
| 2391 return; | |
| 2392 | |
| 2393 SkRect deviceRect; | |
| 2394 if (drawType == UntransformedUnclippedFill) { | |
| 2395 deviceRect = rect; | |
| 2396 } else { | |
| 2397 ASSERT(drawType == ClipFill); | |
| 2398 if (state().m_hasComplexClip) | |
| 2399 return; | |
| 2400 | |
| 2401 SkIRect skIBounds; | |
| 2402 if (!c->getClipDeviceBounds(&skIBounds)) | |
| 2403 return; | |
| 2404 deviceRect = SkRect::Make(skIBounds); | |
| 2405 } | |
| 2406 | |
| 2407 const SkImageInfo& imageInfo = c->imageInfo(); | |
| 2408 if (!deviceRect.contains(SkRect::MakeWH(imageInfo.width(), imageInfo.height( )))) | |
| 2409 return; | |
| 2410 | |
| 2411 bool isSourceOver = true; | |
| 2412 unsigned alpha = 0xFF; | |
| 2413 if (paint) { | |
| 2414 if (paint->getLooper() || paint->getImageFilter() || paint->getMaskFilte r()) | |
| 2415 return; | |
| 2416 | |
| 2417 SkXfermode* xfermode = paint->getXfermode(); | |
| 2418 if (xfermode) { | |
| 2419 SkXfermode::Mode mode; | |
| 2420 if (xfermode->asMode(&mode)) { | |
| 2421 isSourceOver = mode == SkXfermode::kSrcOver_Mode; | |
| 2422 if (!isSourceOver && mode != SkXfermode::kSrc_Mode && mode != Sk Xfermode::kClear_Mode) | |
| 2423 return; // The code below only knows how to handle Src, SrcO ver, and Clear | |
| 2424 } else { | |
| 2425 // unknown xfermode | |
| 2426 ASSERT_NOT_REACHED(); | |
| 2427 return; | |
| 2428 } | |
| 2429 } | |
| 2430 | |
| 2431 alpha = paint->getAlpha(); | |
| 2432 | |
| 2433 if (isSourceOver && imageType == NoImage) { | |
| 2434 SkShader* shader = paint->getShader(); | |
| 2435 if (shader) { | |
| 2436 if (shader->isOpaque() && alpha == 0xFF) | |
| 2437 canvas()->buffer()->willOverwriteCanvas(); | |
| 2438 return; | |
| 2439 } | |
| 2440 } | |
| 2441 } | |
| 2442 | |
| 2443 if (isSourceOver) { | |
| 2444 // With source over, we need to certify that alpha == 0xFF for all pixel s | |
| 2445 if (imageType == NonOpaqueImage) | |
| 2446 return; | |
| 2447 if (alpha < 0xFF) | |
| 2448 return; | |
| 2449 } | |
| 2450 | |
| 2451 canvas()->buffer()->willOverwriteCanvas(); | |
| 2452 } | |
| 2453 | |
| 2385 } // namespace blink | 2454 } // namespace blink |
| OLD | NEW |