| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 #include "core/html/canvas/DOMPath.h" | 56 #include "core/html/canvas/DOMPath.h" |
| 57 #include "core/frame/ImageBitmap.h" | 57 #include "core/frame/ImageBitmap.h" |
| 58 #include "core/rendering/RenderImage.h" | 58 #include "core/rendering/RenderImage.h" |
| 59 #include "core/rendering/RenderLayer.h" | 59 #include "core/rendering/RenderLayer.h" |
| 60 #include "core/rendering/RenderTheme.h" | 60 #include "core/rendering/RenderTheme.h" |
| 61 #include "platform/fonts/FontCache.h" | 61 #include "platform/fonts/FontCache.h" |
| 62 #include "platform/geometry/FloatQuad.h" | 62 #include "platform/geometry/FloatQuad.h" |
| 63 #include "platform/graphics/GraphicsContextStateSaver.h" | 63 #include "platform/graphics/GraphicsContextStateSaver.h" |
| 64 #include "platform/graphics/DrawLooper.h" | 64 #include "platform/graphics/DrawLooper.h" |
| 65 #include "platform/text/TextRun.h" | 65 #include "platform/text/TextRun.h" |
| 66 #include "platform/weborigin/SecurityOrigin.h" | |
| 67 #include "wtf/CheckedArithmetic.h" | 66 #include "wtf/CheckedArithmetic.h" |
| 68 #include "wtf/MathExtras.h" | 67 #include "wtf/MathExtras.h" |
| 69 #include "wtf/OwnPtr.h" | 68 #include "wtf/OwnPtr.h" |
| 70 #include "wtf/Uint8ClampedArray.h" | 69 #include "wtf/Uint8ClampedArray.h" |
| 71 #include "wtf/text/StringBuilder.h" | 70 #include "wtf/text/StringBuilder.h" |
| 72 | 71 |
| 73 using namespace std; | 72 using namespace std; |
| 74 | 73 |
| 75 namespace WebCore { | 74 namespace WebCore { |
| 76 | 75 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 return; | 282 return; |
| 284 | 283 |
| 285 if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentColor(*style
)) | 284 if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentColor(*style
)) |
| 286 return; | 285 return; |
| 287 | 286 |
| 288 if (style->isCurrentColor()) { | 287 if (style->isCurrentColor()) { |
| 289 if (style->hasOverrideAlpha()) | 288 if (style->hasOverrideAlpha()) |
| 290 style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentCo
lor(canvas()), style->overrideAlpha())); | 289 style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentCo
lor(canvas()), style->overrideAlpha())); |
| 291 else | 290 else |
| 292 style = CanvasStyle::createFromRGBA(currentColor(canvas())); | 291 style = CanvasStyle::createFromRGBA(currentColor(canvas())); |
| 293 } else | 292 } else if (canvas()->originClean() && style->canvasPattern() && !style->canv
asPattern()->originClean()) { |
| 294 checkOrigin(style->canvasPattern()); | 293 canvas()->setOriginTainted(); |
| 294 } |
| 295 | 295 |
| 296 realizeSaves(); | 296 realizeSaves(); |
| 297 modifiableState().m_strokeStyle = style.release(); | 297 modifiableState().m_strokeStyle = style.release(); |
| 298 GraphicsContext* c = drawingContext(); | 298 GraphicsContext* c = drawingContext(); |
| 299 if (!c) | 299 if (!c) |
| 300 return; | 300 return; |
| 301 state().m_strokeStyle->applyStrokeColor(c); | 301 state().m_strokeStyle->applyStrokeColor(c); |
| 302 modifiableState().m_unparsedStrokeColor = String(); | 302 modifiableState().m_unparsedStrokeColor = String(); |
| 303 } | 303 } |
| 304 | 304 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 315 return; | 315 return; |
| 316 | 316 |
| 317 if (state().m_fillStyle && state().m_fillStyle->isEquivalentColor(*style)) | 317 if (state().m_fillStyle && state().m_fillStyle->isEquivalentColor(*style)) |
| 318 return; | 318 return; |
| 319 | 319 |
| 320 if (style->isCurrentColor()) { | 320 if (style->isCurrentColor()) { |
| 321 if (style->hasOverrideAlpha()) | 321 if (style->hasOverrideAlpha()) |
| 322 style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentCo
lor(canvas()), style->overrideAlpha())); | 322 style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentCo
lor(canvas()), style->overrideAlpha())); |
| 323 else | 323 else |
| 324 style = CanvasStyle::createFromRGBA(currentColor(canvas())); | 324 style = CanvasStyle::createFromRGBA(currentColor(canvas())); |
| 325 } else | 325 } else if (canvas()->originClean() && style->canvasPattern() && !style->canv
asPattern()->originClean()) { |
| 326 checkOrigin(style->canvasPattern()); | 326 canvas()->setOriginTainted(); |
| 327 } |
| 327 | 328 |
| 328 realizeSaves(); | 329 realizeSaves(); |
| 329 modifiableState().m_fillStyle = style.release(); | 330 modifiableState().m_fillStyle = style.release(); |
| 330 GraphicsContext* c = drawingContext(); | 331 GraphicsContext* c = drawingContext(); |
| 331 if (!c) | 332 if (!c) |
| 332 return; | 333 return; |
| 333 state().m_fillStyle->applyFillColor(c); | 334 state().m_fillStyle->applyFillColor(c); |
| 334 modifiableState().m_unparsedFillColor = String(); | 335 modifiableState().m_unparsedFillColor = String(); |
| 335 } | 336 } |
| 336 | 337 |
| (...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1264 bool CanvasRenderingContext2D::shouldDrawShadows() const | 1265 bool CanvasRenderingContext2D::shouldDrawShadows() const |
| 1265 { | 1266 { |
| 1266 return alphaChannel(state().m_shadowColor) && (state().m_shadowBlur || !stat
e().m_shadowOffset.isZero()); | 1267 return alphaChannel(state().m_shadowColor) && (state().m_shadowBlur || !stat
e().m_shadowOffset.isZero()); |
| 1267 } | 1268 } |
| 1268 | 1269 |
| 1269 enum ImageSizeType { | 1270 enum ImageSizeType { |
| 1270 ImageSizeAfterDevicePixelRatio, | 1271 ImageSizeAfterDevicePixelRatio, |
| 1271 ImageSizeBeforeDevicePixelRatio | 1272 ImageSizeBeforeDevicePixelRatio |
| 1272 }; | 1273 }; |
| 1273 | 1274 |
| 1274 static LayoutSize sizeFor(HTMLImageElement* image, ImageSizeType sizeType) | |
| 1275 { | |
| 1276 LayoutSize size; | |
| 1277 ImageResource* cachedImage = image->cachedImage(); | |
| 1278 if (cachedImage) { | |
| 1279 size = cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FI
XME: Not sure about this. | |
| 1280 | |
| 1281 if (sizeType == ImageSizeAfterDevicePixelRatio && image->renderer() && i
mage->renderer()->isRenderImage() && cachedImage->image() && !cachedImage->image
()->hasRelativeWidth()) | |
| 1282 size.scale(toRenderImage(image->renderer())->imageDevicePixelRatio()
); | |
| 1283 } | |
| 1284 return size; | |
| 1285 } | |
| 1286 | |
| 1287 static IntSize sizeFor(HTMLVideoElement* video) | |
| 1288 { | |
| 1289 if (MediaPlayer* player = video->player()) | |
| 1290 return player->naturalSize(); | |
| 1291 return IntSize(); | |
| 1292 } | |
| 1293 | |
| 1294 static inline FloatRect normalizeRect(const FloatRect& rect) | 1275 static inline FloatRect normalizeRect(const FloatRect& rect) |
| 1295 { | 1276 { |
| 1296 return FloatRect(min(rect.x(), rect.maxX()), | 1277 return FloatRect(min(rect.x(), rect.maxX()), |
| 1297 min(rect.y(), rect.maxY()), | 1278 min(rect.y(), rect.maxY()), |
| 1298 max(rect.width(), -rect.width()), | 1279 max(rect.width(), -rect.width()), |
| 1299 max(rect.height(), -rect.height())); | 1280 max(rect.height(), -rect.height())); |
| 1300 } | 1281 } |
| 1301 | 1282 |
| 1302 static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* s
rcRect, FloatRect* dstRect) | 1283 static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* s
rcRect, FloatRect* dstRect) |
| 1303 { | 1284 { |
| 1304 if (imageRect.contains(*srcRect)) | 1285 if (imageRect.contains(*srcRect)) |
| 1305 return; | 1286 return; |
| 1306 | 1287 |
| 1307 // Compute the src to dst transform | 1288 // Compute the src to dst transform |
| 1308 FloatSize scale(dstRect->size().width() / srcRect->size().width(), dstRect->
size().height() / srcRect->size().height()); | 1289 FloatSize scale(dstRect->size().width() / srcRect->size().width(), dstRect->
size().height() / srcRect->size().height()); |
| 1309 FloatPoint scaledSrcLocation = srcRect->location(); | 1290 FloatPoint scaledSrcLocation = srcRect->location(); |
| 1310 scaledSrcLocation.scale(scale.width(), scale.height()); | 1291 scaledSrcLocation.scale(scale.width(), scale.height()); |
| 1311 FloatSize offset = dstRect->location() - scaledSrcLocation; | 1292 FloatSize offset = dstRect->location() - scaledSrcLocation; |
| 1312 | 1293 |
| 1313 srcRect->intersect(imageRect); | 1294 srcRect->intersect(imageRect); |
| 1314 | 1295 |
| 1315 // To clip the destination rectangle in the same proportion, transform the c
lipped src rect | 1296 // To clip the destination rectangle in the same proportion, transform the c
lipped src rect |
| 1316 *dstRect = *srcRect; | 1297 *dstRect = *srcRect; |
| 1317 dstRect->scale(scale.width(), scale.height()); | 1298 dstRect->scale(scale.width(), scale.height()); |
| 1318 dstRect->move(offset); | 1299 dstRect->move(offset); |
| 1319 } | 1300 } |
| 1320 | 1301 |
| 1321 void CanvasRenderingContext2D::drawImageInternal(Image* image, const FloatRect&
srcRect, const FloatRect& dstRect, const CompositeOperator& op, const blink::Web
BlendMode& blendMode) | 1302 static bool checkImageSource(CanvasImageSource* imageSource, ExceptionState& exc
eptionState) |
| 1322 { | 1303 { |
| 1323 if (!image) | 1304 if (!imageSource) { |
| 1324 return; | 1305 // FIXME: Message should mention ImageBitmap once that feature ships. |
| 1325 | 1306 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, String("HTMLImageElement, HTMLCanvasElement or HTM
LVideoElement"))); |
| 1326 GraphicsContext* c = drawingContext(); | 1307 return false; |
| 1327 if (!c) | |
| 1328 return; | |
| 1329 if (!state().m_invertibleCTM) | |
| 1330 return; | |
| 1331 FloatRect clipBounds; | |
| 1332 if (!drawingContext()->getTransformedClipBounds(&clipBounds)) | |
| 1333 return; | |
| 1334 | |
| 1335 if (rectContainsTransformedRect(dstRect, clipBounds)) { | |
| 1336 c->drawImage(image, dstRect, srcRect, op, blendMode); | |
| 1337 didDraw(clipBounds); | |
| 1338 } else if (isFullCanvasCompositeMode(op)) { | |
| 1339 fullCanvasCompositedDrawImage(image, dstRect, srcRect, op); | |
| 1340 didDraw(clipBounds); | |
| 1341 } else if (op == CompositeCopy) { | |
| 1342 clearCanvas(); | |
| 1343 c->drawImage(image, dstRect, srcRect, op, blendMode); | |
| 1344 didDraw(clipBounds); | |
| 1345 } else { | |
| 1346 FloatRect dirtyRect; | |
| 1347 if (computeDirtyRect(dstRect, &dirtyRect)) { | |
| 1348 c->drawImage(image, dstRect, srcRect, op, blendMode); | |
| 1349 didDraw(dirtyRect); | |
| 1350 } | |
| 1351 } | 1308 } |
| 1309 return true; |
| 1352 } | 1310 } |
| 1353 | 1311 |
| 1354 void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap, float x, float y,
ExceptionState& exceptionState) | 1312 void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource, float x
, float y, ExceptionState& exceptionState) |
| 1355 { | 1313 { |
| 1356 if (!bitmap) { | 1314 if (!checkImageSource(imageSource, exceptionState)) |
| 1357 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "ImageBitmap")); | |
| 1358 return; | 1315 return; |
| 1359 } | 1316 FloatSize destRectSize = imageSource->defaultDestinationSize(); |
| 1360 drawImage(bitmap, x, y, bitmap->width(), bitmap->height(), exceptionState); | 1317 drawImage(imageSource, x, y, destRectSize.width(), destRectSize.height(), ex
ceptionState); |
| 1361 } | 1318 } |
| 1362 | 1319 |
| 1363 void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap, | 1320 void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource, |
| 1364 float x, float y, float width, float height, ExceptionState& exceptionState) | 1321 float x, float y, float width, float height, ExceptionState& exceptionState) |
| 1365 { | 1322 { |
| 1366 if (!bitmap) { | 1323 if (!checkImageSource(imageSource, exceptionState)) |
| 1367 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "ImageBitmap")); | |
| 1368 return; | 1324 return; |
| 1369 } | 1325 FloatSize sourceRectSize = imageSource->sourceSize(); |
| 1370 if (!bitmap->bitmapRect().width() || !bitmap->bitmapRect().height()) | 1326 drawImage(imageSource, 0, 0, sourceRectSize.width(), sourceRectSize.height()
, x, y, width, height, exceptionState); |
| 1371 return; | |
| 1372 | |
| 1373 drawImage(bitmap, 0, 0, bitmap->width(), bitmap->height(), x, y, width, heig
ht, exceptionState); | |
| 1374 } | 1327 } |
| 1375 | 1328 |
| 1376 void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap, | 1329 void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource, |
| 1377 float sx, float sy, float sw, float sh, | 1330 float sx, float sy, float sw, float sh, |
| 1378 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) | 1331 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) |
| 1379 { | 1332 { |
| 1380 if (!bitmap) { | 1333 if (!checkImageSource(imageSource, exceptionState)) |
| 1381 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "ImageBitmap")); | |
| 1382 return; | |
| 1383 } | |
| 1384 | |
| 1385 FloatRect srcRect(sx, sy, sw, sh); | |
| 1386 FloatRect dstRect(dx, dy, dw, dh); | |
| 1387 FloatRect bitmapRect = bitmap->bitmapRect(); | |
| 1388 | |
| 1389 if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfi
nite(dstRect.width()) || !std::isfinite(dstRect.height()) | |
| 1390 || !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::i
sfinite(srcRect.width()) || !std::isfinite(srcRect.height())) | |
| 1391 return; | 1334 return; |
| 1392 | 1335 |
| 1393 if (!dstRect.width() || !dstRect.height() || !srcRect.width() || !srcRect.he
ight()) | |
| 1394 return; | |
| 1395 | |
| 1396 ASSERT(bitmap->height() && bitmap->width()); | |
| 1397 FloatRect normalizedSrcRect = normalizeRect(srcRect); | |
| 1398 FloatRect normalizedDstRect = normalizeRect(dstRect); | |
| 1399 | |
| 1400 // Clip the rects to where the user thinks that the image is situated. | |
| 1401 clipRectsToImageRect(IntRect(IntPoint(), bitmap->size()), &normalizedSrcRect
, &normalizedDstRect); | |
| 1402 | |
| 1403 FloatRect intersectRect = intersection(bitmapRect, normalizedSrcRect); | |
| 1404 FloatRect actualSrcRect(intersectRect); | |
| 1405 | |
| 1406 IntPoint bitmapOffset = bitmap->bitmapOffset(); | |
| 1407 actualSrcRect.move(bitmapOffset - bitmapRect.location()); | |
| 1408 FloatRect imageRect = FloatRect(bitmapOffset, bitmapRect.size()); | |
| 1409 | |
| 1410 FloatRect actualDstRect(FloatPoint(intersectRect.location() - normalizedSrcR
ect.location()), bitmapRect.size()); | |
| 1411 actualDstRect.scale(normalizedDstRect.width() / normalizedSrcRect.width() *
intersectRect.width() / bitmapRect.width(), | |
| 1412 normalizedDstRect.height() / normalizedSrcRect.height() * intersectRect.
height() / bitmapRect.height()); | |
| 1413 actualDstRect.moveBy(normalizedDstRect.location()); | |
| 1414 | |
| 1415 if (!imageRect.intersects(actualSrcRect)) | |
| 1416 return; | |
| 1417 | |
| 1418 RefPtr<Image> imageForRendering = bitmap->bitmapImage(); | |
| 1419 if (!imageForRendering) | |
| 1420 return; | |
| 1421 | |
| 1422 drawImageInternal(imageForRendering.get(), actualSrcRect, actualDstRect, sta
te().m_globalComposite, state().m_globalBlend); | |
| 1423 } | |
| 1424 | |
| 1425 void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float
y, ExceptionState& exceptionState) | |
| 1426 { | |
| 1427 if (!image) { | |
| 1428 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "HTMLImageElement")); | |
| 1429 return; | |
| 1430 } | |
| 1431 LayoutSize destRectSize = sizeFor(image, ImageSizeAfterDevicePixelRatio); | |
| 1432 drawImage(image, x, y, destRectSize.width(), destRectSize.height(), exceptio
nState); | |
| 1433 } | |
| 1434 | |
| 1435 void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, | |
| 1436 float x, float y, float width, float height, ExceptionState& exceptionState) | |
| 1437 { | |
| 1438 if (!image) { | |
| 1439 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "HTMLImageElement")); | |
| 1440 return; | |
| 1441 } | |
| 1442 LayoutSize sourceRectSize = sizeFor(image, ImageSizeBeforeDevicePixelRatio); | |
| 1443 drawImage(image, FloatRect(0, 0, sourceRectSize.width(), sourceRectSize.heig
ht()), FloatRect(x, y, width, height), exceptionState); | |
| 1444 } | |
| 1445 | |
| 1446 void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, | |
| 1447 float sx, float sy, float sw, float sh, | |
| 1448 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) | |
| 1449 { | |
| 1450 drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), excep
tionState); | |
| 1451 } | |
| 1452 | |
| 1453 void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
t& srcRect, const FloatRect& dstRect, ExceptionState& exceptionState) | |
| 1454 { | |
| 1455 drawImage(image, srcRect, dstRect, state().m_globalComposite, state().m_glob
alBlend, exceptionState); | |
| 1456 } | |
| 1457 | |
| 1458 void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
t& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const blink::
WebBlendMode& blendMode, ExceptionState& exceptionState) | |
| 1459 { | |
| 1460 if (!image) { | |
| 1461 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "HTMLImageElement")); | |
| 1462 return; | |
| 1463 } | |
| 1464 | |
| 1465 if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfi
nite(dstRect.width()) || !std::isfinite(dstRect.height()) | |
| 1466 || !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::i
sfinite(srcRect.width()) || !std::isfinite(srcRect.height())) | |
| 1467 return; | |
| 1468 | |
| 1469 ImageResource* cachedImage = image->cachedImage(); | |
| 1470 if (!cachedImage || !image->complete()) | |
| 1471 return; | |
| 1472 | |
| 1473 LayoutSize size = sizeFor(image, ImageSizeBeforeDevicePixelRatio); | |
| 1474 if (!size.width() || !size.height() || !dstRect.width() || !dstRect.height()
|| !srcRect.width() || !srcRect.height()) | |
| 1475 return; | |
| 1476 | |
| 1477 FloatRect normalizedSrcRect = normalizeRect(srcRect); | |
| 1478 FloatRect normalizedDstRect = normalizeRect(dstRect); | |
| 1479 | |
| 1480 FloatRect imageRect = FloatRect(FloatPoint(), size); | |
| 1481 if (!imageRect.intersects(normalizedSrcRect)) | |
| 1482 return; | |
| 1483 | |
| 1484 clipRectsToImageRect(imageRect, &normalizedSrcRect, &normalizedDstRect); | |
| 1485 | |
| 1486 checkOrigin(image); | |
| 1487 | |
| 1488 Image* imageForRendering = cachedImage->imageForRenderer(image->renderer()); | |
| 1489 | |
| 1490 // For images that depend on an unavailable container size, we need to fall
back to the intrinsic | |
| 1491 // object size. http://www.w3.org/TR/2dcontext2/#dom-context-2d-drawimage | |
| 1492 // FIXME: Without a specified image size this should resolve against the can
vas element's size, see: crbug.com/230163. | |
| 1493 if (!image->renderer() && imageForRendering->usesContainerSize()) | |
| 1494 imageForRendering->setContainerSize(imageForRendering->size()); | |
| 1495 | |
| 1496 drawImageInternal(imageForRendering, normalizedSrcRect, normalizedDstRect, o
p, blendMode); | |
| 1497 } | |
| 1498 | |
| 1499 void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, float
x, float y, ExceptionState& exceptionState) | |
| 1500 { | |
| 1501 drawImage(sourceCanvas, 0, 0, sourceCanvas->width(), sourceCanvas->height(),
x, y, sourceCanvas->width(), sourceCanvas->height(), exceptionState); | |
| 1502 } | |
| 1503 | |
| 1504 void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, | |
| 1505 float x, float y, float width, float height, ExceptionState& exceptionState) | |
| 1506 { | |
| 1507 drawImage(sourceCanvas, FloatRect(0, 0, sourceCanvas->width(), sourceCanvas-
>height()), FloatRect(x, y, width, height), exceptionState); | |
| 1508 } | |
| 1509 | |
| 1510 void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, | |
| 1511 float sx, float sy, float sw, float sh, | |
| 1512 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) | |
| 1513 { | |
| 1514 drawImage(sourceCanvas, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh)
, exceptionState); | |
| 1515 } | |
| 1516 | |
| 1517 void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const
FloatRect& srcRect, | |
| 1518 const FloatRect& dstRect, ExceptionState& exceptionState) | |
| 1519 { | |
| 1520 if (!sourceCanvas) { | |
| 1521 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "HTMLCanvasElement")); | |
| 1522 return; | |
| 1523 } | |
| 1524 | |
| 1525 FloatRect srcCanvasRect = FloatRect(FloatPoint(), sourceCanvas->size()); | |
| 1526 | |
| 1527 if (!srcCanvasRect.width() || !srcCanvasRect.height() || !srcRect.width() ||
!srcRect.height()) | |
| 1528 return; | |
| 1529 | |
| 1530 FloatRect normalizedSrcRect = normalizeRect(srcRect); | |
| 1531 FloatRect normalizedDstRect = normalizeRect(dstRect); | |
| 1532 | |
| 1533 if (!srcCanvasRect.intersects(normalizedSrcRect) || !normalizedDstRect.width
() || !normalizedDstRect.height()) | |
| 1534 return; | |
| 1535 | |
| 1536 clipRectsToImageRect(srcCanvasRect, &normalizedSrcRect, &normalizedDstRect); | |
| 1537 | |
| 1538 GraphicsContext* c = drawingContext(); | |
| 1539 if (!c) | |
| 1540 return; | |
| 1541 if (!state().m_invertibleCTM) | 1336 if (!state().m_invertibleCTM) |
| 1542 return; | 1337 return; |
| 1543 | 1338 |
| 1544 // FIXME: Do this through platform-independent GraphicsContext API. | 1339 RefPtr<Image> image; |
| 1545 ImageBuffer* buffer = sourceCanvas->buffer(); | 1340 bool imageSourceIsVolatile = false; |
| 1546 if (!buffer) | 1341 if (!imageSource->isVideoElement()) { |
| 1342 CanvasImageSourceUsage usage = canvas()->asCanvasImageSource() == imageS
ource ? DrawToSelfCanvasImageSourceUsage : DrawCanvasImageSourceUsage; |
| 1343 image = imageSource->getSourceImageForCanvas(exceptionState, usage, &ima
geSourceIsVolatile); |
| 1344 if (!image || !image->width() || !image->height()) |
| 1345 return; |
| 1346 } |
| 1347 |
| 1348 if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dw) || !std::
isfinite(dh) |
| 1349 || !std::isfinite(sx) || !std::isfinite(sy) || !std::isfinite(sw) || !st
d::isfinite(sh) |
| 1350 || !dw || !dh || !sw || !sh) |
| 1547 return; | 1351 return; |
| 1548 | 1352 |
| 1549 FloatRect clipBounds; | 1353 FloatRect clipBounds; |
| 1550 if (!drawingContext()->getTransformedClipBounds(&clipBounds)) | 1354 if (!drawingContext()->getTransformedClipBounds(&clipBounds)) |
| 1551 return; | 1355 return; |
| 1552 | 1356 |
| 1553 checkOrigin(sourceCanvas); | 1357 FloatRect srcRect = normalizeRect(FloatRect(sx, sy, sw, sh)); |
| 1358 FloatRect dstRect = normalizeRect(FloatRect(dx, dy, dw, dh)); |
| 1554 | 1359 |
| 1555 // If we're drawing from one accelerated canvas 2d to another, avoid calling
sourceCanvas->makeRenderingResultsAvailable() | 1360 clipRectsToImageRect(FloatRect(FloatPoint(), imageSource->sourceSize()), &sr
cRect, &dstRect); |
| 1556 // as that will do a readback to software. | |
| 1557 CanvasRenderingContext* sourceContext = sourceCanvas->renderingContext(); | |
| 1558 // FIXME: Implement an accelerated path for drawing from a WebGL canvas to a
2d canvas when possible. | |
| 1559 if (sourceContext && sourceContext->is3d()) | |
| 1560 sourceContext->paintRenderingResultsToCanvas(); | |
| 1561 | 1361 |
| 1562 if (rectContainsTransformedRect(normalizedDstRect, clipBounds)) { | 1362 imageSource->adjustDrawRects(&srcRect, &dstRect); |
| 1563 c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state()
.m_globalComposite, state().m_globalBlend); | |
| 1564 didDraw(clipBounds); | |
| 1565 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { | |
| 1566 fullCanvasCompositedDrawImage(buffer, normalizedDstRect, normalizedSrcRe
ct, state().m_globalComposite); | |
| 1567 didDraw(clipBounds); | |
| 1568 } else if (state().m_globalComposite == CompositeCopy) { | |
| 1569 clearCanvas(); | |
| 1570 c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state()
.m_globalComposite, state().m_globalBlend); | |
| 1571 didDraw(clipBounds); | |
| 1572 } else { | |
| 1573 FloatRect dirtyRect; | |
| 1574 if (computeDirtyRect(normalizedDstRect, clipBounds, &dirtyRect)) { | |
| 1575 c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, sta
te().m_globalComposite, state().m_globalBlend); | |
| 1576 didDraw(dirtyRect); | |
| 1577 } | |
| 1578 } | |
| 1579 | 1363 |
| 1580 // Flush canvas's ImageBuffer when drawImage from WebGL to HW accelerated 2d
canvas | 1364 if (srcRect.isEmpty()) |
| 1581 if (sourceContext && sourceContext->is3d() && is2d() && isAccelerated() && c
anvas()->buffer()) | |
| 1582 canvas()->buffer()->flush(); | |
| 1583 } | |
| 1584 | |
| 1585 void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, float x, float
y, ExceptionState& exceptionState) | |
| 1586 { | |
| 1587 if (!video) { | |
| 1588 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "HTMLVideoElement")); | |
| 1589 return; | 1365 return; |
| 1590 } | |
| 1591 IntSize size = sizeFor(video); | |
| 1592 drawImage(video, x, y, size.width(), size.height(), exceptionState); | |
| 1593 } | |
| 1594 | |
| 1595 void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, | |
| 1596 float x, float y, float width, float height, ExceptionState& exceptionState) | |
| 1597 { | |
| 1598 if (!video) { | |
| 1599 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "HTMLVideoElement")); | |
| 1600 return; | |
| 1601 } | |
| 1602 IntSize size = sizeFor(video); | |
| 1603 drawImage(video, FloatRect(0, 0, size.width(), size.height()), FloatRect(x,
y, width, height), exceptionState); | |
| 1604 } | |
| 1605 | |
| 1606 void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, | |
| 1607 float sx, float sy, float sw, float sh, | |
| 1608 float dx, float dy, float dw, float dh, ExceptionState& exceptionState) | |
| 1609 { | |
| 1610 drawImage(video, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), excep
tionState); | |
| 1611 } | |
| 1612 | |
| 1613 void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRec
t& srcRect, const FloatRect& dstRect, ExceptionState& exceptionState) | |
| 1614 { | |
| 1615 if (!video) { | |
| 1616 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "HTMLVideoElement")); | |
| 1617 return; | |
| 1618 } | |
| 1619 | |
| 1620 if (video->readyState() == HTMLMediaElement::HAVE_NOTHING || video->readySta
te() == HTMLMediaElement::HAVE_METADATA) | |
| 1621 return; | |
| 1622 if (!srcRect.width() || !srcRect.height()) | |
| 1623 return; | |
| 1624 | |
| 1625 FloatRect videoRect = FloatRect(FloatPoint(), sizeFor(video)); | |
| 1626 | |
| 1627 FloatRect normalizedSrcRect = normalizeRect(srcRect); | |
| 1628 FloatRect normalizedDstRect = normalizeRect(dstRect); | |
| 1629 | |
| 1630 if (!videoRect.intersects(normalizedSrcRect) || !normalizedDstRect.width() |
| !normalizedDstRect.height()) | |
| 1631 return; | |
| 1632 | |
| 1633 clipRectsToImageRect(videoRect, &normalizedSrcRect, &normalizedDstRect); | |
| 1634 | 1366 |
| 1635 GraphicsContext* c = drawingContext(); | 1367 GraphicsContext* c = drawingContext(); |
| 1636 if (!c) | 1368 if (!c) |
| 1637 return; | 1369 return; |
| 1638 if (!state().m_invertibleCTM) | |
| 1639 return; | |
| 1640 | 1370 |
| 1641 checkOrigin(video); | 1371 FloatRect dirtyRect = clipBounds; |
| 1372 if (imageSource->isVideoElement()) { |
| 1373 GraphicsContextStateSaver stateSaver(*c); |
| 1374 c->clip(dstRect); |
| 1375 c->translate(dstRect.x(), dstRect.y()); |
| 1376 c->scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() /
srcRect.height())); |
| 1377 c->translate(-srcRect.x(), -srcRect.y()); |
| 1378 static_cast<HTMLVideoElement*>(imageSource)->paintCurrentFrameInContext(
c, IntRect(IntPoint(), roundedIntSize(imageSource->sourceSize()))); |
| 1379 stateSaver.restore(); |
| 1380 computeDirtyRect(dstRect, clipBounds, &dirtyRect); |
| 1381 } else { |
| 1382 CompositeOperator op = c->compositeOperation(); |
| 1383 blink::WebBlendMode blendMode = c->blendModeOperation(); |
| 1384 if (rectContainsTransformedRect(dstRect, clipBounds)) { |
| 1385 c->drawImage(image.get(), dstRect, srcRect, op, blendMode); |
| 1386 } else if (isFullCanvasCompositeMode(op)) { |
| 1387 fullCanvasCompositedDrawImage(image.get(), dstRect, srcRect, op); |
| 1388 } else if (op == CompositeCopy) { |
| 1389 clearCanvas(); |
| 1390 c->drawImage(image.get(), dstRect, srcRect, op, blendMode); |
| 1391 } else { |
| 1392 FloatRect dirtyRect; |
| 1393 computeDirtyRect(dstRect, clipBounds, &dirtyRect); |
| 1394 c->drawImage(image.get(), dstRect, srcRect, op, blendMode); |
| 1395 } |
| 1642 | 1396 |
| 1643 FloatRect dirtyRect; | 1397 if (imageSourceIsVolatile && is2d() && isAccelerated() && canvas()->buff
er()) |
| 1644 if (!computeDirtyRect(normalizedDstRect, &dirtyRect)) | 1398 canvas()->buffer()->flush(); |
| 1645 return; | 1399 } |
| 1646 | 1400 |
| 1647 GraphicsContextStateSaver stateSaver(*c); | 1401 if (canvas()->originClean() && imageSource->wouldTaintOrigin(canvas()->secur
ityOrigin())) |
| 1648 c->clip(normalizedDstRect); | 1402 canvas()->setOriginTainted(); |
| 1649 c->translate(normalizedDstRect.x(), normalizedDstRect.y()); | |
| 1650 c->scale(FloatSize(normalizedDstRect.width() / normalizedSrcRect.width(), no
rmalizedDstRect.height() / normalizedSrcRect.height())); | |
| 1651 c->translate(-normalizedSrcRect.x(), -normalizedSrcRect.y()); | |
| 1652 video->paintCurrentFrameInContext(c, IntRect(IntPoint(), sizeFor(video))); | |
| 1653 stateSaver.restore(); | |
| 1654 | 1403 |
| 1655 didDraw(dirtyRect); | 1404 didDraw(dirtyRect); |
| 1656 } | 1405 } |
| 1657 | 1406 |
| 1407 |
| 1658 void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image, | 1408 void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image, |
| 1659 float sx, float sy, float sw, float sh, | 1409 float sx, float sy, float sw, float sh, |
| 1660 float dx, float dy, float dw, float dh, | 1410 float dx, float dy, float dw, float dh, |
| 1661 const String& compositeOperation) | 1411 const String& compositeOperation) |
| 1662 { | 1412 { |
| 1413 GraphicsContext* c = drawingContext(); |
| 1414 if (!c) |
| 1415 return; |
| 1663 CompositeOperator op; | 1416 CompositeOperator op; |
| 1664 blink::WebBlendMode blendOp = blink::WebBlendModeNormal; | 1417 blink::WebBlendMode blendOp = blink::WebBlendModeNormal; |
| 1665 if (!parseCompositeAndBlendOperator(compositeOperation, op, blendOp) || blen
dOp != blink::WebBlendModeNormal) | 1418 if (!parseCompositeAndBlendOperator(compositeOperation, op, blendOp) || blen
dOp != blink::WebBlendModeNormal) |
| 1666 op = CompositeSourceOver; | 1419 op = CompositeSourceOver; |
| 1667 | 1420 |
| 1668 drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), op, b
link::WebBlendModeNormal, IGNORE_EXCEPTION); | 1421 CompositeOperator savedOp = c->compositeOperation(); |
| 1422 blink::WebBlendMode savedBlendMode = c->blendModeOperation(); |
| 1423 c->setCompositeOperation(op, blink::WebBlendModeNormal); |
| 1424 drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh, IGNORE_EXCEPTION); |
| 1425 c->setCompositeOperation(savedOp, savedBlendMode); |
| 1669 } | 1426 } |
| 1670 | 1427 |
| 1671 void CanvasRenderingContext2D::setAlpha(float alpha) | 1428 void CanvasRenderingContext2D::setAlpha(float alpha) |
| 1672 { | 1429 { |
| 1673 setGlobalAlpha(alpha); | 1430 setGlobalAlpha(alpha); |
| 1674 } | 1431 } |
| 1675 | 1432 |
| 1676 void CanvasRenderingContext2D::setCompositeOperation(const String& operation) | 1433 void CanvasRenderingContext2D::setCompositeOperation(const String& operation) |
| 1677 { | 1434 { |
| 1678 setGlobalCompositeOperation(operation); | 1435 setGlobalCompositeOperation(operation); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1696 FloatQuad quad(rect); | 1453 FloatQuad quad(rect); |
| 1697 FloatQuad transformedQuad(transformedRect); | 1454 FloatQuad transformedQuad(transformedRect); |
| 1698 return state().m_transform.mapQuad(quad).containsQuad(transformedQuad); | 1455 return state().m_transform.mapQuad(quad).containsQuad(transformedQuad); |
| 1699 } | 1456 } |
| 1700 | 1457 |
| 1701 static void drawImageToContext(Image* image, GraphicsContext* context, const Flo
atRect& dest, const FloatRect& src, CompositeOperator op) | 1458 static void drawImageToContext(Image* image, GraphicsContext* context, const Flo
atRect& dest, const FloatRect& src, CompositeOperator op) |
| 1702 { | 1459 { |
| 1703 context->drawImage(image, dest, src, op); | 1460 context->drawImage(image, dest, src, op); |
| 1704 } | 1461 } |
| 1705 | 1462 |
| 1706 static void drawImageToContext(ImageBuffer* imageBuffer, GraphicsContext* contex
t, const FloatRect& dest, const FloatRect& src, CompositeOperator op) | |
| 1707 { | |
| 1708 context->drawImageBuffer(imageBuffer, dest, src, op); | |
| 1709 } | |
| 1710 | |
| 1711 template<class T> void CanvasRenderingContext2D::fullCanvasCompositedDrawImage(
T* image, const FloatRect& dest, const FloatRect& src, CompositeOperator op) | 1463 template<class T> void CanvasRenderingContext2D::fullCanvasCompositedDrawImage(
T* image, const FloatRect& dest, const FloatRect& src, CompositeOperator op) |
| 1712 { | 1464 { |
| 1713 ASSERT(isFullCanvasCompositeMode(op)); | 1465 ASSERT(isFullCanvasCompositeMode(op)); |
| 1714 | 1466 |
| 1715 drawingContext()->beginLayer(1, op); | 1467 drawingContext()->beginLayer(1, op); |
| 1716 drawImageToContext(image, drawingContext(), dest, src, CompositeSourceOver); | 1468 drawImageToContext(image, drawingContext(), dest, src, CompositeSourceOver); |
| 1717 drawingContext()->endLayer(); | 1469 drawingContext()->endLayer(); |
| 1718 } | 1470 } |
| 1719 | 1471 |
| 1720 static void fillPrimitive(const FloatRect& rect, GraphicsContext* context) | 1472 static void fillPrimitive(const FloatRect& rect, GraphicsContext* context) |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1776 else if (r0 < 0 || r1 < 0) | 1528 else if (r0 < 0 || r1 < 0) |
| 1777 exceptionState.throwDOMException(IndexSizeError, String::format("The %s
provided is less than 0.", r0 < 0 ? "r0" : "r1")); | 1529 exceptionState.throwDOMException(IndexSizeError, String::format("The %s
provided is less than 0.", r0 < 0 ? "r0" : "r1")); |
| 1778 | 1530 |
| 1779 if (exceptionState.hadException()) | 1531 if (exceptionState.hadException()) |
| 1780 return nullptr; | 1532 return nullptr; |
| 1781 | 1533 |
| 1782 RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0),
r0, FloatPoint(x1, y1), r1); | 1534 RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0),
r0, FloatPoint(x1, y1), r1); |
| 1783 return gradient.release(); | 1535 return gradient.release(); |
| 1784 } | 1536 } |
| 1785 | 1537 |
| 1786 PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageEleme
nt* image, | 1538 PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(CanvasImageSou
rce* imageSource, |
| 1787 const String& repetitionType, ExceptionState& exceptionState) | 1539 const String& repetitionType, ExceptionState& exceptionState) |
| 1788 { | 1540 { |
| 1789 if (!image) { | 1541 if (!checkImageSource(imageSource, exceptionState)) |
| 1790 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "HTMLImageElement")); | |
| 1791 return nullptr; | 1542 return nullptr; |
| 1792 } | |
| 1793 bool repeatX, repeatY; | 1543 bool repeatX, repeatY; |
| 1794 CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, excepti
onState); | 1544 CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, excepti
onState); |
| 1795 if (exceptionState.hadException()) | 1545 if (exceptionState.hadException()) |
| 1796 return nullptr; | 1546 return nullptr; |
| 1797 | 1547 |
| 1798 if (!image->complete()) | 1548 RefPtr<Image> imageForRendering = imageSource->getSourceImageForCanvas(excep
tionState, PatternCanvasImageSourceUsage); |
| 1549 if (exceptionState.hadException() || !imageForRendering) |
| 1799 return nullptr; | 1550 return nullptr; |
| 1800 | 1551 |
| 1801 ImageResource* cachedImage = image->cachedImage(); | 1552 return CanvasPattern::create(imageForRendering.release(), repeatX, repeatY,
!imageSource->wouldTaintOrigin(canvas()->securityOrigin())); |
| 1802 Image* imageForRendering = cachedImage ? cachedImage->imageForRenderer(image
->renderer()) : 0; | |
| 1803 if (!imageForRendering) | |
| 1804 return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true)
; | |
| 1805 | |
| 1806 // We need to synthesize a container size if a renderer is not available to
provide one. | |
| 1807 if (!image->renderer() && imageForRendering->usesContainerSize()) | |
| 1808 imageForRendering->setContainerSize(imageForRendering->size()); | |
| 1809 | |
| 1810 bool originClean = cachedImage->isAccessAllowed(canvas()->securityOrigin()); | |
| 1811 return CanvasPattern::create(imageForRendering, repeatX, repeatY, originClea
n); | |
| 1812 } | |
| 1813 | |
| 1814 PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElem
ent* canvas, | |
| 1815 const String& repetitionType, ExceptionState& exceptionState) | |
| 1816 { | |
| 1817 if (!canvas) | |
| 1818 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "HTMLCanvasElement")); | |
| 1819 else if (!canvas->width() || !canvas->height()) | |
| 1820 exceptionState.throwDOMException(InvalidStateError, String::format("The
canvas %s is 0.", canvas->width() ? "height" : "width")); | |
| 1821 | |
| 1822 if (exceptionState.hadException()) | |
| 1823 return nullptr; | |
| 1824 | |
| 1825 bool repeatX, repeatY; | |
| 1826 CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, excepti
onState); | |
| 1827 if (exceptionState.hadException()) | |
| 1828 return nullptr; | |
| 1829 return CanvasPattern::create(canvas->copiedImage(), repeatX, repeatY, canvas
->originClean()); | |
| 1830 } | 1553 } |
| 1831 | 1554 |
| 1832 bool CanvasRenderingContext2D::computeDirtyRect(const FloatRect& localRect, Floa
tRect* dirtyRect) | 1555 bool CanvasRenderingContext2D::computeDirtyRect(const FloatRect& localRect, Floa
tRect* dirtyRect) |
| 1833 { | 1556 { |
| 1834 FloatRect clipBounds; | 1557 FloatRect clipBounds; |
| 1835 if (!drawingContext()->getTransformedClipBounds(&clipBounds)) | 1558 if (!drawingContext()->getTransformedClipBounds(&clipBounds)) |
| 1836 return false; | 1559 return false; |
| 1837 return computeDirtyRect(localRect, clipBounds, dirtyRect); | 1560 return computeDirtyRect(localRect, clipBounds, dirtyRect); |
| 1838 } | 1561 } |
| 1839 | 1562 |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2469 const int focusRingWidth = 5; | 2192 const int focusRingWidth = 5; |
| 2470 const int focusRingOutline = 0; | 2193 const int focusRingOutline = 0; |
| 2471 c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor); | 2194 c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor); |
| 2472 | 2195 |
| 2473 c->restore(); | 2196 c->restore(); |
| 2474 | 2197 |
| 2475 didDraw(dirtyRect); | 2198 didDraw(dirtyRect); |
| 2476 } | 2199 } |
| 2477 | 2200 |
| 2478 } // namespace WebCore | 2201 } // namespace WebCore |
| OLD | NEW |