blob: b901fa128ac752e5c96bf3844bd7d1d8ce15b780 [file]
/*
* Copyright 2022 Rive
*/
#ifndef _RIVE_HITTEST_HPP_
#define _RIVE_HITTEST_HPP_
#include "rive/span.hpp"
#include "rive/math/aabb.hpp"
#include "rive/math/path_types.hpp"
#include "rive/math/vec2d.hpp"
#include <cstdint>
#include <vector>
namespace rive
{
class HitTester
{
std::vector<int> m_DW; // width * height delta-windings
Vec2D m_First, m_Prev;
Vec2D m_offset;
float m_height;
int m_IWidth, m_IHeight;
bool m_ExpectsMove;
void recurse_cubic(Vec2D b, Vec2D c, Vec2D d, int count);
public:
HitTester() {}
HitTester(const IAABB& area) { reset(area); }
void reset();
void reset(const IAABB& area);
void move(Vec2D);
void line(Vec2D);
void quad(Vec2D, Vec2D);
void cubic(Vec2D, Vec2D, Vec2D);
void close();
void addRect(const AABB&, const Mat2D&, PathDirection = PathDirection::ccw);
bool test(FillRule = rive::FillRule::nonZero);
static bool testMesh(Vec2D point, Span<Vec2D> verts, Span<uint16_t> indices);
static bool testMesh(const IAABB&, Span<Vec2D> verts, Span<uint16_t> indices);
// Finds `point` in the triangles of `from` and returns the matching point
// of `to`, which shares `indices` (from positions to UVs, or back). The
// topmost triangle holding the point wins; when none does, `inside` is
// false and the nearest triangle is extended past its edges. False when
// there's no usable triangle. `map`, when given, is set to the affine map
// of the triangle used, from `from` to `to`.
static bool mapMesh(
Vec2D point,
Span<const Vec2D> from,
Span<const Vec2D> to,
Span<const uint16_t> indices,
Vec2D* out,
bool* inside,
Mat2D* map = nullptr);
};
} // namespace rive
#endif