render method

  1. @override
void render(
  1. 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;
}