Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Color and add comments #31

Merged
merged 1 commit into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Graphics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#define GRAPHICS_HPP_

#include "graphics/Circle.hpp"
#include "graphics/Color.hpp"
#include "graphics/Ellipse.hpp"
#include "graphics/ColorShape.hpp"
#include "graphics/Group.hpp"
#include "graphics/Line.hpp"
#include "graphics/LinearGradient.hpp"
Expand Down
107 changes: 66 additions & 41 deletions src/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Parser *Parser::instance = nullptr;

namespace {
auto getHexColor = [](std::string color) -> mColor {
auto getHexColor = [](std::string color) -> ColorShape {
std::stringstream ss;
int pos = color.find("#");
if (color.size() < 5 || color[pos + 4] == ' ') {
Expand All @@ -14,7 +14,7 @@ namespace {
r = r * 16 + r;
g = g * 16 + g;
b = b * 16 + b;
return mColor(r, g, b, 255);
return ColorShape(r, g, b, 255);
} else if (color.size() < 6 || color[pos + 5] == ' ') {
ss << std::hex << color.substr(pos + 1, 1) << " "
<< color.substr(pos + 2, 1) << " " << color.substr(pos + 3, 1)
Expand All @@ -25,7 +25,7 @@ namespace {
g = g * 16 + g;
b = b * 16 + b;
a = a * 16 + a;
return mColor(r, g, b, a);
return ColorShape(r, g, b, a);
} else {
ss << std::hex << color.substr(pos + 1, 2) << " "
<< color.substr(pos + 3, 2) << " " << color.substr(pos + 5, 2);
Expand All @@ -36,38 +36,38 @@ namespace {
ss << std::hex << color.substr(pos + 7, 2);
int a;
ss >> a;
return mColor(r, g, b, a);
return ColorShape(r, g, b, a);
}
return mColor(r, g, b, 255);
return ColorShape(r, g, b, 255);
}
};

auto getRgbColor = [](std::string color) -> mColor {
auto getRgbColor = [](std::string color) -> ColorShape {
int r, g, b;
float a = 1;
sscanf(color.c_str(), "rgb(%d,%d,%d,%f)", &r, &g, &b, &a);
return mColor(r, g, b, 255 * a);
return ColorShape(r, g, b, 255 * a);
};

std::string removeExtraSpaces(std::string input) {
input.erase(std::remove(input.begin(), input.end(), '\t'), input.end());
input.erase(std::remove(input.begin(), input.end(), '\n'), input.end());
std::string result;
bool spaceDetected = false;
bool firstSpace = true;
bool space_detected = false;
bool first_space = true;
for (int i = 0; i < input.size(); i++) {
if (input[i] == ' ') {
if (!spaceDetected) {
if (!firstSpace)
if (!space_detected) {
if (!first_space)
result.push_back(input[i]);
else
firstSpace = false;
spaceDetected = true;
first_space = false;
space_detected = true;
}
} else {
result.push_back(input[i]);
firstSpace = false;
spaceDetected = false;
first_space = false;
space_detected = false;
}
}

Expand Down Expand Up @@ -203,10 +203,12 @@ SVGElement *Parser::parseElements(std::string file_name) {

while (node) {
if (std::string(node->name()) == "defs") {
// Parse gradients
GetGradients(node);
prev = node;
node = node->next_sibling();
} else if (std::string(node->name()) == "g") {
// Parse Group attributes
Group *group = dynamic_cast< Group * >(current);
for (auto group_attribute : group->getAttributes()) {
bool found = false;
Expand All @@ -225,6 +227,7 @@ SVGElement *Parser::parseElements(std::string file_name) {
break;
}
}

if (!found && group_attribute.first != "transform") {
char *name =
doc.allocate_string(group_attribute.first.c_str());
Expand All @@ -235,14 +238,17 @@ SVGElement *Parser::parseElements(std::string file_name) {
node->append_attribute(new_attribute);
}
}

Group *new_group = new Group(xmlToString(node->first_attribute()));
new_group->setTransforms(getTransformOrder(node));
current->addElement(new_group);
current = new_group;
prev = node;
node = node->first_node();
} else {
// Parse Shape attributes and add to current group
Group *group = dynamic_cast< Group * >(current);

for (auto group_attribute : group->getAttributes()) {
bool found = false;
for (auto attribute = node->first_attribute(); attribute;
Expand All @@ -260,6 +266,7 @@ SVGElement *Parser::parseElements(std::string file_name) {
break;
}
}

if (!found && group_attribute.first != "transform") {
char *name =
doc.allocate_string(group_attribute.first.c_str());
Expand All @@ -270,11 +277,13 @@ SVGElement *Parser::parseElements(std::string file_name) {
node->append_attribute(new_attribute);
}
}

SVGElement *shape = parseShape(node);
if (shape != NULL) current->addElement(shape);
prev = node;
node = node->next_sibling();
}

if (node == NULL && current != root) {
while (prev->parent()->next_sibling() == NULL) {
current = current->getParent();
Expand Down Expand Up @@ -359,17 +368,17 @@ float Parser::getFloatAttribute(rapidxml::xml_node<> *node, std::string name) {
return result;
}

mColor Parser::parseColor(rapidxml::xml_node<> *node, std::string name,
std::string &id) {
ColorShape Parser::parseColor(rapidxml::xml_node<> *node, std::string name,
std::string &id) {
std::string color = getAttribute(node, name);
color.erase(std::remove(color.begin(), color.end(), ' '), color.end());
if (color.find("url") == std::string::npos) {
for (auto &c : color) c = tolower(c);
}
if (color == "none")
return mColor::Transparent;
return ColorShape::Transparent;
else {
mColor result;
ColorShape result;
if (color.find("url") != std::string::npos) {
if (color.find("'") != std::string::npos) {
id = color.substr(color.find("'") + 1);
Expand All @@ -379,7 +388,7 @@ mColor Parser::parseColor(rapidxml::xml_node<> *node, std::string name,
id = color.substr(color.find("#") + 1);
id.erase(id.find(")"));
}
result = mColor::Transparent;
result = ColorShape::Transparent;
} else if (color.find("#") != std::string::npos) {
result = getHexColor(color);
} else if (color.find("rgb") != std::string::npos) {
Expand Down Expand Up @@ -415,7 +424,7 @@ std::vector< Stop > Parser::getGradientStops(rapidxml::xml_node<> *node) {
while (stop_node) {
if (std::string(stop_node->name()) == "stop") {
std::string id = "";
mColor color = parseColor(stop_node, "stop-color", id);
ColorShape color = parseColor(stop_node, "stop-color", id);
float offset = getFloatAttribute(stop_node, "offset");
if (offset > 1) offset /= 100;
stops.push_back(Stop(color, offset));
Expand Down Expand Up @@ -556,6 +565,7 @@ std::vector< PathPoint > Parser::parsePathPoints(rapidxml::xml_node<> *node) {
}
cur_point = first_point;
handle_points.push_back({first_point, 'm'});

} else if (tolower(points[i].tc) == 'l' ||
tolower(points[i].tc) == 't') {
Vector2Df end_point{cur_point.x + points[i].point.x,
Expand All @@ -565,18 +575,21 @@ std::vector< PathPoint > Parser::parsePathPoints(rapidxml::xml_node<> *node) {
cur_point = end_point;
char TC = tolower(points[i].tc);
handle_points.push_back({end_point, TC});

} else if (tolower(points[i].tc) == 'h') {
Vector2Df end_point{cur_point.x + points[i].point.x, cur_point.y};
if (points[i].tc == 'H')
end_point = Vector2Df{points[i].point.x, cur_point.y};
cur_point = end_point;
handle_points.push_back({end_point, 'h'});

} else if (tolower(points[i].tc) == 'v') {
Vector2Df end_point{cur_point.x, cur_point.y + points[i].point.y};
if (points[i].tc == 'V')
end_point = Vector2Df{cur_point.x, points[i].point.y};
cur_point = end_point;
handle_points.push_back({end_point, 'v'});

} else if (tolower(points[i].tc) == 'c') {
if (i + 2 < n) {
Vector2Df control_point1 =
Expand All @@ -602,6 +615,7 @@ std::vector< PathPoint > Parser::parsePathPoints(rapidxml::xml_node<> *node) {
} else if (tolower(points[i].tc) == 'z') {
cur_point = first_point;
handle_points.push_back({first_point, 'z'});

} else if (tolower(points[i].tc) == 's' ||
tolower(points[i].tc) == 'q') {
if (i + 1 < n) {
Expand All @@ -621,6 +635,7 @@ std::vector< PathPoint > Parser::parsePathPoints(rapidxml::xml_node<> *node) {
handle_points.push_back({control_point1, TC});
handle_points.push_back({control_point2, TC});
}

} else if (tolower(points[i].tc) == 'a') {
Vector2Df end_point{cur_point.x + points[i].point.x,
cur_point.y + points[i].point.y};
Expand All @@ -637,10 +652,12 @@ std::vector< PathPoint > Parser::parsePathPoints(rapidxml::xml_node<> *node) {
std::vector< std::string > Parser::getTransformOrder(
rapidxml::xml_node<> *node) {
std::string transform_tag;
if (std::string(node->name()).find("Gradient") != std::string::npos)
if (std::string(node->name()).find("Gradient") != std::string::npos) {
transform_tag = getAttribute(node, "gradientTransform");
else
} else {
transform_tag = getAttribute(node, "transform");
}

std::vector< std::string > order;
std::stringstream ss(transform_tag);
std::string type;
Expand Down Expand Up @@ -668,8 +685,8 @@ SVGElement *Parser::parseShape(rapidxml::xml_node<> *node) {
SVGElement *shape = NULL;
std::string type = node->name();
std::string id = "";
mColor stroke_color = parseColor(node, "stroke", id);
mColor fill_color = parseColor(node, "fill", id);
ColorShape stroke_color = parseColor(node, "stroke", id);
ColorShape fill_color = parseColor(node, "fill", id);
float stroke_width = getFloatAttribute(node, "stroke-width");
if (type == "line") {
shape = parseLine(node, stroke_color, stroke_width);
Expand All @@ -688,6 +705,7 @@ SVGElement *Parser::parseShape(rapidxml::xml_node<> *node) {
} else if (type == "text") {
shape = parseText(node, fill_color, stroke_color, stroke_width);
}

if (shape != NULL) {
if (type == "text") {
float dx = getFloatAttribute(node, "dx");
Expand All @@ -707,17 +725,18 @@ SVGElement *Parser::parseShape(rapidxml::xml_node<> *node) {
return shape;
}

Line *Parser::parseLine(rapidxml::xml_node<> *node, const mColor &stroke_color,
float stroke_width) {
Line *Parser::parseLine(rapidxml::xml_node<> *node,
const ColorShape &stroke_color, float stroke_width) {
Line *shape = new Line(
Vector2Df(getFloatAttribute(node, "x1"), getFloatAttribute(node, "y1")),
Vector2Df(getFloatAttribute(node, "x2"), getFloatAttribute(node, "y2")),
stroke_color, stroke_width);
return shape;
}

Rect *Parser::parseRect(rapidxml::xml_node<> *node, const mColor &fill_color,
const mColor &stroke_color, float stroke_width) {
Rect *Parser::parseRect(rapidxml::xml_node<> *node,
const ColorShape &fill_color,
const ColorShape &stroke_color, float stroke_width) {
float x = getFloatAttribute(node, "x");
float y = getFloatAttribute(node, "y");
float rx = getFloatAttribute(node, "rx");
Expand All @@ -730,8 +749,9 @@ Rect *Parser::parseRect(rapidxml::xml_node<> *node, const mColor &fill_color,
}

Circle *Parser::parseCircle(rapidxml::xml_node<> *node,
const mColor &fill_color,
const mColor &stroke_color, float stroke_width) {
const ColorShape &fill_color,
const ColorShape &stroke_color,
float stroke_width) {
float cx = getFloatAttribute(node, "cx");
float cy = getFloatAttribute(node, "cy");
float radius = getFloatAttribute(node, "r");
Expand All @@ -740,8 +760,9 @@ Circle *Parser::parseCircle(rapidxml::xml_node<> *node,
return shape;
}

Ell *Parser::parseEllipse(rapidxml::xml_node<> *node, const mColor &fill_color,
const mColor &stroke_color, float stroke_width) {
Ell *Parser::parseEllipse(rapidxml::xml_node<> *node,
const ColorShape &fill_color,
const ColorShape &stroke_color, float stroke_width) {
float radius_x = getFloatAttribute(node, "rx");
float radius_y = getFloatAttribute(node, "ry");
float cx = getFloatAttribute(node, "cx");
Expand All @@ -752,8 +773,9 @@ Ell *Parser::parseEllipse(rapidxml::xml_node<> *node, const mColor &fill_color,
}

Plygon *Parser::parsePolygon(rapidxml::xml_node<> *node,
const mColor &fill_color,
const mColor &stroke_color, float stroke_width) {
const ColorShape &fill_color,
const ColorShape &stroke_color,
float stroke_width) {
Plygon *shape = new Plygon(fill_color, stroke_color, stroke_width);
std::vector< Vector2Df > points = parsePoints(node);
for (auto point : points) {
Expand All @@ -767,8 +789,9 @@ Plygon *Parser::parsePolygon(rapidxml::xml_node<> *node,
}

Plyline *Parser::parsePolyline(rapidxml::xml_node<> *node,
const mColor &fill_color,
const mColor &stroke_color, float stroke_width) {
const ColorShape &fill_color,
const ColorShape &stroke_color,
float stroke_width) {
Plyline *shape = new Plyline(fill_color, stroke_color, stroke_width);
std::vector< Vector2Df > points = parsePoints(node);
for (auto point : points) {
Expand All @@ -781,8 +804,9 @@ Plyline *Parser::parsePolyline(rapidxml::xml_node<> *node,
return shape;
}

Text *Parser::parseText(rapidxml::xml_node<> *node, const mColor &fill_color,
const mColor &stroke_color, float stroke_width) {
Text *Parser::parseText(rapidxml::xml_node<> *node,
const ColorShape &fill_color,
const ColorShape &stroke_color, float stroke_width) {
float x = getFloatAttribute(node, "x");
float y = getFloatAttribute(node, "y");
float font_size = getFloatAttribute(node, "font-size");
Expand All @@ -804,8 +828,9 @@ Text *Parser::parseText(rapidxml::xml_node<> *node, const mColor &fill_color,
return shape;
}

Path *Parser::parsePath(rapidxml::xml_node<> *node, const mColor &fill_color,
const mColor &stroke_color, float stroke_width) {
Path *Parser::parsePath(rapidxml::xml_node<> *node,
const ColorShape &fill_color,
const ColorShape &stroke_color, float stroke_width) {
Path *shape = new Path(fill_color, stroke_color, stroke_width);
std::vector< PathPoint > points = parsePathPoints(node);
for (auto point : points) {
Expand Down
Loading
Loading