Skip to content

Commit

Permalink
Fix dash increment
Browse files Browse the repository at this point in the history
Dashing wasn't incrementing index for dash and could get stuck if 0 length dash was provided. This will leave an empty path if it finds an impossible dashing condition.

Diffs=
b06e05dc1 Fix dash increment (#8038)

Co-authored-by: Luigi Rosso <[email protected]>
  • Loading branch information
luigi-rosso and luigi-rosso committed Sep 3, 2024
1 parent 33a51d0 commit dc59953
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .rive_head
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5c312867e32d4a347e5483dca9798b1dd3dd30d1
b06e05dc18248d218807e00779d35c94bdfb8efe
39 changes: 27 additions & 12 deletions src/shapes/paint/dash_path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ 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; }
float Dash::value() const { return m_value < 0.0 ? 0.0f : m_value; }
bool Dash::percentage() const { return m_percentage; }

void PathDasher::invalidateSourcePath()
Expand Down Expand Up @@ -36,21 +36,36 @@ RenderPath* PathDasher::dash(const RawPath& source,
}
}

int dashIndex = 0;
for (const rcp<ContourMeasure>& contour : m_contours)
// Make sure dashes have some length.
bool hasValidDash = false;
for (auto dash : dashes)
{
float distance = offset.percentage() ? offset.value() * contour->length() : offset.value();
bool draw = true;
while (distance < contour->length())
if (dash.value() > 0.0f)
{
const Dash& dash = dashes[dashIndex];
float dashLength = dash.percentage() ? dash.value() * contour->length() : dash.value();
if (draw)
hasValidDash = true;
break;
}
}
if (hasValidDash)
{
int dashIndex = 0;
for (const rcp<ContourMeasure>& contour : m_contours)
{
float distance =
offset.percentage() ? offset.value() * contour->length() : offset.value();
bool draw = true;
while (distance < contour->length())
{
contour->getSegment(distance, distance + dashLength, &m_rawPath, true);
const Dash& dash = dashes[dashIndex++ % dashes.size()];
float dashLength =
dash.percentage() ? dash.value() * contour->length() : dash.value();
if (draw)
{
contour->getSegment(distance, distance + dashLength, &m_rawPath, true);
}
distance += dashLength;
draw = !draw;
}
distance += dashLength;
draw = !draw;
}
}

Expand Down
29 changes: 29 additions & 0 deletions test/dash_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "rive/shapes/paint/dash_path.hpp"
#include "utils/no_op_factory.hpp"
#include <catch.hpp>
#include <cstdio>

class _TestDasher : public rive::PathDasher
{

public:
rive::RenderPath* dash(const rive::RawPath& source,
rive::Dash offset,
rive::Span<rive::Dash> dashes)
{
rive::NoOpFactory noOpFactory;
return rive::PathDasher::dash(source, &noOpFactory, offset, dashes);
}
};

TEST_CASE("0 length dashes don't cause a crash", "[dashing]")
{
rive::RawPath rawPath;
rawPath.addRect({1, 1, 5, 6});

_TestDasher dasher;
std::vector dashes = {rive::Dash(0.0f, false), rive::Dash(0.0f, false)};

rive::Dash offset(0.0f, false);
dasher.dash(rawPath, offset, dashes);
}

0 comments on commit dc59953

Please sign in to comment.