patchFontLineMetrics function

ByteData patchFontLineMetrics(
  1. ByteData bytes,
  2. String fontFamily, {
  3. double clearance = kLineHeightClearance,
})

bytes with the ascent and descent centred on the font's Latin ink.

Flutter places the baseline at the font's ascent, so a font with spare room for another script sits off-centre when TextStyle.height shrinks its line: the cut is split evenly, but the spare room is not. This is the equivalent of CSS ascent-override and descent-override.

The new line box is lineHeightForFontFamily at clearance, centred on the ink: half the space above the highest letter, half below the lowest. Text with no TextStyle.height gets that line height. A different TextStyle.height keeps the letters centred, with even leading.

Rewrites hhea (ascender, descender, lineGap), and OS/2 (typo and win metrics), so every platform reads the same values. Recomputes the checksums. Returns bytes if the font has no Latin ink data, or is not a TrueType or OpenType file.

Implementation

ByteData patchFontLineMetrics(
  ByteData bytes,
  String fontFamily, {
  double clearance = kLineHeightClearance,
}) {
  final ink = latinInkForFontFamily(fontFamily);
  final height = lineHeightForFontFamily(fontFamily, clearance: clearance);
  if (ink == null || height == null) return bytes;
  final pad = (height - ink.$1 - ink.$2) / 2;
  return patchFontAscentDescent(bytes, ink.$1 + pad, ink.$2 + pad);
}