1 #include "shapes/paint/trim_path.hpp"
2 #include "shapes/metrics_path.hpp"
3 #include "shapes/paint/stroke.hpp"
7 TrimPath::TrimPath() : m_TrimmedPath(makeRenderPath()) {}
8 TrimPath::~TrimPath() { delete m_TrimmedPath; }
10 StatusCode TrimPath::onAddedClean(CoreContext* context)
12 if (!parent()->is<Stroke>())
14 return StatusCode::InvalidObject;
17 parent()->as<Stroke>()->addStrokeEffect(this);
19 return StatusCode::Ok;
22 RenderPath* TrimPath::effectPath(MetricsPath* source)
24 if (m_RenderPath != nullptr)
31 // Source is always a containing (shape) path.
32 const std::vector<MetricsPath*>& subPaths = source->paths();
34 m_TrimmedPath->reset();
35 auto renderOffset = std::fmod(std::fmod(offset(), 1.0f) + 1.0f, 1.0f);
40 float totalLength = source->length();
41 auto startLength = totalLength * (start() + renderOffset);
42 auto endLength = totalLength * (end() + renderOffset);
44 if (endLength < startLength)
46 float swap = startLength;
47 startLength = endLength;
51 if (startLength > totalLength)
53 startLength -= totalLength;
54 endLength -= totalLength;
57 int i = 0, subPathCount = (int) subPaths.size();
60 auto path = subPaths[i % subPathCount];
61 auto pathLength = path->length();
63 if (startLength < pathLength)
65 path->trim(startLength, endLength, true, m_TrimmedPath);
66 endLength -= pathLength;
71 startLength -= pathLength;
72 endLength -= pathLength;
81 for (auto path : subPaths)
83 auto pathLength = path->length();
84 auto startLength = pathLength * (start() + renderOffset);
85 auto endLength = pathLength * (end() + renderOffset);
86 if (endLength < startLength)
88 auto length = startLength;
89 startLength = endLength;
93 if (startLength > pathLength)
95 startLength -= pathLength;
96 endLength -= pathLength;
98 path->trim(startLength, endLength, true, m_TrimmedPath);
99 while (endLength > pathLength)
102 endLength -= pathLength;
103 path->trim(startLength, endLength, false, m_TrimmedPath);
110 m_RenderPath = m_TrimmedPath;
114 void TrimPath::invalidateEffect()
116 m_RenderPath = nullptr;
117 parent()->as<Stroke>()->parent()->addDirt(ComponentDirt::Paint);
120 void TrimPath::startChanged() { invalidateEffect(); }
121 void TrimPath::endChanged() { invalidateEffect(); }
122 void TrimPath::offsetChanged() { invalidateEffect(); }
123 void TrimPath::modeValueChanged() { invalidateEffect(); }