Skip to content

Commit

Permalink
fix incorrect text width with newer (1.43?) Pango
Browse files Browse the repository at this point in the history
Text renders wider or narrower, as if letter-spacing is set, than
it should with newer versions of Pango.

My best understanding of this problem is that around version 1.43
Pango dropped support for subpixel antialiasing because it
switched to Harbuzz for glyph postions instead of Freetype.
For some reason it still rounds the glyph positions by default.

There's no need for node-canvas to support subpixel antialiasing.
The maintainers of the Linux font stack (Behdad and Matthias) have
stated that they wont, and it's subjective, and node-canvas cannot
make any assumptions about DPI anyways.

Reading (warning: lots of drama to wade through):
- https://gitlab.gnome.org/GNOME/pango/-/issues/404
- https://gitlab.gnome.org/GNOME/pango/-/issues/463
- harfbuzz/harfbuzz#1892
- harfbuzz/harfbuzz#2394
  • Loading branch information
chearon committed Jan 2, 2023
1 parent 9f313df commit abd12c8
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -11,6 +11,7 @@ project adheres to [Semantic Versioning](http://semver.org/).
### Added
### Fixed
* Add missing property `canvas` to the `CanvasRenderingContext2D` type
* Fixed glyph positions getting rounded, resulting text having a slight `letter-spacing` effect

2.11.0
==================
Expand Down
5 changes: 5 additions & 0 deletions src/CanvasRenderingContext2d.cc
Expand Up @@ -171,6 +171,11 @@ Context2d::Context2d(Canvas *canvas) {
_canvas = canvas;
_context = canvas->createCairoContext();
_layout = pango_cairo_create_layout(_context);

// As of January 2023, Pango rounds glyph positions which renders text wider
// or narrower than the browser. See #2184 for more information
pango_context_set_round_glyph_positions(pango_layout_get_context(_layout), FALSE);

states.emplace();
state = &states.top();
pango_layout_set_font_description(_layout, state->fontDescription);
Expand Down
5 changes: 5 additions & 0 deletions test/public/tests.js
Expand Up @@ -2693,6 +2693,11 @@ tests['measureText()'] = function (ctx) {
drawWithBBox('right', 195, 195)
}

tests['glyph advances (#2184)'] = function (ctx) {
ctx.font = '8px Arial';
ctx.fillText('A float is a box that is shifted to the left or right on the current line.', 0, 8);
};

tests['image sampling (#1084)'] = function (ctx, done) {
let loaded1, loaded2
const img1 = new Image()
Expand Down

0 comments on commit abd12c8

Please sign in to comment.