kanjivg-tools/Libraries/Kanimaji/Source/SVG.cpp

118 lines
2.8 KiB
C++
Raw Normal View History

#include "SVG.hpp"
#include <format>
namespace Kanimaji::SVG
{
struct Vec2
{
double x;
double y;
friend Vec2 operator+(const Vec2& u, const Vec2& v)
{
return Vec2 {
.x = u.x + v.x,
.y = u.y + v.y,
};
}
};
class Path::Element
{
public:
virtual ~Element() = default;
virtual double Length(Vec2 origin) const = 0;
virtual Vec2 Endpoint(Vec2 origin) const = 0;
};
namespace
{
class ParseError : public Error
{
public:
ParseError(std::size_t current, std::string_view message)
: Error(std::format("[At: {}] {}", current, message))
{}
};
class Move : public Path::Element
{
public:
Move(bool relative, Vec2 move)
: mRelative(relative), mMove(move)
{}
double Length(Vec2 origin) const override
{
return 0;
}
Vec2 Endpoint(Vec2 origin) const override
{
return mRelative ? origin + mMove : mMove;
}
private:
bool mRelative; // 7B padding, oof
Vec2 mMove;
};
class CubicBezier : public Path::Element
{
public:
CubicBezier(bool relative, Vec2 control1, Vec2 control2, Vec2 end)
: mRelative(relative), mControl1(control1), mControl2(control2), mEnd(end)
{}
double Length(Vec2 origin) const override
{
throw Error("not implemented");
}
Vec2 Endpoint(Vec2 origin) const override
{
return mEnd;
}
private:
bool mRelative; // 7B padding, oof
Vec2 mControl1;
Vec2 mControl2;
Vec2 mEnd;
};
using ElementPtr = std::unique_ptr<Path::Element>;
void Parse(std::string_view definition, std::vector<ElementPtr>& elements)
{
std::size_t current = 0;
while (current < definition.size()) {
switch (definition[current]) {
case 'M': [[fallthrough]];
case 'm':
// ParseMove
break;
case 'C': [[fallthrough]];
case 'c':
// ParseCubicBezier
break;
default:
throw ParseError(current, "Unrecognized character");
}
}
}
}
Path::Path(std::string_view definition)
{
Parse(definition, mSegments);
}
Path::~Path() = default;
double Path::Length() const
{
return 0;
}
}