2013-07-16 19:58:43 +00:00
|
|
|
// -*- mode: C++ -*-
|
|
|
|
//
|
2015-01-07 12:53:58 +00:00
|
|
|
// Copyright (C) 2013-2015 Red Hat, Inc.
|
2013-05-28 08:22:08 +00:00
|
|
|
//
|
|
|
|
// This file is part of the GNU Application Binary Interface Generic
|
|
|
|
// Analysis and Instrumentation Library (libabigail). This library is
|
|
|
|
// free software; you can redistribute it and/or modify it under the
|
2013-07-16 19:58:43 +00:00
|
|
|
// terms of the GNU Lesser General Public License as published by the
|
|
|
|
// Free Software Foundation; either version 3, or (at your option) any
|
2013-05-28 08:22:08 +00:00
|
|
|
// later version.
|
|
|
|
|
|
|
|
// This library is distributed in the hope that it will be useful, but
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
2013-07-16 19:58:43 +00:00
|
|
|
// General Lesser Public License for more details.
|
2013-05-28 08:22:08 +00:00
|
|
|
|
2013-07-16 19:58:43 +00:00
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this program; see the file COPYING-LGPLV3. If
|
|
|
|
// not, see <http://www.gnu.org/licenses/>.
|
2013-05-28 08:22:08 +00:00
|
|
|
|
|
|
|
#include "abg-viz-svg.h"
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
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_(<?xml version="1.0" encoding="utf-8"?>
|
|
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
|
|
<svg version="1.1"
|
|
|
|
id="svg2" xml:space="preserve"
|
|
|
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
|
|
xmlns:cc="http://creativecommons.org/ns#"
|
|
|
|
xmlns:svg="http://www.w3.org/2000/svg"
|
|
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
|
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
|
|
)_delimiter_";
|
|
|
|
|
|
|
|
const std::string units("__units");
|
|
|
|
const std::string width("__width");
|
|
|
|
const std::string height("__height");
|
|
|
|
|
|
|
|
std::string strip = R"_delimiter_(x="0__units" y="0__units"
|
|
|
|
width="__width__units" height="__height__units"
|
|
|
|
viewBox="0 0 __width __height" enable-background="new 0 0 __width __height">
|
|
|
|
)_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 << "</svg>" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
svg::add_title()
|
|
|
|
{
|
|
|
|
_M_sstream << "<title>" << _M_title << "</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_(<text x="__x" y="__y" transform="rotate(270 __x __y)" __style>__label</text>
|
|
|
|
)_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 << "<g><!-- vertical labels -->" << std::endl;
|
|
|
|
_M_sstream << offset_strip;
|
|
|
|
_M_sstream << size_strip;
|
|
|
|
_M_sstream << align_strip;
|
|
|
|
_M_sstream << "</g>" << 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_(<path stroke="black" stroke-width="1" d="M __x __y1 L __x __y2"/>
|
|
|
|
)_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 << "<g><!-- vertical lines -->" << std::endl;
|
|
|
|
_M_sstream << strip_1;
|
|
|
|
_M_sstream << strip_2;
|
|
|
|
_M_sstream << strip_3;
|
|
|
|
_M_sstream << strip_4;
|
|
|
|
_M_sstream << "</g>" << 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_(<rect x="__x" y="__y" fill="__color" stroke="__color" stroke-width="1" width="__width" height="__height"/>
|
|
|
|
)_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_(<text x="__x" y="__y" fill="__color" __style>__val</text>
|
|
|
|
)_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 << "<g><!-- row " << _M_y_size << " -->" << std::endl;
|
|
|
|
_M_sstream << rect_strip;
|
|
|
|
_M_sstream << offset_strip;
|
|
|
|
_M_sstream << size_strip;
|
|
|
|
_M_sstream << align_strip;
|
|
|
|
_M_sstream << name_strip;
|
|
|
|
_M_sstream << "</g>" << std::endl;
|
|
|
|
|
|
|
|
++_M_y_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}//end namespace abigail
|