performPaint method

  1. @override
void performPaint(
  1. Buffer buffer,
  2. Offset offset
)
override

Hook for subclasses to implement actual painting.

Implementation

@override
void performPaint(Buffer buffer, Offset offset) {
  final canvas = widget as Canvas;
  var currentBuffer = buffer;
  var startX = offset.dx;
  var startY = offset.dy;
  var clipRect = Rect(0, 0, buffer.width, buffer.height);
  while (currentBuffer is Viewport) {
    final b = currentBuffer.bounds;
    clipRect = Rect(
      b.x + clipRect.x,
      b.y + clipRect.y,
      clipRect.width,
      clipRect.height,
    ).intersect(b);
    startX += b.x;
    startY += b.y;
    currentBuffer = currentBuffer.parent;
  }
  final targetBuffer = currentBuffer;
  final targetWidth = targetBuffer.width;
  clipRect = clipRect.intersect(targetBuffer.activeClip);

  final w = size.width;
  final h = size.height;

  final drawWidth = min(w, canvas.width);
  final drawHeight = min(h, canvas.height);

  final startXInt = startX.toInt();
  final startYInt = startY.toInt();

  final minCx = max(0, clipRect.x - startXInt);
  final maxCx = min(drawWidth, clipRect.x + clipRect.width - startXInt);
  final minCy = max(0, clipRect.y - startYInt);
  final maxCy = min(drawHeight, clipRect.y + clipRect.height - startYInt);

  if (minCx >= maxCx || minCy >= maxCy) return;

  for (var cy = minCy; cy < maxCy; cy++) {
    final ty = startYInt + cy;

    for (var cx = minCx; cx < maxCx; cx++) {
      final tx = startXInt + cx;

      if (canvas.onlyDrawOnSpaces &&
          targetBuffer.getCharacter(tx, ty) != ' ') {
        continue;
      }

      if (canvas.isOccluded != null && canvas.isOccluded!(cx, cy)) continue;

      final idx = cy * canvas.width + cx;
      final dots = canvas._grid[idx];
      if (dots == 0 &&
          canvas._styles[idx] == null &&
          canvas.style == Style.empty) {
        continue;
      }

      final String char;
      if (canvas.renderMode == CanvasRenderMode.quadrants) {
        char = Canvas._quadrantCache[dots];
      } else if (canvas.renderMode == CanvasRenderMode.density ||
          canvas._antiAliased[idx] == 1) {
        char = Canvas._densityCache[dots];
      } else {
        char = Canvas._brailleCache[dots];
      }

      final targetIdx = ty * targetWidth + tx;
      targetBuffer.characters[targetIdx] = char;
      final s = canvas._styles[idx];
      final targetAttrIdx = targetIdx * 3;
      if (s != null) {
        targetBuffer.attributes[targetAttrIdx + 0] =
            s.foreground?.argb ?? canvas.style.foreground?.argb ?? 0;
        targetBuffer.attributes[targetAttrIdx + 1] =
            s.background?.argb ?? canvas.style.background?.argb ?? 0;
        targetBuffer.attributes[targetAttrIdx + 2] =
            s.modifiers | canvas.style.modifiers;
      } else {
        targetBuffer.attributes[targetAttrIdx + 0] =
            canvas.style.foreground?.argb ?? 0;
        targetBuffer.attributes[targetAttrIdx + 1] =
            canvas.style.background?.argb ?? 0;
        targetBuffer.attributes[targetAttrIdx + 2] = canvas.style.modifiers;
      }
    }
  }
}