blob: 920e98f70925a965603bf32f83e799c02ad5cc58 [file]
#include "rive/shapes/shape_paint_path.hpp"
#include "rive/component.hpp"
#include "rive/artboard.hpp"
#include "rive/factory.hpp"
using namespace rive;
ShapePaintPath::ShapePaintPath(bool isLocal) : m_isLocal(isLocal) {}
ShapePaintPath::ShapePaintPath(bool isLocal, FillRule fillRule)
: m_isLocal(isLocal)
, m_fillRule(fillRule)
{}
void ShapePaintPath::rewind()
{
m_rawPath.rewind();
m_isRenderPathDirty = true;
}
void ShapePaintPath::addPath(const RawPath& rawPath, const Mat2D* transform)
{
auto iter = m_rawPath.addPath(rawPath, transform);
m_rawPath.pruneEmptySegments(iter);
m_isRenderPathDirty = true;
}
void ShapePaintPath::addPathClockwise(
const RawPath& rawPath,
const Mat2D* transform)
{
float coarseArea = transform == nullptr
? rawPath.computeCoarseArea()
: rawPath.computeCoarseArea(*transform);
if (coarseArea < 0)
{
addPathBackwards(rawPath, transform);
}
else
{
addPath(rawPath, transform);
}
}
void ShapePaintPath::addPathBackwards(
const RawPath& rawPath,
const Mat2D* transform)
{
auto iter = m_rawPath.addPathBackwards(rawPath, transform);
// RawPath prunes what it adds itself when it transforms it.
if (transform == nullptr)
{
m_rawPath.pruneEmptySegments(iter);
}
m_isRenderPathDirty = true;
}
RenderPath* ShapePaintPath::renderPath(const Component* component)
{
assert(component != nullptr);
return renderPath(component->artboard()->factory());
}
RenderPath* ShapePaintPath::renderPath(Factory* factory)
{
assert(factory != nullptr);
if (!m_renderPath)
{
m_renderPath = factory->makeEmptyRenderPath();
m_renderPath->addRawPath(m_rawPath);
m_renderPath->fillRule(m_fillRule);
m_isRenderPathDirty = false;
}
else if (m_isRenderPathDirty)
{
m_renderPath->rewind();
m_renderPath->addRawPath(m_rawPath);
m_isRenderPathDirty = false;
}
return m_renderPath.get();
}