// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // // Copyright (C) 2013-2022 Red Hat, Inc. #include #include #include "abg-internal.h" // ABG_BEGIN_EXPORT_DECLARATIONS #include "abg-viz-svg.h" ABG_END_EXPORT_DECLARATIONS // namespace abigail { void svg::write() { try { std::string filename(_M_title + ".svg"); std::ofstream f(filename); if (!f.is_open() || !f.good()) throw std::runtime_error("abigail::svg::write fail"); f << _M_sstream.str() << std::endl; } catch(std::exception& e) { throw e; } } // SVG element beginning boilerplate. // Variable: units, x=0, y=0, width, height void svg::start_element() { const std::string start = R"_delimiter_( )_delimiter_"; string_replace(strip, units, units_to_string(_M_canvas._M_units)); string_replace(strip, width, std::to_string(_M_canvas._M_width)); string_replace(strip, height, std::to_string(_M_canvas._M_height)); _M_sstream << start; _M_sstream << strip << std::endl; } // SVG element end boilerplate. void svg::finish_element() { _M_sstream << "" << std::endl; } void svg::add_title() { _M_sstream << "" << _M_title << "" << std::endl; } // Column labels // Variable: x, y void svg::add_y_label() { unsigned int xcur = 0; const unsigned int padding = 10; const std::string x("__x"); const std::string y("__y"); const std::string label("__label"); const std::string style("__style"); const std::string offset("OFFSET"); const std::string size("SIZE"); const std::string align("ALIGN"); // Base text element. std::string text_strip = R"_delimiter_(__label )_delimiter_"; // These parts are the same for every text element ... string_replace(text_strip, y, std::to_string(_M_y_origin - padding)); string_replace(text_strip, style, _M_typo.to_attribute(typography::start)); // ... just the label and the x position in the center of the current column. xcur = _M_x_origin + (.5 * _M_x_space); std::string offset_strip = text_strip; string_replace(offset_strip, x, std::to_string(xcur)); string_replace(offset_strip, label, offset); xcur += _M_x_space; std::string size_strip = text_strip; string_replace(size_strip, x, std::to_string(xcur)); string_replace(size_strip, label, size); xcur += _M_x_space; std::string align_strip = text_strip; string_replace(align_strip, x, std::to_string(xcur)); string_replace(align_strip, label, align); _M_sstream << "" << std::endl; _M_sstream << offset_strip; _M_sstream << size_strip; _M_sstream << align_strip; _M_sstream << "" << std::endl; } // Draws in 4 vertical hairlines. // Variable: x, y, _M_y_size, _M_y_space void svg::add_y_lines() { unsigned int xcur = 0; const unsigned int yend = _M_y_origin + _M_y_size * _M_y_space; const std::string x("__x"); const std::string y1("__y1"); const std::string y2("__y2"); std::string strip = R"_delimiter_( )_delimiter_"; // These parts are the same for every text element ... string_replace(strip, y1, std::to_string(_M_y_origin - _M_y_space)); string_replace(strip, y2, std::to_string(yend)); xcur = _M_x_origin; std::string strip_1 = strip; string_replace(strip_1, x, std::to_string(xcur)); xcur += _M_x_space; std::string strip_2 = strip; string_replace(strip_2, x, std::to_string(xcur)); xcur += _M_x_space; std::string strip_3 = strip; string_replace(strip_3, x, std::to_string(xcur)); xcur += _M_x_space; std::string strip_4 = strip; string_replace(strip_4, x, std::to_string(xcur)); _M_sstream << "" << std::endl; _M_sstream << strip_1; _M_sstream << strip_2; _M_sstream << strip_3; _M_sstream << strip_4; _M_sstream << "" << std::endl; } // Add in a row of data. // Columns assumed to be: offset, size, align, data member name/label // Variable: x, y, row type, void svg::add_y_row(const row& __r) { // Background rectangles are horizontally-oriented on column and row // boundaries, and span the second to third column. unsigned int xcur = 0; std::string chroma; const unsigned int ycur = _M_y_origin + (_M_y_size * _M_y_space) + (.5 * _M_y_space); const std::string x("__x"); const std::string y("__y"); const std::string name("__name"); const std::string style("__style"); const std::string color("__color"); const std::string width("__width"); const std::string height("__height"); const std::string val("__val"); std::string rect_strip = R"_delimiter_( )_delimiter_"; xcur = _M_x_origin + _M_x_space; chroma = color_to_string(__r._M_style._M_fill_color); string_replace(rect_strip, x, std::to_string(xcur)); string_replace(rect_strip, y, std::to_string(ycur - (.5 * _M_y_space))); string_replace(rect_strip, width, std::to_string(_M_x_space * 2)); string_replace(rect_strip, height, std::to_string(_M_y_space)); string_replace(rect_strip, color, chroma); // Text template for each bit of data. std::string text_strip = R"_delimiter_(__val )_delimiter_"; // Column 1 offset // Optional offset, if not a primary type row. std::string offset_strip(text_strip); xcur = _M_x_origin + (.5 * _M_x_space); chroma = color_to_string(abigail::color::black); string_replace(offset_strip, x, std::to_string(xcur)); string_replace(offset_strip, y, std::to_string(ycur)); string_replace(offset_strip, val, std::to_string(__r._M_offset)); string_replace(offset_strip, style, _M_typo.to_attribute(typography::middle)); string_replace(offset_strip, color, chroma); // Column 2 size std::string size_strip(text_strip); xcur += _M_x_space; chroma = color_to_string(__r._M_style._M_text_color); string_replace(size_strip, x, std::to_string(xcur)); string_replace(size_strip, y, std::to_string(ycur)); string_replace(size_strip, val, std::to_string(__r._M_size)); string_replace(size_strip, style, _M_typo.to_attribute(typography::middle)); string_replace(size_strip, color, chroma); // Column 3 align std::string align_strip(text_strip); xcur += _M_x_space; string_replace(align_strip, x, std::to_string(xcur)); string_replace(align_strip, y, std::to_string(ycur)); string_replace(align_strip, val, std::to_string(__r._M_align)); string_replace(align_strip, style, _M_typo.to_attribute(typography::middle)); string_replace(align_strip, color, chroma); // Column 4 data member id const unsigned int padding = 10; std::string name_strip(text_strip); xcur = _M_x_origin + (_M_x_size * _M_x_space) + padding; chroma = color_to_string(abigail::color::black); string_replace(name_strip, x, std::to_string(xcur)); string_replace(name_strip, y, std::to_string(ycur)); string_replace(name_strip, val, __r._M_id); string_replace(name_strip, style, _M_typo.to_attribute(typography::start)); string_replace(name_strip, color, chroma); // Write out stripped strings. _M_sstream << "" << std::endl; _M_sstream << rect_strip; _M_sstream << offset_strip; _M_sstream << size_strip; _M_sstream << align_strip; _M_sstream << name_strip; _M_sstream << "" << std::endl; ++_M_y_size; } }//end namespace abigail