Use HarfBuzz metrics for glyph bounding boxes.
The current code has some serious problems.
-
It uses the glyph path vector to determine an exact bounding box, and does so repeatedly four times each time a glyph is drawn.
-
It uses a random glyph (the 42nd glyph in the font) to expand the "pick" bounding box, and then expands it further by the orignal glyph width which is miscalculated (multiplied by an extra font size value) so it ends up being extremely wide. Picking only works because the pickbox for the next glyph is tested first, so that it masks the too-large pick box.
-
Using the glyph path vector only works for color fonts if a backup 'glyf' table is provided which is missing in fonts like Noto Color Emoji, and in some cases it leads to wrong results and clipping of the SVG glyphs.
This code uses the glyph metric data from HarfBuzz to construct better bounding boxes:
-
An exact bounding box used to determine the bounding box of text objects. It is based on the report x and y bearings of the glyph as well as the width and height of the glyph.
-
A pick bounding box used to determine if a glyph should be picked. It is based on the advance of the glyph in addition to the ascent and descent values for the font.
-
A draw bounding box used to determine the area that needs to be "inked". It is based on the pick bounding box, extended up and down to include text decoration. That is then unioned with the exact bounding box to account for glyphs that extend outside of the font design space (e.g. glyphs for characters than have long tails).
Also fixed:
- Uniformly use 'unsigned int' for the glyph index.
- Correct code that checks for valid Unicode values.
- Ignore Pango glyph number that marks a zero-width empty glyph (e.g. 0xFEOF, an Emoji variant selector).
This code is necessary for future rendering of non-SVG color glyphs.