From 07df730bff76556ffcc4625aad34350bdcb48257 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 23 Sep 2018 09:05:48 +0200 Subject: [PATCH 1/5] ok! --- src/CanvasRenderingContext2d.cc | 27 ++++++++++++++++++++------- test/public/tests.js | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 911efeca1..32d603631 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -1112,8 +1112,8 @@ NAN_METHOD(Context2d::DrawImage) { , dy = 0 , dw = 0 , dh = 0 - , fw = 0 - , fh = 0; + , source_w = 0 + , source_h = 0; cairo_surface_t *surface; @@ -1125,15 +1125,15 @@ NAN_METHOD(Context2d::DrawImage) { if (!img->isComplete()) { return Nan::ThrowError("Image given has not completed loading"); } - fw = sw = img->width; - fh = sh = img->height; + source_w = sw = img->width; + source_h = sh = img->height; surface = img->surface(); // Canvas } else if (Nan::New(Canvas::constructor)->HasInstance(obj)) { Canvas *canvas = Nan::ObjectWrap::Unwrap(obj); - fw = sw = canvas->getWidth(); - fh = sh = canvas->getHeight(); + source_w = sw = canvas->getWidth(); + source_h = sh = canvas->getHeight(); surface = canvas->surface(); // Invalid @@ -1183,7 +1183,8 @@ NAN_METHOD(Context2d::DrawImage) { float fx = (float) dw / sw; float fy = (float) dh / sh; bool needScale = dw != sw || dh != sh; - bool needCut = sw != fw || sh != fh; + bool needCut = sw != source_h || sh != source_h || sx < 0 || sy < 0; + bool needClip = sx < 0 || sy < 0 || sw > source_w || sh > source_h; bool sameCanvas = surface == context->canvas()->surface(); bool needsExtraSurface = sameCanvas || needCut || needScale; @@ -1194,6 +1195,18 @@ NAN_METHOD(Context2d::DrawImage) { surfTemp = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dw, dh); ctxTemp = cairo_create(surfTemp); cairo_scale(ctxTemp, fx, fy); + if (needClip) { + float clip_w = (std::min)(sw, source_w); + float clip_h = (std::min)(sh, source_h); + if (sx > 0) { + clip_w -= sx; + } + if (sy > 0) { + clip_h -= sy; + } + cairo_rectangle(ctxTemp, -sx , -sy , clip_w, clip_h); + cairo_clip(ctxTemp); + } cairo_set_source_surface(ctxTemp, surface, -sx, -sy); cairo_pattern_set_filter(cairo_get_source(ctxTemp), context->state->imageSmoothingEnabled ? context->state->patternQuality : CAIRO_FILTER_NEAREST); cairo_pattern_set_extend(cairo_get_source(ctxTemp), CAIRO_EXTEND_REFLECT); diff --git a/test/public/tests.js b/test/public/tests.js index bed0dde55..ec683844e 100644 --- a/test/public/tests.js +++ b/test/public/tests.js @@ -1199,6 +1199,7 @@ gco.forEach(op => { var img2 = new Image() img1.onload = function () { img2.onload = function () { + ctx.globalAlpha = 0.8 ctx.drawImage(img1, 0, 0) ctx.globalCompositeOperation = op ctx.drawImage(img2, 0, 0) @@ -1210,6 +1211,27 @@ gco.forEach(op => { } }) +gco.forEach(op => { + tests['9 args, transform, globalCompositeOperator ' + op] = function (ctx, done) { + var img1 = new Image() + var img2 = new Image() + img1.onload = function () { + img2.onload = function () { + ctx.globalAlpha = 0.8 + ctx.drawImage(img1, 0, 0) + ctx.globalCompositeOperation = op + ctx.rotate(0.1) + ctx.scale(0.8, 1.2) + ctx.translate(5, -5) + ctx.drawImage(img2, -80, -50, 400, 400, 10, 10, 180, 180) + done() + } + img2.src = imageSrc('newcontent.png') + } + img1.src = imageSrc('existing.png') + } +}) + tests['known bug #416'] = function (ctx, done) { var img1 = new Image() var img2 = new Image() From 8e1daee83b50da4f1fff0f4dfab80f31e2d4210b Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 23 Sep 2018 09:09:04 +0200 Subject: [PATCH 2/5] ok! --- test/public/tests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/public/tests.js b/test/public/tests.js index ec683844e..c3cb7af32 100644 --- a/test/public/tests.js +++ b/test/public/tests.js @@ -1199,7 +1199,7 @@ gco.forEach(op => { var img2 = new Image() img1.onload = function () { img2.onload = function () { - ctx.globalAlpha = 0.8 + ctx.globalAlpha = 0.7 ctx.drawImage(img1, 0, 0) ctx.globalCompositeOperation = op ctx.drawImage(img2, 0, 0) @@ -1217,7 +1217,7 @@ gco.forEach(op => { var img2 = new Image() img1.onload = function () { img2.onload = function () { - ctx.globalAlpha = 0.8 + ctx.globalAlpha = 0.7 ctx.drawImage(img1, 0, 0) ctx.globalCompositeOperation = op ctx.rotate(0.1) From 10f57da7dc9eb0fb4f6aac468078a943da9fc288 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Wed, 3 Oct 2018 05:27:05 +0200 Subject: [PATCH 3/5] added-test --- test/public/tests.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/public/tests.js b/test/public/tests.js index c3cb7af32..ddb7506d1 100644 --- a/test/public/tests.js +++ b/test/public/tests.js @@ -1232,6 +1232,21 @@ gco.forEach(op => { } }) +tests['drawImage issue #1249'] = function (ctx, done) { + var img1 = new Image() + var img2 = new Image() + img1.onload = function () { + img2.onload = function () { + ctx.drawImage(img1, 0, 0, 200, 200) + ctx.drawImage(img2, -8, -8, 18, 18, 0, 0, 200, 200); + ctx.restore() + done() + } + img2.src = imageSrc('checkers.png') + } + img1.src = imageSrc('chrome.jpg') +} + tests['known bug #416'] = function (ctx, done) { var img1 = new Image() var img2 = new Image() From d0a0fe101650dfc838f7213f3fc0af116ccd980a Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Wed, 3 Oct 2018 07:15:52 +0200 Subject: [PATCH 4/5] fix lint --- test/public/tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/public/tests.js b/test/public/tests.js index ddb7506d1..1ecb077e6 100644 --- a/test/public/tests.js +++ b/test/public/tests.js @@ -1238,7 +1238,7 @@ tests['drawImage issue #1249'] = function (ctx, done) { img1.onload = function () { img2.onload = function () { ctx.drawImage(img1, 0, 0, 200, 200) - ctx.drawImage(img2, -8, -8, 18, 18, 0, 0, 200, 200); + ctx.drawImage(img2, -8, -8, 18, 18, 0, 0, 200, 200) ctx.restore() done() } From 3e10322b271027704955eac7b64f8597e292ef09 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 7 Oct 2018 21:32:26 +0200 Subject: [PATCH 5/5] reworked a name --- src/CanvasRenderingContext2d.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 32d603631..8779e8557 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -1183,11 +1183,11 @@ NAN_METHOD(Context2d::DrawImage) { float fx = (float) dw / sw; float fy = (float) dh / sh; bool needScale = dw != sw || dh != sh; - bool needCut = sw != source_h || sh != source_h || sx < 0 || sy < 0; - bool needClip = sx < 0 || sy < 0 || sw > source_w || sh > source_h; + bool needCut = sw != source_w || sh != source_h || sx < 0 || sy < 0; + bool needCairoClip = sx < 0 || sy < 0 || sw > source_w || sh > source_h; bool sameCanvas = surface == context->canvas()->surface(); - bool needsExtraSurface = sameCanvas || needCut || needScale; + bool needsExtraSurface = sameCanvas || needCut || needScale || needCairoClip; cairo_surface_t *surfTemp = NULL; cairo_t *ctxTemp = NULL; @@ -1195,7 +1195,7 @@ NAN_METHOD(Context2d::DrawImage) { surfTemp = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dw, dh); ctxTemp = cairo_create(surfTemp); cairo_scale(ctxTemp, fx, fy); - if (needClip) { + if (needCairoClip) { float clip_w = (std::min)(sw, source_w); float clip_h = (std::min)(sh, source_h); if (sx > 0) {