WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-67652-20131224145449.patch (text/plain), 14.64 KB, created by
Rashmi Shyamasundar
on 2013-12-24 01:22:37 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Rashmi Shyamasundar
Created:
2013-12-24 01:22:37 PST
Size:
14.64 KB
patch
obsolete
>Subversion Revision: 160755 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index cb2020118d3210e1c07dab70a39c404bc0851198..46b8f246165b900b0a5ccacfe8f2913824c8d242 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,23 @@ >+2013-12-23 Rashmi Shyamasundar <rashmi.s2@samsung.com> >+ >+ Negative width/height values not always treated properly by 2D canvas drawImage >+ https://bugs.webkit.org/show_bug.cgi?id=67652 >+ >+ From Blink r154774 by <junov@chromium.org> >+ https://src.chromium.org/viewvc/blink?revision=154798&view=revision >+ >+ Test: fast/canvas/canvas-drawImage-out-of-bounds-src.html >+ >+ According to the canvas specification, as on 24th December 2013 >+ <http://www.w3.org/html/wg/drafts/2dcontext/master/#drawing-images> >+ "When the source rectangle is outside the source image, >+ the source rectangle must be clipped to the source image and the destination rectangle >+ must be clipped in the same proportion." >+ >+ * html/canvas/CanvasRenderingContext2D.cpp: >+ (WebCore::clipRectsToImageRect): >+ (WebCore::CanvasRenderingContext2D::drawImage): >+ > 2013-12-17 Jer Noble <jer.noble@apple.com> > > [MSE] Periodically monitor source buffers. >diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp >index 7a8d729bc074222ec2444227cdd18aa9912ab9a8..420ccf0a5f08eb523fa4a3b3845b934921e9f0e5 100755 >--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp >+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp >@@ -1223,6 +1223,27 @@ static inline FloatRect normalizeRect(const FloatRect& rect) > std::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 dstSize = dstRect.size(); >+ FloatSize srcSize = srcRect.size(); >+ FloatSize scale(dstSize.width() / srcSize.width(), dstSize.height() / srcSize.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::drawImage(HTMLImageElement* image, float x, float y, ExceptionCode& ec) > { > if (!image) { >@@ -1283,8 +1304,9 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec > ec = INDEX_SIZE_ERR; > return; > } >- if (!imageRect.contains(normalizedSrcRect)) >+ if (!imageRect.intersects(normalizedSrcRect)) > return; >+ clipRectsToImageRect(imageRect, normalizedSrcRect, normalizedDstRect); > > GraphicsContext* c = drawingContext(); > if (!c) >@@ -1354,9 +1376,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; >@@ -1381,19 +1408,19 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const > sourceCanvas->makeRenderingResultsAvailable(); > #endif > >- if (rectContainsCanvas(dstRect)) { >- c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend); >+ if (rectContainsCanvas(normalizedDstRect)) { >+ c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend); > didDrawEntireCanvas(); > } else if (isFullCanvasCompositeMode(state().m_globalComposite)) { >- fullCanvasCompositedDrawImage(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite); >+ fullCanvasCompositedDrawImage(buffer, ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, state().m_globalComposite); > didDrawEntireCanvas(); > } else if (state().m_globalComposite == CompositeCopy) { > clearCanvas(); >- c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend); >+ c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend); > didDrawEntireCanvas(); > } else { >- c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend); >- didDraw(dstRect); >+ c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend); >+ didDraw(normalizedDstRect); > } > } > >@@ -1445,9 +1472,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; >@@ -1458,21 +1490,21 @@ void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRec > > #if USE(CG) > if (PassNativeImagePtr image = video->nativeImageForCurrentTime()) { >- c->drawNativeImage(image, FloatSize(video->videoWidth(), video->videoHeight()), ColorSpaceDeviceRGB, dstRect, srcRect); >- if (rectContainsCanvas(dstRect)) >+ c->drawNativeImage(image, FloatSize(video->videoWidth(), video->videoHeight()), ColorSpaceDeviceRGB, normalizedDstRect, srcRect); >+ if (rectContainsCanvas(normalizedDstRect)) > didDrawEntireCanvas(); > else >- didDraw(dstRect); >+ didDraw(normalizedDstRect); > > return; > } > #endif > > 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); >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 0d25941f958ba5a97c536b506671f4fd8397263d..934f6575c96a89c5bab6b4c186ce11ae43199535 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,14 @@ >+2013-12-23 Rashmi Shyamasundar <rashmi.s2@samsung.com> >+ >+ Negative width/height values not always treated properly by 2D canvas drawImage >+ https://bugs.webkit.org/show_bug.cgi?id=67652 >+ >+ From Blink r154774 by <junov@chromium.org> >+ https://src.chromium.org/viewvc/blink?revision=154798&view=revision >+ >+ * fast/canvas/canvas-drawImage-out-of-bounds-src-expected.html: Added. >+ * fast/canvas/canvas-drawImage-out-of-bounds-src.html: Added. >+ > 2013-12-17 Jer Noble <jer.noble@apple.com> > > [MSE] Periodically monitor source buffers. >diff --git a/LayoutTests/fast/canvas/canvas-drawImage-out-of-bounds-src-expected.html b/LayoutTests/fast/canvas/canvas-drawImage-out-of-bounds-src-expected.html >new file mode 100755 >index 0000000000000000000000000000000000000000..d1670f9c9a13a1eff14881edc0a56514f511e37a >--- /dev/null >+++ b/LayoutTests/fast/canvas/canvas-drawImage-out-of-bounds-src-expected.html >@@ -0,0 +1,49 @@ >+<html> >+<body> >+<canvas id="c1" width="250" height="250"></canvas> >+<canvas id="c2" width="250" height="250"></canvas> >+<br> >+<canvas id="c3" width="250" height="250"></canvas> >+<canvas id="c4" width="250" height="250"></canvas> >+<script type="text/javascript"> >+var ctx1 = document.getElementById('c1').getContext('2d'); >+var ctx2 = document.getElementById('c2').getContext('2d'); >+var ctx3 = document.getElementById('c3').getContext('2d'); >+var ctx4 = document.getElementById('c4').getContext('2d'); >+ctx1.fillStyle = 'green'; >+ctx2.fillStyle = 'green'; >+ctx3.fillStyle = 'green'; >+ctx4.fillStyle = 'green'; >+ctx1.fillRect(25, 25, 200, 200); >+ctx2.fillRect(25, 25, 200, 200); >+if (window.createImageBitmap) { >+ ctx4.fillRect(25, 25, 200, 200); >+} >+ >+if (window.testRunner) { >+ testRunner.waitUntilDone(); >+} >+var video = document.createElement("video"); >+video.autoplay = false; >+video.addEventListener("canplaythrough", videoLoaded, false); >+video.src = "resources/green.ogv"; >+ >+function videoLoaded() { >+ var w = video.videoWidth; >+ var h = video.videoHeight; >+ ctx3.drawImage(video, 0, 0, w, h, 75, 75, 100, 100); >+ ctx3.drawImage(video, 0, 0, w, h, 25, 25, 50, 50); >+ ctx3.drawImage(video, 0, 0, w, h, 75, 25, 100, 50); >+ ctx3.drawImage(video, 0, 0, w, h, 175, 25, 50, 50); >+ ctx3.drawImage(video, 0, 0, w, h, 25, 75, 50, 100); >+ ctx3.drawImage(video, 0, 0, w, h, 175, 75, 50, 100); >+ ctx3.drawImage(video, 0, 0, w, h, 25, 175, 50, 50); >+ ctx3.drawImage(video, 0, 0, w, h, 75, 175, 100, 50); >+ ctx3.drawImage(video, 0, 0, w, h, 175, 175, 50, 50); >+ if (window.testRunner) { >+ testRunner.notifyDone(); >+ } >+} >+ >+</script> >+</body></html> >\ No newline at end of file >diff --git a/LayoutTests/fast/canvas/canvas-drawImage-out-of-bounds-src.html b/LayoutTests/fast/canvas/canvas-drawImage-out-of-bounds-src.html >new file mode 100755 >index 0000000000000000000000000000000000000000..76b02d9a13894a10793c79c755da52bb05dea242 >--- /dev/null >+++ b/LayoutTests/fast/canvas/canvas-drawImage-out-of-bounds-src.html >@@ -0,0 +1,98 @@ >+<html> >+<body> >+<canvas id="c1" width="250" height="250"></canvas> >+<canvas id="c2" width="250" height="250"></canvas> >+<br> >+<canvas id="c3" width="250" height="250"></canvas> >+<canvas id="c4" width="250" height="250"></canvas> >+<script type="text/javascript"> >+var canvas1 = document.getElementById('c1'); >+var canvas2 = document.getElementById('c2'); >+var canvas3 = document.getElementById('c3'); >+var canvas4 = document.getElementById('c4'); >+var bgcanvas = document.createElement('canvas'); >+bgcanvas.width = 100; >+bgcanvas.height = 100; >+var bgctx = bgcanvas.getContext('2d'); >+bgctx.fillStyle = 'green'; >+bgctx.fillRect(0, 0, bgcanvas.width, bgcanvas.height); >+var greenSquareURL = bgcanvas.toDataURL(); >+var img = new Image(); >+img.src = greenSquareURL; >+img.onload = function drawOnCanvas() { >+ var ctx1 = canvas1.getContext('2d'); >+ ctx1.drawImage(img, -100, -100, 300, 300, -25, -25, 300, 300); >+ ctx1.drawImage(img, -100, -100, 200, 200, -25, -25, 100, 100); >+ ctx1.drawImage(img, 0, -100, 100, 200, 75, -25, 100, 100); >+ ctx1.drawImage(img, 0, -100, 200, 200, 175, -25, 100, 100); >+ ctx1.drawImage(img, -100, 0, 200, 100, -25, 75, 100, 100); >+ ctx1.drawImage(img, 0, 0, 200, 100, 175, 75, 100, 100); >+ ctx1.drawImage(img, -100, 0, 200, 200, -25, 175, 100, 100); >+ ctx1.drawImage(img, 0, 0, 100, 200, 75, 175, 100, 100); >+ ctx1.drawImage(img, 0, 0, 200, 200, 175, 175, 100, 100); >+}; >+ >+var ctx2 = canvas2.getContext('2d'); >+var ctx3 = canvas3.getContext('2d'); >+var ctx4 = canvas4.getContext('2d'); >+video = document.createElement("video"); >+video.poster = greenSquareURL; >+ >+ctx2.drawImage(bgcanvas, -100, -100, 300, 300, -25, -25, 300, 300); >+ctx2.drawImage(bgcanvas, -100, -100, 200, 200, -25, -25, 100, 100); >+ctx2.drawImage(bgcanvas, 0, -100, 100, 200, 75, -25, 100, 100); >+ctx2.drawImage(bgcanvas, 0, -100, 200, 200, 175, -25, 100, 100); >+ctx2.drawImage(bgcanvas, -100, 0, 200, 100, -25, 75, 100, 100); >+ctx2.drawImage(bgcanvas, 0, 0, 200, 100, 175, 75, 100, 100); >+ctx2.drawImage(bgcanvas, -100, 0, 200, 200, -25, 175, 100, 100); >+ctx2.drawImage(bgcanvas, 0, 0, 100, 200, 75, 175, 100, 100); >+ctx2.drawImage(bgcanvas, 0, 0, 200, 200, 175, 175, 100, 100); >+ >+if (window.testRunner) { >+ testRunner.waitUntilDone(); >+} >+ >+var video = document.createElement("video"); >+video.autoplay = false; >+video.addEventListener("canplaythrough", videoLoaded, false); >+video.src = "resources/green.ogv"; >+ >+function videoLoaded() { >+ var w = video.videoWidth; >+ var h = video.videoHeight; >+ ctx3.drawImage(video, -w, -h, 3*w, 3*h, -25, -25, 300, 300); >+ ctx3.drawImage(video, -w, -h, 2*w, 2*h, -25, -25, 100, 100); >+ ctx3.drawImage(video, 0, -h, w, 2*h, 75, -25, 100, 100); >+ ctx3.drawImage(video, 0, -h, 2*w, 2*h, 175, -25, 100, 100); >+ ctx3.drawImage(video, -w, 0, 2*w, h, -25, 75, 100, 100); >+ ctx3.drawImage(video, 0, 0, 2*w, h, 175, 75, 100, 100); >+ ctx3.drawImage(video, -w, 0, 2*w, 2*h, -25, 175, 100, 100); >+ ctx3.drawImage(video, 0, 0, w, 2*h, 75, 175, 100, 100); >+ ctx3.drawImage(video, 0, 0, 2*w, 2*h, 175, 175, 100, 100); >+ >+ if (window.createImageBitmap) { >+ window.createImageBitmap(img, imageReady); >+ } else { >+ if (window.testRunner) { >+ testRunner.notifyDone(); >+ } >+ } >+} >+ >+function imageReady(imageBitmap) { >+ ctx4.drawImage(imageBitmap, -100, -100, 300, 300, -25, -25, 300, 300); >+ ctx4.drawImage(imageBitmap, -100, -100, 200, 200, -25, -25, 100, 100); >+ ctx4.drawImage(imageBitmap, 0, -100, 100, 200, 75, -25, 100, 100); >+ ctx4.drawImage(imageBitmap, 0, -100, 200, 200, 175, -25, 100, 100); >+ ctx4.drawImage(imageBitmap, -100, 0, 200, 100, -25, 75, 100, 100); >+ ctx4.drawImage(imageBitmap, 0, 0, 200, 100, 175, 75, 100, 100); >+ ctx4.drawImage(imageBitmap, -100, 0, 200, 200, -25, 175, 100, 100); >+ ctx4.drawImage(imageBitmap, 0, 0, 100, 200, 75, 175, 100, 100); >+ ctx4.drawImage(imageBitmap, 0, 0, 200, 200, 175, 175, 100, 100); >+ if (window.testRunner) { >+ testRunner.notifyDone(); >+ } >+} >+ >+</script> >+</body></html> >\ No newline at end of file
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 67652
:
106438
|
106439
|
205262
|
205366
|
205394
|
205451
|
205773
|
206135
|
206136
|
206137
|
207691
|
207692
|
207693
|
219902
|
219907
|
219910
|
219959
|
219964
|
219965
|
220105