paint method

  1. @override
void paint(
  1. PaintingContext context,
  2. Offset offset
)
override

Default paint implementation.

RenderBox paints no self-content; it forwards painting to its RenderBox children. Subclasses override to draw their own content.

Implementation

@override
void paint(PaintingContext context, Offset offset) {
  final originX = offset.dx + x;
  final originY = offset.dy + y;
  final canvas = context.canvas;

  if (_backgroundColor != null) {
    canvas.fillRect(
      Rect.fromLTWH(originX, originY, width, height),
      _backgroundColor!,
    );
  }

  final isEmpty = _lines.length == 1 && _lines[0].isEmpty;
  if (isEmpty && _placeholder != null && !_focused) {
    // Render placeholder dimmed on first row only, cell-aware.
    final dim = Color(
      _color.r * 0.5,
      _color.g * 0.5,
      _color.b * 0.5,
      _color.a,
    );
    final ph = _placeholder!;
    var col = 0;
    for (final cluster in ph.characters) {
      final cw = terminalCellWidth(cluster);
      if (col + cw > width) break;
      canvas.setCell(
        Offset(originX + col, originY),
        cluster,
        dim,
        _backgroundColor ?? Color.transparent,
        0,
      );
      col += cw;
    }
  } else {
    for (var row = 0; row < height; row++) {
      final lineIdx = _scrollLine + row;
      if (lineIdx >= _lines.length) break;
      final line = _lines[lineIdx];
      var cellAccum = 0;
      var paintedCol = 0;
      for (final cluster in line.characters) {
        final cw = terminalCellWidth(cluster);
        if (cellAccum + cw <= _scrollCell) {
          cellAccum += cw;
          continue;
        }
        // The cluster crosses or starts past the scroll boundary. If it
        // straddles the left edge (wide cluster at the boundary), drop it.
        if (cellAccum < _scrollCell) {
          cellAccum += cw;
          continue;
        }
        if (paintedCol + cw > width) break;
        canvas.setCell(
          Offset(originX + paintedCol, originY + row),
          cluster,
          _color,
          _backgroundColor ?? Color.transparent,
          0,
        );
        paintedCol += cw;
        cellAccum += cw;
      }
    }
  }

  if (_focused) {
    final cursorRow = _cursorLine - _scrollLine;
    final line = _lines[_cursorLine.clamp(0, _lines.length - 1)];
    final cursorAbsoluteCell = graphemeIndexToCell(line, _cursorColumn);
    final cursorCol = cursorAbsoluteCell - _scrollCell;
    if (cursorRow >= 0 &&
        cursorRow < height &&
        cursorCol >= 0 &&
        cursorCol < width) {
      _cursorController.showCursor(
        this,
        originX + cursorCol,
        originY + cursorRow,
        style: _cursorStyle,
        color: _cursorColor,
      );
    } else {
      _cursorController.hideCursorFor(this);
    }
  } else {
    _cursorController.hideCursorFor(this);
  }
}