Effing 0.44.0: chrome-plated
We've brought canvas text and layout in line with Chrome, and now check it against references generated from Chrome itself.
Effing 0.44.0 is out, and it’s all about @effing/canvas. The last two
releases moved canvas onto @effing/skia and handed text layout to Skia’s
paragraph engine, making text render faster and hold still under scale
animations, and letting opacity and filters apply to an element as a
whole. This one uses that foundation to make what renderReactElement()
draws match what Chrome draws for the same markup, usually to within a
pixel.
Chrome as the reference
Until now, the canvas comparison tests mostly checked against satori, which is a loose reference for text. 0.44.0 checks against references generated from Chrome instead: each test fixture is laid out in a real Chrome with the same fonts, and canvas has to reproduce the boxes, lines and baselines it ends up with. The references are committed, so the tests themselves don’t need a browser. Where canvas still differs, the test says how, and fails once the difference goes away.
What changes
With Chrome as the yardstick, a lot of small differences surfaced and got fixed. The broad strokes:
- Line heights match Chrome. A
normalline box now includes the font’s line gap, so some text gets a little taller, and explicit line heights place their baselines by Chrome’s rules too. - Text keeps its width. Text that can’t wrap no longer shrinks below its widest word, so it stays centered and overflows on both sides, as in a browser, instead of running off to the right.
<br />is a real line break. It used to be laid out as a flex item of its own. It now breaks the line inside the text around it.- Shadows parse as CSS does.
boxShadowandtextShadowtake lists, colors in any position and the usual units, andinsetshadows and spreads now work.drop-shadow()blurs as CSS defines it. - Fonts behave like
@font-face. Any weight from 1 to 1000 works, font collections load every face, and a font registered under a system font’s name replaces that family outright. - Finer typography. Soft hyphens show a hyphen when a line breaks at them, justified text spreads around CJK characters and no-break spaces, and clamped lines are justified before they’re cut.
Filtered draws, including blurred shadows, are also a lot faster.
Upgrading
Bump your @effing/* packages to 0.44.0. Most renders will look the same
or shift by a pixel here and there, but a few changes are worth checking
for:
- Text with
line-height: normalcan get taller, sofindLargestUsableFontSize()may pick a smaller size than before. - A row of text items that can’t fit now overflows its container instead
of squeezing the text. Give an item
minWidth: 0oroverflow: "hidden"to let it shrink. drop-shadow()blurs twice as much as before. Halve the blur length for the old look.- Register every font style you use under a system font’s name, since the styles you leave out are now synthesized rather than taken from the system font.
The full per-package changelogs are in the release PR.