Browse Source

Merge branch 'fix-fillText-path'

v1.x
Tj Holowaychuk 14 years ago
parent
commit
d2f82f5ab5
  1. 30
      lib/canvas.js
  2. 177
      src/CanvasRenderingContext2d.cc
  3. 4
      src/CanvasRenderingContext2d.h

30
lib/canvas.js

@ -349,36 +349,6 @@ Context2d.prototype.setTransform = function(){
this.transform.apply(this, arguments);
};
/**
* Stroke `text` at (`x`, `y`).
*
* @param {String} text
* @param {Number} x
* @param {Number} y
* @api public
*/
Context2d.prototype.strokeText = function(text, x, y){
this.beginPath();
this.setTextPath(text, x, y);
return this.stroke();
};
/**
* Fill `text` at (`x`, `y`).
*
* @param {String} text
* @param {Number} x
* @param {Number} y
* @api public
*/
Context2d.prototype.fillText = function(text, x, y){
this.beginPath();
this.setTextPath(text, x, y);
return this.fill();
};
/**
* Set the fill style with the given css color string.
*

177
src/CanvasRenderingContext2d.cc

@ -54,10 +54,10 @@ using namespace node;
||!args[1]->IsNumber() \
||!args[2]->IsNumber() \
||!args[3]->IsNumber()) return Undefined(); \
int x = args[0]->Int32Value(); \
int y = args[1]->Int32Value(); \
int width = args[2]->Int32Value(); \
int height = args[3]->Int32Value();
double x = args[0]->Int32Value(); \
double y = args[1]->Int32Value(); \
double width = args[2]->Int32Value(); \
double height = args[3]->Int32Value();
/*
* Text baselines.
@ -97,13 +97,14 @@ Context2d::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "clip", Clip);
NODE_SET_PROTOTYPE_METHOD(t, "fill", Fill);
NODE_SET_PROTOTYPE_METHOD(t, "stroke", Stroke);
NODE_SET_PROTOTYPE_METHOD(t, "fillText", FillText);
NODE_SET_PROTOTYPE_METHOD(t, "strokeText", StrokeText);
NODE_SET_PROTOTYPE_METHOD(t, "fillRect", FillRect);
NODE_SET_PROTOTYPE_METHOD(t, "strokeRect", StrokeRect);
NODE_SET_PROTOTYPE_METHOD(t, "clearRect", ClearRect);
NODE_SET_PROTOTYPE_METHOD(t, "rect", Rect);
NODE_SET_PROTOTYPE_METHOD(t, "setTextBaseline", SetTextBaseline);
NODE_SET_PROTOTYPE_METHOD(t, "setTextAlignment", SetTextAlignment);
NODE_SET_PROTOTYPE_METHOD(t, "setTextPath", SetTextPath);
NODE_SET_PROTOTYPE_METHOD(t, "measureText", MeasureText);
NODE_SET_PROTOTYPE_METHOD(t, "moveTo", MoveTo);
NODE_SET_PROTOTYPE_METHOD(t, "lineTo", LineTo);
@ -767,6 +768,114 @@ Context2d::Stroke(const Arguments &args) {
return Undefined();
}
/*
* Fill text at (x, y).
*/
Handle<Value>
Context2d::FillText(const Arguments &args) {
HandleScope scope;
if (!args[0]->IsString()
|| !args[1]->IsNumber()
|| !args[2]->IsNumber()) return Undefined();
String::Utf8Value str(args[0]);
double x = args[1]->NumberValue();
double y = args[2]->NumberValue();
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
cairo_t *ctx = context->getContext();
// Save path
cairo_save(ctx);
cairo_path_t *path = cairo_copy_path_flat(ctx);
cairo_new_path(ctx);
// Text path
context->setTextPath(*str, x, y);
SET_SOURCE(context->state->fill);
cairo_fill(ctx);
// Restore path
cairo_restore(ctx);
cairo_append_path(ctx, path);
return Undefined();
}
/*
* Stroke text at (x ,y).
*/
Handle<Value>
Context2d::StrokeText(const Arguments &args) {
HandleScope scope;
if (!args[0]->IsString()
|| !args[1]->IsNumber()
|| !args[2]->IsNumber()) return Undefined();
String::Utf8Value str(args[0]);
double x = args[1]->NumberValue();
double y = args[2]->NumberValue();
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
cairo_t *ctx = context->getContext();
// Save path
cairo_save(ctx);
cairo_path_t *path = cairo_copy_path_flat(ctx);
cairo_new_path(ctx);
// Text path
context->setTextPath(*str, x, y);
SET_SOURCE(context->state->stroke);
cairo_stroke(ctx);
// Restore path
cairo_restore(ctx);
cairo_append_path(ctx, path);
return Undefined();
}
void
Context2d::setTextPath(const char *str, double x, double y) {
// Text extents
cairo_text_extents_t te;
cairo_text_extents(_context, str, &te);
// Alignment
switch (state->textAlignment) {
// center
case 0:
x -= te.width / 2 + te.x_bearing;
break;
// right
case 1:
x -= te.width + te.x_bearing;
break;
}
// Baseline approx
// TODO:
switch (state->textBaseline) {
case TEXT_BASELINE_TOP:
case TEXT_BASELINE_HANGING:
y += te.height;
break;
case TEXT_BASELINE_MIDDLE:
y += te.height / 2;
break;
case TEXT_BASELINE_BOTTOM:
y -= te.height / 2;
break;
}
cairo_move_to(_context, x, y);
cairo_text_path(_context, str);
}
/*
* Adds a point to the current subpath.
*/
@ -911,64 +1020,6 @@ Context2d::SetTextAlignment(const Arguments &args) {
return Undefined();
}
/*
* Set text path at x, y.
*/
Handle<Value>
Context2d::SetTextPath(const Arguments &args) {
HandleScope scope;
// Ignore when args are not present
if (!args[0]->IsString()
|| !args[1]->IsNumber()
|| !args[2]->IsNumber()) return Undefined();
String::Utf8Value str(args[0]);
double x = args[1]->NumberValue()
, y = args[2]->NumberValue();
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
cairo_t *ctx = context->getContext();
// Text extents
cairo_text_extents_t te;
cairo_text_extents(ctx, *str, &te);
// Alignment
switch (context->state->textAlignment) {
// center
case 0:
x -= te.width / 2 + te.x_bearing;
break;
// right
case 1:
x -= te.width + te.x_bearing;
break;
}
// Baseline approx
// TODO:
switch (context->state->textBaseline) {
case TEXT_BASELINE_TOP:
case TEXT_BASELINE_HANGING:
y += te.height;
break;
case TEXT_BASELINE_MIDDLE:
y += te.height / 2;
break;
case TEXT_BASELINE_BOTTOM:
y -= te.height / 2;
break;
}
cairo_move_to(ctx, x, y);
cairo_text_path(ctx, *str);
return Undefined();
}
/*
* Fill the rectangle defined by x, y, width and height.
*/

