diff --git a/src/Graphics.hpp b/src/Graphics.hpp index 26862815..b1375433 100644 --- a/src/Graphics.hpp +++ b/src/Graphics.hpp @@ -13,5 +13,6 @@ #include "graphics/RadialGradient.hpp" #include "graphics/Rect.hpp" #include "graphics/Text.hpp" +#include "graphics/ViewBox.hpp" #endif // GRAPHICS_HPP_ diff --git a/src/Parser.cpp b/src/Parser.cpp index 8e1a6404..13cabe9c 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -192,8 +192,9 @@ SVGElement *Parser::parseElements(std::string file_name) { std::string viewbox = getAttribute(svg, "viewBox"); if (viewbox != "") { std::stringstream ss(viewbox); - ss >> this->viewbox.first.x >> this->viewbox.first.y >> - this->viewbox.second.x >> this->viewbox.second.y; + float x, y, w, h; + ss >> x >> y >> w >> h; + this->viewbox = ViewBox(x, y, w, h); } rapidxml::xml_node<> *node = svg->first_node(); rapidxml::xml_node<> *prev = NULL; @@ -321,19 +322,19 @@ float Parser::getFloatAttribute(rapidxml::xml_node<> *node, std::string name) { if (name == "x1" || name == "y1" || name == "fr") result = 0; else if (name == "cx" || name == "cy") - result = name == "cx" ? 0.5 * this->viewbox.second.x - : 0.5 * this->viewbox.second.y; + result = name == "cx" ? 0.5 * this->viewbox.getWidth() + : 0.5 * this->viewbox.getHeight(); else if (name == "r") { - result = sqrt((pow(this->viewbox.second.x, 2) + - pow(this->viewbox.second.y, 2)) / + result = sqrt((pow(this->viewbox.getWidth(), 2) + + pow(this->viewbox.getHeight(), 2)) / 2) / 2; } else if (name == "fx" || name == "fy") result = name == "fx" ? getFloatAttribute(node, "cx") : getFloatAttribute(node, "cy"); else - result = name == "x2" ? this->viewbox.second.x - : this->viewbox.second.y; + result = name == "x2" ? this->viewbox.getWidth() + : this->viewbox.getHeight(); } else { if (name == "stroke-width" || name == "stroke-opacity" || name == "fill-opacity" || name == "opacity" || @@ -347,7 +348,7 @@ float Parser::getFloatAttribute(rapidxml::xml_node<> *node, std::string name) { std::string value = node->first_attribute(name.c_str())->value(); if (value.find("%") != std::string::npos) { result = std::stof(value.substr(0, value.find("%"))) * - this->viewbox.second.x / 100; + this->viewbox.getWidth() / 100; } else if (value.find("pt") != std::string::npos) { result = std::stof(value.substr(0, value.find("pt"))) * 1.33; } else { @@ -827,6 +828,6 @@ Parser::~Parser() { void Parser::printShapesData() { root->printData(); } -std::pair< Vector2Df, Vector2Df > Parser::getViewBox() const { return viewbox; } +ViewBox Parser::getViewBox() const { return viewbox; } Vector2Df Parser::getViewPort() const { return viewport; } \ No newline at end of file diff --git a/src/Parser.hpp b/src/Parser.hpp index 9e09afe4..e6ffde8f 100644 --- a/src/Parser.hpp +++ b/src/Parser.hpp @@ -61,7 +61,7 @@ class Parser { * * @return The viewbox of the SVG file. */ - std::pair< Vector2Df, Vector2Df > getViewBox() const; + ViewBox getViewBox() const; /** * @brief Gets the viewport of the SVG file. @@ -276,8 +276,7 @@ class Parser { SVGElement* root; ///< The root of the SVG file. std::map< std::string, Gradient* > gradients; ///< The gradients of the SVG ///< file. - std::pair< Vector2Df, Vector2Df > - viewbox; ///< The viewbox of the SVG file. + ViewBox viewbox; ///< The viewbox of the SVG file. Vector2Df viewport; ///< The viewport of the SVG file. }; diff --git a/src/graphics/ViewBox.cpp b/src/graphics/ViewBox.cpp new file mode 100644 index 00000000..a6eaa697 --- /dev/null +++ b/src/graphics/ViewBox.cpp @@ -0,0 +1,13 @@ +#include "ViewBox.hpp" + +ViewBox::ViewBox() : x(0), y(0), w(0), h(0) {} + +ViewBox::ViewBox(float X, float Y, float W, float H) : x(X), y(Y), w(W), h(H) {} + +float ViewBox::getX() const { return x; } + +float ViewBox::getY() const { return y; } + +float ViewBox::getWidth() const { return w; } + +float ViewBox::getHeight() const { return h; } \ No newline at end of file diff --git a/src/graphics/ViewBox.hpp b/src/graphics/ViewBox.hpp new file mode 100644 index 00000000..4babb1fc --- /dev/null +++ b/src/graphics/ViewBox.hpp @@ -0,0 +1,58 @@ +#ifndef VIEWBOX_HPP_ +#define VIEWBOX_HPP_ + +class ViewBox { +public: + /** + * @brief Default constructor + * + * Creates a ViewBox(0, 0, 0, 0). + */ + ViewBox(); + + /** + * @brief Construct the ViewBox from its coordinates + * + * @param X X coordinate + * @param Y Y coordinate + * @param W Width + * @param H Height + */ + ViewBox(float X, float Y, float W, float H); + + /** + * @brief Get the X coordinate of the ViewBox + * + * @return X coordinate of the ViewBox + */ + float getX() const; + + /** + * @brief Get the Y coordinate of the ViewBox + * + * @return Y coordinate of the ViewBox + */ + float getY() const; + + /** + * @brief Get the width of the ViewBox + * + * @return Width of the ViewBox + */ + float getWidth() const; + + /** + * @brief Get the height of the ViewBox + * + * @return Height of the ViewBox + */ + float getHeight() const; + +private: + float x; ///< X coordinate of the ViewBox + float y; ///< Y coordinate of the ViewBox + float w; ///< Width of the ViewBox + float h; ///< Height of the ViewBox +}; + +#endif // VIEWBOX_HPP_ \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 25cd3c92..77ca7b42 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,7 +18,7 @@ void OnPaint(HDC hdc, const std::string& filePath, Viewer& viewer) { parser = Parser::getInstance(filePath); } Vector2Df viewport = parser->getViewPort(); - std::pair< Vector2Df, Vector2Df > viewbox = parser->getViewBox(); + ViewBox viewbox = parser->getViewBox(); if (viewport.x == 0 && viewport.y == 0) { viewport.x = viewer.window_size.x; viewport.y = viewer.window_size.y; @@ -31,23 +31,24 @@ void OnPaint(HDC hdc, const std::string& filePath, Viewer& viewer) { graphics.SetInterpolationMode(Gdiplus::InterpolationModeHighQuality); graphics.SetClip(Gdiplus::Rect(0, 0, viewport.x, viewport.y)); - if ((viewport.x != viewbox.second.x || viewport.y != viewbox.second.y) && - viewbox.second.x != 0 && viewbox.second.y != 0) { - float scale_x = viewport.x / viewbox.second.x; - float scale_y = viewport.y / viewbox.second.y; + if ((viewport.x != viewbox.getWidth() || + viewport.y != viewbox.getHeight()) && + viewbox.getWidth() != 0 && viewbox.getHeight() != 0) { + float scale_x = viewport.x / viewbox.getWidth(); + float scale_y = viewport.y / viewbox.getHeight(); float scale = std::min(scale_x, scale_y); graphics.ScaleTransform(scale, scale); float offset_x = 0.0f; float offset_y = 0.0f; - if (viewport.x > viewbox.second.x) { - offset_x = (viewport.x - viewbox.second.x * scale) / 2 / scale; + if (viewport.x > viewbox.getWidth()) { + offset_x = (viewport.x - viewbox.getWidth() * scale) / 2 / scale; } - if (viewport.y > viewbox.second.y) { - offset_y = (viewport.y - viewbox.second.y * scale) / 2 / scale; + if (viewport.y > viewbox.getHeight()) { + offset_y = (viewport.y - viewbox.getHeight() * scale) / 2 / scale; } graphics.TranslateTransform(offset_x, offset_y); } - graphics.TranslateTransform(-viewbox.first.x, -viewbox.first.y); + graphics.TranslateTransform(-viewbox.getX(), -viewbox.getY()); Gdiplus::Matrix matrix; Gdiplus::Region region; @@ -119,6 +120,18 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, std::string filePath; if (__argc > 1) { filePath = __argv[1]; + std::ifstream file(filePath); + if (!file.good()) { + std::cerr << "Error: File path is invalid or does not exist." + << std::endl; + PostQuitMessage(0); + return 0; + } + file.close(); + } else { + std::cerr << "Error: No file path provided." << std::endl; + PostQuitMessage(0); + return 0; } Viewer* viewer = Viewer::getInstance(); switch (message) {