@@ -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);
0 commit comments