izzi
SVG SUBSET C++ API
Loading...
Searching...
No Matches
a60-svg-elements-components.h
Go to the documentation of this file.
1// svg element parts -*- mode: C++ -*-
2
3// Copyright (C) 2014-2025 Benjamin De Kosnik <b.dekosnik@gmail.com>
4
5// This file is part of the alpha60-MiL SVG library. This library is
6// free software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the Free
8// Software Foundation; either version 3, or (at your option) any
9// later version.
10
11// This library is distributed in the hope that it will be useful, but
12// WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15
16#ifndef MiL_SVG_ELEMENTS_COMPONENTS_H
17#define MiL_SVG_ELEMENTS_COMPONENTS_H 1
18
19
20namespace svg {
21
22void
24{
26 te.start_element(t);
27 te.finish_element();
28 add_element(te);
29}
30
31void
33{
34 try
35 {
36 string filename(_M_name + ".svg");
37 std::ofstream f(filename);
38 if (!f.is_open() || !f.good())
39 throw std::runtime_error("svg_element::write fail");
40 f << _M_sstream.str() << std::endl;
41 }
42 catch(std::exception& e)
43 {
44 throw e;
45 }
46}
47
48/// SVG element beginning boilerplate for outermost (containing) svg_element.
49/// Variable: unit, x=0, y=0, width, height
50void
52{
53 const string start = R"_delimiter_(<?xml version="1.0" encoding="utf-8"?>
54<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
55<svg version="1.1"
56 xml:space="preserve"
57 xmlns="http://www.w3.org/2000/svg"
58 xmlns:xlink="http://www.w3.org/1999/xlink"
59 xmlns:html="http://www.w3.org/1999/xhtml"
60)_delimiter_";
61
62 const string id("__id");
63 const string unit("__unit");
64 const string width("__width");
65 const string height("__height");
66
67 string strip = R"_delimiter_(id="__id" x="0__unit" y="0__unit"
68width="__width__unit" height="__height__unit"
69viewBox="0 0 __width __height" enable-background="new 0 0 __width __height" role="img">
70)_delimiter_";
71
72 string_replace(strip, id, _M_name);
74 string_replace(strip, width, std::to_string(_M_area._M_width));
75 string_replace(strip, height, std::to_string(_M_area._M_height));
76
78 _M_sstream << strip << std::endl;
79}
80
81
82/// SVG element for nested svg_element.
83/// Use name, area, unit, typo for viewport frame
84/// @param p origin x,y position
85/// @param desta height, width of destination, iff > _M_area then enlarge.
86void
87svg_element::start_element(const point_2t p, const area destarea,
88 const style& styl)
89{
90 const string id("__id");
91 string start = R"_delimiter_(<svg id="__id" )_delimiter_";
93
94 const string unit("__unit");
95 const string width("__width");
96 const string height("__height");
97 const string dwidth("__dwidth");
98 const string dheight("__dheight");
99 const string px("__x");
100 const string py("__y");
101 string strip = R"_delimiter_(viewBox="0 0 __width __height" x="__x__unit" y="__y__unit" width="__dwidth__unit" height="__dheight__unit" )_delimiter_";
102
104 string_replace(strip, width, std::to_string(_M_area._M_width));
105 string_replace(strip, height, std::to_string(_M_area._M_height));
106
107 const auto [ dw, dh ] = destarea;
108 const auto [ x, y ] = p;
109 string_replace(strip, dwidth, std::to_string(dw));
110 string_replace(strip, dheight, std::to_string(dh));
111 string_replace(strip, px, std::to_string(int(x)));
112 string_replace(strip, py, std::to_string(int(y)));
113
114 // Check to make sure stream starts empty.
115 if (!this->empty())
116 {
117 string m("svg_element::start_element error buffer is not empty: " );
118 m += k::newline;
119 m += this->str();
120 m += k::newline;
121 throw std::runtime_error(m);
122 }
123
124 _M_sstream << start;
125 _M_sstream << strip << std::endl;
126
127 // Only add style if it is not the default argument.
128 const string nostr = to_string(color::none);
129 const string fillstr = to_string(styl._M_fill_color);
130 const bool colornonep = nostr == fillstr;
131 if (!colornonep && (styl._M_fill_opacity != 0 || styl._M_stroke_opacity != 0))
132 {
133 add_style(styl);
134 _M_sstream << k::space;
135 }
136 _M_sstream << '>' << k::newline;
137}
138
139
140void
142{
143 const string f = R"_delimiter_(<defs>
144 <filter id="gblur10" x="0" y="0">
145 <feGaussianBlur in="SourceGraphic" stdDeviation="10" />
146 <feOffset dx="0" dy="0" />
147 </filter>
148 <filter id="gblur20" x="0" y="0">
149 <feGaussianBlur in="SourceGraphic" stdDeviation="20" />
150 <feOffset dx="0" dy="0" />
151 </filter>
152 <filter id="gblur10y" x="0" y="0">
153 <feGaussianBlur in="SourceGraphic" stdDeviation="0, 10" />
154 <feOffset dx="0" dy="0" />
155 </filter>
156 <filter id="gblur20y" x="0" y="0">
157 <feGaussianBlur in="SourceGraphic" stdDeviation="0, 20" />
158 <feOffset dx="0" dy="0" />
159 </filter>
160 </defs>
161)_delimiter_";
162
163 _M_sstream << f << std::endl;
164}
165
166
167/// SVG element end boilerplate.
168void
170{
171 _M_sstream << "</svg>" << std::endl;
172}
173
174} // namespace svg
175
176#endif
stream_type _M_sstream
Virtual, only one buffer.
void add_style(const style &sty)
void add_title(const string &t)
void start_element()
SVG element beginning boilerplate for outermost (containing) svg_element. Variable: unit,...
bool empty()
Empty when the output buffer is.
void start(const string &desc="")
string str() const
void add_element(const element_base &e)
unit
Measurement abstraction for absolute (not relative) measurements.
@ px
Pixel where 1 pixel x 96 PPI = .26 mm.
const string to_string(const unit e)
void string_replace(std::string &target, const std::string &match, const std::string &replace)
Definition a60-svg.h:43
std::tuple< space_type, space_type > point_2t
Point (x,y) in 2D space.
Definition a60-svg.h:65
Datum consolidating style preferences.
color_qi _M_fill_color