diff --git a/src/Parser.hpp b/src/Parser.hpp index 04916947..b2f54250 100644 --- a/src/Parser.hpp +++ b/src/Parser.hpp @@ -5,44 +5,111 @@ #include #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 diff --git a/src/main.cpp b/src/main.cpp index 177ae2e0..f1163def 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,31 +1,20 @@ #include -#include +#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; @@ -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;