| #include "rive/math/path_measure.hpp" |
| |
| using namespace rive; |
| |
| PathMeasure::PathMeasure() : m_length(0.0f) {} |
| |
| PathMeasure::PathMeasure(const RawPath* path, float tol) : m_length(0.0f) |
| { |
| auto measure = ContourMeasureIter(path, tol); |
| for (auto contour = measure.next(); contour != nullptr; |
| contour = measure.next()) |
| { |
| m_length += contour->length(); |
| m_contours.push_back(contour); |
| } |
| } |
| |
| ContourMeasure::PosTanDistance PathMeasure::atDistance(float distance) const |
| { |
| float currentDistance = distance; |
| for (auto contour : m_contours) |
| { |
| float contourLength = contour->length(); |
| if (currentDistance - contourLength <= 0) |
| { |
| return ContourMeasure::PosTanDistance( |
| contour->getPosTan(currentDistance), |
| distance); |
| } |
| currentDistance -= contourLength; |
| } |
| return ContourMeasure::PosTanDistance(); |
| } |
| |
| ContourMeasure::PosTanDistance PathMeasure::atPercentage( |
| float percentageDistance) const |
| { |
| float inRangePercentage = fmodf(percentageDistance, 1.0f); |
| if (inRangePercentage < 0.0f) |
| { |
| inRangePercentage += 1.0f; |
| } |
| |
| // Mod to correct percentage (0-100%) and make sure we actually reach |
| // 100%. |
| if (percentageDistance != 0.0f && inRangePercentage == 0.0f) |
| { |
| inRangePercentage = 1.0f; |
| } |
| |
| return atDistance(m_length * inRangePercentage); |
| } |