RasterFont.fromTtf constructor

RasterFont.fromTtf(
  1. Uint8List regular, {
  2. Uint8List? bold,
  3. Uint8List? italic,
  4. Uint8List? boldItalic,
})

Parses caller-supplied static TrueType faces without filesystem access.

Implementation

factory RasterFont.fromTtf(
  Uint8List regular, {
  Uint8List? bold,
  Uint8List? italic,
  Uint8List? boldItalic,
}) {
  ui.TtfFont parse(Uint8List source) {
    try {
      final bytes = Uint8List.fromList(source);
      _validateFontDirectory(bytes);
      final font = ui.TtfFont.load(bytes);
      final metrics = font.metrics;
      if (metrics.unitsPerEm < 16 ||
          metrics.unitsPerEm > 16384 ||
          metrics.lineHeightAt(1) <= 0 ||
          !metrics.lineHeightAt(1).isFinite) {
        throw const FormatException('Invalid font metrics');
      }
      final space = font.getGlyphId(32);
      if (space == null || font.getAdvanceWidth(space, 1) <= 0) {
        throw const FormatException('Font needs a positive-width space');
      }
      final advance = font.getAdvanceWidth(space, 1);
      for (var rune = 33; rune <= 126; rune++) {
        final id = font.getGlyphId(rune);
        if (id != null &&
            (font.getAdvanceWidth(id, 1) - advance).abs() > 0.00001) {
          throw const FormatException(
            'Font must have fixed-width ASCII metrics',
          );
        }
      }
      return font;
    } on Exception catch (error) {
      throw ArgumentError('Invalid static monospace TrueType font: $error');
    } on Error catch (error) {
      throw ArgumentError('Invalid static monospace TrueType font: $error');
    }
  }

  final result = RasterFont._(
    parse(regular),
    bold == null ? null : parse(bold),
    italic == null ? null : parse(italic),
    boldItalic == null ? null : parse(boldItalic),
  );
  final reference = result._regular;
  for (final face in [result._bold, result._italic, result._boldItalic]) {
    if (face == null) continue;
    final sameAdvance =
        (face.getAdvanceWidth(face.getGlyphId(32)!, 1) -
                reference.getAdvanceWidth(reference.getGlyphId(32)!, 1))
            .abs() <
        0.00001;
    final sameBaseline =
        (face.metrics.baselineOffsetAt(1) -
                reference.metrics.baselineOffsetAt(1))
            .abs() <
        0.00001;
    final sameHeight =
        (face.metrics.lineHeightAt(1) - reference.metrics.lineHeightAt(1))
            .abs() <
        0.00001;
    if (!sameAdvance || !sameBaseline || !sameHeight) {
      throw ArgumentError(
        'Font variants must share the regular face cell metrics',
      );
    }
  }
  return result;
}