Skip to content

Commit

Permalink
allow registerFont after a canvas has been created
Browse files Browse the repository at this point in the history
Fixes #1921
  • Loading branch information
chearon committed Jan 15, 2025
1 parent 52330b8 commit 803333c
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ const myimg = await loadImage('http://server.com/image.png')
> registerFont(path: string, { family: string, weight?: string, style?: string }) => void
> ```
To use a font file that is not installed as a system font, use `registerFont()` to register the font with Canvas. *This must be done before the Canvas is created.*
To use a font file that is not installed as a system font, use `registerFont()` to register the font with Canvas.
```js
const { registerFont, createCanvas } = require('canvas')
Expand Down
7 changes: 6 additions & 1 deletion src/Canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@

using namespace std;

std::vector<FontFace> font_face_list;
std::vector<FontFace> Canvas::font_face_list;

// Increases each time a font is (de)registered
int Canvas::fontSerial = 1;

/*
* Initialize Canvas.
Expand Down Expand Up @@ -734,6 +737,7 @@ Canvas::RegisterFont(const Napi::CallbackInfo& info) {
free(family);
free(weight);
free(style);
fontSerial++;
}

void
Expand All @@ -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();
}

Expand Down
2 changes: 2 additions & 0 deletions src/Canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,11 @@ class Canvas : public Napi::ObjectWrap<Canvas> {
void resurface(Napi::Object This);

Napi::Env env;
static int fontSerial;

private:
Backend* _backend;
Napi::ObjectReference _jsBackend;
Napi::FunctionReference ctor;
static std::vector<FontFace> font_face_list;
};
10 changes: 10 additions & 0 deletions src/CanvasRenderingContext2d.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions src/CanvasRenderingContext2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,5 @@ class Context2d : public Napi::ObjectWrap<Context2d> {
cairo_t *_context = nullptr;
cairo_path_t *_path;
PangoLayout *_layout = nullptr;
int fontSerial = 1;
};

0 comments on commit 803333c

Please sign in to comment.