-
Notifications
You must be signed in to change notification settings - Fork 168
/
lstopo-svg.c
158 lines (129 loc) · 5.05 KB
/
lstopo-svg.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
* Copyright © 2019-2021 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include "private/autogen/config.h"
#include "hwloc.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "lstopo.h"
#define SVG_TEXT_WIDTH(length, fontsize) (((length) * (fontsize))/2)
#define SVG_FONTSIZE_SCALE(size) (((size) * 11) / 9)
static void
native_svg_box(struct lstopo_output *loutput, const struct lstopo_color *lcolor, unsigned depth __hwloc_attribute_unused, unsigned x, unsigned width, unsigned y, unsigned height, hwloc_obj_t obj, unsigned box_id)
{
FILE *file = loutput->file;
unsigned cpukind_style = lstopo_obj_cpukind_style(loutput, obj);
unsigned thickness = loutput->thickness;
int r = lcolor->r, g = lcolor->g, b = lcolor->b;
char id[128] = "";
char class[128] = "";
char complement[12] = "";
char dash[32] = "";
if (box_id)
snprintf(complement, sizeof complement, "_%u", box_id);
if (obj) {
char type[64];
hwloc_obj_type_snprintf(type, sizeof(type), obj, 0);
snprintf(id, sizeof id, " id='%s_%u_rect%s'", type, obj->logical_index, complement);
snprintf(class, sizeof class, " class='%s'", type);
} else {
snprintf(id, sizeof id, " id='anon_rect%s'", complement);
}
if (cpukind_style) {
snprintf(dash, sizeof(dash), " stroke-dasharray=\"%u\"", 1U << cpukind_style);
thickness *= cpukind_style;
}
fprintf(file,"\t<rect%s%s x='%u' y='%u' width='%u' height='%u' fill='rgb(%d,%d,%d)' stroke='rgb(0,0,0)' stroke-width='%u'%s/>\n",
id, class, x, y, width, height, r, g, b, thickness, dash);
}
static void
native_svg_line(struct lstopo_output *loutput, const struct lstopo_color *lcolor, unsigned depth __hwloc_attribute_unused, unsigned x1, unsigned y1, unsigned x2, unsigned y2, hwloc_obj_t obj, unsigned line_id)
{
FILE *file = loutput->file;
int r = lcolor->r, g = lcolor->g, b = lcolor->b;
char id[128] = "";
char class[128] = "";
char complement[12] = "";
if (line_id)
snprintf(complement, sizeof complement, "_%u", line_id);
if (obj) {
char type[64];
hwloc_obj_type_snprintf(type, sizeof(type), obj, 0);
snprintf(id, sizeof id, " id='%s_%u_line%s'", type, obj->logical_index, complement);
snprintf(class, sizeof class, " class='%s'", type);
} else {
snprintf(id, sizeof id, " id='anon_line%s'", complement);
}
fprintf(file,"\t<line%s%s x1='%u' y1='%u' x2='%u' y2='%u' stroke='rgb(%d,%d,%d)' stroke-width='%u'/>\n",
id, class, x1, y1, x2, y2, r, g, b, loutput->thickness);
}
static void
native_svg_textsize(struct lstopo_output *loutput __hwloc_attribute_unused, const char *text __hwloc_attribute_unused, unsigned textlength, unsigned fontsize, unsigned *width)
{
fontsize = SVG_FONTSIZE_SCALE(fontsize);
*width = SVG_TEXT_WIDTH(textlength, fontsize);
}
static void
native_svg_text(struct lstopo_output *loutput, const struct lstopo_color *lcolor, int size, unsigned depth __hwloc_attribute_unused, unsigned x, unsigned y, const char *text, hwloc_obj_t obj, unsigned text_id)
{
FILE *file = loutput->file;
unsigned cpukind_style = lstopo_obj_cpukind_style(loutput, obj);
int r = lcolor->r, g = lcolor->g, b = lcolor->b;
char id[128] = "";
char class[128] = "";
char complement[12] = "";
const char *fontweight = "";
if (text_id)
snprintf(complement, sizeof complement, "_%u", text_id);
if (obj) {
char type[64];
hwloc_obj_type_snprintf(type, sizeof(type), obj, 0);
snprintf(id, sizeof id, " id='%s_%u_text%s'", type, obj->logical_index, complement);
snprintf(class, sizeof class, " class='%s'", type);
} else {
snprintf(id, sizeof id, " id='anon_text%s'", complement);
}
if (cpukind_style % 2)
fontweight = " font-weight='bold'";
fprintf(file,"\t<text%s%s font-family='Monospace'%s x='%u' y='%u' fill='rgb(%d,%d,%d)' font-size='%dpx'>%s</text>\n",
id, class,
fontweight,
x, y+size, r, g, b, size, text);
}
static struct draw_methods native_svg_draw_methods = {
NULL,
NULL,
native_svg_box,
native_svg_line,
native_svg_text,
native_svg_textsize,
};
int output_nativesvg(struct lstopo_output * loutput, const char *filename)
{
FILE *output = open_output(filename, loutput->overwrite);
if (!output) {
fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno));
return -1;
}
loutput->file = output;
loutput->methods = &native_svg_draw_methods;
/* recurse once for preparing sizes and positions */
loutput->drawing = LSTOPO_DRAWING_PREPARE;
output_draw(loutput);
loutput->drawing = LSTOPO_DRAWING_DRAW;
fprintf(output, "<?xml version='1.0' encoding='UTF-8'?>\n");
fprintf(output, "<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='%upx' height='%upx' viewBox='0 0 %upx %upx' version='1.1'>\n",
loutput->width, loutput->height, loutput->width, loutput->height);
/* ready */
declare_colors(loutput);
lstopo_prepare_custom_styles(loutput);
output_draw(loutput);
fprintf(output,"</svg>\n");
if (output != stdout)
fclose(output);
destroy_colors(loutput);
return 0;
}