| #include "rive/artboard.hpp" |
| #include "rive/shapes/paint/stroke.hpp" |
| #include "rive/shapes/paint/stroke_cap.hpp" |
| #include "rive/shapes/paint/stroke_effect.hpp" |
| #include "rive/shapes/paint/stroke_join.hpp" |
| |
| using namespace rive; |
| |
| PathSpace Stroke::pathSpace() const { |
| return transformAffectsStroke() ? PathSpace::Local : PathSpace::World; |
| } |
| |
| RenderPaint* Stroke::initRenderPaint(ShapePaintMutator* mutator) { |
| auto renderPaint = Super::initRenderPaint(mutator); |
| renderPaint->style(RenderPaintStyle::stroke); |
| renderPaint->thickness(thickness()); |
| renderPaint->cap((StrokeCap)cap()); |
| renderPaint->join((StrokeJoin)join()); |
| return renderPaint; |
| } |
| |
| bool Stroke::isVisible() const { return Super::isVisible() && thickness() > 0.0f; } |
| |
| void Stroke::draw(Renderer* renderer, CommandPath* path) { |
| if (!isVisible()) { |
| return; |
| } |
| |
| if (m_Effect != nullptr) { |
| /// We're guaranteed to get a metrics path here if we have an effect. |
| auto factory = artboard()->factory(); |
| path = m_Effect->effectPath(reinterpret_cast<MetricsPath*>(path), factory); |
| } |
| |
| renderer->drawPath(path->renderPath(), renderPaint()); |
| } |
| |
| void Stroke::thicknessChanged() { |
| assert(m_RenderPaint != nullptr); |
| m_RenderPaint->thickness(thickness()); |
| } |
| |
| void Stroke::capChanged() { |
| assert(m_RenderPaint != nullptr); |
| m_RenderPaint->cap((StrokeCap)cap()); |
| } |
| |
| void Stroke::joinChanged() { |
| assert(m_RenderPaint != nullptr); |
| m_RenderPaint->join((StrokeJoin)join()); |
| } |
| |
| void Stroke::addStrokeEffect(StrokeEffect* effect) { m_Effect = effect; } |
| |
| void Stroke::invalidateEffects() { |
| if (m_Effect != nullptr) { |
| m_Effect->invalidateEffect(); |
| } |
| } |