encodeGlyphStream function

Uint8List encodeGlyphStream(
  1. List<QuadCurve> curves,
  2. GlyphBands bands
)

The raw texel stream of one glyph (4 bytes per texel, layout in the library header), relocatable: all internal offsets are relative to the stream start, so streams concatenate into a per-flush atlas unchanged. Throws ArgumentError past u16 addressability - callers fall back to outline strips.

Implementation

Uint8List encodeGlyphStream(List<QuadCurve> curves, GlyphBands bands) {
  final bandCount = bands.bandCount;
  var refEntries = 0;
  for (final b in bands.bands) {
    refEntries += b.length;
  }
  for (final b in bands.vBands) {
    refEntries += b.length;
  }
  final texelCount = 1 + 2 * bandCount + refEntries + 3 * curves.length;
  if (texelCount > 0xFFFF) {
    throw ArgumentError('glyph curve stream too large: $texelCount texels');
  }
  final bytes = Uint8List(texelCount * 4);
  final u16 = ByteData.sublistView(bytes);

  void put(int texel, int lo, int hi) {
    u16.setUint16(texel * 4, lo, Endian.little);
    u16.setUint16(texel * 4 + 2, hi, Endian.little);
  }

  final curveBase = 1 + 2 * bandCount + refEntries;
  put(0, bandCount, curves.length);
  var refAt = 1 + 2 * bandCount;
  for (var b = 0; b < bandCount; b++) {
    put(1 + b, refAt, bands.bands[b].length);
    for (final curveIndex in bands.bands[b]) {
      put(refAt++, curveBase + 3 * curveIndex, 0);
    }
  }
  for (var b = 0; b < bandCount; b++) {
    put(1 + bandCount + b, refAt, bands.vBands[b].length);
    for (final curveIndex in bands.vBands[b]) {
      put(refAt++, curveBase + 3 * curveIndex, 0);
    }
  }
  for (var i = 0; i < curves.length; i++) {
    final c = curves[i];
    put(curveBase + 3 * i, emToFixed(c.x0), emToFixed(c.y0));
    put(curveBase + 3 * i + 1, emToFixed(c.cx), emToFixed(c.cy));
    put(curveBase + 3 * i + 2, emToFixed(c.x1), emToFixed(c.y1));
  }
  return bytes;
}