The stored ValueRecord in the font file only contains the fields
specified in the valueFormat field of the PairPosFormat1 table.
This means we need to construct the ValueRecord dynamically at runtime
and cannot bit_cast it to a struct.
read_value_record(u16 value_format, FixedMemoryStream& stream) takes
a bitmask value_format that describes the available fields of
the ValueRecord and a FixedMemoryStream at the location of the
next ValueRecord. It then advances the stream and returns a complete
ValueRecord.
At the moment, we only understand lookup type 2 (pair adjustment)
so let's ignore lookup tables with other types.
This fixes an issue where we'd choke on Noto Sans versions that come
with a chained context positioning lookup table (type 8).
Fixes#17924
This patch parses enough of GPOS tables to be able to support the
kerning information embedded in Inter.
Since that specific font only applies positioning offsets to the first
glyph in each pair, I was able to get away with not changing our API.
Once we start adding support for more sophisticated positioning, we'll
need to be able to communicate more than a simple "kerning offset" to
the clients of this code.
Ultimately, we should find a way to route all emoji access through
the font code, but for now, this patch adds a special case for fonts
that are known to have embedded color bitmaps so we can test them.
This patch does three things:
- Font::has_color_bitmaps() (true if CBLC and CBDT are present)
- Glyph now knows when its bitmap comes from a color bitmap font
- Painter draws color bitmap glyphs with the appropriate scaling etc
This also removes DirIterator::error_string(), since the same strerror()
string will be included when you print the Error itself. Except in `ls`
which is still using fprintf() for now.
This returns the font's size (distance between ascender and descender)
in pixels, rounded up to the nearest integer.
This is the number we want to use in a lot of UI code, so let's have
a friendly API for it instead of ceil'ing the pixel_size() in a million
random places.
Similar to the FontDatabase, this will be needed for Ladybird to find
emoji images. We now generate just the file name of emoji image in
LibUnicode, and look for that file in the specified path (defaulting to
/res/emoji) at runtime.
Keycap emoji, for example, begin with ASCII digits. Instead, check the
first code point for the Emoji Unicode property.
On a profile of scrolling around on the welcome page in the Browser,
this raises the runtime percentage of Font::glyph_or_emoji_width from
about 0.8% to 1.3%.
On a profile of scrolling around on the welcome page in the Browser,
this drops the runtime percentage of Font::glyph_or_emoji_width from
about 70% to 0.8%.
Currently, we compute the width of text one code point at a time. This
ignores grapheme clusters (emoji in particular). One effect of this is
when highlighting a multi-code point emoji. We will errantly increase
the highlight rect to the sum of all code point widths, rather than
just the width of the resolved emoji bitmap.
This patch adds a "GlyphPage" cache which stores the mapping between
code points and glyph IDs in a segmented table of "pages".
This makes Font::glyph_id_for_code_point() significantly faster by
not reparsing the font tables every time you call it.
In the future, we can add more information to GlyphPage (such as
horizontal metrics for each glyph) to further reduce time spent in
text layout and painting.
As the different Cmap encoding records are guaranteed to be sorted by
their platform ID, we would previously prefer the Macintosh platform
because of its lower ID value. However, this platform is split up into
a lot of encoding formats for different languages, and usually only
English is included. This meant that we could not handle most unicode
characters anymore.
The Windows platform now takes precedence again, as it can handle
arbitrary code points in its supported encodings.
This solution is still far from perfect, but it makes this regression
disappear for now.