Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1064)

Unified Diff: Source/core/html/canvas/CanvasRenderingContext2D.cpp

Issue 19267027: Fixing src rectangle clipping with drawImage (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: retry without video Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « LayoutTests/virtual/gpu/canvas/philip/tests/2d.drawImage.outsidesource-expected.txt ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/html/canvas/CanvasRenderingContext2D.cpp
diff --git a/Source/core/html/canvas/CanvasRenderingContext2D.cpp b/Source/core/html/canvas/CanvasRenderingContext2D.cpp
index b2701331d1dffccff104b5be49378965be011792..ebea8be080f6001be01a558970448f699f7c5bb0 100644
--- a/Source/core/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/core/html/canvas/CanvasRenderingContext2D.cpp
@@ -1191,6 +1191,25 @@ static inline FloatRect normalizeRect(const FloatRect& rect)
max(rect.height(), -rect.height()));
}
+static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* srcRect, FloatRect* dstRect)
+{
+ if (imageRect.contains(*srcRect))
+ return;
+
+ // Compute the src to dst transform
+ FloatSize scale(dstRect->size().width() / srcRect->size().width(), dstRect->size().height() / srcRect->size().height());
+ FloatPoint scaledSrcLocation = srcRect->location();
+ scaledSrcLocation.scale(scale.width(), scale.height());
+ FloatSize offset = dstRect->location() - scaledSrcLocation;
+
+ srcRect->intersect(imageRect);
+
+ // To clip the destination rectangle in the same proportion, transform the clipped src rect
+ *dstRect = *srcRect;
+ dstRect->scale(scale.width(), scale.height());
+ dstRect->move(offset);
+}
+
void CanvasRenderingContext2D::drawImageInternal(Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const BlendMode& blendMode)
{
if (!image)
@@ -1272,9 +1291,11 @@ void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap,
ec = IndexSizeError;
return;
}
- if (!imageRect.contains(normalizedSrcRect))
+ if (!imageRect.intersects(normalizedSrcRect))
return;
+ clipRectsToImageRect(imageRect, &normalizedSrcRect, &actualDstRect);
+
Image* imageForRendering = bitmap->bitmapImage();
drawImageInternal(imageForRendering, normalizedSrcRect, actualDstRect, state().m_globalComposite, state().m_globalBlend);
@@ -1340,9 +1361,11 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
ec = IndexSizeError;
return;
}
- if (!imageRect.contains(normalizedSrcRect))
+ if (!imageRect.intersects(normalizedSrcRect))
return;
+ clipRectsToImageRect(imageRect, &normalizedSrcRect, &normalizedDstRect);
+
CachedImage* cachedImage = image->cachedImage();
if (!cachedImage)
return;
@@ -1400,9 +1423,14 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const
ec = 0;
- if (!srcCanvasRect.contains(normalizeRect(srcRect)) || !dstRect.width() || !dstRect.height())
+ FloatRect normalizedSrcRect = normalizeRect(srcRect);
+ FloatRect normalizedDstRect = normalizeRect(dstRect);
+
+ if (!srcCanvasRect.intersects(normalizedSrcRect) || !normalizedDstRect.width() || !normalizedDstRect.height())
return;
+ clipRectsToImageRect(srcCanvasRect, &normalizedSrcRect, &normalizedDstRect);
+
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -1423,19 +1451,19 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const
if (!isAccelerated() || !sourceContext || !sourceContext->isAccelerated() || !sourceContext->is2d())
sourceCanvas->makeRenderingResultsAvailable();
- if (rectContainsCanvas(dstRect)) {
- c->drawImageBuffer(buffer, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend);
+ if (rectContainsCanvas(normalizedDstRect)) {
+ c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
didDrawEntireCanvas();
} else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- fullCanvasCompositedDrawImage(buffer, dstRect, srcRect, state().m_globalComposite);
+ fullCanvasCompositedDrawImage(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite);
didDrawEntireCanvas();
} else if (state().m_globalComposite == CompositeCopy) {
clearCanvas();
- c->drawImageBuffer(buffer, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend);
+ c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
didDrawEntireCanvas();
} else {
- c->drawImageBuffer(buffer, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend);
- didDraw(dstRect);
+ c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
+ didDraw(normalizedDstRect);
}
}
@@ -1486,9 +1514,14 @@ void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRec
return;
}
- if (!videoRect.contains(normalizeRect(srcRect)) || !dstRect.width() || !dstRect.height())
+ FloatRect normalizedSrcRect = normalizeRect(srcRect);
+ FloatRect normalizedDstRect = normalizeRect(dstRect);
+
+ if (!videoRect.intersects(normalizedSrcRect) || !normalizedDstRect.width() || !normalizedDstRect.height())
return;
+ clipRectsToImageRect(videoRect, &normalizedSrcRect, &normalizedDstRect);
+
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -1498,10 +1531,10 @@ void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRec
checkOrigin(video);
GraphicsContextStateSaver stateSaver(*c);
- c->clip(dstRect);
- c->translate(dstRect.x(), dstRect.y());
- c->scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height()));
- c->translate(-srcRect.x(), -srcRect.y());
+ c->clip(normalizedDstRect);
+ c->translate(normalizedDstRect.x(), normalizedDstRect.y());
+ c->scale(FloatSize(normalizedDstRect.width() / normalizedSrcRect.width(), normalizedDstRect.height() / normalizedSrcRect.height()));
+ c->translate(-normalizedSrcRect.x(), -normalizedSrcRect.y());
video->paintCurrentFrameInContext(c, IntRect(IntPoint(), size(video)));
stateSaver.restore();
didDraw(dstRect);
« no previous file with comments | « LayoutTests/virtual/gpu/canvas/philip/tests/2d.drawImage.outsidesource-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698