From b92797961e63e560fd352b4453883ac65a0958b9 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 09:59:34 -0800 Subject: [PATCH 01/15] Started Context2d#drawImage() --- src/CanvasRenderingContext2d.cc | 55 +++++++++++++++++++++++++-------- src/CanvasRenderingContext2d.h | 1 + 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 7a139ef..9ae0a86 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -9,6 +9,7 @@ #include #include #include "Canvas.h" +#include "Image.h" #include "CanvasRenderingContext2d.h" #include "CanvasGradient.h" @@ -66,6 +67,7 @@ Context2d::Initialize(Handle target) { // Prototype Local proto = t->PrototypeTemplate(); + NODE_SET_PROTOTYPE_METHOD(t, "drawImage", DrawImage); NODE_SET_PROTOTYPE_METHOD(t, "save", Save); NODE_SET_PROTOTYPE_METHOD(t, "restore", Restore); NODE_SET_PROTOTYPE_METHOD(t, "rotate", Rotate); @@ -112,19 +114,6 @@ Context2d::Initialize(Handle target) { target->Set(String::NewSymbol("CanvasRenderingContext2d"), t->GetFunction()); } -/* - * Initialize a new Context2d with the given canvas. - */ - -Handle -Context2d::New(const Arguments &args) { - HandleScope scope; - Canvas *canvas = ObjectWrap::Unwrap(args[0]->ToObject()); - Context2d *context = new Context2d(canvas); - context->Wrap(args.This()); - return args.This(); -} - /* * Create a cairo context. */ @@ -382,6 +371,46 @@ Context2d::blur(cairo_surface_t *surface, int radius) { free( precalc ); } +/* + * Initialize a new Context2d with the given canvas. + */ + +Handle +Context2d::New(const Arguments &args) { + HandleScope scope; + Canvas *canvas = ObjectWrap::Unwrap(args[0]->ToObject()); + Context2d *context = new Context2d(canvas); + context->Wrap(args.This()); + return args.This(); +} + +/* + * Draw image. + */ + +Handle +Context2d::DrawImage(const Arguments &args) { + HandleScope scope; + + if (!args[1]->IsNumber() + || !args[2]->IsNumber()) return Undefined(); + + // TODO: instanceof + Image *img = ObjectWrap::Unwrap(args[0]->ToObject()); + Context2d *context = ObjectWrap::Unwrap(args.This()); + + double x = args[1]->NumberValue(); + double y = args[2]->NumberValue(); + + cairo_t *ctx = context->context(); + cairo_save(ctx); + cairo_set_source_surface(ctx, img->surface(), x, y); + cairo_paint(ctx); + cairo_restore(ctx); + + return Undefined(); +} + /* * Get global alpha. */ diff --git a/src/CanvasRenderingContext2d.h b/src/CanvasRenderingContext2d.h index be85cb3..f8f413b 100644 --- a/src/CanvasRenderingContext2d.h +++ b/src/CanvasRenderingContext2d.h @@ -47,6 +47,7 @@ class Context2d: public node::ObjectWrap { canvas_state_t *state; static void Initialize(Handle target); static Handle New(const Arguments &args); + static Handle DrawImage(const Arguments &args); static Handle Save(const Arguments &args); static Handle Restore(const Arguments &args); static Handle Rotate(const Arguments &args); From 29982a1e77e9780f218864c9331b7290581ba588 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 10:07:29 -0800 Subject: [PATCH 02/15] Started drawImage() w/h --- src/CanvasRenderingContext2d.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 9ae0a86..ef7e9bb 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -399,12 +399,17 @@ Context2d::DrawImage(const Arguments &args) { Image *img = ObjectWrap::Unwrap(args[0]->ToObject()); Context2d *context = ObjectWrap::Unwrap(args.This()); - double x = args[1]->NumberValue(); - double y = args[2]->NumberValue(); - + // Dest point + double dx = args[1]->NumberValue(); + double dy = args[2]->NumberValue(); + + // Dest dimensions + double dw = args[3]->IsNumber() ? args[3]->NumberValue() : img->width; + double dh = args[4]->IsNumber() ? args[4]->NumberValue() : img->height; + cairo_t *ctx = context->context(); cairo_save(ctx); - cairo_set_source_surface(ctx, img->surface(), x, y); + cairo_set_source_surface(ctx, img->surface(), dx, dy); cairo_paint(ctx); cairo_restore(ctx); From 5badfa1e64cca9febfff81e524cd31e7a79bc9d1 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 10:09:35 -0800 Subject: [PATCH 03/15] Grab image surface data --- src/CanvasRenderingContext2d.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index ef7e9bb..56b2239 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -407,11 +407,9 @@ Context2d::DrawImage(const Arguments &args) { double dw = args[3]->IsNumber() ? args[3]->NumberValue() : img->width; double dh = args[4]->IsNumber() ? args[4]->NumberValue() : img->height; + // Draw + uint8_t *src = cairo_image_surface_get_data(img->surface()); cairo_t *ctx = context->context(); - cairo_save(ctx); - cairo_set_source_surface(ctx, img->surface(), dx, dy); - cairo_paint(ctx); - cairo_restore(ctx); return Undefined(); } From a0417d405ac1dcd8471c28978eb7d0bbee3725b9 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 10:16:26 -0800 Subject: [PATCH 04/15] Added Image::data() --- src/CanvasRenderingContext2d.cc | 2 +- src/Image.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 56b2239..3c712f6 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -408,7 +408,7 @@ Context2d::DrawImage(const Arguments &args) { double dh = args[4]->IsNumber() ? args[4]->NumberValue() : img->height; // Draw - uint8_t *src = cairo_image_surface_get_data(img->surface()); + uint8_t *src = img->data(); cairo_t *ctx = context->context(); return Undefined(); diff --git a/src/Image.h b/src/Image.h index 2ee806e..2c77f58 100644 --- a/src/Image.h +++ b/src/Image.h @@ -31,6 +31,7 @@ class Image: public node::ObjectWrap { static void SetOnload(Local prop, Local val, const AccessorInfo &info); static void SetOnerror(Local prop, Local val, const AccessorInfo &info); inline cairo_surface_t *surface(){ return _surface; } + inline uint8_t *data(){ return cairo_image_surface_get_data(_surface); } cairo_status_t loadSurface(); void error(Local); void loaded(); From 0d95752c57913bcd294c913d3f4cc4d6c6d22b06 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 10:21:21 -0800 Subject: [PATCH 05/15] Added Canvas::data() and Canvas::stride() --- src/Canvas.h | 2 ++ src/CanvasRenderingContext2d.cc | 4 +++- src/Image.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Canvas.h b/src/Canvas.h index 3cc83e3..e4bce77 100644 --- a/src/Canvas.h +++ b/src/Canvas.h @@ -60,6 +60,8 @@ class Canvas: public node::ObjectWrap { static Handle StreamPNGSync(const Arguments &args); static Local Error(cairo_status_t status); inline cairo_surface_t *surface(){ return _surface; } + inline uint8_t *data(){ return cairo_image_surface_get_data(_surface); } + inline int stride(){ return cairo_image_surface_get_stride(_surface); } Canvas(int width, int height); void resurface(); diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 3c712f6..3218343 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -408,8 +408,10 @@ Context2d::DrawImage(const Arguments &args) { double dh = args[4]->IsNumber() ? args[4]->NumberValue() : img->height; // Draw - uint8_t *src = img->data(); cairo_t *ctx = context->context(); + uint8_t *dst = context->canvas()->data(); + uint8_t *src = img->data(); + int stride = img->stride(); return Undefined(); } diff --git a/src/Image.h b/src/Image.h index 2c77f58..93c4109 100644 --- a/src/Image.h +++ b/src/Image.h @@ -32,6 +32,7 @@ class Image: public node::ObjectWrap { static void SetOnerror(Local prop, Local val, const AccessorInfo &info); inline cairo_surface_t *surface(){ return _surface; } inline uint8_t *data(){ return cairo_image_surface_get_data(_surface); } + inline int stride(){ return cairo_image_surface_get_stride(_surface); } cairo_status_t loadSurface(); void error(Local); void loaded(); From 2fcc71a469440ad3656d3a53ef5e04166355f585 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 11:08:14 -0800 Subject: [PATCH 06/15] Started drawImage logic --- src/CanvasRenderingContext2d.cc | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 3218343..047185c 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -385,7 +385,7 @@ Context2d::New(const Arguments &args) { } /* - * Draw image. + * Draw image src image to the destination (context). */ Handle @@ -408,10 +408,22 @@ Context2d::DrawImage(const Arguments &args) { double dh = args[4]->IsNumber() ? args[4]->NumberValue() : img->height; // Draw - cairo_t *ctx = context->context(); uint8_t *dst = context->canvas()->data(); + int dstStride = context->canvas()->stride(); uint8_t *src = img->data(); - int stride = img->stride(); + int srcStride = img->stride(); + + for (int y = 0; y < dh; ++y) { + uint32_t *srcRow = (uint32_t *)(src + srcStride * y); + uint32_t *dstRow = (uint32_t *)(dst + dstStride * y); + for (int x = 0; x < dw; ++x) { + uint32_t *srcPixel = srcRow + x; + uint32_t *dstPixel = dstRow + x; + *dstPixel = *srcPixel; + } + } + + // TODO: cairo_surface_mark_dirty_rectangle(surface, x, y, w, h) return Undefined(); } From 33cac3cf5df796610c5f565f81abb82d8e138664 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 11:16:07 -0800 Subject: [PATCH 07/15] More drawImage() --- src/CanvasRenderingContext2d.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 047185c..ef609f6 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -400,12 +400,12 @@ Context2d::DrawImage(const Arguments &args) { Context2d *context = ObjectWrap::Unwrap(args.This()); // Dest point - double dx = args[1]->NumberValue(); - double dy = args[2]->NumberValue(); + int dx = args[1]->NumberValue(); + int dy = args[2]->NumberValue(); // Dest dimensions - double dw = args[3]->IsNumber() ? args[3]->NumberValue() : img->width; - double dh = args[4]->IsNumber() ? args[4]->NumberValue() : img->height; + int dw = args[3]->IsNumber() ? args[3]->NumberValue() : img->width; + int dh = args[4]->IsNumber() ? args[4]->NumberValue() : img->height; // Draw uint8_t *dst = context->canvas()->data(); @@ -415,10 +415,10 @@ Context2d::DrawImage(const Arguments &args) { for (int y = 0; y < dh; ++y) { uint32_t *srcRow = (uint32_t *)(src + srcStride * y); - uint32_t *dstRow = (uint32_t *)(dst + dstStride * y); + uint32_t *dstRow = (uint32_t *)(dst + dstStride * (y + dy)); for (int x = 0; x < dw; ++x) { - uint32_t *srcPixel = srcRow + x; - uint32_t *dstPixel = dstRow + x; + uint32_t *srcPixel = srcRow + x + dx; + uint32_t *dstPixel = dstRow + x + dx; *dstPixel = *srcPixel; } } From bd29b16ea06a7acfd0a3001555e61378086b7210 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 11:22:05 -0800 Subject: [PATCH 08/15] Marking drawImage() rect as dirty --- src/CanvasRenderingContext2d.cc | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index ef609f6..15bf7c5 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -399,6 +399,10 @@ Context2d::DrawImage(const Arguments &args) { Image *img = ObjectWrap::Unwrap(args[0]->ToObject()); Context2d *context = ObjectWrap::Unwrap(args.This()); + // Src point + int sx = 0; + int sy = 0; + // Dest point int dx = args[1]->NumberValue(); int dy = args[2]->NumberValue(); @@ -410,20 +414,27 @@ Context2d::DrawImage(const Arguments &args) { // Draw uint8_t *dst = context->canvas()->data(); int dstStride = context->canvas()->stride(); - uint8_t *src = img->data(); + int srcStride = img->stride(); + uint8_t *src = img->data() + sy * srcStride + sx * 4; for (int y = 0; y < dh; ++y) { - uint32_t *srcRow = (uint32_t *)(src + srcStride * y); uint32_t *dstRow = (uint32_t *)(dst + dstStride * (y + dy)); for (int x = 0; x < dw; ++x) { - uint32_t *srcPixel = srcRow + x + dx; + int bx = x * 4; + uint32_t *srcPixel = (uint32_t *)(src + bx); uint32_t *dstPixel = dstRow + x + dx; *dstPixel = *srcPixel; } + src += srcStride; } - // TODO: cairo_surface_mark_dirty_rectangle(surface, x, y, w, h) + cairo_surface_mark_dirty_rectangle( + context->canvas()->surface() + , dx + , dy + , dw + , dh); return Undefined(); } From e723d8dbac5c69fb8ddb92cc2650e4efa530d452 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 11:25:39 -0800 Subject: [PATCH 09/15] Docs --- src/CanvasRenderingContext2d.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 15bf7c5..0ef4da5 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -386,6 +386,10 @@ Context2d::New(const Arguments &args) { /* * Draw image src image to the destination (context). + * + * dx, dy + * dx, dy, dw, dh + * sx, sy, sw, sh, dx, dy, dw, dh */ Handle From 366880df60434f3cb235ca86c8e97bc1eb674707 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 11:26:20 -0800 Subject: [PATCH 10/15] Todo --- src/CanvasRenderingContext2d.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 0ef4da5..ac59022 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -400,6 +400,7 @@ Context2d::DrawImage(const Arguments &args) { || !args[2]->IsNumber()) return Undefined(); // TODO: instanceof + // TODO: arg handling / boundaries Image *img = ObjectWrap::Unwrap(args[0]->ToObject()); Context2d *context = ObjectWrap::Unwrap(args.This()); From e4a40e5ea23c484d97b6a55c21cad7c9e42dacf4 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 11:45:07 -0800 Subject: [PATCH 11/15] Using cairo_scale() instead --- src/CanvasRenderingContext2d.cc | 48 ++++++++++++++------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index ac59022..35e4da7 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -403,43 +403,35 @@ Context2d::DrawImage(const Arguments &args) { // TODO: arg handling / boundaries Image *img = ObjectWrap::Unwrap(args[0]->ToObject()); Context2d *context = ObjectWrap::Unwrap(args.This()); + cairo_t *ctx = context->context(); // Src point - int sx = 0; - int sy = 0; + int sx = 0 + , sy = 0; // Dest point - int dx = args[1]->NumberValue(); - int dy = args[2]->NumberValue(); + int dx = args[1]->NumberValue() + , dy = args[2]->NumberValue(); // Dest dimensions - int dw = args[3]->IsNumber() ? args[3]->NumberValue() : img->width; - int dh = args[4]->IsNumber() ? args[4]->NumberValue() : img->height; + int height = img->height + , width = img->width; + + int dw = args[3]->IsNumber() ? args[3]->NumberValue() : width + , dh = args[4]->IsNumber() ? args[4]->NumberValue() : height; // Draw - uint8_t *dst = context->canvas()->data(); - int dstStride = context->canvas()->stride(); - - int srcStride = img->stride(); - uint8_t *src = img->data() + sy * srcStride + sx * 4; - - for (int y = 0; y < dh; ++y) { - uint32_t *dstRow = (uint32_t *)(dst + dstStride * (y + dy)); - for (int x = 0; x < dw; ++x) { - int bx = x * 4; - uint32_t *srcPixel = (uint32_t *)(src + bx); - uint32_t *dstPixel = dstRow + x + dx; - *dstPixel = *srcPixel; - } - src += srcStride; + cairo_save(ctx); + if (dw != width || dh != height) { + cairo_scale(ctx + , (float) dw / width + , (float) dh / height + ); } - - cairo_surface_mark_dirty_rectangle( - context->canvas()->surface() - , dx - , dy - , dw - , dh); + // TODO: globalAlpha + cairo_set_source_surface(ctx, img->surface(), dx, dy); + cairo_paint(ctx); + cairo_restore(ctx); return Undefined(); } From 46c6a969aee0fdfe5e8491b6c10fdebd5b6d96c9 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 12:00:40 -0800 Subject: [PATCH 12/15] Refactoring drawImage() --- src/CanvasRenderingContext2d.cc | 56 +++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 35e4da7..918e9a6 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -387,17 +387,18 @@ Context2d::New(const Arguments &args) { /* * Draw image src image to the destination (context). * - * dx, dy - * dx, dy, dw, dh - * sx, sy, sw, sh, dx, dy, dw, dh + * - dx, dy + * - dx, dy, dw, dh + * - sx, sy, sw, sh, dx, dy, dw, dh + * */ Handle Context2d::DrawImage(const Arguments &args) { HandleScope scope; - if (!args[1]->IsNumber() - || !args[2]->IsNumber()) return Undefined(); + if (args.Length() < 3) + return ThrowException(Exception::TypeError(String::New("invalid arguments"))); // TODO: instanceof // TODO: arg handling / boundaries @@ -405,20 +406,43 @@ Context2d::DrawImage(const Arguments &args) { Context2d *context = ObjectWrap::Unwrap(args.This()); cairo_t *ctx = context->context(); - // Src point - int sx = 0 - , sy = 0; - - // Dest point - int dx = args[1]->NumberValue() - , dy = args[2]->NumberValue(); - - // Dest dimensions int height = img->height , width = img->width; - int dw = args[3]->IsNumber() ? args[3]->NumberValue() : width - , dh = args[4]->IsNumber() ? args[4]->NumberValue() : height; + int sx, sy, sw, sh + , dx, dy, dw, dh; + + // Arguments + switch (args.Length()) { + // img, sx, sy, sw, sh, dx, dy, dw, dh + case 9: + sx = args[1]->NumberValue(); + sy = args[2]->NumberValue(); + sw = args[3]->NumberValue(); + sh = args[4]->NumberValue(); + dx = args[5]->NumberValue(); + dy = args[6]->NumberValue(); + dw = args[7]->NumberValue(); + dh = args[8]->NumberValue(); + break; + // img, dx, dy, dw, dh + case 5: + dx = args[1]->NumberValue(); + dy = args[2]->NumberValue(); + dw = args[3]->NumberValue(); + dh = args[4]->NumberValue(); + break; + // img, dx, dy + case 3: + dx = args[1]->NumberValue(); + dy = args[2]->NumberValue(); + dw = width; + dh = height; + break; + default: + // TODO: throw + return ThrowException(Exception::TypeError(String::New("invalid arguments"))); + } // Draw cairo_save(ctx); From 82a3d9cc36f0643ea853b8bebe09b0f38518705c Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 13:37:44 -0800 Subject: [PATCH 13/15] drawImage() working --- src/CanvasRenderingContext2d.cc | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 918e9a6..054a1ad 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -406,10 +406,10 @@ Context2d::DrawImage(const Arguments &args) { Context2d *context = ObjectWrap::Unwrap(args.This()); cairo_t *ctx = context->context(); - int height = img->height - , width = img->width; - - int sx, sy, sw, sh + int sx = 0 + , sy = 0 + , sw = img->width + , sh = img->height , dx, dy, dw, dh; // Arguments @@ -436,8 +436,8 @@ Context2d::DrawImage(const Arguments &args) { case 3: dx = args[1]->NumberValue(); dy = args[2]->NumberValue(); - dw = width; - dh = height; + dw = img->width; + dh = img->height; break; default: // TODO: throw @@ -446,16 +446,28 @@ Context2d::DrawImage(const Arguments &args) { // Draw cairo_save(ctx); - if (dw != width || dh != height) { + + // Source surface + cairo_surface_t *src = cairo_surface_create_for_rectangle( + img->surface() + , sx + , sy + , sw + , sh); + + // Scale src + if (dw != sw || dh != sh) { cairo_scale(ctx - , (float) dw / width - , (float) dh / height + , (float) dw / sw + , (float) dh / sh ); } // TODO: globalAlpha - cairo_set_source_surface(ctx, img->surface(), dx, dy); + cairo_set_source_surface(ctx, src, dx, dy); cairo_paint(ctx); + cairo_restore(ctx); + cairo_surface_destroy(src); return Undefined(); } From b05b5fc154b997f3b64340d628dc339d57dec385 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 13:54:42 -0800 Subject: [PATCH 14/15] Fixed cairo_set_source_surface() point due to scale --- src/CanvasRenderingContext2d.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 054a1ad..ce2a678 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -457,10 +457,11 @@ Context2d::DrawImage(const Arguments &args) { // Scale src if (dw != sw || dh != sh) { - cairo_scale(ctx - , (float) dw / sw - , (float) dh / sh - ); + double fx = (double) dw / sw; + double fy = (double) dh / sh; + cairo_scale(ctx, fx, fy); + dx /= fx; + dy /= fy; } // TODO: globalAlpha cairo_set_source_surface(ctx, src, dx, dy); From bb34bc716d81e669302aaf6fa1c29eb94a056646 Mon Sep 17 00:00:00 2001 From: Tj Holowaychuk Date: Fri, 12 Nov 2010 13:55:47 -0800 Subject: [PATCH 15/15] Fixed drawImage() globalAlpha support --- src/CanvasRenderingContext2d.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index ce2a678..339de5d 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -444,7 +444,7 @@ Context2d::DrawImage(const Arguments &args) { return ThrowException(Exception::TypeError(String::New("invalid arguments"))); } - // Draw + // Start draw cairo_save(ctx); // Source surface @@ -463,9 +463,10 @@ Context2d::DrawImage(const Arguments &args) { dx /= fx; dy /= fy; } - // TODO: globalAlpha + + // Paint cairo_set_source_surface(ctx, src, dx, dy); - cairo_paint(ctx); + cairo_paint_with_alpha(ctx, context->state->globalAlpha); cairo_restore(ctx); cairo_surface_destroy(src);