libabigail/src/abg-viz-svg.cc
Dodji Seketeli 76837d1cbf Update copyright years
* include/abg-comp-filter.h: Update copyright years.
	* include/abg-comparison.h: Likewise.
	* include/abg-config.h: Likewise.
	* include/abg-corpus.h: Likewise.
	* include/abg-diff-utils.h: Likewise.
	* include/abg-dwarf-reader.h: Likewise.
	* include/abg-fwd.h: Likewise.
	* include/abg-hash.h: Likewise.
	* include/abg-ini.h: Likewise.
	* include/abg-ir.h: Likewise.
	* include/abg-libxml-utils.h: Likewise.
	* include/abg-libzip-utils.h: Likewise.
	* include/abg-reader.h: Likewise.
	* include/abg-sptr-utils.h: Likewise.
	* include/abg-traverse.h: Likewise.
	* include/abg-viz-common.h: Likewise.
	* include/abg-viz-dot.h: Likewise.
	* include/abg-viz-svg.h: Likewise.
	* include/abg-writer.h: Likewise.
	* src/abg-comp-filter.cc: Likewise.
	* src/abg-comparison.cc: Likewise.
	* src/abg-config.cc: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-diff-utils.cc: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-hash.cc: Likewise.
	* src/abg-ini.cc: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-libxml-utils.cc: Likewise.
	* src/abg-libzip-utils.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-traverse.cc: Likewise.
	* src/abg-viz-common.cc: Likewise.
	* src/abg-viz-dot.cc: Likewise.
	* src/abg-viz-svg.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tests/print-diff-tree.cc: Likewise.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-diff2.cc: Likewise.
	* tests/test-ir-walker.cc: Likewise.
	* tests/test-lookup-syms.cc: Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/test-read-write.cc: Likewise.
	* tests/test-utils.cc: Likewise.
	* tests/test-utils.h: Likewise.
	* tests/test-write-read-archive.cc: Likewise.
	* tools/abg-tools-utils.cc: Likewise.
	* tools/abg-tools-utils.h: Likewise.
	* tools/abiar.cc: Likewise.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abisym.cc: Likewise.
	* tools/binilint.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-07 17:52:10 +01:00

276 lines
8.8 KiB
C++

// -*- mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
//
// 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
// terms of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 3, or (at your option) any
// 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
// General Lesser Public License for more details.
// 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/>.
#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