44 static char *sdasharray =
"5,2";
46 static char *sdotarray =
"1,5";
48 #ifndef HAVE_STRCASECMP
52 static void svg_bzptarray(
GVJ_t * job,
pointf * A,
int n)
59 if (A[0].x <= A[n-1].x) {
61 for (i = 0; i < n; i++) {
73 for (i = n-1; i >= 0; i--) {
87 static void svg_print_id_class(
GVJ_t * job,
char*
id,
char* idx,
char* kind,
void* obj)
95 gvprintf(job,
"\" class=\"%s", kind);
96 if ((str =
agget(obj,
"class")) && *str) {
105 switch (color.
type) {
110 if (color.
u.
rgba[3] == 0)
111 gvputs(job,
"transparent");
121 static void svg_grstyle(
GVJ_t * job,
int filled,
int gid)
135 gvprintf(job,
"\" fill-opacity=\"%f",
140 gvputs(job,
"\" stroke=\"");
141 svg_print_color(job, obj->
pencolor);
143 gvputs(job,
"\" stroke-width=\"");
147 gvprintf(job,
"\" stroke-dasharray=\"%s", sdasharray);
149 gvprintf(job,
"\" stroke-dasharray=\"%s", sdotarray);
153 gvprintf(job,
"\" stroke-opacity=\"%f",
159 static void svg_comment(
GVJ_t * job,
char *str)
166 static void svg_begin_job(
GVJ_t * job)
170 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
171 if ((s =
agget(job->
gvc->
g,
"stylesheet")) && s[0]) {
172 gvputs(job,
"<?xml-stylesheet href=\"");
174 gvputs(job,
"\" type=\"text/css\"?>\n");
177 gvputs(job,
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n");
179 " \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"");
182 " [\n <!ATTLIST svg xmlns:xlink CDATA #FIXED \"http://www.w3.org/1999/xlink\">\n]");
184 gvputs(job,
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
186 " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
189 gvputs(job,
"<!-- Generated by ");
199 static void svg_begin_graph(
GVJ_t * job)
211 gvprintf(job,
"<svg width=\"%dpt\" height=\"%dpt\"\n",
213 gvprintf(job,
" viewBox=\"%.2f %.2f %.2f %.2f\"",
219 gvputs(job,
" xmlns=\"http://www.w3.org/2000/svg\"");
221 gvputs(job,
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"");
225 static void svg_end_graph(
GVJ_t * job)
230 static void svg_begin_layer(
GVJ_t * job,
char *layername,
int layerNum,
235 svg_print_id_class(job, layername,
NULL,
"layer", obj->
u.
g);
239 static void svg_end_layer(
GVJ_t * job)
248 static void svg_begin_page(
GVJ_t * job)
254 svg_print_id_class(job, obj->
id,
NULL,
"graph", obj->
u.
g);
255 gvputs(job,
" transform=\"scale(");
268 gvputs(job,
"</title>\n");
272 static void svg_end_page(
GVJ_t * job)
277 static void svg_begin_cluster(
GVJ_t * job)
281 svg_print_id_class(job, obj->
id,
NULL,
"cluster", obj->
u.
sg);
285 gvputs(job,
"</title>\n");
288 static void svg_end_cluster(
GVJ_t * job)
293 static void svg_begin_node(
GVJ_t * job)
302 svg_print_id_class(job, obj->
id, idx,
"node", obj->
u.
n);
306 gvputs(job,
"</title>\n");
309 static void svg_end_node(
GVJ_t * job)
314 static void svg_begin_edge(
GVJ_t * job)
319 svg_print_id_class(job, obj->
id,
NULL,
"edge", obj->
u.
e);
326 gvputs(job,
"</title>\n");
329 static void svg_end_edge(
GVJ_t * job)
335 svg_begin_anchor(
GVJ_t * job,
char *href,
char *tooltip,
char *target,
349 gvputs(job,
" xlink:type=\"simple\"");
351 if (href && href[0]) {
352 gvputs(job,
" xlink:href=\"");
362 gvputs(job,
" xlink:href=\"#");
367 if (tooltip && tooltip[0]) {
368 gvputs(job,
" xlink:title=\"");
372 if (target && target[0]) {
373 gvputs(job,
" target=\"");
380 static void svg_end_anchor(
GVJ_t * job)
394 switch (span->
just) {
396 gvputs(job,
" text-anchor=\"start\"");
399 gvputs(job,
" text-anchor=\"end\"");
403 gvputs(job,
" text-anchor=\"middle\"");
436 gvprintf(job,
" font-family=\"%s", family);
441 gvprintf(job,
" font-weight=\"%s\"", weight);
443 gvprintf(job,
" font-stretch=\"%s\"", stretch);
445 gvprintf(job,
" font-style=\"%s\"", style);
449 if ((flags &
HTML_BF) && !weight)
450 gvprintf(job,
" font-weight=\"bold\"");
451 if ((flags &
HTML_IF) && !style)
452 gvprintf(job,
" font-style=\"italic\"");
455 gvprintf(job,
" text-decoration=\"");
461 gvprintf(job,
"%soverline", (comma?
",":
""));
465 gvprintf(job,
"%sline-through", (comma?
",":
""));
469 gvprintf(job,
" baseline-shift=\"super\"");
471 gvprintf(job,
" baseline-shift=\"sub\"");
481 gvprintf(job,
" fill=\"#%02x%02x%02x\"",
493 gvputs(job,
"<tspan x=\"0\" dy=\"");
499 gvprintf (job,
"</tspan></textPath>");
506 static int svg_gradstyle(
GVJ_t * job,
pointf * A,
int n)
515 G[0].
x = G[0].
y = G[1].
x = G[1].
y = 0.;
519 "<defs>\n<linearGradient id=\"l_%d\" gradientUnits=\"userSpaceOnUse\" ",
id);
532 gvputs(job,
"<stop offset=\"0\" style=\"stop-color:");
534 gvputs(job,
";stop-opacity:");
544 gvputs(job,
"<stop offset=\"1\" style=\"stop-color:");
546 gvputs(job,
";stop-opacity:");
552 gvputs(job,
";\"/>\n</linearGradient>\n</defs>\n");
559 static int svg_rgradstyle(
GVJ_t * job,
pointf * A,
int n)
574 ifx = 50 * (1 + cos(angle));
575 ify = 50 * (1 - sin(angle));
578 "<defs>\n<radialGradient id=\"r_%d\" cx=\"50%%\" cy=\"50%%\" r=\"75%%\" fx=\"%d%%\" fy=\"%d%%\">\n",
580 gvputs(job,
"<stop offset=\"0\" style=\"stop-color:");
582 gvputs(job,
";stop-opacity:");
589 gvputs(job,
"<stop offset=\"1\" style=\"stop-color:");
591 gvputs(job,
";stop-opacity:");
597 gvputs(job,
";\"/>\n</radialGradient>\n</defs>\n");
602 static void svg_ellipse(
GVJ_t * job,
pointf * A,
int filled)
608 gid = svg_gradstyle(job, A, 2);
610 gid = svg_rgradstyle(job, A, 2);
613 svg_grstyle(job, filled, gid);
626 svg_bezier(
GVJ_t * job,
pointf * A,
int n,
int arrow_at_start,
627 int arrow_at_end,
int filled)
633 gid = svg_gradstyle(job, A, n);
635 gid = svg_rgradstyle(job, A, n);
643 svg_grstyle(job, filled, gid);
645 svg_bzptarray(job, A, n);
649 static void svg_polygon(
GVJ_t * job,
pointf * A,
int n,
int filled)
653 gid = svg_gradstyle(job, A, n);
655 gid = svg_rgradstyle(job, A, n);
658 svg_grstyle(job, filled, gid);
659 gvputs(job,
" points=\"");
660 for (i = 0; i < n; i++) {
673 static void svg_polyline(
GVJ_t * job,
pointf * A,
int n)
678 svg_grstyle(job, 0, 0);
679 gvputs(job,
" points=\"");
680 for (i = 0; i < n; i++) {
691 static char *svg_knowncolors[] = {
692 "aliceblue",
"antiquewhite",
"aqua",
"aquamarine",
"azure",
693 "beige",
"bisque",
"black",
"blanchedalmond",
"blue",
694 "blueviolet",
"brown",
"burlywood",
695 "cadetblue",
"chartreuse",
"chocolate",
"coral",
696 "cornflowerblue",
"cornsilk",
"crimson",
"cyan",
697 "darkblue",
"darkcyan",
"darkgoldenrod",
"darkgray",
698 "darkgreen",
"darkgrey",
"darkkhaki",
"darkmagenta",
699 "darkolivegreen",
"darkorange",
"darkorchid",
"darkred",
700 "darksalmon",
"darkseagreen",
"darkslateblue",
"darkslategray",
701 "darkslategrey",
"darkturquoise",
"darkviolet",
"deeppink",
702 "deepskyblue",
"dimgray",
"dimgrey",
"dodgerblue",
703 "firebrick",
"floralwhite",
"forestgreen",
"fuchsia",
704 "gainsboro",
"ghostwhite",
"gold",
"goldenrod",
"gray",
705 "green",
"greenyellow",
"grey",
706 "honeydew",
"hotpink",
"indianred",
707 "indigo",
"ivory",
"khaki",
708 "lavender",
"lavenderblush",
"lawngreen",
"lemonchiffon",
709 "lightblue",
"lightcoral",
"lightcyan",
"lightgoldenrodyellow",
710 "lightgray",
"lightgreen",
"lightgrey",
"lightpink",
711 "lightsalmon",
"lightseagreen",
"lightskyblue",
712 "lightslategray",
"lightslategrey",
"lightsteelblue",
713 "lightyellow",
"lime",
"limegreen",
"linen",
714 "magenta",
"maroon",
"mediumaquamarine",
"mediumblue",
715 "mediumorchid",
"mediumpurple",
"mediumseagreen",
716 "mediumslateblue",
"mediumspringgreen",
"mediumturquoise",
717 "mediumvioletred",
"midnightblue",
"mintcream",
718 "mistyrose",
"moccasin",
719 "navajowhite",
"navy",
"oldlace",
720 "olive",
"olivedrab",
"orange",
"orangered",
"orchid",
721 "palegoldenrod",
"palegreen",
"paleturquoise",
722 "palevioletred",
"papayawhip",
"peachpuff",
"peru",
"pink",
723 "plum",
"powderblue",
"purple",
724 "red",
"rosybrown",
"royalblue",
725 "saddlebrown",
"salmon",
"sandybrown",
"seagreen",
"seashell",
726 "sienna",
"silver",
"skyblue",
"slateblue",
"slategray",
727 "slategrey",
"snow",
"springgreen",
"steelblue",
728 "tan",
"teal",
"thistle",
"tomato",
"turquoise",
730 "wheat",
"white",
"whitesmoke",
731 "yellow",
"yellowgreen"
771 sizeof(svg_knowncolors) /
sizeof(
char *),
void s1(graph_t *, node_t *)
#define GVDEVICE_BINARY_FORMAT
char * xml_url_string(char *s)
char * strdup_and_subst_obj(char *str, void *obj)
#define GVRENDER_DOES_TRANSFORM
char * agget(void *obj, char *name)
#define GVRENDER_Y_GOES_DOWN
int gvputs(GVJ_t *job, const char *s)
#define GVRENDER_DOES_TARGETS
#define GVRENDER_DOES_TOOLTIPS
#define GVDEVICE_DOES_LAYERS
char * xml_string(char *s)
CGRAPH_API char * agnameof(void *)
double yoffset_centerline
PostscriptAlias * postscript_alias
gvplugin_installed_t gvdevice_svg_types[]
void gvprintdouble(GVJ_t *job, double num)
#define GVRENDER_DOES_MAPS
int strcasecmp(const char *s1, const char *s2)
#define GVDEVICE_COMPRESSED_FORMAT
#define GVRENDER_DOES_LABELS
gvrender_engine_t svg_engine
gvplugin_installed_t gvrender_svg_types[]
gvdevice_features_t device_features_svg
#define GVDEVICE_DOES_TRUECOLOR
gvrender_features_t render_features_svg
void gvprintf(GVJ_t *job, const char *format,...)
gvdevice_features_t device_features_svgz
char * xml_string0(char *s, boolean raw)
void get_gradient_points(pointf *A, pointf *G, int n, float angle, int flags)