blob: 84d41245d9807febfd012823a95f90614915b861 [file] [log] [blame] [edit]
/*
* Copyright 2022 Rive
*/
#pragma once
#include "rive/math/raw_path.hpp"
#include "rive/renderer.hpp"
namespace rive
{
// RenderPath implementation for Rive's pixel local storage renderer.
class RiveRenderPath : public LITE_RTTI_OVERRIDE(RenderPath, RiveRenderPath)
{
public:
RiveRenderPath() = default;
RiveRenderPath(FillRule fillRule, RawPath& rawPath);
void rewind() override;
void fillRule(FillRule rule) override { m_fillRule = rule; }
void moveTo(float x, float y) override;
void lineTo(float x, float y) override;
void cubicTo(float ox, float oy, float ix, float iy, float x, float y)
override;
void close() override;
void addPath(CommandPath* p, const Mat2D& m) override
{
addRenderPath(p->renderPath(), m);
}
void addRenderPath(RenderPath* path, const Mat2D& matrix) override;
void addRenderPathBackwards(RenderPath* path,
const Mat2D& transform) override;
void addRawPath(const RawPath& path) override;
const RawPath& getRawPath() const { return m_rawPath; }
FillRule getFillRule() const { return m_fillRule; }
const AABB& getBounds() const;
// Approximates the area of the path by linearizing it with a coarse
// tolerance of 8px in artboard space.
constexpr static float kCoarseAreaTolerance = 8;
float getCoarseArea() const;
// Determine if the path's signed, post-transform area is positive.
bool isClockwiseDominant(const Mat2D& viewMatrix) const;
uint64_t getRawPathMutationID() const;
// 1-dimensional feathering along the normal vector quits looking like a
// blur when there is strong curvature. This method returns a copy of the
// path with shorter, flatter curves that will more accurately depict a
// gaussian blur when drawn with the given feather.
//
// TODO: Move this work to the GPU.
rcp<RiveRenderPath> makeSoftenedCopyForFeathering(float feather,
float matrixMaxScale);
#ifdef DEBUG
// Allows ref holders to guarantee the rawPath doesn't mutate during a
// specific time.
void lockRawPathMutations() const { ++m_rawPathMutationLockCount; }
void unlockRawPathMutations() const
{
assert(m_rawPathMutationLockCount > 0);
--m_rawPathMutationLockCount;
}
#endif
private:
FillRule m_fillRule = FillRule::nonZero;
RawPath m_rawPath;
mutable AABB m_bounds;
mutable float m_coarseArea;
mutable uint64_t m_rawPathMutationID;
enum Dirt
{
kPathBoundsDirt = 1 << 0,
kRawPathMutationIDDirt = 1 << 1,
kPathCoarseAreaDirt = 1 << 2,
kAllDirt = ~0,
};
mutable uint32_t m_dirt = kAllDirt;
RIVE_DEBUG_CODE(mutable int m_rawPathMutationLockCount = 0;)
};
} // namespace rive