// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.6
part of engine;

/// A complex, one-dimensional subset of a plane.
///
/// A path consists of a number of subpaths, and a _current point_.
///
/// Subpaths consist of segments of various types, such as lines,
/// arcs, or beziers. Subpaths can be open or closed, and can
/// self-intersect.
///
/// Closed subpaths enclose a (possibly discontiguous) region of the
/// plane based on the current [fillType].
///
/// The _current point_ is initially at the origin. After each
/// operation adding a segment to a subpath, the current point is
/// updated to the end of that segment.
///
/// Paths can be drawn on canvases using [Canvas.drawPath], and can
/// used to create clip regions using [Canvas.clipPath].
class SurfacePath implements ui.Path {
  final List<Subpath> subpaths;
  ui.PathFillType _fillType = ui.PathFillType.nonZero;

  Subpath get _currentSubpath => subpaths.isEmpty ? null : subpaths.last;

  List<PathCommand> get _commands => _currentSubpath?.commands;

  /// The current x-coordinate for this path.
  double get _currentX => _currentSubpath?.currentX ?? 0.0;

  /// The current y-coordinate for this path.
  double get _currentY => _currentSubpath?.currentY ?? 0.0;

  /// Recorder used for hit testing paths.
  static ui.RawRecordingCanvas _rawRecorder;

  SurfacePath() : subpaths = <Subpath>[];

  /// Creates a copy of another [Path].
  ///
  /// This copy is fast and does not require additional memory unless either
  /// the `source` path or the path returned by this constructor are modified.
  SurfacePath.from(SurfacePath source) : subpaths = _deepCopy(source.subpaths);

  SurfacePath._shallowCopy(SurfacePath source)
      : subpaths = List<Subpath>.from(source.subpaths);

  SurfacePath._clone(this.subpaths, this._fillType);

  static List<Subpath> _deepCopy(List<Subpath> source) {
    // The last sub path can potentially still be mutated by calling ops.
    // Copy all sub paths except the last active one which needs a deep copy.
    final List<Subpath> paths = [];
    int len = source.length;
    if (len != 0) {
      --len;
      for (int i = 0; i < len; i++) {
        paths.add(source[i]);
      }
      paths.add(source[len].shift(const ui.Offset(0, 0)));
    }
    return paths;
  }

  /// Determines how the interior of this path is calculated.
  ///
  /// Defaults to the non-zero winding rule, [PathFillType.nonZero].
  @override
  ui.PathFillType get fillType => _fillType;
  @override
  set fillType(ui.PathFillType value) {
    _fillType = value;
  }

  /// Opens a new subpath with starting point (x, y).
  void _openNewSubpath(double x, double y) {
    subpaths.add(Subpath(x, y));
    _setCurrentPoint(x, y);
  }

  /// Sets the current point to (x, y).
  void _setCurrentPoint(double x, double y) {
    _currentSubpath.currentX = x;
    _currentSubpath.currentY = y;
  }

  /// Starts a new subpath at the given coordinate.
  @override
  void moveTo(double x, double y) {
    _openNewSubpath(x, y);
    _commands.add(MoveTo(x, y));
  }

  /// Starts a new subpath at the given offset from the current point.
  @override
  void relativeMoveTo(double dx, double dy) {
    final double newX = _currentX + dx;
    final double newY = _currentY + dy;
    _openNewSubpath(newX, newY);
    _commands.add(MoveTo(newX, newY));
  }

  /// Adds a straight line segment from the current point to the given
  /// point.
  @override
  void lineTo(double x, double y) {
    if (subpaths.isEmpty) {
      moveTo(0.0, 0.0);
    }
    _commands.add(LineTo(x, y));
    _setCurrentPoint(x, y);
  }

  /// Adds a straight line segment from the current point to the point
  /// at the given offset from the current point.
  @override
  void relativeLineTo(double dx, double dy) {
    final double newX = _currentX + dx;
    final double newY = _currentY + dy;
    if (subpaths.isEmpty) {
      moveTo(0.0, 0.0);
    }
    _commands.add(LineTo(newX, newY));
    _setCurrentPoint(newX, newY);
  }

  void _ensurePathStarted() {
    if (subpaths.isEmpty) {
      subpaths.add(Subpath(0.0, 0.0));
    }
  }

  /// Adds a quadratic bezier segment that curves from the current
  /// point to the given point (x2,y2), using the control point
  /// (x1,y1).
  @override
  void quadraticBezierTo(double x1, double y1, double x2, double y2) {
    _ensurePathStarted();
    _commands.add(QuadraticCurveTo(x1, y1, x2, y2));
    _setCurrentPoint(x2, y2);
  }

