I spotted this leak when WebContent was exiting with ASan enabled on a
page with a media element. MediaPaintable calls Gfx::Font::width(),
which calls through to measure_text_width(), which then drops an
hb_buffer_t* without freeing it.
This patch introduces a per-Gfx::Font cache for harfbuzz text shaping
results. As long as the same OpenType features are used, we now cache
the results of harfbuzz shaping, saving massive amounts of time during
text layout.
As an example, it saves multiple seconds when loading the ECMAScript
specification at <https://tc39.es/ecma262>. Before this change, harfbuzz
shaping was taking up roughly 11% of a profile of loading that page.
The cache brings it down to 1.8%.
Note that the cache currently grows unbounded. I've left a FIXME about
adding some limits.
We currently have a mixup in LibWeb between code unit offset and glyph
offset during hit testing. These extra fields will allow us to correct
this discrepency.
Previously we would omit the letter spacing for the end glyph of each
chunk in a misguided attempt to conform to the spec's instruction that
we "really should not append letter spacing to the right or trailing
edge of a line", this behaviour can be removed entirely as other
browsers (Firefox, Chrome) don't implement it either.
Instead of using the first font from the FontCascadeList for all glyphs
in a text, we perform a text shaping process that finds a suitable font
for each glyph and returns a list of glyph runs, where each glyph run
represents consecutive glyphs using the same font.