diff --git a/CHANGELOG.md b/CHANGELOG.md index 8aa4a39e4..33c2b1cd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ project adheres to [Semantic Versioning](http://semver.org/). ### Changed * Replaced `simple-get ` with ` Node.js builtin` `fetch` (#2309) * `ctx.font` has a new C++ parser and is 2x-400x faster. Please file an issue if you experience different results, as caching has been removed. +* The restriction of registering fonts before a canvas is created has been removed. You can now register a font as late as right before the `fillText` call ([#1921](https://github.com/Automattic/node-canvas/issues/1921)) ### Added * Support for accessibility and links in PDFs diff --git a/src/Canvas.cc b/src/Canvas.cc index 7b208bec2..b4fe25120 100644 --- a/src/Canvas.cc +++ b/src/Canvas.cc @@ -38,7 +38,10 @@ using namespace std; -std::vector font_face_list; +std::vector Canvas::font_face_list; + +// Increases each time a font is (de)registered +int Canvas::fontSerial = 1; /* * Initialize Canvas. @@ -734,6 +737,7 @@ Canvas::RegisterFont(const Napi::CallbackInfo& info) { free(family); free(weight); free(style); + fontSerial++; } void @@ -749,6 +753,7 @@ Canvas::DeregisterAllFonts(const Napi::CallbackInfo& info) { }); font_face_list.clear(); + fontSerial++; if (!success) Napi::Error::New(env, "Could not deregister one or more fonts").ThrowAsJavaScriptException(); } diff --git a/src/Canvas.h b/src/Canvas.h index eb19843e5..3883c5137 100644 --- a/src/Canvas.h +++ b/src/Canvas.h @@ -91,9 +91,11 @@ class Canvas : public Napi::ObjectWrap { void resurface(Napi::Object This); Napi::Env env; + static int fontSerial; private: Backend* _backend; Napi::ObjectReference _jsBackend; Napi::FunctionReference ctor; + static std::vector font_face_list; }; diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index d294a4b35..2feabcd15 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -2472,6 +2472,16 @@ Context2d::paintText(const Napi::CallbackInfo&info, bool stroke) { PangoLayout *layout = this->layout(); + // If fonts have been registered, the PangoContext is using an outdated FontMap + if (canvas()->fontSerial != fontSerial) { + pango_context_set_font_map( + pango_layout_get_context(layout), + pango_cairo_font_map_get_default() + ); + + fontSerial = canvas()->fontSerial; + } + pango_layout_set_text(layout, str.c_str(), -1); pango_cairo_update_layout(context(), layout); diff --git a/src/CanvasRenderingContext2d.h b/src/CanvasRenderingContext2d.h index 16cd42d34..16c79cb95 100644 --- a/src/CanvasRenderingContext2d.h +++ b/src/CanvasRenderingContext2d.h @@ -227,4 +227,5 @@ class Context2d : public Napi::ObjectWrap { cairo_t *_context = nullptr; cairo_path_t *_path; PangoLayout *_layout = nullptr; + int fontSerial = 1; };