From 33a51d0ca0a1007e7e06f2f7a757b227b00c81c6 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Mon, 2 Sep 2024 23:13:36 +0000 Subject: [PATCH] Fixing tool drawing A lot of the tool draw methods aren't implemented with "render" for the Rive Renderer. The Joystick, TextTool, and others weren't working. This PR cleans them up and removes a bunch of dependent methods which are no longer necessary. It also mostly gets the StateMachine stage to completely work with the Renderer abstraction (save for the icons which hack back to Canvas). When this part gets wrapped we can move to Rive Renderer for the state machine stage too. ~~This is in draft because I still have to get dashing working with RenderPath (which the state machine uses).~~ Diffs= 5c312867e Fixing tool drawing (#8028) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- include/rive/shapes/paint/dash_path.hpp | 39 ++++++++++++++ src/shapes/paint/dash_path.cpp | 70 +++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 include/rive/shapes/paint/dash_path.hpp create mode 100644 src/shapes/paint/dash_path.cpp diff --git a/.rive_head b/.rive_head index 5f2e0675..56f720e4 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -2bd842b54b10e487731fcb51c728098d4956996a +5c312867e32d4a347e5483dca9798b1dd3dd30d1 diff --git a/include/rive/shapes/paint/dash_path.hpp b/include/rive/shapes/paint/dash_path.hpp new file mode 100644 index 00000000..a5d10545 --- /dev/null +++ b/include/rive/shapes/paint/dash_path.hpp @@ -0,0 +1,39 @@ +#ifndef _RIVE_DASH_PATH_HPP_ +#define _RIVE_DASH_PATH_HPP_ + +#include "rive/shapes/paint/stroke_effect.hpp" +#include "rive/renderer.hpp" +#include "rive/math/raw_path.hpp" +#include "rive/math/contour_measure.hpp" + +namespace rive +{ +class Dash +{ +public: + Dash(); + Dash(float value, bool percentage); + + float value() const; + bool percentage() const; + +private: + float m_value; + bool m_percentage; +}; + +class PathDasher +{ +protected: + void invalidateSourcePath(); + void invalidateDash(); + RenderPath* dash(const RawPath& source, Factory* factory, Dash offset, Span dashes); + +private: + RawPath m_rawPath; + RenderPath* m_renderPath = nullptr; + rcp m_dashedPath; + std::vector> m_contours; +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/src/shapes/paint/dash_path.cpp b/src/shapes/paint/dash_path.cpp new file mode 100644 index 00000000..21b6b03b --- /dev/null +++ b/src/shapes/paint/dash_path.cpp @@ -0,0 +1,70 @@ +#include "rive/shapes/paint/dash_path.hpp" +#include "rive/factory.hpp" + +using namespace rive; + +Dash::Dash() : m_value(0.0f), m_percentage(false) {} +Dash::Dash(float value, bool percentage) : m_value(value), m_percentage(percentage) {} +float Dash::value() const { return m_value; } +bool Dash::percentage() const { return m_percentage; } + +void PathDasher::invalidateSourcePath() +{ + m_contours.clear(); + invalidateDash(); +} +void PathDasher::invalidateDash() { m_renderPath = nullptr; } + +RenderPath* PathDasher::dash(const RawPath& source, + Factory* factory, + Dash offset, + Span dashes) +{ + if (m_renderPath != nullptr) + { + // Previous result hasn't been invalidated, it's still good. + return m_renderPath; + } + + m_rawPath.rewind(); + if (m_contours.empty()) + { + ContourMeasureIter iter(&source); + while (auto meas = iter.next()) + { + m_contours.push_back(meas); + } + } + + int dashIndex = 0; + for (const rcp& contour : m_contours) + { + float distance = offset.percentage() ? offset.value() * contour->length() : offset.value(); + bool draw = true; + while (distance < contour->length()) + { + const Dash& dash = dashes[dashIndex]; + float dashLength = dash.percentage() ? dash.value() * contour->length() : dash.value(); + if (draw) + { + contour->getSegment(distance, distance + dashLength, &m_rawPath, true); + } + distance += dashLength; + draw = !draw; + } + } + + if (!m_dashedPath) + { + m_dashedPath = factory->makeEmptyRenderPath(); + } + else + { + m_dashedPath->rewind(); + } + + m_renderPath = m_dashedPath.get(); + m_rawPath.addTo(m_renderPath); + + return m_renderPath; +} \ No newline at end of file