#include "gvplugin_render.h"
#include "gvplugin_device.h"
#include "gvio.h"
+#include "memory.h"
typedef enum { FORMAT_VML, FORMAT_VMLZ, } format_type;
-extern char *xml_string(char *str);
-
-char graphcoords[256];
-
-#if defined(WIN32) && !defined(__MINGW32_VERSION) /* MinGW already defines snprintf */
-static int
-snprintf (char *str, int n, char *fmt, ...)
+unsigned int graphHeight,graphWidth;
+/* this is a direct copy fromlib/common/labels.c */
+static int xml_isentity(char *s)
{
-int ret;
-va_list a;
-va_start (a, fmt);
-ret = _vsnprintf (str, n, fmt, a);
-va_end (a);
-return ret;
+ s++; /* already known to be '&' */
+ if (*s == '#') {
+ s++;
+ if (*s == 'x' || *s == 'X') {
+ s++;
+ while ((*s >= '0' && *s <= '9')
+ || (*s >= 'a' && *s <= 'f')
+ || (*s >= 'A' && *s <= 'F'))
+ s++;
+ } else {
+ while (*s >= '0' && *s <= '9')
+ s++;
+ }
+ } else {
+ while ((*s >= 'a' && *s <= 'z')
+ || (*s >= 'A' && *s <= 'Z'))
+ s++;
+ }
+ if (*s == ';')
+ return 1;
+ return 0;
}
-#endif
static void vml_bzptarray(GVJ_t * job, pointf * A, int n)
{
c = "m "; /* first point */
for (i = 0; i < n; i++) {
- gvprintf(job, "%s%.0f,%.0f ", c, A[i].x, -A[i].y);
+ /* integers only in path! */
+ gvprintf(job, "%s%.0f,%.0f ", c, A[i].x, graphHeight-A[i].y);
if (i == 0)
c = "c "; /* second point */
else
c = ""; /* remaining points */
}
+ gvputs(job, "\"");
}
static void vml_print_color(GVJ_t * job, gvcolor_t color)
{
obj_state_t *obj = job->obj;
- gvputs(job, "<v:stroke fillcolor=\"");
- if (filled)
- vml_print_color(job, obj->fillcolor);
- else
- gvputs(job, "none");
- gvputs(job, "\" strokecolor=\"");
+ gvputs(job, "<v:stroke color=\"");
vml_print_color(job, obj->pencolor);
if (obj->penwidth != PENWIDTH_NORMAL)
- gvprintf(job, "\" stroke-weight=\"%g", obj->penwidth);
+ gvprintf(job, "\" weight=\"%.0fpt", obj->penwidth);
if (obj->pen == PEN_DASHED) {
gvputs(job, "\" dashstyle=\"dash");
} else if (obj->pen == PEN_DOTTED) {
gvputs(job, "\" />");
}
-static void vml_grstrokeattr(GVJ_t * job)
-{
- obj_state_t *obj = job->obj;
-
- gvputs(job, " strokecolor=\"");
- vml_print_color(job, obj->pencolor);
- if (obj->penwidth != PENWIDTH_NORMAL)
- gvprintf(job, "\" stroke-weight=\"%g", obj->penwidth);
- if (obj->pen == PEN_DASHED) {
- gvputs(job, "\" dashstyle=\"dash");
- } else if (obj->pen == PEN_DOTTED) {
- gvputs(job, "\" dashstyle=\"dot");
- }
- gvputs(job, "\"");
-}
static void vml_grfill(GVJ_t * job, int filled)
{
obj_state_t *obj = job->obj;
- gvputs(job, "<v:fill color=\"");
- if (filled)
+ if (filled){
+ gvputs(job, " filled=\"true\" fillcolor=\"");
vml_print_color(job, obj->fillcolor);
- else
- gvputs(job, "none");
- gvputs(job, "\" />");
+ gvputs(job, "\" ");
+ }else{
+ gvputs(job, " filled=\"false\" ");
+ }
}
+/* html_string is a modified version of xml_string */
+char *html_string(char *s)
+{
+ static char *buf = NULL;
+ static int bufsize = 0;
+ char *p, *sub, *prev = NULL;
+ int len, pos = 0;
+ int temp,cnt,remaining=0;
+ char workstr[16];
+ long unsigned int charnum=0;
+ unsigned char byte;
+ unsigned char mask;
+
+
+ if (!buf) {
+ bufsize = 64;
+ buf = gmalloc(bufsize);
+ }
+ p = buf;
+ while (s && *s) {
+ if (pos > (bufsize - 8)) {
+ bufsize *= 2;
+ buf = grealloc(buf, bufsize);
+ p = buf + pos;
+ }
+ /* escape '&' only if not part of a legal entity sequence */
+ if (*s == '&' && !(xml_isentity(s))) {
+ sub = "&";
+ len = 5;
+ }
+ /* '<' '>' are safe to substitute even if string is already UTF-8 coded
+ * since UTF-8 strings won't contain '<' or '>' */
+ else if (*s == '<') {
+ sub = "<";
+ len = 4;
+ }
+ else if (*s == '>') {
+ sub = ">";
+ len = 4;
+ }
+ else if (*s == '-') { /* can't be used in xml comment strings */
+ sub = "-";
+ len = 5;
+ }
+ else if (*s == ' ' && prev && *prev == ' ') {
+ /* substitute 2nd and subsequent spaces with required_spaces */
+ sub = " "; /* inkscape doesn't recognise */
+ len = 6;
+ }
+ else if (*s == '"') {
+ sub = """;
+ len = 6;
+ }
+ else if (*s == '\'') {
+ sub = "'";
+ len = 5;
+ }
+ else if ((unsigned char)*s > 127) {
+ byte=(unsigned char)*s;
+ cnt=0;
+ for (mask=127; mask < byte; mask=mask >>1){
+ cnt++;
+ byte=byte & mask;
+ }
+ if (cnt>1){
+ charnum=byte;
+ remaining=cnt-1;
+ }else{
+ charnum=charnum<<6;
+ charnum+=byte;
+ remaining--;
+ }
+ if (remaining>0){
+ s++;
+ continue;
+ }
+ /* we will build the html value right-to-left
+ * (least significant-to-most) */
+ workstr[15]=';';
+ sub=&workstr[14];
+ len=3; /* &# + ; */
+ do {
+ temp=charnum%10;
+ *(sub--)=(char)((int)'0'+ temp);
+ charnum/=10;
+ len++;
+ if (len>12){ /* 12 is arbitrary, but clearly in error */
+ fprintf(stderr, "Error during conversion to \"UTF-8\". Quiting.\n");
+ exit(1);
+ }
+ } while (charnum>0);
+ *(sub--)='#';
+ *(sub)='&';
+ }
+ else {
+ sub = s;
+ len = 1;
+ }
+ while (len--) {
+ *p++ = *sub++;
+ pos++;
+ }
+ prev = s;
+ s++;
+ }
+ *p = '\0';
+ return buf;
+}
static void vml_comment(GVJ_t * job, char *str)
{
gvputs(job, " <!-- ");
- gvputs(job, xml_string(str));
+ gvputs(job, html_string(str));
gvputs(job, " -->\n");
}
-
static void vml_begin_job(GVJ_t * job)
{
- gvputs(job, "<?xml version=\"1.1\" encoding=\"UTF-8\" ?>\n");
-
- gvputs(job, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ");
- gvputs(job, "\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n");
- gvputs(job, "<html xml:lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\" ");
- gvputs(job, "xmlns:v=\"urn:schemas-microsoft-com:vml\"");
- gvputs(job, ">");
-
+ gvputs(job, "<HTML>\n");
gvputs(job, "\n<!-- Generated by ");
- gvputs(job, xml_string(job->common->info[0]));
+ gvputs(job, html_string(job->common->info[0]));
gvputs(job, " version ");
- gvputs(job, xml_string(job->common->info[1]));
+ gvputs(job, html_string(job->common->info[1]));
gvputs(job, " (");
- gvputs(job, xml_string(job->common->info[2]));
- gvputs(job, ")\n");
- gvputs(job, " -->\n");
+ gvputs(job, html_string(job->common->info[2]));
+ gvputs(job, ")\n-->\n");
}
static void vml_begin_graph(GVJ_t * job)
{
obj_state_t *obj = job->obj;
- gvputs(job, "<head>");
- if (agnameof(obj->u.g)[0]) {
- gvputs(job, "<title>");
- gvputs(job, xml_string(agnameof(obj->u.g)));
- gvputs(job, "</title>");
- }
- gvprintf(job, "<!-- Pages: %d -->\n</head>\n", job->pagesArraySize.x * job->pagesArraySize.y);
-
- snprintf(graphcoords, sizeof(graphcoords), "style=\"width: %.0fpt; height: %.0fpt\" coordsize=\"%.0f,%.0f\" coordorigin=\"-4,-%.0f\"",
- job->width*.75, job->height*.75,
- job->width*.75, job->height*.75,
- job->height*.75 - 4);
-
- gvprintf(job, "<body>\n<div class=\"graph\" %s>\n", graphcoords);
- gvputs(job, "<style type=\"text/css\">\nv\\:* {\nbehavior: url(#default#VML);display:inline-block;position: absolute; left: 0px; top: 0px;\n}\n</style>\n");
-/* graphcoords[0] = '\0'; */
+ graphHeight =(int)(job->bb.UR.y - job->bb.LL.y);
+ graphWidth =(int)(job->bb.UR.x - job->bb.LL.x);
+ gvputs(job, "<HEAD>");
+ gvputs(job, "<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
+
+ if (obj->u.g->name[0]) {
+ gvputs(job, "<TITLE>");
+ gvputs(job, html_string(obj->u.g->name));
+ gvputs(job, "</TITLE>");
+ }
+ gvprintf(job, "<!-- Pages: %d -->\n", job->pagesArraySize.x * job->pagesArraySize.y);
+
+/* the next chunk and all the "DIV" stuff is not required,
+ * but it helps with non-IE browsers */
+ gvputs(job, " <SCRIPT LANGUAGE='Javascript'>\n");
+ gvputs(job, " function browsercheck()\n");
+ gvputs(job, " {\n");
+ gvputs(job, " var ua = window.navigator.userAgent\n");
+ gvputs(job, " var msie = ua.indexOf ( 'MSIE ' )\n");
+ gvputs(job, " var ievers;\n");
+ gvputs(job, " var item;\n");
+ gvputs(job, " var VMLyes=new Array('_VML1_','_VML2_');\n");
+ gvputs(job, " var VMLno=new Array('_notVML1_','_notVML2_');\n");
+ gvputs(job, " if ( msie > 0 ){ // If Internet Explorer, return version number\n");
+ gvputs(job, " ievers= parseInt (ua.substring (msie+5, ua.indexOf ('.', msie )))\n");
+ gvputs(job, " }\n");
+ gvputs(job, " if (ievers>=5){\n");
+ gvputs(job, " for (x in VMLyes){\n");
+ gvputs(job, " item = document.getElementById(VMLyes[x]);\n");
+ gvputs(job, " if (item) {\n");
+ gvputs(job, " item.style.visibility='visible';\n");
+ gvputs(job, " }\n");
+ gvputs(job, " }\n");
+ gvputs(job, " for (x in VMLno){\n");
+ gvputs(job, " item = document.getElementById(VMLno[x]);\n");
+ gvputs(job, " if (item) {\n");
+ gvputs(job, " item.style.visibility='hidden';\n");
+ gvputs(job, " }\n");
+ gvputs(job, " }\n");
+ gvputs(job, " }else{\n");
+ gvputs(job, " for (x in VMLyes){\n");
+ gvputs(job, " item = document.getElementById(VMLyes[x]);\n");
+ gvputs(job, " if (item) {\n");
+ gvputs(job, " item.style.visibility='hidden';\n");
+ gvputs(job, " }\n");
+ gvputs(job, " }\n");
+ gvputs(job, " for (x in VMLno){\n");
+ gvputs(job, " item = document.getElementById(VMLno[x]);\n");
+ gvputs(job, " if (item) {\n");
+ gvputs(job, " item.style.visibility='visible';\n");
+ gvputs(job, " }\n");
+ gvputs(job, " }\n");
+ gvputs(job, " }\n");
+ gvputs(job, " }\n");
+ gvputs(job, " </SCRIPT>\n");
+
+ gvputs(job, "</HEAD>");
+ gvputs(job, "<BODY onload='browsercheck();'>\n");
+ /* add 10pt pad to the bottom of the graph */
+ gvputs(job, "<DIV id='_VML1_' style=\"position:relative; display:inline; visibility:hidden");
+ gvprintf(job, " width: %dpt; height: %dpt\">\n", graphWidth, 10+graphHeight);
+ gvputs(job, "<STYLE>\n");
+ gvputs(job, "v\\:* { behavior: url(#default#VML);display:inline-block}\n");
+ gvputs(job, "</STYLE>\n");
+ gvputs(job, "<xml:namespace ns=\"urn:schemas-microsoft-com:vml\" prefix=\"v\" />\n");
+
+ gvputs(job, " <v:group style=\"position:relative; ");
+ gvprintf(job, " width: %dpt; height: %dpt\"", graphWidth, graphHeight);
+ gvprintf(job, " coordorigin=\"0,0\" coordsize=\"%d,%d\" >", graphWidth, graphHeight);
}
static void vml_end_graph(GVJ_t * job)
{
- gvputs(job, "</div>\n</body>\n");
+ gvputs(job, "</v:group>\n");
+ gvputs(job, "</DIV>\n");
+ /* add 10pt pad to the bottom of the graph */
+ gvputs(job, "<DIV id='_VML2_' style=\"position:relative;visibility:hidden\">\n");
+ gvputs(job, "<!-- insert any other html content here -->\n");
+ gvputs(job, "</DIV>\n");
+ gvputs(job, "<DIV id='_notVML1_' style=\"position:relative;\">\n");
+ gvputs(job, "<!-- this should only display on NON-IE browsers -->\n");
+ gvputs(job, "<H2>Sorry, this diagram will only display correctly on Internet Explorer 5 (and up) browsers.</H2>\n");
+ gvputs(job, "</DIV>\n");
+ gvputs(job, "<DIV id='_notVML2_' style=\"position:relative;\">\n");
+ gvputs(job, "<!-- insert any other NON-IE html content here -->\n");
+ gvputs(job, "</DIV>\n");
+
+ gvputs(job, "</BODY>\n</HTML>");
}
static void
vml_begin_anchor(GVJ_t * job, char *href, char *tooltip, char *target, char *id)
{
- gvputs(job, " <a");
+ gvputs(job, "<a");
if (href && href[0])
- gvprintf(job, " href=\"%s\"", xml_string(href));
+ gvprintf(job, " href=\"%s\"", html_string(href));
if (tooltip && tooltip[0])
- gvprintf(job, " title=\"%s\"", xml_string(tooltip));
+ gvprintf(job, " title=\"%s\"", html_string(tooltip));
if (target && target[0])
- gvprintf(job, " target=\"%s\"", xml_string(target));
+ gvprintf(job, " target=\"%s\"", html_string(target));
gvputs(job, ">\n");
}
static void vml_end_anchor(GVJ_t * job)
{
- gvputs(job, " </a>\n");
+ gvputs(job, "</a>\n");
}
static void vml_textpara(GVJ_t * job, pointf p, textpara_t * para)
{
+ pointf p1,p2;
obj_state_t *obj = job->obj;
- gvputs(job, " <div");
switch (para->just) {
case 'l':
- gvputs(job, " style=\"text-align: left; ");
+ p1.x=p.x;
break;
case 'r':
- gvputs(job, " style=\"text-align: right; ");
+ p1.x=p.x-para->width;
break;
default:
case 'n':
- gvputs(job, " style=\"text-align: center; ");
+ p1.x=p.x-(para->width/2);
break;
}
- gvprintf(job, "position: absolute; left: %gpx; top: %gpx;", p.x/.75, job->height - p.y/.75 - 14);
+ p2.x=p1.x+para->width;
+ if (para->height < para->fontsize){
+ para->height = 1 + (1.1*para->fontsize);
+ }
+
+ p1.x-=8; /* vml textbox margin fudge factor */
+ p2.x+=8; /* vml textbox margin fudge factor */
+ p2.y=graphHeight-(p.y);
+ p1.y=(p2.y-para->height);
+ /* text "y" was too high
+ * Graphviz uses "baseline", VML seems to use bottom of descenders - so we fudge a little
+ * (heuristics - based on eyeballs) */
+ if (para->fontsize <12.){ /* see graphs/directed/arrows.dot */
+ p1.y+=1.4+para->fontsize/5; /* adjust by approx. descender */
+ p2.y+=1.4+para->fontsize/5; /* adjust by approx. descender */
+ }else{
+ p1.y+=2+para->fontsize/5; /* adjust by approx. descender */
+ p2.y+=2+para->fontsize/5; /* adjust by approx. descender */
+ }
+
+ gvprintf(job, "<v:rect style=\"position:absolute; ");
+ gvprintf(job, " left: %.2f; top: %.2f;", p1.x, p1.y);
+ gvprintf(job, " width: %.2f; height: %.2f\"", p2.x-p1.x, p2.y-p1.y);
+ gvputs(job, " stroked=\"false\" filled=\"false\">\n");
+ gvputs(job, "<v:textbox inset=\"0,0,0,0\" style=\"position:absolute; v-text-wrapping:'false';padding:'0';");
+
if (para->postscript_alias) {
- gvprintf(job, " font-family: '%s';", para->postscript_alias->family);
+ gvprintf(job, "font-family: '%s';", para->postscript_alias->family);
if (para->postscript_alias->weight)
- gvprintf(job, " font-weight: %s;", para->postscript_alias->weight);
+ gvprintf(job, "font-weight: %s;", para->postscript_alias->weight);
if (para->postscript_alias->stretch)
- gvprintf(job, " font-stretch: %s;", para->postscript_alias->stretch);
+ gvprintf(job, "font-stretch: %s;", para->postscript_alias->stretch);
if (para->postscript_alias->style)
- gvprintf(job, " font-style: %s;", para->postscript_alias->style);
+ gvprintf(job, "font-style: %s;", para->postscript_alias->style);
}
else {
- gvprintf(job, " font-family: \'%s\';", para->fontname);
+ gvprintf(job, "font-family: \'%s\';", para->fontname);
}
- /* FIXME - even inkscape requires a magic correction to fontsize. Why? */
- gvprintf(job, " font-size: %.2fpt;", para->fontsize * 0.81);
+ gvprintf(job, " font-size: %.2fpt;", para->fontsize);
switch (obj->pencolor.type) {
case COLOR_STRING:
if (strcasecmp(obj->pencolor.u.string, "black"))
default:
assert(0); /* internal error */
}
- gvputs(job, "\">");
- gvputs(job, xml_string(para->str));
- gvputs(job, "</div>\n");
+ gvputs(job, "\"><center>");
+ gvputs(job, html_string(para->str));
+ gvputs(job, "</center></v:textbox>\n");
+ gvputs(job, "</v:rect>\n");
}
static void vml_ellipse(GVJ_t * job, pointf * A, int filled)
-{
+{
+ double dx, dy, left, right, top, bottom;
+
/* A[] contains 2 points: the center and corner. */
-
- gvputs(job, " <v:oval");
+ gvputs(job, " <v:oval style=\"position:absolute;");
- vml_grstrokeattr(job);
+ dx=A[1].x-A[0].x;
+ dy=A[1].y-A[0].y;
- gvputs(job, " style=\"position: absolute;");
+ top=graphHeight-(A[0].y+dy);
+ bottom=top+dy+dy;
+ left=A[0].x - dx;
+ right=A[1].x;
+ gvprintf(job, " left: %.2f; top: %.2f;",left, top);
+ gvprintf(job, " width: %.2f; height: %.2f\"", 2*dx, 2*dy);
- gvprintf(job, " left: %gpt; top: %gpt;", 2*A[0].x - A[1].x+4, job->height*.75 - A[1].y-4);
- gvprintf(job, " width: %gpt; height: %gpt;", 2*(A[1].x - A[0].x), 2*(A[1].y - A[0].y));
- gvputs(job, "\">");
- vml_grstroke(job, filled);
vml_grfill(job, filled);
+ gvputs(job, " >");
+ vml_grstroke(job, filled);
gvputs(job, "</v:oval>\n");
}
vml_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
int arrow_at_end, int filled)
{
- gvprintf(job, " <v:shape %s><!-- bezier --><v:path", graphcoords);
- gvputs(job, " v=\"");
- vml_bzptarray(job, A, n);
- gvputs(job, "\" />");
- vml_grstroke(job, filled);
- gvputs(job, "</v:path>");
+ gvputs(job, " <v:shape style=\"position:absolute; ");
+ gvprintf(job, " width: %d; height: %d\"", graphWidth, graphHeight);
+
vml_grfill(job, filled);
- gvputs(job, "</v:shape>\n");
+ gvputs(job, " >");
+ vml_grstroke(job, filled);
+ gvputs(job, "<v:path v=\"");
+ vml_bzptarray(job, A, n);
+ gvputs(job, "/></v:shape>\n");
}
static void vml_polygon(GVJ_t * job, pointf * A, int n, int filled)
{
int i;
+ double px,py;
- gvputs(job, " <v:shape");
- vml_grstrokeattr(job);
- gvprintf(job, " %s><!-- polygon --><v:path", graphcoords);
- gvputs(job, " v=\"");
+ gvputs(job, " <v:shape style=\"position:absolute; ");
+ gvprintf(job, " width: %d; height: %d\"", graphWidth, graphHeight);
+ vml_grfill(job, filled);
+ gvputs(job, " >");
+ vml_grstroke(job, filled);
+
+ gvputs(job, "<v:path v=\"");
for (i = 0; i < n; i++)
{
- if (i==0) gvputs(job, "m ");
- gvprintf(job, "%.0f,%.0f ", A[i].x, -A[i].y);
+ px=A[i].x;
+ py= (graphHeight-A[i].y);
+ if (i==0){
+ gvputs(job, "m ");
+ }
+ /* integers only in path */
+ gvprintf(job, "%.0f %.0f ", px, py);
if (i==0) gvputs(job, "l ");
- if (i==n-1) gvputs(job, "x e ");
+ if (i==n-1) gvputs(job, "x e \"/>");
}
- gvputs(job, "\">");
- vml_grstroke(job, filled);
- gvputs(job, "</v:path>");
- vml_grfill(job, filled);
gvputs(job, "</v:shape>\n");
}
{
int i;
- gvprintf(job, " <v:shape %s><!-- polyline --><v:path", graphcoords);
- gvputs(job, " v=\"");
+ gvputs(job, " <v:shape style=\"position:absolute; ");
+ gvprintf(job, " width: %d; height: %d\" filled=\"false\">", graphWidth, graphHeight);
+ gvputs(job, "<v:path v=\"");
for (i = 0; i < n; i++)
{
if (i==0) gvputs(job, " m ");
- gvprintf(job, "%.0f,%.0f ", A[i].x, -A[i].y);
+ gvprintf(job, "%.0f,%.0f ", A[i].x, graphHeight-A[i].y);
if (i==0) gvputs(job, " l ");
if (i==n-1) gvputs(job, " e "); /* no x here for polyline */
}
- gvputs(job, "\">");
+ gvputs(job, "\"/>");
vml_grstroke(job, 0); /* no fill here for polyline */
- gvputs(job, "</v:path>");
gvputs(job, "</v:shape>\n");
-
}
-/* color names from http://www.w3.org/TR/VML/types.html */
+/* color names from
+ http://msdn.microsoft.com/en-us/library/bb250525(VS.85).aspx#t.color
+*/
/* NB. List must be LANG_C sorted */
static char *vml_knowncolors[] = {
- "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure",
- "beige", "bisque", "black", "blanchedalmond", "blue",
- "blueviolet", "brown", "burlywood",
- "cadetblue", "chartreuse", "chocolate", "coral",
- "cornflowerblue", "cornsilk", "crimson", "cyan",
- "darkblue", "darkcyan", "darkgoldenrod", "darkgray",
- "darkgreen", "darkgrey", "darkkhaki", "darkmagenta",
- "darkolivegreen", "darkorange", "darkorchid", "darkred",
- "darksalmon", "darkseagreen", "darkslateblue", "darkslategray",
- "darkslategrey", "darkturquoise", "darkviolet", "deeppink",
- "deepskyblue", "dimgray", "dimgrey", "dodgerblue",
- "firebrick", "floralwhite", "forestgreen", "fuchsia",
- "gainsboro", "ghostwhite", "gold", "goldenrod", "gray",
- "green", "greenyellow", "grey",
- "honeydew", "hotpink", "indianred",
- "indigo", "ivory", "khaki",
- "lavender", "lavenderblush", "lawngreen", "lemonchiffon",
- "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow",
- "lightgray", "lightgreen", "lightgrey", "lightpink",
- "lightsalmon", "lightseagreen", "lightskyblue",
- "lightslategray", "lightslategrey", "lightsteelblue",
- "lightyellow", "lime", "limegreen", "linen",
- "magenta", "maroon", "mediumaquamarine", "mediumblue",
- "mediumorchid", "mediumpurple", "mediumseagreen",
- "mediumslateblue", "mediumspringgreen", "mediumturquoise",
- "mediumvioletred", "midnightblue", "mintcream",
- "mistyrose", "moccasin",
- "navajowhite", "navy", "oldlace",
- "olive", "olivedrab", "orange", "orangered", "orchid",
- "palegoldenrod", "palegreen", "paleturquoise",
- "palevioletred", "papayawhip", "peachpuff", "peru", "pink",
- "plum", "powderblue", "purple",
- "red", "rosybrown", "royalblue",
- "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell",
- "sienna", "silver", "skyblue", "slateblue", "slategray",
- "slategrey", "snow", "springgreen", "steelblue",
- "tan", "teal", "thistle", "tomato", "turquoise",
- "violet",
- "wheat", "white", "whitesmoke",
- "yellow", "yellowgreen"
+ "aqua", "black", "blue", "fuchsia",
+ "gray", "green", "lime", "maroon",
+ "navy", "olive", "purple", "red",
+ "silver", "teal", "white", "yellow"
};
gvrender_engine_t vml_engine = {
0, /* vml_end_edge */
vml_begin_anchor,
vml_end_anchor,
- 0, /* vml_begin_label */
- 0, /* vml_end_label */
+ 0, /* vml_begin_label */
+ 0, /* vml_end_label */
vml_textpara,
0, /* vml_resolve_color */
vml_ellipse,
| GVRENDER_DOES_MAPS
| GVRENDER_DOES_TARGETS
| GVRENDER_DOES_TOOLTIPS, /* flags */
- 4., /* default pad - graph units */
+ 0., /* default pad - graph units */
vml_knowncolors, /* knowncolors */
sizeof(vml_knowncolors) / sizeof(char *), /* sizeof knowncolors */
RGBA_BYTE, /* color_type */
#endif
{0, NULL, 0, NULL, NULL}
};
+