Skip to content

Commit

Permalink
Fix and update parser with circle, ellipse
Browse files Browse the repository at this point in the history
  • Loading branch information
hoangfitus committed Nov 2, 2023
1 parent 226ca39 commit 4c15835
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 45 deletions.
115 changes: 91 additions & 24 deletions src/Parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,111 @@
#include <vector>

#include "Circle.hpp"
#include "Ellipse.hpp"
#include "pugixml.hpp"

using namespace std;

namespace parser {
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file("./sample/sample.svg");
pugi::xml_node svg = doc.child("svg");

auto get_attribute = [&](pugi::xml_node node, string name) {
pugi::xml_node loadFile(string path) {
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file(path.c_str());
if (!result) {
cout << "Error: " << result.description() << endl;
exit(-1);
}
pugi::xml_node svg = doc.child("svg");
return svg;
}

string getAttribute(pugi::xml_node node, string name) {
auto attr = node.attribute(name.c_str());
if (!attr) {
if (name == "fill")
return "rgb(0,0,0)";
else if (name == "stroke")
return "none";
else if (name == "stroke-width" || name == "stroke-opacity" ||
name == "fill-opacity")
return "1";
else if (name == "r" || name == "cx" || name == "cy" ||
name == "x" || name == "y" || name == "width" ||
name == "height")
return "0";
}
return attr.value();
};

vector< sf::Shape > parseSVG() {
vector< sf::Shape > shapes;
sf::Color parseColor(pugi::xml_node node, string color) {
for (auto& c : color) c = tolower(c);
if (color == "none")
return sf::Color::Transparent;
else if (color.find("rgb") == string::npos) {
switch (color[0]) {
case 'b':
if (color[2] == 'a')
return sf::Color::Black;
else
return sf::Color::Blue;
case 'g':
return sf::Color::Green;
case 'r':
return sf::Color::Red;
case 'y':
return sf::Color::Yellow;
case 'c':
return sf::Color::Cyan;
case 'm':
return sf::Color::Magenta;
case 'w':
return sf::Color::White;
default:
return sf::Color::Transparent;
}
} else {
unsigned int r = 0, g = 0, b = 0, a;
sscanf(color.c_str(), "rgb(%u,%u,%u)", &r, &g, &b);
a = stoi(getAttribute(node, "stroke-opacity")) * 255;
return sf::Color(r, g, b, a);
}
}

vector< sf::Shape* > parseSVG() {
pugi::xml_node svg = loadFile("../sample/sample.svg");
vector< sf::Shape* > shapes;
for (pugi::xml_node tool = svg.first_child(); tool;
tool = tool.next_sibling()) {
if (tool.name() == "circle") {
unsigned int r = 0, g = 0, b = 0, a;
string stroke = get_attribute(tool, "stroke");
sscanf(stroke.c_str(), "rgb(%u,%u,%u)", &r, &g, &b);
a = stoi(get_attribute(tool, "stroke-opacity")) * 255;
sf::Color stroke_color(r, g, b, a);

string fill = get_attribute(tool, "fill");
sscanf(fill.c_str(), "rgb(%u,%u,%u)", &r, &g, &b);
a = stoi(get_attribute(tool, "fill-opacity")) * 255;
sf::Color fill_color(r, g, b, a);

Circle shape(stof(get_attribute(tool, "r")),
stof(get_attribute(tool, "cx")),
stof(get_attribute(tool, "cy")), fill_color,
stroke_color,
stof(get_attribute(tool, "stroke-width")));
shapes.push_back(shape);
if (tool.name() == string("circle")) {
sf::Color stroke_color =
parseColor(tool, getAttribute(tool, "stroke"));
sf::Color fill_color =
parseColor(tool, getAttribute(tool, "fill"));
float stroke_width = stof(getAttribute(tool, "stroke-width"));

Circle* circle =
new Circle(stof(getAttribute(tool, "r")),
stof(getAttribute(tool, "cx")),
stof(getAttribute(tool, "cy")), fill_color,
stroke_color, stroke_width);
shapes.push_back(circle);
} else if (tool.name() == string("ellipse")) {
sf::Color stroke_color =
parseColor(tool, getAttribute(tool, "stroke"));
sf::Color fill_color =
parseColor(tool, getAttribute(tool, "fill"));
float stroke_width = stof(getAttribute(tool, "stroke-width"));

Ellipse* circle =
new Ellipse(sf::Vector2f(stof(getAttribute(tool, "rx")),
stof(getAttribute(tool, "ry"))),
stof(getAttribute(tool, "cx")),
stof(getAttribute(tool, "cy")), fill_color,
stroke_color, stroke_width);
shapes.push_back(circle);
}
}
return shapes;
}

} // namespace parser
Expand Down
33 changes: 12 additions & 21 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,31 +1,20 @@
#include <SFML/Graphics.hpp>
#include <iostream>

#include "Circle.hpp"
#include "Ellipse.hpp"
#include "Parser.hpp"
#include "pugixml.hpp"

int main() {
constexpr int screen_width = 1600;
constexpr int screen_height = 900;

pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file("sample/pic.svg");
if (!result) return -1;

auto get_attribute = [&](std::string name) {
auto node = doc.child("svg").child("circle");
auto attr = node.attribute(name.c_str());
return attr.value();
};

int pos_x = std::stoi(get_attribute("cx"));
int pos_y = std::stoi(get_attribute("cy"));
float radius = std::stof(get_attribute("r"));

std::vector< sf::Shape* > shapes = parser::parseSVG();
sf::ContextSettings settings;
settings.antialiasingLevel = 16;
sf::RenderWindow window(sf::VideoMode(screen_width, screen_height),
"svg-reader-version-0.1");
sf::CircleShape shape(radius, 1000);
shape.setPosition(pos_x, pos_y);
shape.setFillColor(sf::Color::Red);
"svg-reader-version-0.1", sf::Style::Default,
settings);

while (window.isOpen()) {
sf::Event event;
Expand All @@ -34,8 +23,10 @@ int main() {
if (event.type == sf::Event::Closed) window.close();
}

window.clear();
window.draw(shape);
window.clear(sf::Color::White);
for (auto shape : shapes) {
window.draw(*shape);
}
window.display();
}
return 0;
Expand Down

0 comments on commit 4c15835

Please sign in to comment.