Browse Source

Merge pull request #165 from c-spencer/master

Add textDrawingMode context2d property for controlling whether to use paths or glyphs.
v1.x
TJ Holowaychuk 13 years ago
parent
commit
8127ee527f
  1. 8
      Readme.md
  2. 58
      src/CanvasRenderingContext2d.cc
  3. 8
      src/CanvasRenderingContext2d.h

8
Readme.md

@ -132,6 +132,14 @@ Given one of the values below will alter pattern (gradients, images, etc) render
- good
- best
### CanvasRenderingContext2d#textDrawingMode
Can be either `path` or `glyph`. Using `glyph` is much faster than `path` for drawing, and when using a PDF context will embed the text natively, so will be selectable and lower filesize. The downside is that cairo does not have any subpixel precision for `glyph`, so this will be noticeably lower quality for text positioning in cases such as rotated text. Also, strokeText in `glyph` will act the same as fillText, except using the stroke style for the fill.
Defaults to _path_.
This property is tracked as part of the canvas state in save/restore.
### Global Composite Operations
In addition to those specified and commonly implemented by browsers, the following have been added:

58
src/CanvasRenderingContext2d.cc

@ -110,6 +110,7 @@ Context2d::Initialize(Handle<Object> target) {
proto->SetAccessor(String::NewSymbol("shadowOffsetY"), GetShadowOffsetY, SetShadowOffsetY);
proto->SetAccessor(String::NewSymbol("shadowBlur"), GetShadowBlur, SetShadowBlur);
proto->SetAccessor(String::NewSymbol("antialias"), GetAntiAlias, SetAntiAlias);
proto->SetAccessor(String::NewSymbol("textDrawingMode"), GetTextDrawingMode, SetTextDrawingMode);
target->Set(String::NewSymbol("CanvasRenderingContext2d"), constructor->GetFunction());
}
@ -135,6 +136,7 @@ Context2d::Context2d(Canvas *canvas) {
state->stroke = transparent;
state->shadow = transparent_black;
state->patternQuality = CAIRO_FILTER_GOOD;
state->textDrawingMode = TEXT_DRAW_PATHS;
}
/*
@ -932,6 +934,38 @@ Context2d::SetAntiAlias(Local<String> prop, Local<Value> val, const AccessorInfo
cairo_set_antialias(ctx, a);
}
/*
* Get text drawing mode.
*/
Handle<Value>
Context2d::GetTextDrawingMode(Local<String> prop, const AccessorInfo &info) {
HandleScope scope;
Context2d *context = ObjectWrap::Unwrap<Context2d>(info.This());
const char *mode;
if (context->state->textDrawingMode == TEXT_DRAW_PATHS) {
mode = "path";
} else if (context->state->textDrawingMode == TEXT_DRAW_GLYPHS) {
mode = "glyph";
}
return scope.Close(String::NewSymbol(mode));
}
/*
* Set text drawing mode.
*/
void
Context2d::SetTextDrawingMode(Local<String> prop, Local<Value> val, const AccessorInfo &info) {
String::AsciiValue str(val->ToString());
Context2d *context = ObjectWrap::Unwrap<Context2d>(info.This());
if (0 == strcmp("path", *str)) {
context->state->textDrawingMode = TEXT_DRAW_PATHS;
} else if (0 == strcmp("glyph", *str)) {
context->state->textDrawingMode = TEXT_DRAW_GLYPHS;
}
}
/*
* Get miter limit.
*/
@ -1448,8 +1482,13 @@ Context2d::FillText(const Arguments &args) {
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
context->savePath();
context->setTextPath(*str, x, y);
context->fill();
if (context->state->textDrawingMode == TEXT_DRAW_GLYPHS) {
context->fill();
context->setTextPath(*str, x, y);
} else if (context->state->textDrawingMode == TEXT_DRAW_PATHS) {
context->setTextPath(*str, x, y);
context->fill();
}
context->restorePath();
return Undefined();
@ -1473,8 +1512,13 @@ Context2d::StrokeText(const Arguments &args) {
Context2d *context = ObjectWrap::Unwrap<Context2d>(args.This());
context->savePath();
context->setTextPath(*str, x, y);
context->stroke();
if (context->state->textDrawingMode == TEXT_DRAW_GLYPHS) {
context->stroke();
context->setTextPath(*str, x, y);
} else if (context->state->textDrawingMode == TEXT_DRAW_PATHS) {
context->setTextPath(*str, x, y);
context->stroke();
}
context->restorePath();
return Undefined();
@ -1529,7 +1573,11 @@ Context2d::setTextPath(const char *str, double x, double y) {
}
cairo_move_to(_context, x, y);
cairo_text_path(_context, str);
if (state->textDrawingMode == TEXT_DRAW_PATHS) {
cairo_text_path(_context, str);
} else if (state->textDrawingMode == TEXT_DRAW_GLYPHS) {
cairo_show_text(_context, str);
}
}
/*

8
src/CanvasRenderingContext2d.h

@ -12,6 +12,11 @@
#include "Canvas.h"
#include "CanvasGradient.h"
typedef enum {
TEXT_DRAW_PATHS,
TEXT_DRAW_GLYPHS
} canvas_draw_mode_t;
/*
* State struct.
*
@ -34,6 +39,7 @@ typedef struct {
int shadowBlur;
double shadowOffsetX;
double shadowOffsetY;
canvas_draw_mode_t textDrawingMode;
} canvas_state_t;
class Context2d: public node::ObjectWrap {
@ -95,6 +101,7 @@ class Context2d: public node::ObjectWrap {
static Handle<Value> GetShadowOffsetY(Local<String> prop, const AccessorInfo &info);
static Handle<Value> GetShadowBlur(Local<String> prop, const AccessorInfo &info);
static Handle<Value> GetAntiAlias(Local<String> prop, const AccessorInfo &info);
static Handle<Value> GetTextDrawingMode(Local<String> prop, const AccessorInfo &info);
static void SetPatternQuality(Local<String> prop, Local<Value> val, const AccessorInfo &info);
static void SetGlobalCompositeOperation(Local<String> prop, Local<Value> val, const AccessorInfo &info);
static void SetGlobalAlpha(Local<String> prop, Local<Value> val, const AccessorInfo &info);
@ -107,6 +114,7 @@ class Context2d: public node::ObjectWrap {
static void SetShadowOffsetY(Local<String> prop, Local<Value> val, const AccessorInfo &info);
static void SetShadowBlur(Local<String> prop, Local<Value> val, const AccessorInfo &info);
static void SetAntiAlias(Local<String> prop, Local<Value> val, const AccessorInfo &info);
static void SetTextDrawingMode(Local<String> prop, Local<Value> val, const AccessorInfo &info);
inline void setContext(cairo_t *ctx) { _context = ctx; }
inline cairo_t *context(){ return _context; }
inline Canvas *canvas(){ return _canvas; }

Loading…
Cancel
Save