buildLocalPath method

Path? buildLocalPath({
  1. bool copy = true,
})

Builds a local path centered around (0,0), or returns null if invalid.

The returned path is in the node's local coordinate space. The caller is responsible for applying transform.

By default, this method returns a defensive copy of the cached geometry so external callers cannot accidentally mutate internal cache state.

For performance-sensitive internal call sites, pass copy: false and treat the returned path as immutable (read-only).

Implementation

Path? buildLocalPath({bool copy = true}) {
  if (_cacheResolved &&
      _cachedSvgPathData == _svgPathData &&
      _cachedFillRule == _fillRule) {
    final cached = _cachedLocalPath;
    if (cached == null) return null;
    return copy ? _copyPath(cached) : cached;
  }
  if (_svgPathData.trim().isEmpty) {
    _cacheResolved = true;
    _cachedSvgPathData = _svgPathData;
    _cachedFillRule = _fillRule;
    _cachedLocalPath = null;
    _cachedLocalPathBounds = null;
    _recordBuildLocalPathFailure(reason: 'empty-svg-path-data');
    return null;
  }
  try {
    final path = parseSvgPathData(_svgPathData);
    final metrics = path.computeMetrics();
    var hasNonZeroLength = false;
    for (final metric in metrics) {
      if (metric.length > 0) {
        hasNonZeroLength = true;
        break;
      }
    }
    if (!hasNonZeroLength) {
      _cacheResolved = true;
      _cachedSvgPathData = _svgPathData;
      _cachedFillRule = _fillRule;
      _cachedLocalPath = null;
      _cachedLocalPathBounds = null;
      _recordBuildLocalPathFailure(reason: 'svg-path-has-no-nonzero-length');
      return null;
    }
    final bounds = path.getBounds();
    final centered = path.shift(-bounds.center);
    centered.fillType = _fillRule == PathFillRule.evenOdd
        ? PathFillType.evenOdd
        : PathFillType.nonZero;
    final centeredBounds = centered.getBounds();
    _cacheResolved = true;
    _cachedSvgPathData = _svgPathData;
    _cachedFillRule = _fillRule;
    _cachedLocalPath = centered;
    _cachedLocalPathBounds = centeredBounds;
    _clearBuildLocalPathFailure();
    return copy ? _copyPath(centered) : centered;
  } catch (e, st) {
    _cacheResolved = true;
    _cachedSvgPathData = _svgPathData;
    _cachedFillRule = _fillRule;
    _cachedLocalPath = null;
    _cachedLocalPathBounds = null;
    _recordBuildLocalPathFailure(
      reason: 'exception-while-building-local-path',
      exception: e,
      stackTrace: st,
    );
    return null;
  }
}