render method
void
render(
- Buffer buffer
)
override
Implementation
@override
void render(Buffer buffer) {
resize(buffer.width(), buffer.height());
_diagnostics.clear();
_omittedDiagnostics = 0;
final image = img.Image(
width: _width * _cellWidth + options.padding * 2,
height: _height * _cellHeight + options.padding * 2,
numChannels: 4,
);
_fill(image, 0, 0, image.width, image.height, options.background);
for (var y = 0; y < _height; y++) {
for (var x = 0; x < _width; x++) {
final style = buffer.cellAt(x, y)?.style ?? const UvStyle();
_fill(
image,
_left(x),
_top(y),
_cellWidth,
_cellHeight,
_paintPolicy.resolve(style).background,
);
}
}
for (var y = 0; y < _height; y++) {
for (var x = 0; x < _width; x++) {
final cell = buffer.cellAt(x, y);
if (cell == null) continue;
final style = cell.style;
if (cell.width < 0 || cell.width > 5) {
_diagnose(
'Cell width is outside the supported 0–5 column range',
x,
y,
'invalid-cell-width',
);
continue;
}
final span = math.min(math.max(1, cell.width), _width - x);
if ((style.attrs & ~255) != 0) {
_diagnose(
'Unsupported attribute bits',
x,
y,
'unsupported-attribute',
);
}
if (cell.drawable != null ||
cell.diffOption.isSkip ||
cell.diffOption.isForcedWidth ||
cell.content.contains('\x1b')) {
_diagnose(
'External graphics are not part of a raster cell capture',
x,
y,
'unsupported-cell',
);
continue;
}
if ((style.attrs & Attr.conceal) != 0 || cell.width == 0) continue;
final paint = _paintPolicy.resolve(style);
final fg = paint.foreground;
if (cell.content.isNotEmpty && cell.content != ' ') {
final runes = cell.content.runes.toList();
if (runes.length != 1) {
_diagnose(
'Multi-codepoint graphemes require a shaping backend',
x,
y,
'unsupported-grapheme',
);
} else {
final variant = _variant(style.attrs);
if (variant == null) {
_diagnose(
'Requested bold/italic font face was not supplied',
x,
y,
'missing-variant',
);
} else {
final glyph = variant.getGlyphId(runes.single);
if (glyph == null || glyph == 0) {
_diagnose(
'Font has no glyph for U+${runes.single.toRadixString(16).toUpperCase()}',
x,
y,
'missing-glyph',
);
} else {
final outline = variant.getGlyphOutline(glyph);
if (outline == null) {
_diagnose(
'Cannot decode glyph outline',
x,
y,
'invalid-glyph',
);
} else {
try {
if (_masks.length >= 512) _masks.clear();
final mask = _masks.putIfAbsent(
(variant, glyph),
() => _GlyphMask.rasterize(
outline,
options.fontSize / variant.metrics.unitsPerEm,
),
);
_paintMask(
image,
mask,
_left(x),
_top(y) + _baseline,
span * _cellWidth,
_top(y),
fg,
);
} on FormatException catch (error) {
_diagnose(error.message, x, y, 'invalid-glyph');
}
}
}
}
}
}
_decorations(image, x, y, span, style, paint);
}
}
if (_omittedDiagnostics > 0) {
_diagnostics.add(
RasterDiagnostic(
'$_omittedDiagnostics additional cell diagnostics omitted',
code: 'diagnostic-limit',
),
);
}
if (options.strict && _diagnostics.isNotEmpty) {
throw StateError(_diagnostics.first.toString());
}
_image = image;
}