From: Magnus Jacobsson Date: Wed, 27 Jul 2022 12:28:44 +0000 (+0200) Subject: tests: SvgAnalyzer: add handling of the 'fill' attribute X-Git-Tag: 5.0.1~7^2~11 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9712e31b6c8b68be2431a027d50d71c2aa11fe23;p=graphviz tests: SvgAnalyzer: add handling of the 'fill' attribute --- diff --git a/tests/svg_analyzer.cpp b/tests/svg_analyzer.cpp index 339a88d01..2bc011657 100644 --- a/tests/svg_analyzer.cpp +++ b/tests/svg_analyzer.cpp @@ -115,6 +115,10 @@ void SVGAnalyzer::set_class(std::string_view class_) { current_element().attributes.class_ = class_; } +void SVGAnalyzer::set_fill(std::string_view fill) { + current_element().attributes.fill = fill; +} + void SVGAnalyzer::set_height(double height) { current_element().attributes.height = height; } diff --git a/tests/svg_analyzer.h b/tests/svg_analyzer.h index 5a2e77770..12a201f9a 100644 --- a/tests/svg_analyzer.h +++ b/tests/svg_analyzer.h @@ -27,6 +27,7 @@ public: void on_enter_element_text() override; void on_enter_element_title() override; void on_exit_element() override; + void set_fill(std::string_view fill) override; void set_height(double height) override; void set_id(std::string_view id) override; void set_class(std::string_view) override; diff --git a/tests/svg_analyzer_interface.h b/tests/svg_analyzer_interface.h index d2091a231..a574770d3 100644 --- a/tests/svg_analyzer_interface.h +++ b/tests/svg_analyzer_interface.h @@ -27,6 +27,7 @@ public: virtual void on_enter_element_title() = 0; virtual void on_exit_element() = 0; virtual void set_class(std::string_view) = 0; + virtual void set_fill(std::string_view fill) = 0; virtual void set_height(double height) = 0; virtual void set_id(std::string_view id) = 0; virtual void set_text(std::string_view text) = 0; diff --git a/tests/svg_element.cpp b/tests/svg_element.cpp index 35768d83a..55e5c5676 100644 --- a/tests/svg_element.cpp +++ b/tests/svg_element.cpp @@ -36,6 +36,25 @@ static std::string xml_encode(const std::string &text) { return out; } +// convert a valid color specification to the flavor that Graphviz uses +static std::string to_graphviz_color(const std::string &color) { + if (color == "rgb(0,0,0)") { + return "black"; + } else if (color == "rgb(255,255,255)") { + return "white"; + } else if (color.starts_with("rgb")) { + const auto comma1 = color.find_first_of(","); + const auto r = std::stoi(color.substr(4, comma1 - 1)); + const auto comma2 = color.find_first_of(",", comma1 + 1); + const auto g = std::stoi(color.substr(comma1 + 1, comma2 - 1)); + const auto close_par = color.find_first_of(")", comma2 + 1); + const auto b = std::stoi(color.substr(comma2 + 1, close_par - 1)); + return fmt::format("#{:02x}{:02x}{:02x}", r, g, b); + } else { + return color; + } +} + void SVG::SVGElement::append_attribute(std::string &output, const std::string &attribute) const { if (attribute.empty()) { @@ -47,6 +66,14 @@ void SVG::SVGElement::append_attribute(std::string &output, output += attribute; } +std::string SVG::SVGElement::fill_attribute_to_string() const { + if (attributes.fill.empty()) { + return ""; + } + + return fmt::format(R"(fill="{}")", to_graphviz_color(attributes.fill)); +} + std::string SVG::SVGElement::id_attribute_to_string() const { if (attributes.id.empty()) { return ""; @@ -93,7 +120,7 @@ void SVG::SVGElement::to_string_impl(std::string &output, append_attribute(attributes_str, id_attribute_to_string()); switch (type) { case SVG::SVGElementType::Ellipse: - // ignore for now + append_attribute(attributes_str, fill_attribute_to_string()); break; case SVG::SVGElementType::Group: attributes_str += fmt::format(R"( class="{}")", attributes.class_); @@ -105,13 +132,13 @@ void SVG::SVGElement::to_string_impl(std::string &output, } break; case SVG::SVGElementType::Path: - // ignore for now + append_attribute(attributes_str, fill_attribute_to_string()); break; case SVG::SVGElementType::Polygon: - // ignore for now + append_attribute(attributes_str, fill_attribute_to_string()); break; case SVG::SVGElementType::Polyline: - // ignore for now + append_attribute(attributes_str, fill_attribute_to_string()); break; case SVG::SVGElementType::Svg: attributes_str += fmt::format( diff --git a/tests/svg_element.h b/tests/svg_element.h index 8b8d6cc45..87d27bfc4 100644 --- a/tests/svg_element.h +++ b/tests/svg_element.h @@ -42,6 +42,7 @@ std::string_view tag(SVG::SVGElementType type); struct SVGAttributes { std::string class_; + std::string fill; double height; std::string id; std::optional transform; @@ -82,6 +83,7 @@ private: void append_attribute(std::string &output, const std::string &attribute) const; std::string id_attribute_to_string() const; + std::string fill_attribute_to_string() const; void to_string_impl(std::string &output, std::size_t indent_size, std::size_t current_indent) const; }; diff --git a/tests/svgpp_context.cpp b/tests/svgpp_context.cpp index b8a14853f..ea32be5e3 100644 --- a/tests/svgpp_context.cpp +++ b/tests/svgpp_context.cpp @@ -1,10 +1,17 @@ #include +#include #include +#include #include "svg_analyzer_interface.h" #include "svgpp_context.h" +static std::string to_color_string(SvgppContext::color_t color) { + return fmt::format("rgb({},{},{})", (color >> 16) & 0xff, (color >> 8) & 0xff, + (color >> 0) & 0xff); +} + SvgppContext::SvgppContext(ISVGAnalyzer *svgAnalyzer) : m_svgAnalyzer(svgAnalyzer){}; @@ -119,6 +126,21 @@ void SvgppContext::set(svgpp::tag::attribute::cx a, const double v) { (void)v; } +void SvgppContext::set(svgpp::tag::attribute::fill, svgpp::tag::value::none) { + m_svgAnalyzer->set_fill("none"); +} + +void SvgppContext::set(svgpp::tag::attribute::fill, + svgpp::tag::value::currentColor) { + throw std::runtime_error{ + "the 'fill' attribute 'currentColor' value is not yet implemented"}; +} + +void SvgppContext::set(svgpp::tag::attribute::fill, color_t color, + svgpp::tag::skip_icc_color) { + m_svgAnalyzer->set_fill(to_color_string(color)); +} + void SvgppContext::transform_matrix(const boost::array &matrix) { double a = matrix.at(0); double b = matrix.at(1); diff --git a/tests/svgpp_context.h b/tests/svgpp_context.h index 8c0568b09..f024f0e3e 100644 --- a/tests/svgpp_context.h +++ b/tests/svgpp_context.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -48,6 +49,56 @@ public: void path_exit(); void set(svgpp::tag::attribute::cy cy, double v); void set(svgpp::tag::attribute::cx cx, double v); + + void set(svgpp::tag::attribute::fill, svgpp::tag::value::none); + void set(svgpp::tag::attribute::fill, svgpp::tag::value::currentColor); + using color_t = int; + void set(svgpp::tag::attribute::fill, color_t color, + svgpp::tag::skip_icc_color = svgpp::tag::skip_icc_color()); + template void set(svgpp::tag::attribute::fill, IRI const &) { + throw std::runtime_error{ + "this flavor of the 'fill' attribute is not yet implemented"}; + }; + template + void set(svgpp::tag::attribute::fill, svgpp::tag::iri_fragment, IRI const &) { + throw std::runtime_error{ + "this flavor of the 'fill' attribute is not yet implemented"}; + }; + template + void set(svgpp::tag::attribute::fill, IRI const &, svgpp::tag::value::none) { + throw std::runtime_error{ + "this flavor of the 'fill' attribute is not yet implemented"}; + }; + template + void set(svgpp::tag::attribute::fill, svgpp::tag::iri_fragment, IRI const &, + svgpp::tag::value::none) { + throw std::runtime_error{ + "this flavor of the 'fill' attribute is not yet implemented"}; + }; + template + void set(svgpp::tag::attribute::fill, IRI const &, + svgpp::tag::value::currentColor) { + throw std::runtime_error{ + "this flavor of the 'fill' attribute is not yet implemented"}; + }; + template + void set(svgpp::tag::attribute::fill, svgpp::tag::iri_fragment, IRI const &, + svgpp::tag::value::currentColor) { + throw std::runtime_error{ + "this flavor of the 'fill' attribute is not yet implemented"}; + }; + template + void set(svgpp::tag::attribute::fill, IRI const &, color_t, + svgpp::tag::skip_icc_color = svgpp::tag::skip_icc_color()) { + throw std::runtime_error{ + "this flavor of the 'fill' attribute is not yet implemented"}; + }; + template + void set(svgpp::tag::attribute::fill, svgpp::tag::iri_fragment, IRI const &, + color_t, svgpp::tag::skip_icc_color = svgpp::tag::skip_icc_color()) { + throw std::runtime_error{ + "this flavor of the 'fill' attribute is not yet implemented"}; + }; void transform_matrix(const boost::array &matrix); void set(svgpp::tag::attribute::r r, double v); void set(svgpp::tag::attribute::rx rx, double v); diff --git a/tests/svgpp_document_traverser.cpp b/tests/svgpp_document_traverser.cpp index 19133e7bc..a73c9599c 100644 --- a/tests/svgpp_document_traverser.cpp +++ b/tests/svgpp_document_traverser.cpp @@ -27,6 +27,7 @@ void traverseDocumentWithSvgpp(SvgppContext &context, char *text) { using processed_attributes_t = boost::mpl::set") { + if (recreated_svg_lines[i] == "") { // stop comparison here since we do not yet handle all attributes on the // 'polygon' element break; @@ -140,8 +140,8 @@ TEST_CASE( CHECK(recreated_svg.find("a") != std::string::npos); CHECK(recreated_svg.find("b") != std::string::npos); } - CHECK(recreated_svg.find("") != std::string::npos); - CHECK(recreated_svg.find("") != std::string::npos); + CHECK(recreated_svg.find("") != std::string::npos); + CHECK(recreated_svg.find("") != std::string::npos); CHECK(recreated_svg.find("") != std::string::npos); CHECK(recreated_svg.find("") != std::string::npos); CHECK(recreated_svg.find("") != std::string::npos);