Skip to content

Commit

Permalink
Add path Q, S, T attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasAugust12 committed Dec 20, 2023
1 parent f440d2c commit 30308af
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 52 deletions.
92 changes: 87 additions & 5 deletions src/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,12 +428,13 @@ std::vector< PathPoint > Parser::parsePathPoints(xml_node<> *node) {
std::stringstream ss(path_string);
std::string element;
PathPoint pPoint{{0, 0}, 'M'};

while (ss >> element) {
if (std::isalpha(element[0])) {
pPoint.tc = element[0];
if (tolower(pPoint.tc) == 'm' || tolower(pPoint.tc) == 'l' ||
tolower(pPoint.tc) == 'c')
tolower(pPoint.tc) == 'c' || tolower(pPoint.tc) == 's' ||
tolower(pPoint.tc) == 'q' || tolower(pPoint.tc) == 't' ||
tolower(pPoint.tc) == 'a')
ss >> pPoint.point.x >> pPoint.point.y;
else if (tolower(pPoint.tc) == 'h') {
ss >> pPoint.point.x;
Expand All @@ -444,7 +445,9 @@ std::vector< PathPoint > Parser::parsePathPoints(xml_node<> *node) {
}
} else {
if (tolower(pPoint.tc) == 'm' || tolower(pPoint.tc) == 'l' ||
tolower(pPoint.tc) == 'c') {
tolower(pPoint.tc) == 'c' || tolower(pPoint.tc) == 's' ||
tolower(pPoint.tc) == 'q' || tolower(pPoint.tc) == 't' ||
tolower(pPoint.tc) == 'a') {
if (tolower(pPoint.tc) == 'm') pPoint.tc = 'L';
pPoint.point.x = std::stof(element);
ss >> pPoint.point.y;
Expand All @@ -458,8 +461,87 @@ std::vector< PathPoint > Parser::parsePathPoints(xml_node<> *node) {
}
points.push_back(pPoint);
}

return points;
std::vector< PathPoint > handle_points;

Vector2Df firstPoint{0, 0}, curPoint{0, 0};
int n = points.size();
for (int i = 0; i < n; i++) {
if (tolower(points[i].tc) == 'm') {
firstPoint = points[i].point;
if (points[i].tc == 'm') {
firstPoint.x = curPoint.x + points[i].point.x;
firstPoint.y = curPoint.y + points[i].point.y;
}
curPoint = firstPoint;
handle_points.push_back({firstPoint, 'm'});
} else if (tolower(points[i].tc) == 'l' ||
tolower(points[i].tc) == 't') {
Vector2Df endPoint{curPoint.x + points[i].point.x,
curPoint.y + points[i].point.y};
if (points[i].tc == 'L' || points[i].tc == 'T')
endPoint = points[i].point;
curPoint = endPoint;
char TC = tolower(points[i].tc);
handle_points.push_back({endPoint, TC});
} else if (tolower(points[i].tc) == 'h') {
Vector2Df endPoint{curPoint.x + points[i].point.x, curPoint.y};
if (points[i].tc == 'H')
endPoint = Vector2Df{points[i].point.x, curPoint.y};
curPoint = endPoint;
handle_points.push_back({endPoint, 'h'});
} else if (points[i].tc == 'v') {
Vector2Df endPoint{curPoint.x, curPoint.y + points[i].point.y};
if (points[i].tc == 'V')
endPoint = Vector2Df{curPoint.x, points[i].point.y};
curPoint = endPoint;
handle_points.push_back({endPoint, 'v'});
} else if (tolower(points[i].tc) == 'c') {
if (i + 2 < n) {
Vector2Df controlPoint1 =
Vector2Df{curPoint.x + points[i].point.x,
curPoint.y + points[i].point.y};
Vector2Df controlPoint2 =
Vector2Df{curPoint.x + points[i + 1].point.x,
curPoint.y + points[i + 1].point.y};
Vector2Df controlPoint3 =
Vector2Df{curPoint.x + points[i + 2].point.x,
curPoint.y + points[i + 2].point.y};
if (points[i].tc == 'C') {
controlPoint1 = points[i].point;
controlPoint2 = points[i + 1].point;
controlPoint3 = points[i + 2].point;
}
i += 2;
curPoint = controlPoint3;
handle_points.push_back({controlPoint1, 'c'});
handle_points.push_back({controlPoint2, 'c'});
handle_points.push_back({controlPoint3, 'c'});
}
} else if (tolower(points[i].tc) == 'z') {
curPoint = firstPoint;
handle_points.push_back({firstPoint, 'z'});
} else if (tolower(points[i].tc) == 's' ||
tolower(points[i].tc) == 'q') {
if (i + 1 < n) {
Vector2Df controlPoint1 =
Vector2Df{curPoint.x + points[i].point.x,
curPoint.y + points[i].point.y};
Vector2Df controlPoint2 =
Vector2Df{curPoint.x + points[i + 1].point.x,
curPoint.y + points[i + 1].point.y};
if (points[i].tc == 'S' || points[i].tc == 'Q') {
controlPoint1 = points[i].point;
controlPoint2 = points[i + 1].point;
}
i += 1;
curPoint = controlPoint2;
char TC = tolower(points[i].tc);
handle_points.push_back({controlPoint1, TC});
handle_points.push_back({controlPoint2, TC});
}
}
}
return handle_points;
}

std::vector< std::string > Parser::getTransformOrder(xml_node<> *node) {
Expand Down
127 changes: 80 additions & 47 deletions src/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,41 +297,16 @@ void Renderer::drawPath(Gdiplus::Graphics& graphics, Path* path) const {
Vector2Df first_point{0, 0}, cur_point{0, 0};

for (int i = 0; i < n; ++i) {
if (points[i].tc == 'M') {
if (points[i].tc == 'm') {
first_point = points[i].point;
gdi_path.StartFigure();
cur_point = first_point;
} else if (points[i].tc == 'm') {
first_point.x = cur_point.x + points[i].point.x;
first_point.y = cur_point.y + points[i].point.y;
gdi_path.StartFigure();
cur_point = first_point;
} else if (points[i].tc == 'L') {
} else if (points[i].tc == 'l' || points[i].tc == 'h' ||
points[i].tc == 'v') {
gdi_path.AddLine(cur_point.x, cur_point.y, points[i].point.x,
points[i].point.y);
cur_point = points[i].point;
} else if (points[i].tc == 'l') {
Vector2Df endPoint{cur_point.x + points[i].point.x,
cur_point.y + points[i].point.y};
gdi_path.AddLine(cur_point.x, cur_point.y, endPoint.x, endPoint.y);
cur_point = endPoint;
} else if (points[i].tc == 'H') {
Vector2Df endPoint{points[i].point.x, cur_point.y};
gdi_path.AddLine(cur_point.x, cur_point.y, endPoint.x, endPoint.y);
cur_point = endPoint;
} else if (points[i].tc == 'h') {
Vector2Df endPoint{cur_point.x + points[i].point.x, cur_point.y};
gdi_path.AddLine(cur_point.x, cur_point.y, endPoint.x, endPoint.y);
cur_point = endPoint;
} else if (points[i].tc == 'V') {
Vector2Df endPoint{cur_point.x, points[i].point.y};
gdi_path.AddLine(cur_point.x, cur_point.y, endPoint.x, endPoint.y);
cur_point = endPoint;
} else if (points[i].tc == 'v') {
Vector2Df endPoint{cur_point.x, cur_point.y + points[i].point.y};
gdi_path.AddLine(cur_point.x, cur_point.y, endPoint.x, endPoint.y);
cur_point = endPoint;
} else if (points[i].tc == 'C') {
} else if (points[i].tc == 'c') {
if (i + 2 < n) {
Vector2Df control_point1 = points[i].point;
Vector2Df control_point2 = points[i + 1].point;
Expand All @@ -343,27 +318,85 @@ void Renderer::drawPath(Gdiplus::Graphics& graphics, Path* path) const {
i += 2;
cur_point = control_point3;
}
} else if (points[i].tc == 'c') {
if (i + 2 < n) {
Vector2Df control_point1 =
Vector2Df{cur_point.x + points[i].point.x,
cur_point.y + points[i].point.y};
Vector2Df control_point2 =
Vector2Df{cur_point.x + points[i + 1].point.x,
cur_point.y + points[i + 1].point.y};
Vector2Df control_point3 =
Vector2Df{cur_point.x + points[i + 2].point.x,
cur_point.y + points[i + 2].point.y};
gdi_path.AddBezier(cur_point.x, cur_point.y, control_point1.x,
control_point1.y, control_point2.x,
control_point2.y, control_point3.x,
control_point3.y);
i += 2;
cur_point = control_point3;
}
} else if (points[i].tc == 'Z' || points[i].tc == 'z') {
gdi_path.CloseFigure();
cur_point = first_point;
} else if (points[i].tc == 's') {
if (i + 1 < n) {
Vector2Df auto_control_point;
if (i > 0 &&
(points[i - 1].tc == 'c' || points[i - 1].tc == 's')) {
auto_control_point.x =
cur_point.x * 2 - points[i - 2].point.x;
auto_control_point.y =
cur_point.y * 2 - points[i - 2].point.y;
} else {
auto_control_point = cur_point;
}
Vector2Df control_point2 = points[i].point;
Vector2Df control_point3 = points[i + 1].point;
gdi_path.AddBezier(cur_point.x, cur_point.y,
auto_control_point.x, auto_control_point.y,
control_point2.x, control_point2.y,
control_point3.x, control_point3.y);
i += 1;
cur_point = points[i + 1].point;
}
} else if (points[i].tc == 'q') {
if (i + 1 < n) {
Vector2Df control_point1{
static_cast< float >(cur_point.x +
2.0 / 3.0 *
(points[i].point.x - cur_point.x)),
static_cast< float >(
cur_point.y +
2.0 / 3.0 * (points[i].point.y - cur_point.y))};
Vector2Df control_point2{
static_cast< float >(
points[i + 1].point.x +
2.0 / 3.0 *
(points[i].point.x - points[i + 1].point.x)),
static_cast< float >(
points[i + 1].point.y +
2.0 / 3.0 *
(points[i].point.y - points[i + 1].point.y))};
Vector2Df endPoint{points[i + 1].point.x,
points[i + 1].point.y};

gdi_path.AddBezier(cur_point.x, cur_point.y, control_point1.x,
control_point1.y, control_point2.x,
control_point2.y, endPoint.x, endPoint.y);

cur_point = endPoint;
i += 1;
}
} else if (points[i].tc == 't') {
Vector2Df auto_control_point;
if (i > 0 && (points[i - 1].tc == 'q' || points[i - 1].tc == 't')) {
auto_control_point.x = cur_point.x * 2 - points[i - 2].point.x;
auto_control_point.y = cur_point.y * 2 - points[i - 2].point.y;
} else {
auto_control_point = cur_point;
}
Vector2Df control_point1{
static_cast< float >(cur_point.x +
2.0 / 3.0 *
(auto_control_point.x - cur_point.x)),
static_cast< float >(cur_point.y +
2.0 / 3.0 *
(auto_control_point.y - cur_point.y))};
Vector2Df control_point2{
static_cast< float >(
points[i].point.x +
2.0 / 3.0 * (auto_control_point.x - points[i].point.x)),
static_cast< float >(
points[i].point.y +
2.0 / 3.0 * (auto_control_point.y - points[i].point.y))};
Vector2Df endPoint{points[i].point.x, points[i].point.y};
gdi_path.AddBezier(cur_point.x, cur_point.y, control_point1.x,
control_point1.y, control_point2.x,
control_point2.y, endPoint.x, endPoint.y);
cur_point = endPoint;
}
}
graphics.FillPath(path_fill, &gdi_path);
Expand Down

0 comments on commit 30308af

Please sign in to comment.