  /// Adds a quadratic bezier segment that curves from the current
  /// point to the point at the offset (x2,y2) from the current point,
  /// using the control point at the offset (x1,y1) from the current
  /// point.
  @override
  void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2) {
    _ensurePathStarted();
    _commands.add(QuadraticCurveTo(
        x1 + _currentX, y1 + _currentY, x2 + _currentX, y2 + _currentY));
    _setCurrentPoint(x2 + _currentX, y2 + _currentY);
  }

  /// Adds a cubic bezier segment that curves from the current point
  /// to the given point (x3,y3), using the control points (x1,y1) and
  /// (x2,y2).
  @override
  void cubicTo(
      double x1, double y1, double x2, double y2, double x3, double y3) {
    _ensurePathStarted();
    _commands.add(BezierCurveTo(x1, y1, x2, y2, x3, y3));
    _setCurrentPoint(x3, y3);
  }

  /// Adds a cubic bezier segment that curves from the current point
  /// to the point at the offset (x3,y3) from the current point, using
  /// the control points at the offsets (x1,y1) and (x2,y2) from the
  /// current point.
  @override
  void relativeCubicTo(
      double x1, double y1, double x2, double y2, double x3, double y3) {
    _ensurePathStarted();
    _commands.add(BezierCurveTo(x1 + _currentX, y1 + _currentY, x2 + _currentX,
        y2 + _currentY, x3 + _currentX, y3 + _currentY));
    _setCurrentPoint(x3 + _currentX, y3 + _currentY);
  }

  /// Adds a bezier segment that curves from the current point to the
  /// given point (x2,y2), using the control points (x1,y1) and the
  /// weight w. If the weight is greater than 1, then the curve is a
  /// hyperbola; if the weight equals 1, it's a parabola; and if it is
  /// less than 1, it is an ellipse.
  @override
  void conicTo(double x1, double y1, double x2, double y2, double w) {
    final List<ui.Offset> quads =
        Conic(_currentX, _currentY, x1, y1, x2, y2, w).toQuads();
    final int len = quads.length;
    for (int i = 1; i < len; i += 2) {
      quadraticBezierTo(
          quads[i].dx, quads[i].dy, quads[i + 1].dx, quads[i + 1].dy);
    }
  }

  /// Adds a bezier segment that curves from the current point to the
  /// point at the offset (x2,y2) from the current point, using the
  /// control point at the offset (x1,y1) from the current point and
  /// the weight w. If the weight is greater than 1, then the curve is
  /// a hyperbola; if the weight equals 1, it's a parabola; and if it
  /// is less than 1, it is an ellipse.
  @override
  void relativeConicTo(double x1, double y1, double x2, double y2, double w) {
    conicTo(_currentX + x1, _currentY + y1, _currentX + x2, _currentY + y2, w);
  }

  /// If the `forceMoveTo` argument is false, adds a straight line
  /// segment and an arc segment.
  ///
  /// If the `forceMoveTo` argument is true, starts a new subpath
  /// consisting of an arc segment.
  ///
  /// In either case, the arc segment consists of the arc that follows
  /// the edge of the oval bounded by the given rectangle, from
  /// startAngle radians around the oval up to startAngle + sweepAngle
  /// radians around the oval, with zero radians being the point on
  /// the right hand side of the oval that crosses the horizontal line
  /// that intersects the center of the rectangle and with positive
  /// angles going clockwise around the oval.
  ///
  /// The line segment added if `forceMoveTo` is false starts at the
  /// current point and ends at the start of the arc.
  @override
  void arcTo(
      ui.Rect rect, double startAngle, double sweepAngle, bool forceMoveTo) {
    assert(rectIsValid(rect));
    final ui.Offset center = rect.center;
    final double radiusX = rect.width / 2;
    final double radiusY = rect.height / 2;
    final double startX = radiusX * math.cos(startAngle) + center.dx;
    final double startY = radiusY * math.sin(startAngle) + center.dy;
    if (forceMoveTo) {
      _openNewSubpath(startX, startY);
    } else {
      lineTo(startX, startY);
    }
    _commands.add(Ellipse(center.dx, center.dy, radiusX, radiusY, 0.0,
        startAngle, startAngle + sweepAngle, sweepAngle.isNegative));

    _setCurrentPoint(radiusX * math.cos(startAngle + sweepAngle) + center.dx,
        radiusY * math.sin(startAngle + sweepAngle) + center.dy);
  }

  /// Appends up to four conic curves weighted to describe an oval of `radius`
  /// and rotated by `rotation`.
  ///
  /// The first curve begins from the last point in the path and the last ends
  /// at `arcEnd`. The curves follow a path in a direction determined by
  /// `clockwise` and `largeArc` in such a way that the sweep angle
  /// is always less than 360 degrees.
  ///
  /// A simple line is appended if either either radii are zero or the last
  /// point in the path is `arcEnd`. The radii are scaled to fit the last path
  /// point if both are greater than zero but too small to describe an arc.
  ///
  /// See Conversion from endpoint to center parametrization described in
  /// https://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
  /// as reference for implementation.
  @override
  void arcToPoint(
    ui.Offset arcEnd, {
    ui.Radius radius = ui.Radius.zero,
    double rotation = 0.0,
    bool largeArc = false,
    bool clockwise = true,
  }) {
    assert(offsetIsValid(arcEnd));
    assert(radiusIsValid(radius));
    // _currentX, _currentY are the coordinates of start point on path,
    // arcEnd is final point of arc.
    // rx,ry are the radii of the eclipse (semi-major/semi-minor axis)
    // largeArc is false if arc is spanning less than or equal to 180 degrees.
    // clockwise is false if arc sweeps through decreasing angles or true
    // if sweeping through increasing angles.
    // rotation is the angle from the x-axis of the current coordinate
    // system to the x-axis of the eclipse.

    double rx = radius.x.abs();
    double ry = radius.y.abs();

    // If the current point and target point for the arc are identical, it
    // should be treated as a zero length path. This ensures continuity in
    // animations.
    final bool isSamePoint = _currentX == arcEnd.dx && _currentY == arcEnd.dy;

    // If rx = 0 or ry = 0 then this arc is treated as a straight line segment
    // (a "lineto") joining the endpoints.
    // http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters
    if (isSamePoint || rx.toInt() == 0 || ry.toInt() == 0) {
      _commands.add(LineTo(arcEnd.dx, arcEnd.dy));
      _setCurrentPoint(arcEnd.dx, arcEnd.dy);
      return;
    }

    // As an intermediate point to finding center parametrization, place the
    // origin on the midpoint between start/end points and rotate to align
    // coordinate axis with axes of the ellipse.
    final double midPointX = (_currentX - arcEnd.dx) / 2.0;
    final double midPointY = (_currentY - arcEnd.dy) / 2.0;

    // Convert rotation or radians.
    final double xAxisRotation = math.pi * rotation / 180.0;

    // Cache cos/sin value.
    final double cosXAxisRotation = math.cos(xAxisRotation);
    final double sinXAxisRotation = math.sin(xAxisRotation);

    // Calculate rotate midpoint as x/yPrime.
    final double xPrime =
        (cosXAxisRotation * midPointX) + (sinXAxisRotation * midPointY);
    final double yPrime =
        (-sinXAxisRotation * midPointX) + (cosXAxisRotation * midPointY);

    // Check if the radii are big enough to draw the arc, scale radii if not.
    // http://www.w3.org/TR/SVG/implnote.html#ArcCorrectionOutOfRangeRadii
    double rxSquare = rx * rx;
    double rySquare = ry * ry;
    final double xPrimeSquare = xPrime * xPrime;
    final double yPrimeSquare = yPrime * yPrime;

    double radiiScale = (xPrimeSquare / rxSquare) + (yPrimeSquare / rySquare);
    if (radiiScale > 1) {
      radiiScale = math.sqrt(radiiScale);
      rx *= radiiScale;
      ry *= radiiScale;
      rxSquare = rx * rx;
      rySquare = ry * ry;
    }

    // Compute transformed center. eq. 5.2
    final double distanceSquare =
        (rxSquare * yPrimeSquare) + rySquare * xPrimeSquare;
    final double cNumerator = (rxSquare * rySquare) - distanceSquare;
    double scaleFactor = math.sqrt(math.max(cNumerator / distanceSquare, 0.0));
    if (largeArc == clockwise) {
      scaleFactor = -scaleFactor;
    }
    // Ready to compute transformed center.
    final double cxPrime = scaleFactor * ((rx * yPrime) / ry);
    final double cyPrime = scaleFactor * (-(ry * xPrime) / rx);

    // Rotate to find actual center.
    final double cx = cosXAxisRotation * cxPrime -
        sinXAxisRotation * cyPrime +
        ((_currentX + arcEnd.dx) / 2.0);
    final double cy = sinXAxisRotation * cxPrime +
        cosXAxisRotation * cyPrime +
        ((_currentY + arcEnd.dy) / 2.0);

    // Calculate start angle and sweep.
    // Start vector is from midpoint of start/end points to transformed center.
    final double startVectorX = (xPrime - cxPrime) / rx;
    final double startVectorY = (yPrime - cyPrime) / ry;

    final double startAngle = math.atan2(startVectorY, startVectorX);
    final double endVectorX = (-xPrime - cxPrime) / rx;
    final double endVectorY = (-yPrime - cyPrime) / ry;
    double sweepAngle = math.atan2(endVectorY, endVectorX) - startAngle;

    if (clockwise && sweepAngle < 0) {
      sweepAngle += math.pi * 2.0;
    } else if (!clockwise && sweepAngle > 0) {
      sweepAngle -= math.pi * 2.0;
    }

    _commands.add(Ellipse(cx, cy, rx, ry, xAxisRotation, startAngle,
        startAngle + sweepAngle, sweepAngle.isNegative));

    _setCurrentPoint(arcEnd.dx, arcEnd.dy);
  }

  /// Appends up to four conic curves weighted to describe an oval of `radius`
  /// and rotated by `rotation`.
  ///
  /// The last path point is described by (px, py).
  ///
  /// The first curve begins from the last point in the path and the last ends
  /// at `arcEndDelta.dx + px` and `arcEndDelta.dy + py`. The curves follow a
  /// path in a direction determined by `clockwise` and `largeArc`
  /// in such a way that the sweep angle is always less than 360 degrees.
  ///
  /// A simple line is appended if either either radii are zero, or, both
  /// `arcEndDelta.dx` and `arcEndDelta.dy` are zero. The radii are scaled to
  /// fit the last path point if both are greater than zero but too small to
  /// describe an arc.
  @override
  void relativeArcToPoint(
    ui.Offset arcEndDelta, {
    ui.Radius radius = ui.Radius.zero,
    double rotation = 0.0,
    bool largeArc = false,
    bool clockwise = true,
  }) {
    assert(offsetIsValid(arcEndDelta));
    assert(radiusIsValid(radius));
    arcToPoint(
        ui.Offset(_currentX + arcEndDelta.dx, _currentY + arcEndDelta.dy),
        radius: radius,
        rotation: rotation,
        largeArc: largeArc,
        clockwise: clockwise);
  }

  /// Adds a new subpath that consists of four lines that outline the
  /// given rectangle.
  @override
  void addRect(ui.Rect rect) {
    assert(rectIsValid(rect));
    _openNewSubpath(rect.left, rect.top);
    _commands.add(RectCommand(rect.left, rect.top, rect.width, rect.height));
  }

  /// Adds a new subpath that consists of a curve that forms the
  /// ellipse that fills the given rectangle.
  ///
  /// To add a circle, pass an appropriate rectangle as `oval`.
  /// [Rect.fromCircle] can be used to easily describe the circle's center
  /// [Offset] and radius.
  @override
  void addOval(ui.Rect oval) {
    assert(rectIsValid(oval));
    final ui.Offset center = oval.center;
    final double radiusX = oval.width / 2;
    final double radiusY = oval.height / 2;

    /// At startAngle = 0, the path will begin at center + cos(0) * radius.
    _openNewSubpath(center.dx + radiusX, center.dy);
    _commands.add(Ellipse(
        center.dx, center.dy, radiusX, radiusY, 0.0, 0.0, 2 * math.pi, false));
  }

  /// Adds a new subpath with one arc segment that consists of the arc
  /// that follows the edge of the oval bounded by the given
  /// rectangle, from startAngle radians around the oval up to
  /// startAngle + sweepAngle radians around the oval, with zero
  /// radians being the point on the right hand side of the oval that
  /// crosses the horizontal line that intersects the center of the
  /// rectangle and with positive angles going clockwise around the
  /// oval.
  @override
  void addArc(ui.Rect oval, double startAngle, double sweepAngle) {
    assert(rectIsValid(oval));
    final ui.Offset center = oval.center;
    final double radiusX = oval.width / 2;
    final double radiusY = oval.height / 2;
    _openNewSubpath(radiusX * math.cos(startAngle) + center.dx,
        radiusY * math.sin(startAngle) + center.dy);
    _commands.add(Ellipse(center.dx, center.dy, radiusX, radiusY, 0.0,
        startAngle, startAngle + sweepAngle, sweepAngle.isNegative));

    _setCurrentPoint(radiusX * math.cos(startAngle + sweepAngle) + center.dx,
        radiusY * math.sin(startAngle + sweepAngle) + center.dy);
  }

  /// Adds a new subpath with a sequence of line segments that connect the given
  /// points.
  ///
  /// If `close` is true, a final line segment will be added that connects the
  /// last point to the first point.
  ///
  /// The `points` argument is interpreted as offsets from the origin.
  @override
  void addPolygon(List<ui.Offset> points, bool close) {
    assert(points != null);
    if (points.isEmpty) {
      return;
    }

    moveTo(points.first.dx, points.first.dy);
    for (int i = 1; i < points.length; i++) {
      final ui.Offset point = points[i];
      lineTo(point.dx, point.dy);
    }
    if (close) {
      this.close();
    } else {
      _setCurrentPoint(points.last.dx, points.last.dy);
    }
  }

  /// Adds a new subpath that consists of the straight lines and
  /// curves needed to form the rounded rectangle described by the
  /// argument.
  @override
  void addRRect(ui.RRect rrect) {
    assert(rrectIsValid(rrect));

    // Set the current point to the top left corner of the rectangle (the
    // point on the top of the rectangle farthest to the left that isn't in
    // the rounded corner).
    // TODO(het): Is this the current point in Flutter?
    _openNewSubpath(rrect.tallMiddleRect.left, rrect.top);
    _commands.add(RRectCommand(rrect));
  }

  /// Adds a new subpath that consists of the given `path` offset by the given
  /// `offset`.
  ///
  /// If `matrix4` is specified, the path will be transformed by this matrix
  /// after the matrix is translated by the given offset. The matrix is a 4x4
  /// matrix stored in column major order.
  @override
  void addPath(ui.Path path, ui.Offset offset, {Float64List matrix4}) {
    assert(path != null); // path is checked on the engine side
    assert(offsetIsValid(offset));
    if (matrix4 != null) {
      _addPathWithMatrix(path, offset.dx, offset.dy, toMatrix32(matrix4));
    } else {
      _addPath(path, offset.dx, offset.dy);
    }
  }

  void _addPath(SurfacePath path, double dx, double dy) {
    if (dx == 0.0 && dy == 0.0) {
      subpaths.addAll(path.subpaths);
    } else {
      subpaths.addAll(path
          ._transform(Matrix4.translationValues(dx, dy, 0.0).storage)
          .subpaths);
    }
  }

  void _addPathWithMatrix(
      SurfacePath path, double dx, double dy, Float32List matrix) {
    assert(matrix4IsValid(matrix));
    final Matrix4 transform = Matrix4.fromFloat32List(matrix);
    transform.translate(dx, dy);
    subpaths.addAll(path._transform(transform.storage).subpaths);
  }

  /// Adds the given path to this path by extending the current segment of this
  /// path with the first segment of the given path.
  ///
  /// If `matrix4` is specified, the path will be transformed by this matrix
  /// after the matrix is translated by the given `offset`.  The matrix is a 4x4
  /// matrix stored in column major order.
  @override
  void extendWithPath(ui.Path path, ui.Offset offset, {Float64List matrix4}) {
    assert(path != null); // path is checked on the engine side
    assert(offsetIsValid(offset));
    if (matrix4 != null) {
      final Float32List matrix32 = toMatrix32(matrix4);
      assert(matrix4IsValid(matrix32));
      _extendWithPathAndMatrix(path, offset.dx, offset.dy, matrix32);
    } else {
      _extendWithPath(path, offset.dx, offset.dy);
    }
  }

  void _extendWithPath(SurfacePath path, double dx, double dy) {
    if (dx == 0.0 && dy == 0.0) {
      assert(path.subpaths.length == 1);
      _ensurePathStarted();
      _commands.addAll(path.subpaths.single.commands);
      _setCurrentPoint(
          path.subpaths.single.currentX, path.subpaths.single.currentY);
    } else {
      throw UnimplementedError('Cannot extend path with non-zero offset');
    }
  }

  void _extendWithPathAndMatrix(
      SurfacePath path, double dx, double dy, Float32List matrix) {
    throw UnimplementedError('Cannot extend path with transform matrix');
  }

  /// Closes the last subpath, as if a straight line had been drawn
  /// from the current point to the first point of the subpath.
  @override
  void close() {
    _ensurePathStarted();
    _commands.add(const CloseCommand());
    _setCurrentPoint(_currentSubpath.startX, _currentSubpath.startY);
  }

  /// Clears the [Path] object of all subpaths, returning it to the
  /// same state it had when it was created. The _current point_ is
  /// reset to the origin.
  @override
  void reset() {
    subpaths.clear();
  }

  /// Tests to see if the given point is within the path. (That is, whether the
  /// point would be in the visible portion of the path if the path was used
  /// with [Canvas.clipPath].)
  ///
  /// The `point` argument is interpreted as an offset from the origin.
  ///
  /// Returns true if the point is in the path, and false otherwise.
  ///
  /// Note: Not very efficient, it creates a canvas, plays path and calls
  /// Context2D isPointInPath. If performance becomes issue, retaining
  /// RawRecordingCanvas can remove create/remove rootElement cost.
  @override
  bool contains(ui.Offset point) {
    assert(offsetIsValid(point));
    final int subPathCount = subpaths.length;
    if (subPathCount == 0) {
      return false;
    }
    final double pointX = point.dx;
    final double pointY = point.dy;
    if (subPathCount == 1) {
      // Optimize for rect/roundrect checks.
      final Subpath subPath = subpaths[0];
      if (subPath.commands.length == 1) {
        final PathCommand cmd = subPath.commands[0];
        if (cmd is RectCommand) {
          if (pointY < cmd.y || pointY > (cmd.y + cmd.height)) {
            return false;
          }
          if (pointX < cmd.x || pointX > (cmd.x + cmd.width)) {
            return false;
          }
          return true;
        } else if (cmd is RRectCommand) {
          final ui.RRect rRect = cmd.rrect;
          if (pointY < rRect.top || pointY > rRect.bottom) {
            return false;
          }
          if (pointX < rRect.left || pointX > rRect.right) {
            return false;
          }
          final double rRectWidth = rRect.width;
          final double rRectHeight = rRect.height;
          final double tlRadiusX = math.min(rRect.tlRadiusX, rRectWidth / 2.0);
          final double tlRadiusY = math.min(rRect.tlRadiusY, rRectHeight / 2.0);
          if (pointX < (rRect.left + tlRadiusX) &&
              pointY < (rRect.top + tlRadiusY)) {
            // Top left corner
            return _ellipseContains(pointX, pointY, rRect.left + tlRadiusX,
                rRect.top + tlRadiusY, tlRadiusX, tlRadiusY);
          }
          final double trRadiusX = math.min(rRect.trRadiusX, rRectWidth / 2.0);
          final double trRadiusY = math.min(rRect.trRadiusY, rRectHeight / 2.0);
          if (pointX >= (rRect.right - trRadiusX) &&
              pointY < (rRect.top + trRadiusY)) {
            // Top right corner
            return _ellipseContains(pointX, pointY, rRect.right - trRadiusX,
                rRect.top + trRadiusY, trRadiusX, trRadiusY);
          }
          final double brRadiusX = math.min(rRect.brRadiusX, rRectWidth / 2.0);
          final double brRadiusY = math.min(rRect.brRadiusY, rRectHeight / 2.0);
          if (pointX >= (rRect.right - brRadiusX) &&
              pointY >= (rRect.bottom - brRadiusY)) {
            // Bottom right corner
            return _ellipseContains(pointX, pointY, rRect.right - brRadiusX,
                rRect.bottom - brRadiusY, trRadiusX, trRadiusY);
          }
          final double blRadiusX = math.min(rRect.blRadiusX, rRectWidth / 2.0);
          final double blRadiusY = math.min(rRect.blRadiusY, rRectHeight / 2.0);
          if (pointX < (rRect.left + blRadiusX) &&
              pointY >= (rRect.bottom - blRadiusY)) {
            // Bottom left corner
            return _ellipseContains(pointX, pointY, rRect.left + blRadiusX,
                rRect.bottom - blRadiusY, trRadiusX, trRadiusY);
          }
          return true;
        }
        // TODO: For improved performance, handle Ellipse special case.
      }
    }
    final ui.Size size = window.physicalSize;
    // If device pixel ratio has changed we can't reuse prior raw recorder.
    if (_rawRecorder != null &&
        _rawRecorder._devicePixelRatio !=
            EngineWindow.browserDevicePixelRatio) {
      _rawRecorder = null;
    }
    final double dpr = window.devicePixelRatio;
    _rawRecorder ??=
        ui.RawRecordingCanvas(ui.Size(size.width / dpr, size.height / dpr));
    // Account for the shift due to padding.
    _rawRecorder.translate(-BitmapCanvas.kPaddingPixels.toDouble(),
        -BitmapCanvas.kPaddingPixels.toDouble());
    _rawRecorder.drawPath(
        this, (SurfacePaint()..color = const ui.Color(0xFF000000)).paintData);
    final double recorderDevicePixelRatio = _rawRecorder._devicePixelRatio;
    final bool result = _rawRecorder._canvasPool.context.isPointInPath(
        pointX * recorderDevicePixelRatio, pointY * recorderDevicePixelRatio);
    _rawRecorder.dispose();
    return result;
  }

  /// Returns a copy of the path with all the segments of every
  /// subpath translated by the given offset.
  @override
  SurfacePath shift(ui.Offset offset) {
    assert(offsetIsValid(offset));
    final List<Subpath> shiftedSubPaths = <Subpath>[];
    for (final Subpath subPath in subpaths) {
      shiftedSubPaths.add(subPath.shift(offset));
    }
    return SurfacePath._clone(shiftedSubPaths, fillType);
  }

  /// Returns a copy of the path with all the segments of every
  /// sub path transformed by the given matrix.
  @override
  SurfacePath transform(Float64List matrix4) {
    return _transform(toMatrix32(matrix4));
  }

  SurfacePath _transform(Float32List matrix) {
    assert(matrix4IsValid(matrix));
    final SurfacePath transformedPath = SurfacePath();
    for (final Subpath subPath in subpaths) {
      for (final PathCommand cmd in subPath.commands) {
        cmd.transform(matrix, transformedPath);
      }
    }
    return transformedPath;
  }

  /// Computes the bounding rectangle for this path.
  ///
  /// A path containing only axis-aligned points on the same straight line will
  /// have no area, and therefore `Rect.isEmpty` will return true for such a
  /// path. Consider checking `rect.width + rect.height > 0.0` instead, or
  /// using the [computeMetrics] API to check the path length.
  ///
  /// For many more elaborate paths, the bounds may be inaccurate.  For example,
  /// when a path contains a circle, the points used to compute the bounds are
  /// the circle's implied control points, which form a square around the
  /// circle; if the circle has a transformation applied using [transform] then
  /// that square is rotated, and the (axis-aligned, non-rotated) bounding box
  /// therefore ends up grossly overestimating the actual area covered by the
  /// circle.
  // see https://skia.org/user/api/SkPath_Reference#SkPath_getBounds
  @override
  ui.Rect getBounds() {
    // Sufficiently small number for curve eq.
    const double epsilon = 0.000000001;
    bool ltrbInitialized = false;
    double left = 0.0, top = 0.0, right = 0.0, bottom = 0.0;
    double curX = 0.0;
    double curY = 0.0;
    double minX = 0.0, maxX = 0.0, minY = 0.0, maxY = 0.0;
    for (Subpath subpath in subpaths) {
      for (PathCommand op in subpath.commands) {
        bool skipBounds = false;
        switch (op.type) {
          case PathCommandTypes.moveTo:
            final MoveTo cmd = op;
            curX = minX = maxX = cmd.x;
            curY = minY = maxY = cmd.y;
            break;
          case PathCommandTypes.lineTo:
            final LineTo cmd = op;
            curX = minX = maxX = cmd.x;
            curY = minY = maxY = cmd.y;
            break;
          case PathCommandTypes.ellipse:
            final Ellipse cmd = op;
            // Rotate 4 corners of bounding box.
            final double rx = cmd.radiusX;
            final double ry = cmd.radiusY;
            final double cosVal = math.cos(cmd.rotation);
            final double sinVal = math.sin(cmd.rotation);
            final double rxCos = rx * cosVal;
            final double ryCos = ry * cosVal;
            final double rxSin = rx * sinVal;
            final double rySin = ry * sinVal;

            final double leftDeltaX = rxCos - rySin;
            final double rightDeltaX = -rxCos - rySin;
            final double topDeltaY = ryCos + rxSin;
            final double bottomDeltaY = ryCos - rxSin;

            final double centerX = cmd.x;
            final double centerY = cmd.y;

            double rotatedX = centerX + leftDeltaX;
            double rotatedY = centerY + topDeltaY;
            minX = maxX = rotatedX;
            minY = maxY = rotatedY;

            rotatedX = centerX + rightDeltaX;
            rotatedY = centerY + bottomDeltaY;
            minX = math.min(minX, rotatedX);
            maxX = math.max(maxX, rotatedX);
            minY = math.min(minY, rotatedY);
            maxY = math.max(maxY, rotatedY);

            rotatedX = centerX - leftDeltaX;
            rotatedY = centerY - topDeltaY;
            minX = math.min(minX, rotatedX);
            maxX = math.max(maxX, rotatedX);
            minY = math.min(minY, rotatedY);
            maxY = math.max(maxY, rotatedY);

            rotatedX = centerX - rightDeltaX;
            rotatedY = centerY - bottomDeltaY;
            minX = math.min(minX, rotatedX);
            maxX = math.max(maxX, rotatedX);
            minY = math.min(minY, rotatedY);
            maxY = math.max(maxY, rotatedY);

            curX = centerX + cmd.radiusX;
            curY = centerY;
            break;
          case PathCommandTypes.quadraticCurveTo:
            final QuadraticCurveTo cmd = op;
            final double x1 = curX;
            final double y1 = curY;
            final double cpX = cmd.x1;
            final double cpY = cmd.y1;
            final double x2 = cmd.x2;
            final double y2 = cmd.y2;

            minX = math.min(x1, x2);
            minY = math.min(y1, y2);
            maxX = math.max(x1, x2);
            maxY = math.max(y1, y2);

            // Curve equation : (1-t)(1-t)P1 + 2t(1-t)CP + t*t*P2.
            // At extrema's derivative = 0.
            // Solve for
            // -2x1+2tx1 + 2cpX + 4tcpX + 2tx2 = 0
            // -2x1 + 2cpX +2t(x1 + 2cpX + x2) = 0
            // t = (x1 - cpX) / (x1 - 2cpX + x2)

            double denom = x1 - (2 * cpX) + x2;
            if (denom.abs() > epsilon) {
              final num t1 = (x1 - cpX) / denom;
              if ((t1 >= 0) && (t1 <= 1.0)) {
                // Solve (x,y) for curve at t = tx to find extrema
                final num tprime = 1.0 - t1;
                final num extremaX = (tprime * tprime * x1) +
                    (2 * t1 * tprime * cpX) +
                    (t1 * t1 * x2);
                final num extremaY = (tprime * tprime * y1) +
                    (2 * t1 * tprime * cpY) +
                    (t1 * t1 * y2);
                // Expand bounds.
                minX = math.min(minX, extremaX);
                maxX = math.max(maxX, extremaX);
                minY = math.min(minY, extremaY);
                maxY = math.max(maxY, extremaY);
              }
            }
            // Now calculate dy/dt = 0
            denom = y1 - (2 * cpY) + y2;
            if (denom.abs() > epsilon) {
              final num t2 = (y1 - cpY) / denom;
              if ((t2 >= 0) && (t2 <= 1.0)) {
                final num tprime2 = 1.0 - t2;
                final num extrema2X = (tprime2 * tprime2 * x1) +
                    (2 * t2 * tprime2 * cpX) +
                    (t2 * t2 * x2);
                final num extrema2Y = (tprime2 * tprime2 * y1) +
                    (2 * t2 * tprime2 * cpY) +
                    (t2 * t2 * y2);
                // Expand bounds.
                minX = math.min(minX, extrema2X);
                maxX = math.max(maxX, extrema2X);
                minY = math.min(minY, extrema2Y);
                maxY = math.max(maxY, extrema2Y);
              }
            }
            curX = x2;
            curY = y2;
            break;
          case PathCommandTypes.bezierCurveTo:
            final BezierCurveTo cmd = op;
            final double startX = curX;
            final double startY = curY;
            final double cpX1 = cmd.x1;
            final double cpY1 = cmd.y1;
            final double cpX2 = cmd.x2;
            final double cpY2 = cmd.y2;
            final double endX = cmd.x3;
            final double endY = cmd.y3;
            // Bounding box is defined by all points on the curve where
            // monotonicity changes.
            minX = math.min(startX, endX);
            minY = math.min(startY, endY);
            maxX = math.max(startX, endX);
            maxY = math.max(startY, endY);

            double extremaX;
            double extremaY;
            double a, b, c;

            // Check for simple case of strong ordering before calculating
            // extrema
            if (!(((startX < cpX1) && (cpX1 < cpX2) && (cpX2 < endX)) ||
                ((startX > cpX1) && (cpX1 > cpX2) && (cpX2 > endX)))) {
              // The extrema point is dx/dt B(t) = 0
              // The derivative of B(t) for cubic bezier is a quadratic equation
              // with multiple roots
              // B'(t) = a*t*t + b*t + c*t
              a = -startX + (3 * (cpX1 - cpX2)) + endX;
              b = 2 * (startX - (2 * cpX1) + cpX2);
              c = -startX + cpX1;

              // Now find roots for quadratic equation with known coefficients
              // a,b,c
              // The roots are (-b+-sqrt(b*b-4*a*c)) / 2a
              num s = (b * b) - (4 * a * c);
              // If s is negative, we have no real roots
              if ((s >= 0.0) && (a.abs() > epsilon)) {
                if (s == 0.0) {
                  // we have only 1 root
                  final num t = -b / (2 * a);
                  final num tprime = 1.0 - t;
                  if ((t >= 0.0) && (t <= 1.0)) {
                    extremaX = ((tprime * tprime * tprime) * startX) +
                        ((3 * tprime * tprime * t) * cpX1) +
                        ((3 * tprime * t * t) * cpX2) +
                        (t * t * t * endX);
                    minX = math.min(extremaX, minX);
                    maxX = math.max(extremaX, maxX);
                  }
                } else {
                  // we have 2 roots
                  s = math.sqrt(s);
                  num t = (-b - s) / (2 * a);
                  num tprime = 1.0 - t;
                  if ((t >= 0.0) && (t <= 1.0)) {
                    extremaX = ((tprime * tprime * tprime) * startX) +
                        ((3 * tprime * tprime * t) * cpX1) +
                        ((3 * tprime * t * t) * cpX2) +
                        (t * t * t * endX);
                    minX = math.min(extremaX, minX);
                    maxX = math.max(extremaX, maxX);
                  }
                  // check 2nd root
                  t = (-b + s) / (2 * a);
                  tprime = 1.0 - t;
                  if ((t >= 0.0) && (t <= 1.0)) {
                    extremaX = ((tprime * tprime * tprime) * startX) +
                        ((3 * tprime * tprime * t) * cpX1) +
                        ((3 * tprime * t * t) * cpX2) +
                        (t * t * t * endX);

                    minX = math.min(extremaX, minX);
                    maxX = math.max(extremaX, maxX);
                  }
                }
              }
            }

            // Now calc extremes for dy/dt = 0 just like above
            if (!(((startY < cpY1) && (cpY1 < cpY2) && (cpY2 < endY)) ||
                ((startY > cpY1) && (cpY1 > cpY2) && (cpY2 > endY)))) {
              // The extrema point is dy/dt B(t) = 0
              // The derivative of B(t) for cubic bezier is a quadratic equation
              // with multiple roots
              // B'(t) = a*t*t + b*t + c*t
              a = -startY + (3 * (cpY1 - cpY2)) + endY;
              b = 2 * (startY - (2 * cpY1) + cpY2);
              c = -startY + cpY1;

              // Now find roots for quadratic equation with known coefficients
              // a,b,c
              // The roots are (-b+-sqrt(b*b-4*a*c)) / 2a
              num s = (b * b) - (4 * a * c);
              // If s is negative, we have no real roots
              if ((s >= 0.0) && (a.abs() > epsilon)) {
                if (s == 0.0) {
                  // we have only 1 root
                  final num t = -b / (2 * a);
                  final num tprime = 1.0 - t;
                  if ((t >= 0.0) && (t <= 1.0)) {
                    extremaY = ((tprime * tprime * tprime) * startY) +
                        ((3 * tprime * tprime * t) * cpY1) +
                        ((3 * tprime * t * t) * cpY2) +
                        (t * t * t * endY);
                    minY = math.min(extremaY, minY);
                    maxY = math.max(extremaY, maxY);
                  }
                } else {
                  // we have 2 roots
                  s = math.sqrt(s);
                  final num t = (-b - s) / (2 * a);
                  final num tprime = 1.0 - t;
                  if ((t >= 0.0) && (t <= 1.0)) {
                    extremaY = ((tprime * tprime * tprime) * startY) +
                        ((3 * tprime * tprime * t) * cpY1) +
                        ((3 * tprime * t * t) * cpY2) +
                        (t * t * t * endY);
                    minY = math.min(extremaY, minY);
                    maxY = math.max(extremaY, maxY);
                  }
                  // check 2nd root
                  final num t2 = (-b + s) / (2 * a);
                  final num tprime2 = 1.0 - t2;
                  if ((t2 >= 0.0) && (t2 <= 1.0)) {
                    extremaY = ((tprime2 * tprime2 * tprime2) * startY) +
                        ((3 * tprime2 * tprime2 * t2) * cpY1) +
                        ((3 * tprime2 * t2 * t2) * cpY2) +
                        (t2 * t2 * t2 * endY);
                    minY = math.min(extremaY, minY);
                    maxY = math.max(extremaY, maxY);
                  }
                }
              }
            }
            break;
          case PathCommandTypes.rect:
            final RectCommand cmd = op;
            minX = cmd.x;
            double width = cmd.width;
            if (cmd.width < 0) {
              minX -= width;
              width = -width;
            }
            minY = cmd.y;
            double height = cmd.height;
            if (cmd.height < 0) {
              minY -= height;
              height = -height;
            }
            curX = minX;
            maxX = minX + width;
            curY = minY;
            maxY = minY + height;
            break;
          case PathCommandTypes.rRect:
            final RRectCommand cmd = op;
            final ui.RRect rRect = cmd.rrect;
            curX = minX = rRect.left;
            maxX = rRect.left + rRect.width;
            curY = minY = rRect.top;
            maxY = rRect.top + rRect.height;
            break;
          case PathCommandTypes.close:
          default:
            skipBounds = false;
            break;
        }
        if (!skipBounds) {
          if (!ltrbInitialized) {
            left = minX;
            right = maxX;
            top = minY;
            bottom = maxY;
            ltrbInitialized = true;
          } else {
            left = math.min(left, minX);
            right = math.max(right, maxX);
            top = math.min(top, minY);
            bottom = math.max(bottom, maxY);
          }
        }
      }
    }
    return ltrbInitialized
        ? ui.Rect.fromLTRB(left, top, right, bottom)
        : ui.Rect.zero;
  }

  /// Creates a [PathMetrics] object for this path.
  ///
  /// If `forceClosed` is set to true, the contours of the path will be measured
  /// as if they had been closed, even if they were not explicitly closed.
  @override
  SurfacePathMetrics computeMetrics({bool forceClosed = false}) {
    return SurfacePathMetrics._(this, forceClosed);
  }

  /// Detects if path is rounded rectangle and returns rounded rectangle or
  /// null.
  ///
  /// Used for web optimization of physical shape represented as
  /// a persistent div.
  ui.RRect get webOnlyPathAsRoundedRect {
    if (subpaths.length != 1) {
      return null;
    }
    final Subpath subPath = subpaths[0];
    if (subPath.commands.length != 1) {
      return null;
    }
    final PathCommand command = subPath.commands[0];
    return (command is RRectCommand) ? command.rrect : null;
  }

  /// Detects if path is simple rectangle and returns rectangle or null.
  ///
  /// Used for web optimization of physical shape represented as
  /// a persistent div.
  ui.Rect get webOnlyPathAsRect {
    if (subpaths.length != 1) {
      return null;
    }
    final Subpath subPath = subpaths[0];
    if (subPath.commands.length != 1) {
      return null;
    }
    final PathCommand command = subPath.commands[0];
    return (command is RectCommand)
        ? ui.Rect.fromLTWH(command.x, command.y, command.width, command.height)
        : null;
  }

  /// Detects if path is simple oval and returns [Ellipse] or null.
  ///
  /// Used for web optimization of physical shape represented as
  /// a persistent div.
  Ellipse get webOnlyPathAsCircle {
    if (subpaths.length != 1) {
      return null;
    }
    final Subpath subPath = subpaths[0];
    if (subPath.commands.length != 1) {
      return null;
    }
    final PathCommand command = subPath.commands[0];
    if (command is Ellipse) {
      final Ellipse ellipse = command;
      if ((ellipse.endAngle - ellipse.startAngle) % (2 * math.pi) == 0.0) {
        return ellipse;
      }
    }
    return null;
  }

  /// Serializes this path to a value that's sent to a CSS custom painter for
  /// painting.
  List<dynamic> webOnlySerializeToCssPaint() {
    final List<dynamic> serializedSubpaths = <dynamic>[];
    for (int i = 0; i < subpaths.length; i++) {
      serializedSubpaths.add(subpaths[i].serializeToCssPaint());
    }
    return serializedSubpaths;
  }

  @override
  String toString() {
    if (assertionsEnabled) {
      return 'Path(${subpaths.join(', ')})';
    } else {
      return super.toString();
    }
  }
}

// Returns true if point is inside ellipse.
bool _ellipseContains(double px, double py, double centerX, double centerY,
    double radiusX, double radiusY) {
  final double dx = px - centerX;
  final double dy = py - centerY;
  return ((dx * dx) / (radiusX * radiusX)) + ((dy * dy) / (radiusY * radiusY)) <
      1.0;
}
