font_for_code_point() was the heaviest function in layout profiles
of a YouTube page (216ms CPU out of 2900ms total). Every call walked
the full cascade and ran a virtual contains_glyph() against each
entry, even though the result is the same for most ASCII code points
across a document.
Add a 128-entry direct-mapped cache keyed by code point that stores
the resolved Font pointer on first lookup. Subsequent ASCII lookups
become a null check plus a load.
No invalidation is needed: m_fonts is append-only, and the cascade
returns the first matching font, so once an entry claims a code
point, later appends cannot change the answer.
When rendering text, if none of the fonts in the cascade list contain a
glyph for a given code point, we now query Skia's font manager to find
a system font that can render it.
By keeping track of the enclosing range around all Unicode ranges of a
FontCascadeList entry, we can quickly reject any code point that's
outside all ranges.
This knocks font_for_code_point() from 7% to 3% in the profile when
scrolling on https://screenshotone.com/