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 Intel Corporation. All rights reserved. | 8 * Copyright (C) 2012 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 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1184 } | 1184 } |
| 1185 | 1185 |
| 1186 static inline FloatRect normalizeRect(const FloatRect& rect) | 1186 static inline FloatRect normalizeRect(const FloatRect& rect) |
| 1187 { | 1187 { |
| 1188 return FloatRect(min(rect.x(), rect.maxX()), | 1188 return FloatRect(min(rect.x(), rect.maxX()), |
| 1189 min(rect.y(), rect.maxY()), | 1189 min(rect.y(), rect.maxY()), |
| 1190 max(rect.width(), -rect.width()), | 1190 max(rect.width(), -rect.width()), |
| 1191 max(rect.height(), -rect.height())); | 1191 max(rect.height(), -rect.height())); |
| 1192 } | 1192 } |
| 1193 | 1193 |
| 1194 static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect& s rcRect, FloatRect& dstRect) | |
|
Stephen White
2013/07/22 22:02:06
Just personal style, but when it comes to argument
Justin Novosad
2013/07/23 17:38:34
Done.
| |
| 1195 { | |
| 1196 if (imageRect.contains(srcRect)) | |
| 1197 return; | |
| 1198 | |
| 1199 // Compute the src to dst transform | |
| 1200 FloatSize scale(dstRect.size().width() / srcRect.size().width(), dstRect.siz e().height() / srcRect.size().height()); | |
| 1201 FloatPoint scaledSrcLocation = srcRect.location(); | |
| 1202 scaledSrcLocation.scale(scale.width(), scale.height()); | |
| 1203 FloatSize offset = dstRect.location() - scaledSrcLocation; | |
| 1204 | |
| 1205 srcRect.intersect(imageRect); | |
| 1206 | |
| 1207 // To clip the destination rectangle in the same proportion, transform the c lipped src rect | |
| 1208 dstRect = srcRect; | |
| 1209 dstRect.scale(scale.width(), scale.height()); | |
| 1210 dstRect.move(offset); | |
| 1211 } | |
| 1212 | |
| 1194 void CanvasRenderingContext2D::drawImageInternal(Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const BlendMode& blendMode) | 1213 void CanvasRenderingContext2D::drawImageInternal(Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const BlendMode& blendMode) |
| 1195 { | 1214 { |
| 1196 if (!image) | 1215 if (!image) |
| 1197 return; | 1216 return; |
| 1198 | 1217 |
| 1199 GraphicsContext* c = drawingContext(); | 1218 GraphicsContext* c = drawingContext(); |
| 1200 if (!c) | 1219 if (!c) |
| 1201 return; | 1220 return; |
| 1202 if (!state().m_invertibleCTM) | 1221 if (!state().m_invertibleCTM) |
| 1203 return; | 1222 return; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1265 FloatRect normalizedDstRect = normalizeRect(dstRect); | 1284 FloatRect normalizedDstRect = normalizeRect(dstRect); |
| 1266 FloatRect actualDstRect(FloatPoint(bitmap->bitmapOffset()), bitmap->bitmapSi ze()); | 1285 FloatRect actualDstRect(FloatPoint(bitmap->bitmapOffset()), bitmap->bitmapSi ze()); |
| 1267 actualDstRect.scale(normalizedDstRect.width() / bitmap->width(), normalizedD stRect.height() / bitmap->height()); | 1286 actualDstRect.scale(normalizedDstRect.width() / bitmap->width(), normalizedD stRect.height() / bitmap->height()); |
| 1268 actualDstRect.moveBy(normalizedDstRect.location()); | 1287 actualDstRect.moveBy(normalizedDstRect.location()); |
| 1269 | 1288 |
| 1270 FloatRect imageRect = FloatRect(FloatPoint(), bitmap->bitmapSize()); | 1289 FloatRect imageRect = FloatRect(FloatPoint(), bitmap->bitmapSize()); |
| 1271 if (!srcRect.width() || !srcRect.height()) { | 1290 if (!srcRect.width() || !srcRect.height()) { |
| 1272 ec = IndexSizeError; | 1291 ec = IndexSizeError; |
| 1273 return; | 1292 return; |
| 1274 } | 1293 } |
| 1275 if (!imageRect.contains(normalizedSrcRect)) | 1294 if (!imageRect.intersects(normalizedSrcRect)) |
| 1276 return; | 1295 return; |
| 1277 | 1296 |
| 1297 clipRectsToImageRect(imageRect, normalizedSrcRect, actualDstRect); | |
| 1298 | |
| 1278 Image* imageForRendering = bitmap->bitmapImage(); | 1299 Image* imageForRendering = bitmap->bitmapImage(); |
| 1279 | 1300 |
| 1280 drawImageInternal(imageForRendering, normalizedSrcRect, actualDstRect, state ().m_globalComposite, state().m_globalBlend); | 1301 drawImageInternal(imageForRendering, normalizedSrcRect, actualDstRect, state ().m_globalComposite, state().m_globalBlend); |
| 1281 } | 1302 } |
| 1282 | 1303 |
| 1283 void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y, ExceptionCode& ec) | 1304 void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y, ExceptionCode& ec) |
| 1284 { | 1305 { |
| 1285 if (!image) { | 1306 if (!image) { |
| 1286 ec = TypeMismatchError; | 1307 ec = TypeMismatchError; |
| 1287 return; | 1308 return; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1333 return; | 1354 return; |
| 1334 | 1355 |
| 1335 FloatRect normalizedSrcRect = normalizeRect(srcRect); | 1356 FloatRect normalizedSrcRect = normalizeRect(srcRect); |
| 1336 FloatRect normalizedDstRect = normalizeRect(dstRect); | 1357 FloatRect normalizedDstRect = normalizeRect(dstRect); |
| 1337 | 1358 |
| 1338 FloatRect imageRect = FloatRect(FloatPoint(), size(image)); | 1359 FloatRect imageRect = FloatRect(FloatPoint(), size(image)); |
| 1339 if (!srcRect.width() || !srcRect.height()) { | 1360 if (!srcRect.width() || !srcRect.height()) { |
| 1340 ec = IndexSizeError; | 1361 ec = IndexSizeError; |
| 1341 return; | 1362 return; |
| 1342 } | 1363 } |
| 1343 if (!imageRect.contains(normalizedSrcRect)) | 1364 if (!imageRect.intersects(normalizedSrcRect)) |
| 1344 return; | 1365 return; |
| 1345 | 1366 |
| 1367 clipRectsToImageRect(imageRect, normalizedSrcRect, normalizedDstRect); | |
| 1368 | |
| 1346 CachedImage* cachedImage = image->cachedImage(); | 1369 CachedImage* cachedImage = image->cachedImage(); |
| 1347 if (!cachedImage) | 1370 if (!cachedImage) |
| 1348 return; | 1371 return; |
| 1349 | 1372 |
| 1350 checkOrigin(image); | 1373 checkOrigin(image); |
| 1351 | 1374 |
| 1352 Image* imageForRendering = cachedImage->imageForRenderer(image->renderer()); | 1375 Image* imageForRendering = cachedImage->imageForRenderer(image->renderer()); |
| 1353 | 1376 |
| 1354 // For images that depend on an unavailable container size, we need to fall back to the intrinsic | 1377 // For images that depend on an unavailable container size, we need to fall back to the intrinsic |
| 1355 // object size. http://www.w3.org/TR/2dcontext2/#dom-context-2d-drawimage | 1378 // object size. http://www.w3.org/TR/2dcontext2/#dom-context-2d-drawimage |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1393 return; | 1416 return; |
| 1394 } | 1417 } |
| 1395 | 1418 |
| 1396 if (!srcRect.width() || !srcRect.height()) { | 1419 if (!srcRect.width() || !srcRect.height()) { |
| 1397 ec = IndexSizeError; | 1420 ec = IndexSizeError; |
| 1398 return; | 1421 return; |
| 1399 } | 1422 } |
| 1400 | 1423 |
| 1401 ec = 0; | 1424 ec = 0; |
| 1402 | 1425 |
| 1403 if (!srcCanvasRect.contains(normalizeRect(srcRect)) || !dstRect.width() || ! dstRect.height()) | 1426 FloatRect normalizedSrcRect = normalizeRect(srcRect); |
| 1427 FloatRect normalizedDstRect = normalizeRect(dstRect); | |
| 1428 | |
| 1429 if (!srcCanvasRect.intersects(normalizedSrcRect) || !normalizedDstRect.width () || !normalizedDstRect.height()) | |
| 1404 return; | 1430 return; |
| 1405 | 1431 |
| 1432 clipRectsToImageRect(srcCanvasRect, normalizedSrcRect, normalizedDstRect); | |
| 1433 | |
| 1406 GraphicsContext* c = drawingContext(); | 1434 GraphicsContext* c = drawingContext(); |
| 1407 if (!c) | 1435 if (!c) |
| 1408 return; | 1436 return; |
| 1409 if (!state().m_invertibleCTM) | 1437 if (!state().m_invertibleCTM) |
| 1410 return; | 1438 return; |
| 1411 | 1439 |
| 1412 // FIXME: Do this through platform-independent GraphicsContext API. | 1440 // FIXME: Do this through platform-independent GraphicsContext API. |
| 1413 ImageBuffer* buffer = sourceCanvas->buffer(); | 1441 ImageBuffer* buffer = sourceCanvas->buffer(); |
| 1414 if (!buffer) | 1442 if (!buffer) |
| 1415 return; | 1443 return; |
| 1416 | 1444 |
| 1417 checkOrigin(sourceCanvas); | 1445 checkOrigin(sourceCanvas); |
| 1418 | 1446 |
| 1419 // If we're drawing from one accelerated canvas 2d to another, avoid calling sourceCanvas->makeRenderingResultsAvailable() | 1447 // If we're drawing from one accelerated canvas 2d to another, avoid calling sourceCanvas->makeRenderingResultsAvailable() |
| 1420 // as that will do a readback to software. | 1448 // as that will do a readback to software. |
| 1421 CanvasRenderingContext* sourceContext = sourceCanvas->renderingContext(); | 1449 CanvasRenderingContext* sourceContext = sourceCanvas->renderingContext(); |
| 1422 // FIXME: Implement an accelerated path for drawing from a WebGL canvas to a 2d canvas when possible. | 1450 // FIXME: Implement an accelerated path for drawing from a WebGL canvas to a 2d canvas when possible. |
| 1423 if (!isAccelerated() || !sourceContext || !sourceContext->isAccelerated() || !sourceContext->is2d()) | 1451 if (!isAccelerated() || !sourceContext || !sourceContext->isAccelerated() || !sourceContext->is2d()) |
| 1424 sourceCanvas->makeRenderingResultsAvailable(); | 1452 sourceCanvas->makeRenderingResultsAvailable(); |
| 1425 | 1453 |
| 1426 if (rectContainsCanvas(dstRect)) { | 1454 if (rectContainsCanvas(normalizedDstRect)) { |
| 1427 c->drawImageBuffer(buffer, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend); | 1455 c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state() .m_globalComposite, state().m_globalBlend); |
| 1428 didDrawEntireCanvas(); | 1456 didDrawEntireCanvas(); |
| 1429 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { | 1457 } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { |
| 1430 fullCanvasCompositedDrawImage(buffer, dstRect, srcRect, state().m_global Composite); | 1458 fullCanvasCompositedDrawImage(buffer, normalizedDstRect, normalizedSrcRe ct, state().m_globalComposite); |
| 1431 didDrawEntireCanvas(); | 1459 didDrawEntireCanvas(); |
| 1432 } else if (state().m_globalComposite == CompositeCopy) { | 1460 } else if (state().m_globalComposite == CompositeCopy) { |
| 1433 clearCanvas(); | 1461 clearCanvas(); |
| 1434 c->drawImageBuffer(buffer, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend); | 1462 c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state() .m_globalComposite, state().m_globalBlend); |
| 1435 didDrawEntireCanvas(); | 1463 didDrawEntireCanvas(); |
| 1436 } else { | 1464 } else { |
| 1437 c->drawImageBuffer(buffer, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend); | 1465 c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state() .m_globalComposite, state().m_globalBlend); |
| 1438 didDraw(dstRect); | 1466 didDraw(normalizedDstRect); |
| 1439 } | 1467 } |
| 1440 } | 1468 } |
| 1441 | 1469 |
| 1442 void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, float x, float y, ExceptionCode& ec) | 1470 void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, float x, float y, ExceptionCode& ec) |
| 1443 { | 1471 { |
| 1444 if (!video) { | 1472 if (!video) { |
| 1445 ec = TypeMismatchError; | 1473 ec = TypeMismatchError; |
| 1446 return; | 1474 return; |
| 1447 } | 1475 } |
| 1448 IntSize s = size(video); | 1476 IntSize s = size(video); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1479 | 1507 |
| 1480 if (video->readyState() == HTMLMediaElement::HAVE_NOTHING || video->readySta te() == HTMLMediaElement::HAVE_METADATA) | 1508 if (video->readyState() == HTMLMediaElement::HAVE_NOTHING || video->readySta te() == HTMLMediaElement::HAVE_METADATA) |
| 1481 return; | 1509 return; |
| 1482 | 1510 |
| 1483 FloatRect videoRect = FloatRect(FloatPoint(), size(video)); | 1511 FloatRect videoRect = FloatRect(FloatPoint(), size(video)); |
| 1484 if (!srcRect.width() || !srcRect.height()) { | 1512 if (!srcRect.width() || !srcRect.height()) { |
| 1485 ec = IndexSizeError; | 1513 ec = IndexSizeError; |
| 1486 return; | 1514 return; |
| 1487 } | 1515 } |
| 1488 | 1516 |
| 1489 if (!videoRect.contains(normalizeRect(srcRect)) || !dstRect.width() || !dstR ect.height()) | 1517 FloatRect normalizedSrcRect = normalizeRect(srcRect); |
| 1518 FloatRect normalizedDstRect = normalizeRect(dstRect); | |
| 1519 | |
| 1520 if (!videoRect.intersects(normalizeRect(normalizedSrcRect)) || !normalizedDs tRect.width() || !normalizedDstRect.height()) | |
|
aandrey
2013/07/23 09:25:40
remove redundant normalizeRect() call?
Justin Novosad
2013/07/23 17:38:34
Done.
| |
| 1490 return; | 1521 return; |
| 1491 | 1522 |
| 1523 clipRectsToImageRect(videoRect, normalizedSrcRect, normalizedDstRect); | |
| 1524 | |
| 1492 GraphicsContext* c = drawingContext(); | 1525 GraphicsContext* c = drawingContext(); |
| 1493 if (!c) | 1526 if (!c) |
| 1494 return; | 1527 return; |
| 1495 if (!state().m_invertibleCTM) | 1528 if (!state().m_invertibleCTM) |
| 1496 return; | 1529 return; |
| 1497 | 1530 |
| 1498 checkOrigin(video); | 1531 checkOrigin(video); |
| 1499 | 1532 |
| 1500 GraphicsContextStateSaver stateSaver(*c); | 1533 GraphicsContextStateSaver stateSaver(*c); |
| 1501 c->clip(dstRect); | 1534 c->clip(normalizedDstRect); |
| 1502 c->translate(dstRect.x(), dstRect.y()); | 1535 c->translate(normalizedDstRect.x(), normalizedDstRect.y()); |
| 1503 c->scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() / src Rect.height())); | 1536 c->scale(FloatSize(normalizedDstRect.width() / normalizedSrcRect.width(), no rmalizedDstRect.height() / normalizedSrcRect.height())); |
| 1504 c->translate(-srcRect.x(), -srcRect.y()); | 1537 c->translate(-normalizedSrcRect.x(), -normalizedSrcRect.y()); |
| 1505 video->paintCurrentFrameInContext(c, IntRect(IntPoint(), size(video))); | 1538 video->paintCurrentFrameInContext(c, IntRect(IntPoint(), size(video))); |
| 1506 stateSaver.restore(); | 1539 stateSaver.restore(); |
| 1507 didDraw(dstRect); | 1540 didDraw(dstRect); |
| 1508 } | 1541 } |
| 1509 | 1542 |
| 1510 void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image, | 1543 void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image, |
| 1511 float sx, float sy, float sw, float sh, | 1544 float sx, float sy, float sw, float sh, |
| 1512 float dx, float dy, float dw, float dh, | 1545 float dx, float dy, float dw, float dh, |
| 1513 const String& compositeOperation) | 1546 const String& compositeOperation) |
| 1514 { | 1547 { |
| (...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2301 } | 2334 } |
| 2302 | 2335 |
| 2303 PassRefPtr<Canvas2DContextAttributes> CanvasRenderingContext2D::getContextAttrib utes() const | 2336 PassRefPtr<Canvas2DContextAttributes> CanvasRenderingContext2D::getContextAttrib utes() const |
| 2304 { | 2337 { |
| 2305 RefPtr<Canvas2DContextAttributes> attributes = Canvas2DContextAttributes::cr eate(); | 2338 RefPtr<Canvas2DContextAttributes> attributes = Canvas2DContextAttributes::cr eate(); |
| 2306 attributes->setAlpha(m_hasAlpha); | 2339 attributes->setAlpha(m_hasAlpha); |
| 2307 return attributes.release(); | 2340 return attributes.release(); |
| 2308 } | 2341 } |
| 2309 | 2342 |
| 2310 } // namespace WebCore | 2343 } // namespace WebCore |
| OLD | NEW |