kopia lustrzana https://github.com/jameshball/osci-render
107 wiersze
4.2 KiB
C++
107 wiersze
4.2 KiB
C++
#include "CurveTo.h"
|
|
#include "../shape/CubicBezierCurve.h"
|
|
#include "../shape/QuadraticBezierCurve.h"
|
|
|
|
std::vector<std::unique_ptr<Shape>> CurveTo::absolute(SvgState& state, std::vector<float>& args) {
|
|
return parseCurveTo(state, args, true, true, false);
|
|
}
|
|
|
|
std::vector<std::unique_ptr<Shape>> CurveTo::relative(SvgState& state, std::vector<float>& args) {
|
|
return parseCurveTo(state, args, false, true, false);
|
|
}
|
|
|
|
std::vector<std::unique_ptr<Shape>> CurveTo::smoothAbsolute(SvgState& state, std::vector<float>& args) {
|
|
return parseCurveTo(state, args, true, true, true);
|
|
}
|
|
|
|
std::vector<std::unique_ptr<Shape>> CurveTo::smoothRelative(SvgState& state, std::vector<float>& args) {
|
|
return parseCurveTo(state, args, false, true, true);
|
|
}
|
|
|
|
std::vector<std::unique_ptr<Shape>> CurveTo::quarticAbsolute(SvgState& state, std::vector<float>& args) {
|
|
return parseCurveTo(state, args, true, false, false);
|
|
}
|
|
|
|
std::vector<std::unique_ptr<Shape>> CurveTo::quarticRelative(SvgState& state, std::vector<float>& args) {
|
|
return parseCurveTo(state, args, false, false, false);
|
|
}
|
|
|
|
std::vector<std::unique_ptr<Shape>> CurveTo::quarticSmoothAbsolute(SvgState& state, std::vector<float>& args) {
|
|
return parseCurveTo(state, args, true, false, true);
|
|
}
|
|
|
|
std::vector<std::unique_ptr<Shape>> CurveTo::quarticSmoothRelative(SvgState& state, std::vector<float>& args) {
|
|
return parseCurveTo(state, args, false, false, true);
|
|
}
|
|
|
|
|
|
// Parses curveto commands (C, c, S, s, Q, q, T, and t commands)
|
|
// isCubic should be true for parsing C, c, S, and s commands
|
|
// isCubic should be false for parsing Q, q, T, and t commands
|
|
// isSmooth should be true for parsing S, s, T, and t commands
|
|
// isSmooth should be false for parsing C, c, Q, and q commands
|
|
std::vector<std::unique_ptr<Shape>> CurveTo::parseCurveTo(SvgState& state, std::vector<float>& args, bool isAbsolute, bool isCubic, bool isSmooth) {
|
|
int expectedArgs = isCubic ? 4 : 2;
|
|
if (!isSmooth) {
|
|
expectedArgs += 2;
|
|
}
|
|
|
|
if (args.size() % expectedArgs != 0 || args.size() < expectedArgs) {
|
|
return {};
|
|
}
|
|
|
|
auto curves = std::vector<std::unique_ptr<Shape>>();
|
|
|
|
for (int i = 0; i < args.size(); i += expectedArgs) {
|
|
Vector2 controlPoint1;
|
|
Vector2 controlPoint2;
|
|
|
|
if (isSmooth) {
|
|
if (isCubic) {
|
|
if (!state.prevCubicControlPoint.has_value()) {
|
|
controlPoint1 = state.currPoint;
|
|
} else {
|
|
controlPoint1 = state.prevCubicControlPoint.value();
|
|
}
|
|
} else {
|
|
if (!state.prevQuadraticControlPoint.has_value()) {
|
|
controlPoint1 = state.currPoint;
|
|
} else {
|
|
controlPoint1 = state.prevQuadraticControlPoint.value();
|
|
}
|
|
}
|
|
} else {
|
|
controlPoint1 = Vector2(args[i], args[i + 1]);
|
|
}
|
|
|
|
if (isCubic) {
|
|
controlPoint2 = Vector2(args[i + expectedArgs - 4], args[i + expectedArgs - 3]);
|
|
}
|
|
|
|
Vector2 newPoint(args[i + expectedArgs - 2], args[i + expectedArgs - 1]);
|
|
|
|
if (!isAbsolute) {
|
|
if (!isSmooth) {
|
|
controlPoint1.translate(state.currPoint.x, state.currPoint.y);
|
|
}
|
|
controlPoint2.translate(state.currPoint.x, state.currPoint.y);
|
|
newPoint.translate(state.currPoint.x, state.currPoint.y);
|
|
}
|
|
|
|
if (isSmooth) {
|
|
controlPoint1.reflectRelativeToVector(state.currPoint.x, state.currPoint.y);
|
|
}
|
|
|
|
if (isCubic) {
|
|
curves.push_back(std::make_unique<CubicBezierCurve>(state.currPoint.x, state.currPoint.y, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, newPoint.x, newPoint.y));
|
|
state.currPoint = newPoint;
|
|
state.prevCubicControlPoint = controlPoint2;
|
|
} else {
|
|
curves.push_back(std::make_unique<QuadraticBezierCurve>(state.currPoint.x, state.currPoint.y, controlPoint1.x, controlPoint1.y, newPoint.x, newPoint.y));
|
|
state.currPoint = newPoint;
|
|
state.prevQuadraticControlPoint = controlPoint1;
|
|
}
|
|
}
|
|
|
|
return curves;
|
|
} |