current_element().attributes.class_ = class_;
}
+void SVGAnalyzer::set_height(double height) {
+ current_element().attributes.height = height;
+}
+
void SVGAnalyzer::set_text(std::string_view text) {
auto &element = current_element();
element.text = text;
}
}
+void SVGAnalyzer::set_width(double width) {
+ current_element().attributes.width = width;
+}
+
void SVGAnalyzer::set_graphviz_version(std::string_view version) {
m_svg.graphviz_version = version;
}
void on_enter_element_text() override;
void on_enter_element_title() override;
void on_exit_element() override;
+ void set_height(double height) override;
void set_class(std::string_view) override;
void set_text(std::string_view text) override;
+ void set_width(double width) override;
std::size_t num_svgs() const { return m_num_svgs; };
std::size_t num_groups() const { return m_num_groups; };
std::size_t num_circles() const { return m_num_circles; };
virtual void on_enter_element_title() = 0;
virtual void on_exit_element() = 0;
virtual void set_class(std::string_view) = 0;
+ virtual void set_height(double height) = 0;
virtual void set_text(std::string_view text) = 0;
+ virtual void set_width(double width) = 0;
};
SVG::SVGElement::SVGElement(SVGElementType type) : type(type) {}
+static double px_to_pt(double px) {
+ // a `pt` is 0.75 `px`. See e.g.
+ // https://oreillymedia.github.io/Using_SVG/guide/units.html
+ return px * 3 / 4;
+}
+
static std::string xml_encode(const std::string &text) {
std::string out;
for (const char &ch : text) {
// ignore for now
break;
case SVG::SVGElementType::Svg:
- // ignore for now
+ attributes_str += fmt::format(R"(width="{}pt" height="{}pt")",
+ std::lround(px_to_pt(attributes.width)),
+ std::lround(px_to_pt(attributes.height)));
break;
case SVG::SVGElementType::Text:
// ignore for now
#pragma once
+#include <cmath>
#include <string>
#include <string_view>
#include <vector>
struct SVGAttributes {
std::string class_;
+ double height;
+ double width;
};
/**
(void)v;
}
-void SvgppContext::set(svgpp::tag::attribute::width a, const double v) {
- (void)a;
- (void)v;
+void SvgppContext::set(svgpp::tag::attribute::width, const double v) {
+ m_svgAnalyzer->set_width(v);
}
-void SvgppContext::set(svgpp::tag::attribute::height a, const double v) {
- (void)a;
- (void)v;
+void SvgppContext::set(svgpp::tag::attribute::height, const double v) {
+ m_svgAnalyzer->set_height(v);
}
void SvgppContext::set(svgpp::tag::attribute::class_,
using processed_attributes_t =
boost::mpl::set<svgpp::traits::shapes_attributes_by_element,
- svgpp::tag::attribute::class_ //
+ svgpp::tag::attribute::class_, //
+ svgpp::tag::attribute::height, //
+ svgpp::tag::attribute::width //
>::type;
svgpp::document_traversal<
boost::split(recreated_svg_lines, recreated_svg, boost::is_any_of("\n"));
for (std::size_t i = 0; i < original_svg_lines.size(); i++) {
REQUIRE(i < recreated_svg_lines.size());
- if (recreated_svg_lines[i] == "<svg>") {
- // stop comparison here since we do not yet handle attributes on the
+ if (recreated_svg_lines[i].starts_with("<svg width=\"")) {
+ // stop comparison here since we do not yet handle all attributes on the
// 'svg' element
break;
}
// do some sanity checks of the parts of the recreated SVG that we cannot
// yet compare with the original SVG
- CHECK(recreated_svg.find("<svg>") != std::string::npos);
+ CHECK(recreated_svg.find("<svg width=\"") != std::string::npos);
+ CHECK(recreated_svg.find("\" height=\"") != std::string::npos);
CHECK(recreated_svg.find("</svg>") != std::string::npos);
CHECK(recreated_svg.find("<g class=\"graph\">") != std::string::npos);
CHECK(recreated_svg.find("<g class=\"node\">") != std::string::npos);