]> granicus.if.org Git - graphviz/commitdiff
remove VML output renderer
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sun, 22 Jan 2023 01:04:06 +0000 (17:04 -0800)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Thu, 26 Jan 2023 01:46:31 +0000 (17:46 -0800)
Gitlab: closes #799

CHANGELOG.md
ci/clang_format.py
plugin/core/CMakeLists.txt
plugin/core/Makefile.am
plugin/core/gvloadimage_core.c
plugin/core/gvplugin_core.c
plugin/core/gvplugin_core.vcxproj
plugin/core/gvplugin_core.vcxproj.filters
plugin/core/gvrender_core_vml.c [deleted file]

index a1331e5f3c9b221df116b4b1dffade88616c0c95..574e728cbea6551e2989a93863d9922af4537114 100644 (file)
@@ -4,7 +4,12 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## [Unreleased (7.1.1)]
+## [Unreleased (8.0.0)]
+
+### Changed
+
+- The VML output renderer has been removed. This format has been superseded by
+  SVG. #799
 
 ### Fixed
 
index ba2e4cdf0b3a2d0b88078119d614433648c7c347..5c927595ded9e827d434b98fcface51db6f1cb24 100644 (file)
@@ -647,7 +647,6 @@ EXCLUDE = (
   "plugin/core/gvrender_core_ps.c",
   "plugin/core/gvrender_core_svg.c",
   "plugin/core/gvrender_core_tk.c",
-  "plugin/core/gvrender_core_vml.c",
   "plugin/devil/gvdevice_devil.c",
   "plugin/devil/gvplugin_devil.c",
   "plugin/dot_layout/gvlayout_dot_layout.c",
index 0a1be67ce0c2c1bf2950ee23cd3b0d7ed2bb595f..63ca193c781cd75eada83cf205fc51a7cf5924cf 100644 (file)
@@ -15,7 +15,6 @@ add_library(gvplugin_core SHARED
   gvrender_core_ps.c
   gvrender_core_svg.c
   gvrender_core_tk.c
-  gvrender_core_vml.c
 )
 
 target_include_directories(gvplugin_core PRIVATE
index 094cbd6a8a29a1469e4ef73ab3d63b788c9f445b..c19417260aff5aae94f87a571729a9895cd9eb0f 100644 (file)
@@ -28,7 +28,6 @@ libgvplugin_core_C_la_SOURCES = \
        gvrender_core_ps.c \
        gvrender_core_svg.c \
        gvrender_core_tk.c \
-       gvrender_core_vml.c \
        gvrender_core_pov.c \
        gvrender_core_pic.c \
        gvloadimage_core.c
index 8e88c2be64111952f62e655a678ff9c4049cf4ce..b77b99411a491a14a0bccf9cf679399412ffab68 100644 (file)
@@ -37,7 +37,6 @@ typedef enum {
     FORMAT_PNG_FIG,  FORMAT_GIF_FIG,  FORMAT_JPEG_FIG,
     FORMAT_PNG_VRML, FORMAT_GIF_VRML, FORMAT_JPEG_VRML,
     FORMAT_PS_PS, FORMAT_PSLIB_PS, 
-    FORMAT_PNG_VML, FORMAT_GIF_VML, FORMAT_JPEG_VML, 
     FORMAT_GIF_TK,
 } format_type;
 
@@ -238,16 +237,6 @@ static void core_loadimage_pslib(GVJ_t * job, usershape_t *us, boxf b, bool fill
     }
 }
 
-static void core_loadimage_vml(GVJ_t * job, usershape_t *us, boxf b, bool filled)
-{
-    (void)filled;
-
-    int  graphHeight = (int)(job->bb.UR.y - job->bb.LL.y);
-    gvprintf (job, "<v:image src=\"%s\" style=\" position:absolute; width:%.2f; height:%.2f; left:%.2f ; top:%.2f\"",
-           us->name,  b.UR.x - b.LL.x, b.UR.y - b.LL.y, b.LL.x, graphHeight-b.UR.y);
-    gvputs(job, " />\n");
-}
-
 static void core_loadimage_tk(GVJ_t * job, usershape_t *us, boxf b, bool filled)
 {
     (void)filled;
@@ -295,10 +284,6 @@ static gvloadimage_engine_t engine_xdot = {
     core_loadimage_xdot
 };
 
-static gvloadimage_engine_t engine_vml = {
-    core_loadimage_vml
-};
-
 static gvloadimage_engine_t engine_tk = {
     core_loadimage_tk
 };
@@ -355,12 +340,6 @@ gvplugin_installed_t gvloadimage_core_types[] = {
 
     {FORMAT_SVG_SVG, "svg:svg", 1, &engine_svg, NULL},
 
-    {FORMAT_PNG_VML, "png:vml", 1, &engine_vml, NULL},
-    {FORMAT_GIF_VML, "gif:vml", 1, &engine_vml, NULL},
-    {FORMAT_JPEG_VML, "jpeg:vml", 1, &engine_vml, NULL},
-    {FORMAT_JPEG_VML, "jpe:vml", 1, &engine_vml, NULL},
-    {FORMAT_JPEG_VML, "jpg:vml", 1, &engine_vml, NULL},
-
     {FORMAT_GIF_TK, "gif:tk", 1, &engine_tk, NULL},
 
     {0, NULL, 0, NULL, NULL}
index 33f53f0837854875a0b98d904679d000c5c78502..9e145c6ea6d8134141ce8b94b0f40aaec56b18ad 100644 (file)
@@ -18,7 +18,6 @@ extern gvplugin_installed_t gvdevice_ps_types[];
 extern gvplugin_installed_t gvdevice_svg_types[];
 extern gvplugin_installed_t gvdevice_json_types[];
 extern gvplugin_installed_t gvdevice_tk_types[];
-extern gvplugin_installed_t gvdevice_vml_types[];
 extern gvplugin_installed_t gvdevice_pic_types[];
 extern gvplugin_installed_t gvdevice_pov_types[];
 
@@ -30,7 +29,6 @@ extern gvplugin_installed_t gvrender_ps_types[];
 extern gvplugin_installed_t gvrender_svg_types[];
 extern gvplugin_installed_t gvrender_json_types[];
 extern gvplugin_installed_t gvrender_tk_types[];
-extern gvplugin_installed_t gvrender_vml_types[];
 extern gvplugin_installed_t gvrender_pic_types[];
 extern gvplugin_installed_t gvrender_pov_types[];
 
@@ -48,7 +46,6 @@ static gvplugin_api_t apis[] = {
     {API_device, gvdevice_svg_types},
     {API_device, gvdevice_json_types},
     {API_device, gvdevice_tk_types},
-    {API_device, gvdevice_vml_types},
     {API_device, gvdevice_pic_types},
     {API_device, gvdevice_pov_types},
 
@@ -60,7 +57,6 @@ static gvplugin_api_t apis[] = {
     {API_render, gvrender_svg_types},
     {API_render, gvrender_json_types},
     {API_render, gvrender_tk_types},
-    {API_render, gvrender_vml_types},
     {API_render, gvrender_pic_types},
     {API_render, gvrender_pov_types},
 
index 0450677a2a64a668dfce828993dd265f7c0cc4b3..7b3a2c35304d9459d3ee7b37ac5fc41d98088993 100644 (file)
     <ClCompile Include="gvrender_core_ps.c" />
     <ClCompile Include="gvrender_core_svg.c" />
     <ClCompile Include="gvrender_core_tk.c" />
-    <ClCompile Include="gvrender_core_vml.c" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\lib\cdt\cdt.vcxproj">
index f7bb22fa162184083904775713ff174a56f08329..d21d9d7b2e715d66f37678f6daadcfe1b3ea4517 100644 (file)
@@ -50,9 +50,6 @@
     <ClCompile Include="gvrender_core_tk.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="gvrender_core_vml.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="gvrender_core_json.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/plugin/core/gvrender_core_vml.c b/plugin/core/gvrender_core_vml.c
deleted file mode 100644 (file)
index 023cd05..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-/*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property 
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: Details at https://graphviz.org
- *************************************************************************/
-
-#include "config.h"
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include <common/macros.h>
-#include <common/const.h>
-#include <common/types.h>
-#include <common/utils.h>
-
-#include <gvc/gvplugin_render.h>
-#include <gvc/gvplugin_device.h>
-#include <gvc/gvio.h>
-#include <cgraph/strcasecmp.h>
-#include <cgraph/unreachable.h>
-
-typedef enum { FORMAT_VML, FORMAT_VMLZ, } format_type;
-
-unsigned int  graphHeight,graphWidth;
-
-static void vml_bzptarray(GVJ_t * job, pointf * A, int n)
-{
-    int i;
-    char *c;
-
-    c = "m ";                  /* first point */
-    for (i = 0; i < n; i++) {
-        /* 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)
-{
-    switch (color.type) {
-    case COLOR_STRING:
-       gvputs(job, color.u.string);
-       break;
-    case RGBA_BYTE:
-       if (color.u.rgba[3] == 0) /* transparent */
-           gvputs(job, "none");
-       else
-           gvprintf(job, "#%02x%02x%02x",
-               color.u.rgba[0], color.u.rgba[1], color.u.rgba[2]);
-       break;
-    default:
-       UNREACHABLE(); // internal error
-    }
-}
-
-static void vml_grstroke(GVJ_t * job, int filled)
-{
-    (void)filled;
-
-    obj_state_t *obj = job->obj;
-
-    gvputs(job, "<v:stroke color=\"");
-    vml_print_color(job, obj->pencolor);
-    if (obj->penwidth != PENWIDTH_NORMAL)
-       gvprintf(job, "\" weight=\"%.0fpt", 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;
-
-    if (filled){
-        gvputs(job, " filled=\"true\" fillcolor=\"");
-       vml_print_color(job, obj->fillcolor);
-        gvputs(job, "\" ");
-    }else{
-       gvputs(job, " filled=\"false\" ");
-    }
-}
-
-// wrapper around `xml_escape` to set flags for HTML escaping
-static void html_puts(GVJ_t *job, const char *s) {
-  const xml_flags_t flags = {.dash = 1, .nbsp = 1, .utf8 = 1};
-  (void)xml_escape(s, flags, (int(*)(void*, const char*))gvputs, job);
-}
-
-static void vml_comment(GVJ_t * job, char *str)
-{
-    gvputs(job, "      <!-- ");
-    html_puts(job, str);
-    gvputs(job, " -->\n");
-}
-static void vml_begin_job(GVJ_t * job)
-{
-    gvputs(job, "<HTML>\n");
-    gvputs(job, "\n<!-- Generated by ");
-    html_puts(job, job->common->info[0]);
-    gvputs(job, " version ");
-    html_puts(job, job->common->info[1]);
-    gvputs(job, " (");
-    html_puts(job, job->common->info[2]);
-    gvputs(job, ")\n-->\n");
-}
-
-static void vml_begin_graph(GVJ_t * job)
-{
-    obj_state_t *obj = job->obj;
-    char *name;
-
-    graphHeight = (unsigned)(job->bb.UR.y - job->bb.LL.y);
-    graphWidth  = (unsigned)(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");
-
-    name = agnameof(obj->u.g);
-    if (name[0]) {
-        gvputs(job, "<TITLE>");
-        html_puts(job, 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: %upt; height: %upt\">\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: %upt; height: %upt\"", graphWidth, graphHeight);
-    gvprintf(job, " coordorigin=\"0,0\" coordsize=\"%u,%u\" >", graphWidth, graphHeight);
-}
-
-static void vml_end_graph(GVJ_t * job)
-{
-   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>\n");
-}
-
-static void
-vml_begin_anchor(GVJ_t * job, char *href, char *tooltip, char *target, char *id)
-{
-    (void)id;
-
-    gvputs(job, "<a");
-    if (href && href[0]) {
-       gvputs(job, " href=\"");
-       html_puts(job, href);
-       gvputs(job, "\"");
-    }
-    if (tooltip && tooltip[0]) {
-       gvputs(job, " title=\"");
-       html_puts(job, tooltip);
-       gvputs(job, "\"");
-    }
-    if (target && target[0]) {
-       gvputs(job, " target=\"");
-       html_puts(job, target);
-       gvputs(job, "\"");
-    }
-    gvputs(job, ">\n");
-}
-
-static void vml_end_anchor(GVJ_t * job)
-{
-    gvputs(job, "</a>\n");
-}
-
-static void vml_textspan(GVJ_t * job, pointf p, textspan_t * span)
-{
-    pointf p1,p2;
-    obj_state_t *obj = job->obj;
-    PostscriptAlias *pA;
-
-    switch (span->just) {
-    case 'l':
-       p1.x=p.x;
-       break;
-    case 'r':
-       p1.x=p.x-span->size.x;
-       break;
-    default:
-    case 'n':
-       p1.x=p.x-(span->size.x/2);
-       break;
-    }
-    p2.x=p1.x+span->size.x;
-    if (span->size.y <  span->font->size){
-      span->size.y = 1 + (1.1*span->font->size);
-    }
-
-    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-span->size.y);
-    /* 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 (span->font->size <12.){ /*     see graphs/directed/arrows.gv  */
-      p1.y+=1.4+span->font->size/5; /* adjust by approx. descender */
-      p2.y+=1.4+span->font->size/5; /* adjust by approx. descender */
-    }else{
-      p1.y+=2+span->font->size/5; /* adjust by approx. descender */
-      p2.y+=2+span->font->size/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';");
-
-    pA = span->font->postscript_alias;
-    if (pA) {
-        gvprintf(job, "font-family: '%s';", pA->family);
-        if (pA->weight)
-           gvprintf(job, "font-weight: %s;", pA->weight);
-        if (pA->stretch)
-           gvprintf(job, "font-stretch: %s;", pA->stretch);
-        if (pA->style)
-           gvprintf(job, "font-style: %s;", pA->style);
-    }
-    else {
-        gvprintf(job, "font-family: \'%s\';", span->font->name);
-    }
-    gvprintf(job, " font-size: %.2fpt;", span->font->size);
-    switch (obj->pencolor.type) {
-    case COLOR_STRING:
-       if (strcasecmp(obj->pencolor.u.string, "black"))
-           gvprintf(job, "color:%s;", obj->pencolor.u.string);
-       break;
-    case RGBA_BYTE:
-       gvprintf(job, "color:#%02x%02x%02x;",
-               obj->pencolor.u.rgba[0], obj->pencolor.u.rgba[1], obj->pencolor.u.rgba[2]);
-       break;
-    default:
-       UNREACHABLE(); // internal error
-    }
-    gvputs(job, "\"><center>");
-    html_puts(job, span->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, top;
-
-    /* A[] contains 2 points: the center and corner. */
-    gvputs(job, "  <v:oval style=\"position:absolute;");
-
-    dx=A[1].x-A[0].x;
-    dy=A[1].y-A[0].y;
-
-    top=graphHeight-(A[0].y+dy);
-    left=A[0].x - dx;
-    gvprintf(job, " left: %.2f; top: %.2f;",left, top);
-    gvprintf(job, " width: %.2f; height: %.2f\"", 2*dx, 2*dy);
-
-    vml_grfill(job, filled);
-    gvputs(job, " >");
-    vml_grstroke(job, filled);
-    gvputs(job, "</v:oval>\n");
-}
-
-static void
-vml_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
-             int arrow_at_end, int filled)
-{
-    (void)arrow_at_start;
-    (void)arrow_at_end;
-
-    gvputs(job, " <v:shape style=\"position:absolute; ");
-    gvprintf(job, " width: %u; height: %u\"", graphWidth, graphHeight);
-
-    vml_grfill(job, filled);
-    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 style=\"position:absolute; ");
-    gvprintf(job, " width: %u; height: %u\"", graphWidth, graphHeight);
-    vml_grfill(job, filled);
-    gvputs(job, " >");
-    vml_grstroke(job, filled);
-
-    gvputs(job, "<v:path  v=\"");
-    for (i = 0; i < n; i++)
-    {
-        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 \"/>");
-    }
-    gvputs(job, "</v:shape>\n");
-}
-
-static void vml_polyline(GVJ_t * job, pointf * A, int n)
-{
-    int i;
-
-    gvputs(job, " <v:shape style=\"position:absolute; ");
-    gvprintf(job, " width: %u; height: %u\" 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, graphHeight-A[i].y);
-        if (i==0) gvputs(job, " l ");
-        if (i==n-1) gvputs(job, " e "); /* no x here for polyline */
-    }
-    gvputs(job, "\"/>");
-    vml_grstroke(job, 0);                 /* no fill here for polyline */
-    gvputs(job, "</v:shape>\n");
-}
-
-/* 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[] = {
-     "aqua",  "black",  "blue", "fuchsia", 
-     "gray",  "green", "lime",  "maroon", 
-     "navy",  "olive",  "purple",  "red",
-     "silver",  "teal",  "white",  "yellow"
-};
-
-gvrender_engine_t vml_engine = {
-    vml_begin_job,
-    0,                         /* vml_end_job */
-    vml_begin_graph,
-    vml_end_graph,
-    0,                          /* vml_begin_layer */
-    0,                          /* vml_end_layer */
-    0,                          /* vml_begin_page */
-    0,                          /* vml_end_page */
-    0,                          /* vml_begin_cluster */
-    0,                          /* vml_end_cluster */
-    0,                         /* vml_begin_nodes */
-    0,                         /* vml_end_nodes */
-    0,                         /* vml_begin_edges */
-    0,                         /* vml_end_edges */
-    0,                          /* vml_begin_node */
-    0,                          /* vml_end_node */
-    0,                          /* vml_begin_edge */
-    0,                          /* vml_end_edge */
-    vml_begin_anchor,
-    vml_end_anchor,
-    0,                          /* vml_begin_label */
-    0,                          /* vml_end_label */
-    vml_textspan,
-    0,                         /* vml_resolve_color */
-    vml_ellipse,
-    vml_polygon,
-    vml_bezier,
-    vml_polyline,
-    vml_comment,
-    0,                         /* vml_library_shape */
-};
-
-gvrender_features_t render_features_vml = {
-    GVRENDER_Y_GOES_DOWN
-        | GVRENDER_DOES_TRANSFORM
-       | GVRENDER_DOES_LABELS
-       | GVRENDER_DOES_MAPS
-       | GVRENDER_DOES_TARGETS
-       | GVRENDER_DOES_TOOLTIPS, /* flags */
-    0.,                         /* default pad - graph units */
-    vml_knowncolors,           /* knowncolors */
-    sizeof(vml_knowncolors) / sizeof(char *),  /* sizeof knowncolors */
-    RGBA_BYTE,                 /* color_type */
-};
-
-gvdevice_features_t device_features_vml = {
-    GVDEVICE_DOES_TRUECOLOR,   /* flags */
-    {0.,0.},                   /* default margin - points */
-    {0.,0.},                    /* default page width, height - points */
-    {96.,96.},                 /* default dpi */
-};
-
-gvdevice_features_t device_features_vmlz = {
-    GVDEVICE_DOES_TRUECOLOR
-      | GVDEVICE_COMPRESSED_FORMAT,    /* flags */
-    {0.,0.},                   /* default margin - points */
-    {0.,0.},                    /* default page width, height - points */
-    {96.,96.},                 /* default dpi */
-};
-
-gvplugin_installed_t gvrender_vml_types[] = {
-    {FORMAT_VML, "vml", 1, &vml_engine, &render_features_vml},
-    {0, NULL, 0, NULL, NULL}
-};
-
-gvplugin_installed_t gvdevice_vml_types[] = {
-    {FORMAT_VML, "vml:vml", 1, NULL, &device_features_vml},
-#if HAVE_LIBZ
-    {FORMAT_VMLZ, "vmlz:vml", 1, NULL, &device_features_vmlz},
-#endif
-    {0, NULL, 0, NULL, NULL}
-};
-