paint method

void paint(
  1. Canvas canvas
)

Do not override this method as it applies the basic transformations. Override $applyPaint if you want to use Canvas directly.

Implementation

void paint(ui.Canvas canvas) {
  /// Check if the object has visible area and if it's visible
  if (!$hasVisibleArea || !visible) {
    return;
  }
  $onPreTransform?.dispatch(canvas);

  /// Check if the object has any transformations.
  final hasScale = _scaleX != 1 || _scaleY != 1;
  final hasTranslate = _x != 0 || _y != 0;
  final hasPivot = _pivotX != 0 || _pivotY != 0;
  final hasSkew = _skewX != 0 || _skewY != 0;
  final needSave = hasTranslate ||
      hasScale ||
      rotation != 0 ||
      hasPivot ||
      hasSkew ||
      _is3D;

  final $hasFilters = hasFilters;
  // final hasColorize = $colorize?.alpha > 0 ?? false;
  // var _saveLayer = this is DisplayObjectContainer &&
  //     (this as DisplayObjectContainer).hasChildren &&
  //     ($alpha != 1 || $hasColorize || $hasFilters);
  var saveLayer =
      allowSaveLayer && $alpha != 1 || $hasColorize || $hasFilters;
  // if (this is DisplayObjectContainer &&
  //     (this as DisplayObjectContainer).hasChildren) {
  // }

  final hasMask = mask != null || maskRect != null;
  final showDebugBounds =
      DisplayBoundsDebugger.debugBoundsMode == DebugBoundsMode.internal &&
          ($debugBounds || DisplayBoundsDebugger.debugAll);

  GRect? cacheLocalBoundsRect;
  if (showDebugBounds || saveLayer) {
    // _cacheLocalBoundsRect = bounds.toNative();
    cacheLocalBoundsRect = bounds;
  }

  List<GComposerFilter>? composerFilters;
  var filterHidesObject = false;
  if (saveLayer) {
//       TODO: static painter seems to have some issues, try local var later.
    /// using local Painter now to avoid problems.
    final alphaPaint = filterPaint;
    if (alpha < 1) {
      alphaPaint.color = kColorBlack.withOpacity(alpha);
    }

    /// check colorize if it needs a unique Paint instead.
    alphaPaint.colorFilter = null;
    alphaPaint.imageFilter = null;
    alphaPaint.maskFilter = null;
    if ($hasColorize) {
      alphaPaint.colorFilter = ui.ColorFilter.mode(
        $colorize!,
        ui.BlendMode.srcATop,
      );
    }
    ui.Rect? nativeLayerBounds;
    var layerBounds = getBounds($parent);
    if ($hasFilters) {
      /// TODO: Find a common implementation for filter bounds.
      // layerBounds = getFilterBounds(layerBounds, alphaPaint);
      layerBounds = layerBounds!.clone();
      GRect? resultBounds;
      for (var filter in $filters!) {
        resultBounds ??= layerBounds.clone();
        filter.update();
        filter.expandBounds(layerBounds, resultBounds);
        if (filter is GComposerFilter) {
          composerFilters ??= <GComposerFilter>[];
          composerFilters.add(filter);
        } else {
          filter.currentObject = this;
          filter.resolvePaint(alphaPaint);
          filter.currentObject = null;
        }
      }
      layerBounds = resultBounds;
    }
    $debugLastLayerBounds = layerBounds;
    // canvas.saveLayer(layerBounds.toNative(), alphaPaint);
    if ($useSaveLayerBounds) {
      nativeLayerBounds = layerBounds!.toNative();
    }
    canvas.saveLayer(nativeLayerBounds, alphaPaint);
  }
  if (needSave) {
    // onPreTransform.dispatch();
    canvas.save();
    var m = transformationMatrix.toNative();
    if (_is3D) {
      /// TODO: experimental, just transforms
      final m2 = GMatrix().toNative();
      m2.setEntry(3, 2, 0.004);
      m2.translate(_pivotX, _pivotY);
      if (z != 0) {
        m2.translate(.0, .0, z);
      }
      m2.rotateX(_rotationX);
      m2.rotateY(_rotationY);
      m2.translate(-_pivotX, -_pivotY);
      m.multiply(m2);
    }
    canvas.transform(m.storage);
  }

  if (hasMask) {
    canvas.save();
    if (maskRect != null) {
      $applyMaskRect(canvas);
    } else {
      mask!.$applyPaint(canvas);
    }
  }

  if (composerFilters != null) {
    for (var filter in composerFilters) {
      if (filter.hideObject ||
          (filter is GDropShadowFilter && filter.innerShadow)) {
        filterHidesObject = true;
      }
      filter.currentObject = this;
      filter.process(canvas, $applyPaint);
      filter.currentObject = null;
    }
  }
  $onPrePaint?.dispatch(canvas);
  if (!filterHidesObject) {
    $applyPaint(canvas);
  }
  $onPostPaint?.dispatch(canvas);

  if (hasMask) {
    canvas.restore();
  }
  if (showDebugBounds) {
    final paint = $debugBoundsPaint ?? _debugPaint;
    final linePaint = paint.clone();
    linePaint.color = linePaint.color.withOpacity(.3);
    final rect = cacheLocalBoundsRect!.toNative();
    canvas.drawLine(rect.topLeft, rect.bottomRight, linePaint);
    canvas.drawLine(rect.topRight, rect.bottomLeft, linePaint);
    canvas.drawRect(rect, paint);
  }
  if (needSave) {
    canvas.restore();
  }
  if (saveLayer) {
    canvas.restore();
  }
}