4
src/CanvasRenderingContext2d.h

@ -60,6 +60,8 @@ class Context2d: public node::ObjectWrap {
static Handle<Value> Clip(const Arguments &args);
static Handle<Value> Fill(const Arguments &args);
static Handle<Value> Stroke(const Arguments &args);
static Handle<Value> FillText(const Arguments &args);
static Handle<Value> StrokeText(const Arguments &args);
static Handle<Value> SetFont(const Arguments &args);
static Handle<Value> SetFillRGBA(const Arguments &args);
static Handle<Value> SetStrokeRGBA(const Arguments &args);
@ -68,7 +70,6 @@ class Context2d: public node::ObjectWrap {
static Handle<Value> SetStrokePattern(const Arguments &args);
static Handle<Value> SetTextBaseline(const Arguments &args);
static Handle<Value> SetTextAlignment(const Arguments &args);
static Handle<Value> SetTextPath(const Arguments &args);
static Handle<Value> MeasureText(const Arguments &args);
static Handle<Value> BezierCurveTo(const Arguments &args);
static Handle<Value> QuadraticCurveTo(const Arguments &args);
@ -99,6 +100,7 @@ class Context2d: public node::ObjectWrap {
static void SetShadowBlur(Local<String> prop, Local<Value> val, const AccessorInfo &info);
inline cairo_t *getContext(){ return _context; }
inline Canvas *getCanvas(){ return _canvas; }
void setTextPath(const char *str, double x, double y);
void saveState();
void restoreState();

Loading…
Cancel
Save