blob: 514282a9957e60acaba3fd112f65c5ef6121944f [file] [log] [blame]
#include "rive/shapes/shape_paint_container.hpp"
#include "rive/artboard.hpp"
#include "rive/component.hpp"
#include "rive/renderer.hpp"
#include "rive/shapes/metrics_path.hpp"
#include "rive/shapes/paint/fill.hpp"
#include "rive/shapes/paint/stroke.hpp"
#include "rive/shapes/shape.hpp"
using namespace rive;
ShapePaintContainer* ShapePaintContainer::from(Component* component)
{
switch (component->coreType())
{
case Artboard::typeKey:
return component->as<Artboard>();
break;
case Shape::typeKey:
return component->as<Shape>();
break;
}
return nullptr;
}
void ShapePaintContainer::addPaint(ShapePaint* paint)
{
m_ShapePaints.push_back(paint);
}
PathSpace ShapePaintContainer::pathSpace() const
{
PathSpace space = m_DefaultPathSpace;
for (auto paint : m_ShapePaints)
{
space |= paint->pathSpace();
}
return space;
}
void ShapePaintContainer::invalidateStrokeEffects()
{
for (auto paint : m_ShapePaints)
{
if (paint->is<Stroke>())
{
paint->as<Stroke>()->invalidateEffects();
}
}
}
CommandPath* ShapePaintContainer::makeCommandPath(PathSpace space)
{
// Force a render path if we specifically request to use it for clipping or
// this shape is used for clipping.
bool needForRender = ((space | m_DefaultPathSpace) & PathSpace::Clipping) ==
PathSpace::Clipping;
bool needForEffects = false;
for (auto paint : m_ShapePaints)
{
if (space != PathSpace::Neither &&
(space & paint->pathSpace()) != space)
{
continue;
}
if (paint->is<Stroke>() && paint->as<Stroke>()->hasStrokeEffect())
{
needForEffects = true;
}
else
{
needForRender = true;
}
}
if (needForEffects && needForRender)
{
return new RenderMetricsPath();
}
else if (needForEffects)
{
return new OnlyMetricsPath();
}
else
{
return rive::makeRenderPath();
}
}