Utilities for rawpath - addPath() - operator== Diffs= f9a5698be Add != operator
diff --git a/.rive_head b/.rive_head index 944c886..a3be2d6 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -698af558ea299e28e9524d4e874f33ba7b18aa99 +f9a5698be92024c4c4a1b7337575f85341d89211
diff --git a/include/rive/math/raw_path.hpp b/include/rive/math/raw_path.hpp index cb03941..7a89329 100644 --- a/include/rive/math/raw_path.hpp +++ b/include/rive/math/raw_path.hpp
@@ -31,6 +31,9 @@ RawPath() {} ~RawPath() {} + bool operator==(const RawPath& o) const; + bool operator!=(const RawPath& o) const { return !(*this == o); } + bool empty() const { return m_Points.empty(); } AABB bounds() const; @@ -77,6 +80,8 @@ void addOval(const AABB&, PathDirection = PathDirection::cw); void addPoly(Span<const Vec2D>, bool isClosed); + void addPath(const RawPath&, const Mat2D* = nullptr); + class Iter { const Vec2D* m_currPts; const PathVerb* m_currVerb;
diff --git a/src/math/raw_path.cpp b/src/math/raw_path.cpp index 8e56837..5f45a8c 100644 --- a/src/math/raw_path.cpp +++ b/src/math/raw_path.cpp
@@ -4,6 +4,8 @@ #include "rive/math/raw_path.hpp" #include <cmath> +#include <cstring> +#include <algorithm> using namespace rive; @@ -13,6 +15,10 @@ std::size_t verbCount) : m_Points(points, points + pointCount), m_Verbs(verbs, verbs + verbCount) {} +bool RawPath::operator==(const RawPath& o) const { + return m_Points == o.m_Points && m_Verbs == o.m_Verbs; +} + AABB RawPath::bounds() const { if (this->empty()) { return {0, 0, 0, 0}; @@ -167,6 +173,21 @@ } } +void RawPath::addPath(const RawPath& src, const Mat2D* mat) { + m_Verbs.insert(m_Verbs.end(), src.m_Verbs.cbegin(), src.m_Verbs.cend()); + + if (mat) { + const auto oldPointCount = m_Points.size(); + m_Points.resize(oldPointCount + src.m_Points.size()); + Vec2D* dst = m_Points.data() + oldPointCount; + for (auto i = 0; i < src.m_Points.size(); ++i) { + dst[i] = *mat * src.m_Points[i]; + } + } else { + m_Points.insert(m_Points.end(), src.m_Points.cbegin(), src.m_Points.cend()); + } +} + ////////////////////////////////////////////////////////////////////////// namespace rive {
diff --git a/test/raw_path_test.cpp b/test/raw_path_test.cpp index 8b34f66..e24bf9e 100644 --- a/test/raw_path_test.cpp +++ b/test/raw_path_test.cpp
@@ -235,3 +235,65 @@ REQUIRE((rec && is_move(rec) && eq(rec.pts[0], 1, 2))); REQUIRE(rec.pts == move_pts); } + +TEST_CASE("addPath", "[rawpath]") { + using PathMaker = void (*)(RawPath * sink); + + const PathMaker makers[] = { + [](RawPath* sink) {}, + [](RawPath* sink) { + sink->moveTo(1, 2); + sink->lineTo(3, 4); + }, + [](RawPath* sink) { + sink->moveTo(1, 2); + sink->lineTo(3, 4); + sink->close(); + }, + [](RawPath* sink) { + sink->moveTo(1, 2); + sink->lineTo(3, 4); + sink->quadTo(5, 6, 7, 8); + sink->cubicTo(9, 10, 11, 12, 13, 14); + sink->close(); + }, + }; + constexpr size_t N = sizeof(makers) / sizeof(makers[0]); + + auto direct = [](PathMaker m0, PathMaker m1, const Mat2D* mx) { + RawPath p; + m0(&p); + m1(&p); + if (mx) { + p.transformInPlace(*mx); + } + return p; + }; + auto useadd = [](PathMaker m0, PathMaker m1, const Mat2D* mx) { + RawPath p; + + RawPath tmp; + m0(&tmp); + p.addPath(tmp, mx); + + tmp.reset(); + m1(&tmp); + p.addPath(tmp, mx); + return p; + }; + + for (auto i = 0; i < N; ++i) { + for (auto j = 0; j < N; ++j) { + RawPath p0, p1; + + p0 = direct(makers[i], makers[j], nullptr); + p1 = useadd(makers[i], makers[j], nullptr); + REQUIRE(p0 == p1); + + auto mx = Mat2D::fromScale(2, 3); + p0 = direct(makers[i], makers[j], &mx); + p1 = useadd(makers[i], makers[j], &mx); + REQUIRE(p0 == p1); + } + } +}