From 18e3edfc282df18997ea9b33dca9d785ffd1d7ad Mon Sep 17 00:00:00 2001 From: c-spencer Date: Wed, 2 May 2012 09:46:22 +0100 Subject: [PATCH] Add textDrawingMode context property. --- Readme.md | 6 +++++ src/CanvasRenderingContext2d.cc | 46 ++++++++++++++++++++++++++++++--- src/CanvasRenderingContext2d.h | 3 +++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/Readme.md b/Readme.md index d5547f3..be736a2 100644 --- a/Readme.md +++ b/Readme.md @@ -132,6 +132,12 @@ 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. + +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: diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 588b4e9..e6ff9ec 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -110,6 +110,7 @@ Context2d::Initialize(Handle 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->textDrawingPaths = true; } /* @@ -932,6 +934,38 @@ Context2d::SetAntiAlias(Local prop, Local val, const AccessorInfo cairo_set_antialias(ctx, a); } +/* + * Get text drawing mode. + */ + +Handle +Context2d::GetTextDrawingMode(Local prop, const AccessorInfo &info) { + HandleScope scope; + Context2d *context = ObjectWrap::Unwrap(info.This()); + const char *mode; + if (context->state->textDrawingPaths) { + mode = "path"; + } else { + mode = "glyph"; + } + return scope.Close(String::NewSymbol(mode)); +} + +/* + * Set text drawing mode. + */ + +void +Context2d::SetTextDrawingMode(Local prop, Local val, const AccessorInfo &info) { + String::AsciiValue str(val->ToString()); + Context2d *context = ObjectWrap::Unwrap(info.This()); + if (0 == strcmp("path", *str)) { + context->state->textDrawingPaths = true; + } else if (0 == strcmp("glyph", *str)) { + context->state->textDrawingPaths = false; + } +} + /* * Get miter limit. */ @@ -1448,8 +1482,9 @@ Context2d::FillText(const Arguments &args) { Context2d *context = ObjectWrap::Unwrap(args.This()); context->savePath(); + if (!context->state->textDrawingPaths) context->fill(); context->setTextPath(*str, x, y); - context->fill(); + if (context->state->textDrawingPaths) context->fill(); context->restorePath(); return Undefined(); @@ -1473,8 +1508,9 @@ Context2d::StrokeText(const Arguments &args) { Context2d *context = ObjectWrap::Unwrap(args.This()); context->savePath(); + if (!context->state->textDrawingPaths) context->stroke(); context->setTextPath(*str, x, y); - context->stroke(); + if (context->state->textDrawingPaths) context->stroke(); context->restorePath(); return Undefined(); @@ -1529,7 +1565,11 @@ Context2d::setTextPath(const char *str, double x, double y) { } cairo_move_to(_context, x, y); - cairo_text_path(_context, str); + if (state->textDrawingPaths) { + cairo_text_path(_context, str); + } else { + cairo_show_text(_context, str); + } } /* diff --git a/src/CanvasRenderingContext2d.h b/src/CanvasRenderingContext2d.h index a5448e9..58fa2a7 100644 --- a/src/CanvasRenderingContext2d.h +++ b/src/CanvasRenderingContext2d.h @@ -34,6 +34,7 @@ typedef struct { int shadowBlur; double shadowOffsetX; double shadowOffsetY; + bool textDrawingPaths; } canvas_state_t; class Context2d: public node::ObjectWrap { @@ -95,6 +96,7 @@ class Context2d: public node::ObjectWrap { static Handle GetShadowOffsetY(Local prop, const AccessorInfo &info); static Handle GetShadowBlur(Local prop, const AccessorInfo &info); static Handle GetAntiAlias(Local prop, const AccessorInfo &info); + static Handle GetTextDrawingMode(Local prop, const AccessorInfo &info); static void SetPatternQuality(Local prop, Local val, const AccessorInfo &info); static void SetGlobalCompositeOperation(Local prop, Local val, const AccessorInfo &info); static void SetGlobalAlpha(Local prop, Local val, const AccessorInfo &info); @@ -107,6 +109,7 @@ class Context2d: public node::ObjectWrap { static void SetShadowOffsetY(Local prop, Local val, const AccessorInfo &info); static void SetShadowBlur(Local prop, Local val, const AccessorInfo &info); static void SetAntiAlias(Local prop, Local val, const AccessorInfo &info); + static void SetTextDrawingMode(Local prop, Local val, const AccessorInfo &info); inline void setContext(cairo_t *ctx) { _context = ctx; } inline cairo_t *context(){ return _context; } inline Canvas *canvas(){ return _canvas; }