diff --git a/CHANGELOG.md b/CHANGELOG.md index 98cba4534..79119fecd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ project adheres to [Semantic Versioning](http://semver.org/). ================== ### Changed ### Added +* Added `ctx.lang` to set the ISO language code for text ### Fixed 3.1.2 diff --git a/index.d.ts b/index.d.ts index 43ff107d0..27ab0c341 100644 --- a/index.d.ts +++ b/index.d.ts @@ -291,6 +291,7 @@ export class CanvasRenderingContext2D { textAlign: CanvasTextAlign; canvas: Canvas; direction: 'ltr' | 'rtl'; + lang: string; } export class CanvasGradient { diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 15c5c80f5..2342a57e5 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -43,7 +43,7 @@ constexpr double twoPi = M_PI * 2.; #define PANGO_LAYOUT_GET_METRICS(LAYOUT) pango_context_get_metrics( \ pango_layout_get_context(LAYOUT), \ pango_layout_get_font_description(LAYOUT), \ - pango_context_get_language(pango_layout_get_context(LAYOUT))) + pango_language_from_string(state->lang.c_str())) inline static bool checkArgs(const Napi::CallbackInfo&info, double *args, int argsNum, int offset = 0){ Napi::Env env = info.Env(); @@ -162,7 +162,8 @@ Context2d::Initialize(Napi::Env& env, Napi::Object& exports) { InstanceAccessor<&Context2d::GetFont, &Context2d::SetFont>("font", napi_default_jsproperty), InstanceAccessor<&Context2d::GetTextBaseline, &Context2d::SetTextBaseline>("textBaseline", napi_default_jsproperty), InstanceAccessor<&Context2d::GetTextAlign, &Context2d::SetTextAlign>("textAlign", napi_default_jsproperty), - InstanceAccessor<&Context2d::GetDirection, &Context2d::SetDirection>("direction", napi_default_jsproperty) + InstanceAccessor<&Context2d::GetDirection, &Context2d::SetDirection>("direction", napi_default_jsproperty), + InstanceAccessor<&Context2d::GetLanguage, &Context2d::SetLanguage>("lang", napi_default_jsproperty) }); exports.Set("CanvasRenderingContext2d", ctor); @@ -786,6 +787,25 @@ Context2d::SetDirection(const Napi::CallbackInfo& info, const Napi::Value& value state->direction = dir; } +/* + * Get language. + */ +Napi::Value +Context2d::GetLanguage(const Napi::CallbackInfo& info) { + return Napi::String::New(env, state->lang); +} + +/* + * Set language. + */ +void +Context2d::SetLanguage(const Napi::CallbackInfo& info, const Napi::Value& value) { + if (!value.IsString()) return; + + std::string lang = value.As(); + state->lang = lang; +} + /* * Put image data. * @@ -2490,6 +2510,9 @@ Context2d::paintText(const Napi::CallbackInfo& info, bool stroke) { checkFonts(); pango_layout_set_text(layout, str.c_str(), -1); + if (state->lang != "") { + pango_context_set_language(pango_layout_get_context(_layout), pango_language_from_string(state->lang.c_str())); + } pango_cairo_update_layout(context(), layout); PangoDirection pango_dir = state->direction == "ltr" ? PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL; @@ -2802,6 +2825,9 @@ Context2d::MeasureText(const Napi::CallbackInfo& info) { checkFonts(); pango_layout_set_text(layout, str.Utf8Value().c_str(), -1); + if (state->lang != "") { + pango_context_set_language(pango_layout_get_context(_layout), pango_language_from_string(state->lang.c_str())); + } pango_cairo_update_layout(ctx, layout); // Normally you could use pango_layout_get_pixel_extents and be done, or use diff --git a/src/CanvasRenderingContext2d.h b/src/CanvasRenderingContext2d.h index 341e5936d..1d9548895 100644 --- a/src/CanvasRenderingContext2d.h +++ b/src/CanvasRenderingContext2d.h @@ -36,6 +36,7 @@ struct canvas_state_t { canvas_draw_mode_t textDrawingMode = TEXT_DRAW_PATHS; bool imageSmoothingEnabled = true; std::string direction = "ltr"; + std::string lang = ""; canvas_state_t() { fontDescription = pango_font_description_from_string("sans"); @@ -61,6 +62,7 @@ struct canvas_state_t { fontDescription = pango_font_description_copy(other.fontDescription); font = other.font; imageSmoothingEnabled = other.imageSmoothingEnabled; + lang = other.lang; } ~canvas_state_t() { @@ -157,6 +159,7 @@ class Context2d : public Napi::ObjectWrap { Napi::Value GetFont(const Napi::CallbackInfo& info); Napi::Value GetTextBaseline(const Napi::CallbackInfo& info); Napi::Value GetTextAlign(const Napi::CallbackInfo& info); + Napi::Value GetLanguage(const Napi::CallbackInfo& info); void SetPatternQuality(const Napi::CallbackInfo& info, const Napi::Value& value); void SetImageSmoothingEnabled(const Napi::CallbackInfo& info, const Napi::Value& value); void SetGlobalCompositeOperation(const Napi::CallbackInfo& info, const Napi::Value& value); @@ -179,6 +182,7 @@ class Context2d : public Napi::ObjectWrap { void SetFont(const Napi::CallbackInfo& info, const Napi::Value& value); void SetTextBaseline(const Napi::CallbackInfo& info, const Napi::Value& value); void SetTextAlign(const Napi::CallbackInfo& info, const Napi::Value& value); + void SetLanguage(const Napi::CallbackInfo& info, const Napi::Value& value); #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 16, 0) void BeginTag(const Napi::CallbackInfo& info); void EndTag(const Napi::CallbackInfo& info); diff --git a/test/canvas.test.js b/test/canvas.test.js index 01156d089..4655c31c7 100644 --- a/test/canvas.test.js +++ b/test/canvas.test.js @@ -2490,7 +2490,8 @@ describe('Canvas', function () { ['patternQuality', 'best'], // ['quality', 'best'], // doesn't do anything, TODO remove ['textDrawingMode', 'glyph'], - ['antialias', 'gray'] + ['antialias', 'gray'], + ['lang', 'eu'] ] for (const [k, v] of state) {