From e06ed99dec70c2fd13ca4e1a0c32cf57243d3b05 Mon Sep 17 00:00:00 2001 From: c-spencer Date: Wed, 2 May 2012 11:13:17 +0100 Subject: [PATCH] Partial TextMetrics support. --- src/CanvasRenderingContext2d.cc | 44 +++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index e6ff9ec..2b67150 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -1667,6 +1667,9 @@ Context2d::SetFont(const Arguments &args) { /* * Return the given text extents. + * TODO: Support for: + * hangingBaseline, ideographicBaseline, + * fontBoundingBoxAscent, fontBoundingBoxDescent */ Handle @@ -1680,9 +1683,50 @@ Context2d::MeasureText(const Arguments &args) { Local obj = Object::New(); cairo_text_extents_t te; + cairo_font_extents_t fe; + cairo_text_extents(ctx, *str, &te); + cairo_font_extents(ctx, &fe); + obj->Set(String::New("width"), Number::New(te.x_advance)); + double x_offset; + switch (context->state->textAlignment) { + case 0: // center + x_offset = te.width / 2; + break; + case 1: // right + x_offset = te.width; + break; + default: // left + x_offset = 0.0; + } + + obj->Set(String::New("actualBoundingBoxLeft"), Number::New(x_offset - te.x_bearing)); + obj->Set(String::New("actualBoundingBoxRight"), Number::New((te.x_bearing + te.width) - x_offset)); + + double y_offset; + switch (context->state->textBaseline) { + case TEXT_BASELINE_TOP: + case TEXT_BASELINE_HANGING: + y_offset = fe.ascent; + break; + case TEXT_BASELINE_MIDDLE: + y_offset = fe.ascent/2; + break; + case TEXT_BASELINE_BOTTOM: + y_offset = -fe.descent; + break; + default: + y_offset = 0.0; + } + obj->Set(String::New("actualBoundingBoxAscent"), Number::New(-(te.y_bearing + y_offset))); + obj->Set(String::New("actualBoundingBoxDescent"), Number::New(te.height + te.y_bearing + y_offset)); + + obj->Set(String::New("emHeightAscent"), Number::New(fe.ascent - y_offset)); + obj->Set(String::New("emHeightDescent"), Number::New(fe.descent + y_offset)); + obj->Set(String::New("alphabeticBaseline"), Number::New(-y_offset)); + return scope.Close(obj); }