Skip to content

Commit aaf7137

Browse files
astururzbjornson
authored andcommitted
Fix drawImage regression with particular use case of 9 arguments. (#1251)
* ok! * ok! * added-test * fix lint * reworked a name
1 parent ddda5d3 commit aaf7137

File tree

2 files changed

+58
-8
lines changed

2 files changed

+58
-8
lines changed

src/CanvasRenderingContext2d.cc

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,8 +1112,8 @@ NAN_METHOD(Context2d::DrawImage) {
11121112
, dy = 0
11131113
, dw = 0
11141114
, dh = 0
1115-
, fw = 0
1116-
, fh = 0;
1115+
, source_w = 0
1116+
, source_h = 0;
11171117

11181118
cairo_surface_t *surface;
11191119

@@ -1125,15 +1125,15 @@ NAN_METHOD(Context2d::DrawImage) {
11251125
if (!img->isComplete()) {
11261126
return Nan::ThrowError("Image given has not completed loading");
11271127
}
1128-
fw = sw = img->width;
1129-
fh = sh = img->height;
1128+
source_w = sw = img->width;
1129+
source_h = sh = img->height;
11301130
surface = img->surface();
11311131

11321132
// Canvas
11331133
} else if (Nan::New(Canvas::constructor)->HasInstance(obj)) {
11341134
Canvas *canvas = Nan::ObjectWrap::Unwrap<Canvas>(obj);
1135-
fw = sw = canvas->getWidth();
1136-
fh = sh = canvas->getHeight();
1135+
source_w = sw = canvas->getWidth();
1136+
source_h = sh = canvas->getHeight();
11371137
surface = canvas->surface();
11381138

11391139
// Invalid
@@ -1183,17 +1183,30 @@ NAN_METHOD(Context2d::DrawImage) {
11831183
float fx = (float) dw / sw;
11841184
float fy = (float) dh / sh;
11851185
bool needScale = dw != sw || dh != sh;
1186-
bool needCut = sw != fw || sh != fh;
1186+
bool needCut = sw != source_w || sh != source_h || sx < 0 || sy < 0;
1187+
bool needCairoClip = sx < 0 || sy < 0 || sw > source_w || sh > source_h;
11871188

11881189
bool sameCanvas = surface == context->canvas()->surface();
1189-
bool needsExtraSurface = sameCanvas || needCut || needScale;
1190+
bool needsExtraSurface = sameCanvas || needCut || needScale || needCairoClip;
11901191
cairo_surface_t *surfTemp = NULL;
11911192
cairo_t *ctxTemp = NULL;
11921193

11931194
if (needsExtraSurface) {
11941195
surfTemp = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dw, dh);
11951196
ctxTemp = cairo_create(surfTemp);
11961197
cairo_scale(ctxTemp, fx, fy);
1198+
if (needCairoClip) {
1199+
float clip_w = (std::min)(sw, source_w);
1200+
float clip_h = (std::min)(sh, source_h);
1201+
if (sx > 0) {
1202+
clip_w -= sx;
1203+
}
1204+
if (sy > 0) {
1205+
clip_h -= sy;
1206+
}
1207+
cairo_rectangle(ctxTemp, -sx , -sy , clip_w, clip_h);
1208+
cairo_clip(ctxTemp);
1209+
}
11971210
cairo_set_source_surface(ctxTemp, surface, -sx, -sy);
11981211
cairo_pattern_set_filter(cairo_get_source(ctxTemp), context->state->imageSmoothingEnabled ? context->state->patternQuality : CAIRO_FILTER_NEAREST);
11991212
cairo_pattern_set_extend(cairo_get_source(ctxTemp), CAIRO_EXTEND_REFLECT);

test/public/tests.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,7 @@ gco.forEach(op => {
12391239
var img2 = new Image()
12401240
img1.onload = function () {
12411241
img2.onload = function () {
1242+
ctx.globalAlpha = 0.7
12421243
ctx.drawImage(img1, 0, 0)
12431244
ctx.globalCompositeOperation = op
12441245
ctx.drawImage(img2, 0, 0)
@@ -1250,6 +1251,42 @@ gco.forEach(op => {
12501251
}
12511252
})
12521253

1254+
gco.forEach(op => {
1255+
tests['9 args, transform, globalCompositeOperator ' + op] = function (ctx, done) {
1256+
var img1 = new Image()
1257+
var img2 = new Image()
1258+
img1.onload = function () {
1259+
img2.onload = function () {
1260+
ctx.globalAlpha = 0.7
1261+
ctx.drawImage(img1, 0, 0)
1262+
ctx.globalCompositeOperation = op
1263+
ctx.rotate(0.1)
1264+
ctx.scale(0.8, 1.2)
1265+
ctx.translate(5, -5)
1266+
ctx.drawImage(img2, -80, -50, 400, 400, 10, 10, 180, 180)
1267+
done()
1268+
}
1269+
img2.src = imageSrc('newcontent.png')
1270+
}
1271+
img1.src = imageSrc('existing.png')
1272+
}
1273+
})
1274+
1275+
tests['drawImage issue #1249'] = function (ctx, done) {
1276+
var img1 = new Image()
1277+
var img2 = new Image()
1278+
img1.onload = function () {
1279+
img2.onload = function () {
1280+
ctx.drawImage(img1, 0, 0, 200, 200)
1281+
ctx.drawImage(img2, -8, -8, 18, 18, 0, 0, 200, 200)
1282+
ctx.restore()
1283+
done()
1284+
}
1285+
img2.src = imageSrc('checkers.png')
1286+
}
1287+
img1.src = imageSrc('chrome.jpg')
1288+
}
1289+
12531290
tests['known bug #416'] = function (ctx, done) {
12541291
var img1 = new Image()
12551292
var img2 = new Image()

0 commit comments

Comments
 (0)