hitTest static method

bool hitTest(
  1. UDocShape shape,
  2. UDocShapeGeometry geometry,
  3. Offset pixel, {
  4. double slop = 8,
})

Whether pixel touches shape.

Implementation

static bool hitTest(UDocShape shape, UDocShapeGeometry geometry, Offset pixel, {double slop = 8}) {
  final List<Offset> points = shape.points.map(geometry.toPixels).toList();
  if (points.isEmpty) return false;
  final double tolerance = slop + max(0.8, geometry.lengthToPixels(shape.strokeWidth)) / 2;
  switch (shape.kind) {
    case UDocShapeKind.pen:
    case UDocShapeKind.highlighter:
      for (int i = 1; i < points.length; i++) {
        if (_segmentDistance(pixel, points[i - 1], points[i]) <= tolerance) return true;
      }
      return points.length == 1 && (points.first - pixel).distance <= tolerance;
    case UDocShapeKind.line:
    case UDocShapeKind.arrow:
    case UDocShapeKind.doubleArrow:
      return points.length >= 2 && _segmentDistance(pixel, points.first, points.last) <= tolerance;
    case UDocShapeKind.ellipse:
      final Rect box = Rect.fromPoints(points.first, points.last);
      if (box.width < 1 || box.height < 1) return box.inflate(tolerance).contains(pixel);
      final double nx = (pixel.dx - box.center.dx) / (box.width / 2);
      final double ny = (pixel.dy - box.center.dy) / (box.height / 2);
      final double value = sqrt(nx * nx + ny * ny);
      return shape.fillColor != null ? value <= 1.05 : (value - 1).abs() * min(box.width, box.height) / 2 <= tolerance;
    case UDocShapeKind.rectangle:
    case UDocShapeKind.roundedRectangle:
      final Rect box = Rect.fromPoints(points.first, points.last);
      if (shape.fillColor != null) return box.inflate(tolerance).contains(pixel);
      return box.inflate(tolerance).contains(pixel) && !box.deflate(tolerance).contains(pixel);
    case UDocShapeKind.areaHighlight:
    case UDocShapeKind.textBox:
    case UDocShapeKind.stickyNote:
      return pixelBounds(shape, geometry).inflate(slop / 2).contains(pixel);
  }
}