kmalloc: Avoid code duplication.
[dragonfly.git] / usr.bin / evtranalyze / svg.c
blob5c153b2045f30b664498fea043d303a3ba536d34
1 /*
2 * Copyright (c) 2009, 2010 Aggelos Economopoulos. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 * 3. Neither the name of The DragonFly Project nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific, prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
32 #include <assert.h>
33 #include <math.h>
34 #include <stdio.h>
35 #include <stdlib.h>
37 #include "xml.h"
38 #include "svg.h"
39 #include "trivial.h"
41 enum {
42 MAX_VALSTR_LEN = 30,
45 struct svg_rect {
46 struct xml_element el;
47 struct xml_attribute x, y, w, h, cl;
48 char x_val[MAX_VALSTR_LEN];
49 char y_val[MAX_VALSTR_LEN];
50 char w_val[MAX_VALSTR_LEN];
51 char h_val[MAX_VALSTR_LEN];
54 struct svg_text {
55 struct xml_element el;
56 struct xml_attribute x, y, cl;
57 struct xml_attribute fontsize, transform;
58 char x_val[MAX_VALSTR_LEN];
59 char y_val[MAX_VALSTR_LEN];
60 char fontsize_val[MAX_VALSTR_LEN];
61 char transform_val[MAX_VALSTR_LEN * 4];
64 struct svg_line {
65 struct xml_element el;
66 struct xml_attribute x1, y1, x2, y2, cl;
67 struct xml_attribute transform;
68 char x1_val[MAX_VALSTR_LEN], y1_val[MAX_VALSTR_LEN];
69 char x2_val[MAX_VALSTR_LEN], y2_val[MAX_VALSTR_LEN];
70 char transform_val[MAX_VALSTR_LEN * 6];
73 struct svg_document {
74 xml_document_t xml;
75 const char *css;
76 struct xml_element svg;
77 struct xml_attribute svg_attrs[2];
78 struct svg_text text;
81 static char default_css[] =
82 "<![CDATA["
83 "rect.generic { fill: green; stroke: black; stroke-width: 0.01;}"
84 "rect.thread { fill: yellow; stroke: black; stroke-width: 0.01;}"
85 "rect.inactive { fill: grey; stroke: black; stroke-width: 0.01;}"
86 "text.generic { fill: black; stroke: none;}]]>";
88 static
89 int
90 svg_transform_print(svg_transform_t tf, char *buf, size_t len)
92 static double eps = 0.0001;
93 char *p;
94 int c;
96 if (!tf) {
97 assert(len >= 1);
98 buf[0] = '\0';
99 return 0;
101 p = buf;
102 if ((fabs(tf->tx) > eps) && (fabs(tf->ty) > eps)) {
103 c = snprintf(buf, len, "translate(%.20lf,%.20lf)", tf->tx,
104 tf->ty);
105 len -= c;
106 if (len <= 0)
107 return !0;
108 p += c;
110 if ((fabs(tf->sx - 1) > eps) && (fabs(tf->sy - 1) > eps)) {
111 c = snprintf(p, len, "%sscale(%.20lf,%.20lf)",
112 (p == buf) ? "" : " ", tf->sx, tf->sy);
113 len -= c;
114 if (len <= 0)
115 return !0;
116 p += c;
118 if (fabs(tf->rot) > eps) {
119 c = snprintf(p, len, "%srotate(%.2lf)",
120 (p == buf) ? "" : " ", tf->rot);
121 len -= c;
122 if (len <= 0)
123 return !0;
124 p += c;
126 return 0;
129 static
130 void
131 svg_rect_init(struct svg_rect *rect, const char *cl)
133 xml_elem_init(&rect->el, "rect");
134 xml_attribute_init(&rect->x, "x", NULL);
135 xml_elem_set_attribute(&rect->el, &rect->x);
136 xml_attribute_init(&rect->y, "y", NULL);
137 xml_elem_set_attribute(&rect->el, &rect->y);
138 xml_attribute_init(&rect->w, "width", NULL);
139 xml_elem_set_attribute(&rect->el, &rect->w);
140 xml_attribute_init(&rect->h, "height", NULL);
141 xml_elem_set_attribute(&rect->el, &rect->h);
142 if (cl) {
143 xml_attribute_init(&rect->cl, "class", cl);
144 xml_elem_set_attribute(&rect->el, &rect->cl);
149 * In the future, we might want to stick the rectangle in the
150 * <defs> element at this point and then <use> it in the rest
151 * of the document.
153 struct svg_rect *
154 svg_rect_new(const char *cl)
156 struct svg_rect *r;
158 if (!(r = malloc(sizeof(*r))))
159 return r;
160 svg_rect_init(r, cl);
161 return r;
166 svg_rect_draw(svg_document_t doc, struct svg_rect *rect, double x,
167 double y, double w, double h)
169 snprintf(&rect->x_val[0], sizeof(rect->x_val), "%.20lf", x);
170 xml_attribute_set_value(&rect->x, &rect->x_val[0]);
171 snprintf(&rect->y_val[0], sizeof(rect->y_val), "%lf", y);
172 xml_attribute_set_value(&rect->y, &rect->y_val[0]);
173 snprintf(&rect->w_val[0], sizeof(rect->w_val), "%.20lf", w);
174 xml_attribute_set_value(&rect->w, &rect->w_val[0]);
175 snprintf(&rect->h_val[0], sizeof(rect->h_val), "%lf", h);
176 xml_attribute_set_value(&rect->h, &rect->h_val[0]);
178 xml_elem_closed(doc->xml, &rect->el);
179 return 0;
182 static
183 void
184 svg_text_init(struct svg_text *text, const char *cl)
186 xml_elem_init(&text->el, "text");
187 #if remove
188 xml_attribute_init(&text->x, "x", NULL);
189 xml_elem_set_attribute(&text->el, &text->x);
190 xml_attribute_init(&text->y, "y", NULL);
191 xml_elem_set_attribute(&text->el, &text->y);
192 #endif
193 xml_attribute_init(&text->fontsize, "font-size", NULL);
194 xml_elem_set_attribute(&text->el, &text->fontsize);
195 xml_attribute_init(&text->transform, "transform", NULL);
196 xml_elem_set_attribute(&text->el, &text->transform);
198 if (cl) {
199 xml_attribute_init(&text->cl, "class", cl);
200 xml_elem_set_attribute(&text->el, &text->cl);
205 struct svg_text *
206 svg_text_new(const char *cl)
208 svg_text_t text;
210 if (!(text = malloc(sizeof(*text))))
211 return text;
212 svg_text_init(text, cl);
213 return text;
217 svg_text_draw(svg_document_t doc, svg_text_t text, svg_transform_t tf,
218 const char *str, double fontsize)
220 #if remove
221 snprintf(&text->x_val[0], sizeof(text->x_val), "%.20lf", x);
222 xml_attribute_set_value(&text->x, &text->x_val[0]);
223 snprintf(&text->y_val[0], sizeof(text->y_val), "%.20lf", y);
224 xml_attribute_set_value(&text->y, &text->y_val[0]);
225 #endif
226 snprintf(&text->fontsize_val[0], sizeof(text->fontsize_val), "%.20lf",
227 fontsize);
228 xml_attribute_set_value(&text->fontsize, &text->fontsize_val[0]);
229 if (svg_transform_print(tf, &text->transform_val[0],
230 sizeof(text->transform_val)))
231 return !0;
232 xml_attribute_set_value(&text->transform, &text->transform_val[0]);
233 xml_elem_set_value(&text->el, str);
235 xml_elem_closed(doc->xml, &text->el);
236 return 0;
239 static
240 void
241 svg_line_init(struct svg_line *line, const char *cl)
243 xml_elem_init(&line->el, "line");
244 xml_attribute_init(&line->x1, "x1", NULL);
245 xml_elem_set_attribute(&line->el, &line->x1);
246 xml_attribute_init(&line->x2, "x2", NULL);
247 xml_elem_set_attribute(&line->el, &line->x2);
248 xml_attribute_init(&line->y1, "y1", NULL);
249 xml_elem_set_attribute(&line->el, &line->y1);
250 xml_attribute_init(&line->y2, "y2", NULL);
251 xml_elem_set_attribute(&line->el, &line->y2);
253 xml_attribute_init(&line->transform, "transform", NULL);
254 xml_elem_set_attribute(&line->el, &line->transform);
256 if (cl) {
257 xml_attribute_init(&line->cl, "class", cl);
258 xml_elem_set_attribute(&line->el, &line->cl);
263 struct svg_line *
264 svg_line_new(const char *cl)
266 svg_line_t line;
268 if (!(line = malloc(sizeof(*line))))
269 return line;
270 svg_line_init(line, cl);
271 return line;
275 svg_line_draw(svg_document_t doc, svg_line_t line, double x1, double _y1,
276 double x2, double y2, svg_transform_t tf)
278 snprintf(&line->x1_val[0], sizeof(line->x1_val), "%.20lf", x1);
279 xml_attribute_set_value(&line->x1, &line->x1_val[0]);
281 snprintf(&line->x2_val[0], sizeof(line->x2_val), "%.20lf", x2);
282 xml_attribute_set_value(&line->x2, &line->x2_val[0]);
284 snprintf(&line->y1_val[0], sizeof(line->y1_val), "%.10lf", _y1);
285 xml_attribute_set_value(&line->y1, &line->y1_val[0]);
287 snprintf(&line->y2_val[0], sizeof(line->y2_val), "%.20lf", y2);
288 xml_attribute_set_value(&line->y2, &line->y2_val[0]);
290 xml_attribute_set_value(&line->transform, &line->transform_val[0]);
291 if (svg_transform_print(tf,
292 &line->transform_val[0],
293 sizeof(line->transform_val)))
294 return !0;
295 xml_elem_closed(doc->xml, &line->el);
296 return 0;
299 svg_document_t
300 svg_document_create(const char *path)
302 svg_document_t svg;
303 struct xml_element style, defs;
304 struct xml_attribute type;
306 if (!(svg = malloc(sizeof(*svg))))
307 return NULL;
308 if (!(svg->xml = xml_document_create(path))) {
309 free(svg);
310 return NULL;
312 svg->css = &default_css[0];
313 xml_attribute_init(&type, "type", "text/css");
314 xml_elem_init(&defs, "defs");
315 xml_elem_init(&style, "style");
316 xml_elem_set_attribute(&style, &type);
317 xml_elem_init(&svg->svg, "svg");
318 xml_attribute_init(&svg->svg_attrs[0], "version", "1.1");
319 xml_elem_set_attribute(&svg->svg, &svg->svg_attrs[0]);
320 xml_attribute_init(&svg->svg_attrs[1], "xmlns",
321 "http://www.w3.org/2000/svg");
322 xml_elem_set_attribute(&svg->svg, &svg->svg_attrs[1]);
323 xml_elem_begin(svg->xml, &svg->svg);
324 xml_elem_begin(svg->xml, &defs);
325 xml_elem_set_value(&style, svg->css);
326 xml_elem_closed(svg->xml, &style);
327 xml_elem_close(svg->xml, &defs);
329 return svg;
333 svg_document_close(svg_document_t svg)
335 xml_elem_close(svg->xml, &svg->svg);
336 xml_document_close(svg->xml);
337 return 0;