encodeGlyphStream function
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;
}