Browse Source

Merge branch 'strokeStyle'

v1.x
Tj Holowaychuk 15 years ago
parent
commit
7271eb8f49
  1. 41
      lib/canvas.js
  2. 84
      src/context2d.cc
  3. 8
      src/context2d.h
  4. 23
      test/canvas.test.js

41
lib/canvas.js

@ -111,6 +111,13 @@ Canvas.prototype.getContext = function(contextId){
}
};
/**
* Set the fill style with the given css color string.
*
* @see exports.parseColor()
* @api public
*/
Context2d.prototype.__defineSetter__('fillStyle', function(val){
var rgba = exports.parseColor(val) || [0,0,0,1];
this.lastFillStyle = rgba;
@ -121,7 +128,41 @@ Context2d.prototype.__defineSetter__('fillStyle', function(val){
, rgba[3]);
});
/**
* Get the current fill style string.
*
* @api public
*/
Context2d.prototype.__defineGetter__('fillStyle', function(){
var rgba = this.lastFillStyle;
return 'rgba(' + rgba[0] + ',' + rgba[1] + ',' + rgba[2] + ',' + rgba[3] + ')';
});
/**
* Set the stroke style with the given css color string.
*
* @see exports.parseColor()
* @api public
*/
Context2d.prototype.__defineSetter__('strokeStyle', function(val){
var rgba = exports.parseColor(val) || [0,0,0,1];
this.lastStrokeStyle = rgba;
this.setStrokeRGBA(
rgba[0]
, rgba[1]
, rgba[2]
, rgba[3]);
});
/**
* Get the current stroke style string.
*
* @api public
*/
Context2d.prototype.__defineGetter__('strokeStyle', function(){
var rgba = this.lastStrokeStyle;
return 'rgba(' + rgba[0] + ',' + rgba[1] + ',' + rgba[2] + ',' + rgba[3] + ')';
});

84
src/context2d.cc

@ -12,6 +12,27 @@
using namespace v8;
using namespace node;
/*
* Set RGBA.
*/
#define RGBA(_,R,G,B,A) \
_.r = R; \
_.g = G; \
_.b = B; \
_.a = A; \
/*
* Set source RGBA.
*/
#define SET_SOURCE_RGBA(C) \
cairo_set_source_rgba(ctx \
, C.r \
, C.g \
, C.b \
, C.a);
/*
* Rectangle arg assertions.
*/
@ -30,6 +51,24 @@ using namespace node;
int width = args[2]->Int32Value(); \
int height = args[3]->Int32Value();
/*
* RGBA arg assertions.
*/
#define RGBA_ARGS \
if (!args[0]->IsNumber()) \
return ThrowException(Exception::TypeError(String::New("r required"))); \
if (!args[1]->IsNumber()) \
return ThrowException(Exception::TypeError(String::New("g required"))); \
if (!args[2]->IsNumber()) \
return ThrowException(Exception::TypeError(String::New("b required"))); \
if (!args[3]->IsNumber()) \
return ThrowException(Exception::TypeError(String::New("alpha required"))); \
int r = args[0]->Int32Value(); \
int g = args[1]->Int32Value(); \
int b = args[2]->Int32Value(); \
double a = args[3]->NumberValue();
/*
* Initialize Context2d.
*/
@ -55,6 +94,7 @@ Context2d::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "closePath", ClosePath);
NODE_SET_PROTOTYPE_METHOD(t, "arc", Arc);
NODE_SET_PROTOTYPE_METHOD(t, "setFillRGBA", SetFillRGBA);
NODE_SET_PROTOTYPE_METHOD(t, "setStrokeRGBA", SetStrokeRGBA);
target->Set(String::NewSymbol("Context2d"), t->GetFunction());
}
@ -78,7 +118,8 @@ Context2d::New(const Arguments &args) {
Context2d::Context2d(Canvas *canvas): ObjectWrap() {
_canvas = canvas;
_context = cairo_create(canvas->getSurface());
cairo_set_source_rgba(_context, 0, 0, 0, 1);
RGBA(fill,0,0,0,1);
RGBA(stroke,0,0,0,1);
}
/*
@ -90,30 +131,28 @@ Context2d::~Context2d() {
}
/*
* Set fill RGBA, use internally for fillStyle=
* Set fill RGBA, used internally for fillStyle=
*/
Handle<Value>
Context2d::SetFillRGBA(const Arguments &args) {
HandleScope scope;
RGBA_ARGS;
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
RGBA(context->fill,r,g,b,a);
return Undefined();
}
if (!args[0]->IsNumber())
return ThrowException(Exception::TypeError(String::New("r required")));
if (!args[1]->IsNumber())
return ThrowException(Exception::TypeError(String::New("g required")));
if (!args[2]->IsNumber())
return ThrowException(Exception::TypeError(String::New("b required")));
if (!args[3]->IsNumber())
return ThrowException(Exception::TypeError(String::New("alpha required")));
/*
* Set stroke RGBA, used internally for strokeStyle=
*/
Handle<Value>
Context2d::SetStrokeRGBA(const Arguments &args) {
HandleScope scope;
RGBA_ARGS;
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
cairo_set_source_rgba(context->getContext()
, args[0]->Int32Value()
, args[1]->Int32Value()
, args[2]->Int32Value()
, args[3]->NumberValue());
RGBA(context->stroke,r,g,b,a);
return Undefined();
}
@ -182,7 +221,9 @@ Handle<Value>
Context2d::Fill(const Arguments &args) {
HandleScope scope;
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
cairo_fill(context->getContext());
cairo_t *ctx = context->getContext();
SET_SOURCE_RGBA(context->fill);
cairo_fill_preserve(ctx);
return Undefined();
}
@ -194,7 +235,9 @@ Handle<Value>
Context2d::Stroke(const Arguments &args) {
HandleScope scope;
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
cairo_stroke(context->getContext());
cairo_t *ctx = context->getContext();
SET_SOURCE_RGBA(context->stroke);
cairo_stroke_preserve(ctx);
return Undefined();
}
@ -251,6 +294,7 @@ Context2d::FillRect(const Arguments &args) {
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
cairo_t *ctx = context->getContext();
cairo_rectangle(ctx, x, y, width, height);
SET_SOURCE_RGBA(context->fill);
cairo_fill(ctx);
return Undefined();
}
@ -266,6 +310,7 @@ Context2d::StrokeRect(const Arguments &args) {
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
cairo_t *ctx = context->getContext();
cairo_rectangle(ctx, x, y, width, height);
SET_SOURCE_RGBA(context->stroke);
cairo_stroke(ctx);
return Undefined();
}
@ -282,6 +327,7 @@ Context2d::ClearRect(const Arguments &args) {
cairo_t *ctx = context->getContext();
cairo_set_operator(ctx, CAIRO_OPERATOR_CLEAR);
cairo_rectangle(ctx, x, y, width, height);
SET_SOURCE_RGBA(context->fill);
cairo_fill(ctx);
cairo_set_operator(ctx, CAIRO_OPERATOR_OVER);
return Undefined();

8
src/context2d.h

@ -10,8 +10,15 @@
#include "canvas.h"
typedef struct {
unsigned char r, g, b;
double a;
} rgba_t;
class Context2d: public node::ObjectWrap {
public:
rgba_t fill;
rgba_t stroke;
static void Initialize(Handle<Object> target);
static Handle<Value> New(const Arguments &args);
static Handle<Value> BeginPath(const Arguments &args);
@ -19,6 +26,7 @@ class Context2d: public node::ObjectWrap {
static Handle<Value> Fill(const Arguments &args);
static Handle<Value> Stroke(const Arguments &args);
static Handle<Value> SetFillRGBA(const Arguments &args);
static Handle<Value> SetStrokeRGBA(const Arguments &args);
static Handle<Value> BezierCurveTo(const Arguments &args);
static Handle<Value> LineTo(const Arguments &args);
static Handle<Value> MoveTo(const Arguments &args);

23
test/canvas.test.js

@ -171,6 +171,29 @@ module.exports = {
, 'Canvas#bezierCurveTo() failed');
},
'test fill with stroke': function(assert){
var canvas = new Canvas(200, 200)
, ctx = canvas.getContext('2d')
, path = __dirname + '/fillWithStroke.png';
ctx.beginPath();
ctx.arc(75,75,50,0,Math.PI*2,true);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.fillStyle = 'red';
ctx.strokeStyle = 'yellow';
ctx.arc(75,75,30,0,Math.PI*2,true);
ctx.fill();
ctx.stroke();
assertChecksum(
canvas
, path
, '0437605377cc9840c58cb166fb0b89d4'
, 'fill with stroke failed');
},
'test Canvas#fillStyle=': function(assert){
var canvas = new Canvas(200, 200)
, ctx = canvas.getContext('2d')

Loading…
Cancel
Save