From f93019f8e1ea6368054cae28d61dca519224ee8a Mon Sep 17 00:00:00 2001 From: ellson Date: Sat, 24 Jun 2006 16:51:22 +0000 Subject: [PATCH] some work on vrml plugin --- CMakeLists.txt | 27 ++- lib/common/utils.c | 3 +- lib/gvc/gvloadimage.c | 7 +- plugin/gd/gvplugin_gd.c | 2 + plugin/gd/gvrender_gd.c | 203 ++++------------ plugin/gd/gvrender_gd_vrml.c | 435 +++++++++------------------------- plugin/pango/gvplugin_pango.c | 2 +- 7 files changed, 182 insertions(+), 497 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fb86a296..2530c7bd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,14 +3,20 @@ PROJECT(graphviz) -SUBDIRS( - lib - cmd - tclpkg - doc - contrib - graphs -) +SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake + +ADD_SUBDIRECTORY(lib) +ADD_SUBDIRECTORY(cmd) +ADD_SUBDIRECTORY(tclpkg) +ADD_SUBDIRECTORY(doc) +ADD_SUBDIRECTORY(contrib) +ADD_SUBDIRECTORY(graphs) + +# create config.h +#INCLUDE (ConfigureChecks.cmake) +#CONFIGURE_FILE (config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h ) + +ADD_DEFINITIONS( -DHAVE_CONFIG_H ) CONFIGURE_FILE( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall.cmake.in" @@ -19,8 +25,7 @@ CONFIGURE_FILE( ) ADD_CUSTOM_TARGET(uninstall - "${CMAKE_COMMAND}" -P - "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" ) # FIXME - this config.h comes from ./configure @@ -30,8 +35,6 @@ ADD_CUSTOM_COMMAND( COMMAND cat < ${CMAKE_CURRENT_SOURCE_DIR}/config.h > ${CMAKE_BINARY_DIR}/config.h ) -ADD_DEFINITIONS( -DHAVE_CONFIG_H ) - # FIXME - this ast_common.h comes from ./configure ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_BINARY_DIR}/ast_common.h diff --git a/lib/common/utils.c b/lib/common/utils.c index 9bdef0ce1..e2e431778 100644 --- a/lib/common/utils.c +++ b/lib/common/utils.c @@ -200,8 +200,7 @@ point coord(node_t * n) * "Right" are non-null. * */ -pointf Bezier(pointf * V, int degree, double t, pointf * Left, - pointf * Right) +pointf Bezier(pointf * V, int degree, double t, pointf * Left, pointf * Right) { int i, j; /* Index variables */ pointf Vtemp[W_DEGREE + 1][W_DEGREE + 1]; diff --git a/lib/gvc/gvloadimage.c b/lib/gvc/gvloadimage.c index 98868d8a0..50dbd5953 100644 --- a/lib/gvc/gvloadimage.c +++ b/lib/gvc/gvloadimage.c @@ -31,6 +31,9 @@ #include "gvcint.h" #include "gvcproc.h" +/* for agerr() */ +#include "graph.h" + int gvloadimage_select(GVJ_t * job, char *str) { gvplugin_available_t *plugin; @@ -55,8 +58,8 @@ void gvloadimage(GVJ_t * job, usershape_t *us, boxf b, bool filled, char *target strcat(type, "2"); strcat(type, target); - if (type) - gvloadimage_select(job, type); + if (gvloadimage_select(job, type) == NO_SUPPORT) + agerr (AGWARN, "No loadimage plugin for \"%s\"\n", type); if ((gvli = job->loadimage.engine) && gvli->loadimage) gvli->loadimage(job, us, b, filled); diff --git a/plugin/gd/gvplugin_gd.c b/plugin/gd/gvplugin_gd.c index b003014c1..1444007fe 100644 --- a/plugin/gd/gvplugin_gd.c +++ b/plugin/gd/gvplugin_gd.c @@ -17,11 +17,13 @@ #include "gvplugin.h" extern gvplugin_installed_t gvrender_gd_types; +extern gvplugin_installed_t gvrender_vrml_types; extern gvplugin_installed_t gvtextlayout_gd_types; extern gvplugin_installed_t gvloadimage_gd_types; static gvplugin_api_t apis[] = { {API_render, &gvrender_gd_types}, + {API_render, &gvrender_vrml_types}, {API_textlayout, &gvtextlayout_gd_types}, {API_loadimage, &gvloadimage_gd_types}, {(api_t)0, 0}, diff --git a/plugin/gd/gvrender_gd.c b/plugin/gd/gvrender_gd.c index c0a986778..ec5bd1ef6 100644 --- a/plugin/gd/gvrender_gd.c +++ b/plugin/gd/gvrender_gd.c @@ -25,6 +25,7 @@ #include "gvplugin_render.h" + #ifdef HAVE_LIBGD #include "gd.h" @@ -33,6 +34,7 @@ typedef enum { FORMAT_GD, FORMAT_GD2, FORMAT_GIF, FORMAT_JPEG, FORMAT_PNG, extern int mapbool(char *); extern char *safefile(char *shapefilename); +extern pointf Bezier(pointf * V, int degree, double t, pointf * Left, pointf * Right); #define BEZIERSUBDIVISION 10 @@ -41,47 +43,6 @@ extern char *safefile(char *shapefilename); /* fontsize at which text is rendered by a simple line */ #define FONTSIZE_TOO_SMALL 1.5 -/* from Glassner's Graphics Gems */ -#define W_DEGREE 5 - -/* - * Bezier : - * Evaluate a Bezier curve at a particular parameter value - * Fill in control points for resulting sub-curves if "Left" and - * "Right" are non-null. - * - */ -static pointf Bezier(pointf * V, int degree, double t, pointf * Left, - pointf * Right) -{ - int i, j; /* Index variables */ - pointf Vtemp[W_DEGREE + 1][W_DEGREE + 1]; - - /* Copy control points */ - for (j = 0; j <= degree; j++) { - Vtemp[0][j] = V[j]; - } - - /* Triangle computation */ - for (i = 1; i <= degree; i++) { - for (j = 0; j <= degree - i; j++) { - Vtemp[i][j].x = - (1.0 - t) * Vtemp[i - 1][j].x + t * Vtemp[i - 1][j + 1].x; - Vtemp[i][j].y = - (1.0 - t) * Vtemp[i - 1][j].y + t * Vtemp[i - 1][j + 1].y; - } - } - - if (Left != NULL) - for (j = 0; j <= degree; j++) - Left[j] = Vtemp[j][0]; - if (Right != NULL) - for (j = 0; j <= degree; j++) - Right[j] = Vtemp[degree - j][j]; - - return (Vtemp[degree][0]); -} - static void gdgen_resolve_color(GVJ_t * job, gvcolor_t * color) { gdImagePtr im = (gdImagePtr) job->surface; @@ -415,45 +376,35 @@ static void gdgen_textpara(GVJ_t * job, pointf p, textpara_t * para) } } -static void -gdgen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start, - int arrow_at_end, int filled) +int gdgen_set_penstyle(GVJ_t * job, gdImagePtr im, gdImagePtr brush) { gvstyle_t *style = job->style; - gdImagePtr im = (gdImagePtr) job->surface; - pointf p0, p1, V[4]; - int i, j, step; - int dashstyle[20]; - int pen, width; - gdImagePtr brush = NULL; - gdPoint F[4]; - - if (!im) - return; + int i, pen, width, dashstyle[40]; if (style->pen == PEN_DASHED) { - for (i = 0; i < 10; i++) + for (i = 0; i < 20; i++) dashstyle[i] = style->pencolor.u.index; - for (; i < 20; i++) + for (; i < 40; i++) dashstyle[i] = transparent; gdImageSetStyle(im, dashstyle, 20); pen = gdStyled; } else if (style->pen == PEN_DOTTED) { for (i = 0; i < 2; i++) dashstyle[i] = style->pencolor.u.index; - for (; i < 12; i++) + for (; i < 24; i++) dashstyle[i] = transparent; - gdImageSetStyle(im, dashstyle, 12); + gdImageSetStyle(im, dashstyle, 24); pen = gdStyled; } else { pen = style->pencolor.u.index; } - width = style->penwidth; + width = style->penwidth * job->scale.x; if (width < PENWIDTH_NORMAL) - width = PENWIDTH_NORMAL; /* gd can't do thin lines */ + width = PENWIDTH_NORMAL; /* gd can't do thin lines */ gdImageSetThickness(im, width); - if (style->penwidth != PENWIDTH_NORMAL) { + /* use brush instead of Thickness to improve end butts */ + if (width != PENWIDTH_NORMAL) { brush = gdImageCreate(width, width); gdImagePaletteCopy(brush, im); gdImageFilledRectangle(brush, 0, 0, width - 1, width - 1, @@ -465,31 +416,40 @@ gdgen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start, pen = gdBrushed; } - V[3].x = A[0].x; - V[3].y = A[0].y; - F[0].x = ROUND(A[0].x); - F[0].y = ROUND(A[0].y); - F[3].x = ROUND(A[n-1].x); - F[3].y = ROUND(A[n-1].y); + return pen; +} + +static void +gdgen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start, + int arrow_at_end, int filled) +{ + gvstyle_t *style = job->style; + gdImagePtr im = (gdImagePtr) job->surface; + pointf p0, p1, V[4]; + int i, j, step, pen; + gdImagePtr brush = NULL; + gdPoint F[4]; + + if (!im) + return; + + pen = gdgen_set_penstyle(job, im, brush); + + V[3] = A[0]; + PF2P(A[0], F[0]); + PF2P(A[n-1], F[3]); for (i = 0; i + 3 < n; i += 3) { V[0] = V[3]; - for (j = 1; j <= 3; j++) { - V[j].x = A[i + j].x; - V[j].y = A[i + j].y; - } + for (j = 1; j <= 3; j++) + V[j] = A[i + j]; p0 = V[0]; for (step = 1; step <= BEZIERSUBDIVISION; step++) { - p1 = Bezier(V, 3, (double) step / BEZIERSUBDIVISION, NULL, - NULL); - gdImageLine(im, ROUND(p0.x), ROUND(p0.y), ROUND(p1.x), - ROUND(p1.y), pen); - if (filled) { - F[1].x = ROUND(p0.x); - F[1].y = ROUND(p0.y); - F[2].x = ROUND(p1.x); - F[2].y = ROUND(p1.y); + p1 = Bezier(V, 3, (double) step / BEZIERSUBDIVISION, NULL, NULL); + PF2P(p0, F[1]); + PF2P(p1, F[2]); + gdImageLine(im, F[1].x, F[1].y, F[2].x, F[2].y, pen); + if (filled) gdImageFilledPolygon(im, F, 4, style->fillcolor.u.index); - } p0 = p1; } } @@ -501,49 +461,16 @@ static void gdgen_polygon(GVJ_t * job, pointf * A, int n, int filled) { gvstyle_t *style = job->style; gdImagePtr im = (gdImagePtr) job->surface; + gdImagePtr brush = NULL; int i; gdPoint *points; - int dashstyle[20]; - int pen, width; - gdImagePtr brush = NULL; + int pen; if (!im) return; - if (style->pen == PEN_DASHED) { - for (i = 0; i < 10; i++) - dashstyle[i] = style->pencolor.u.index; - for (; i < 20; i++) - dashstyle[i] = transparent; - gdImageSetStyle(im, dashstyle, 20); - pen = gdStyled; - } else if (style->pen == PEN_DOTTED) { - for (i = 0; i < 2; i++) - dashstyle[i] = style->pencolor.u.index; - for (; i < 12; i++) - dashstyle[i] = transparent; - gdImageSetStyle(im, dashstyle, 12); - pen = gdStyled; - } else { - pen = style->pencolor.u.index; - } + pen = gdgen_set_penstyle(job, im, brush); - width = style->penwidth * job->scale.x; - if (width < PENWIDTH_NORMAL) - width = PENWIDTH_NORMAL; /* gd can't do thin lines */ - gdImageSetThickness(im, width); - /* use brush instead of Thickness to improve end butts */ - if (width != PENWIDTH_NORMAL) { - brush = gdImageCreate(width, width); - gdImagePaletteCopy(brush, im); - gdImageFilledRectangle(brush, 0, 0, width - 1, width - 1, - style->pencolor.u.index); - gdImageSetBrush(im, brush); - if (pen == gdStyled) - pen = gdStyledBrushed; - else - pen = gdBrushed; - } points = malloc(n * sizeof(gdPoint)); for (i = 0; i < n; i++) { points[i].x = ROUND(A[i].x); @@ -563,50 +490,16 @@ static void gdgen_ellipse(GVJ_t * job, pointf * A, int filled) gvstyle_t *style = job->style; gdImagePtr im = (gdImagePtr) job->surface; double dx, dy; - int i; - int dashstyle[40]; /* need 2* size for arcs, I don't know why */ - int pen, width; + int pen; gdImagePtr brush = NULL; if (!im) return; - if (style->pen == PEN_DASHED) { - for (i = 0; i < 20; i++) - dashstyle[i] = style->pencolor.u.index; - for (; i < 40; i++) - dashstyle[i] = transparent; - gdImageSetStyle(im, dashstyle, 40); - pen = gdStyled; - } else if (style->pen == PEN_DOTTED) { - for (i = 0; i < 2; i++) - dashstyle[i] = style->pencolor.u.index; - for (; i < 24; i++) - dashstyle[i] = transparent; - gdImageSetStyle(im, dashstyle, 24); - pen = gdStyled; - } else { - pen = style->pencolor.u.index; - } + pen = gdgen_set_penstyle(job, im, brush); - width = style->penwidth * job->scale.x; - if (width < PENWIDTH_NORMAL) - width = PENWIDTH_NORMAL; /* gd can't do thin lines */ - gdImageSetThickness(im, width); - /* use brush instead of Thickness to improve outline appearance */ - if (width != PENWIDTH_NORMAL) { - brush = gdImageCreate(width, width); - gdImagePaletteCopy(brush, im); - gdImageFilledRectangle(brush, 0, 0, width - 1, width - 1, - style->pencolor.u.index); - gdImageSetBrush(im, brush); - if (pen == gdStyled) - pen = gdStyledBrushed; - else - pen = gdBrushed; - } - dx = fabs(2 * (A[1].x - A[0].x)); - dy = fabs(2 * (A[1].y - A[0].y)); + dx = 2 * (A[1].x - A[0].x); + dy = 2 * (A[1].y - A[0].y); if (filled) gdImageFilledEllipse(im, ROUND(A[0].x), ROUND(A[0].y), diff --git a/plugin/gd/gvrender_gd_vrml.c b/plugin/gd/gvrender_gd_vrml.c index 96b8df6e7..6f1e0f970 100644 --- a/plugin/gd/gvrender_gd_vrml.c +++ b/plugin/gd/gvrender_gd_vrml.c @@ -26,8 +26,15 @@ #include "gvplugin_render.h" -#ifdef HAVE_GD_PNG +#ifdef HAVE_LIBGD #include "gd.h" + +#ifdef HAVE_GD_PNG + +/* for N_GNEW() */ +#include "memory.h" + +/* for ? */ #include "graph.h" /* for late_double() */ @@ -39,39 +46,17 @@ extern shape_kind shapeOf(node_t *); +extern pointf Bezier(pointf * V, int degree, double t, pointf * Left, pointf * Right); +extern int gdgen_set_penstyle(GVJ_t * job, gdImagePtr im, gdImagePtr brush); + typedef enum { FORMAT_VRML, } format_type; #ifndef MAXFLOAT #define MAXFLOAT 10000000. #endif -#define NONE 0 -#define NODE 1 -#define EDGE 2 -#define CLST 3 - #define BEZIERSUBDIVISION 10 -/* font modifiers */ -#define REGULAR 0 -#define BOLD 1 -#define ITALIC 2 - -/* patterns */ -#define P_SOLID 0 -#define P_NONE 15 -#define P_DOTTED 4 /* i wasn't sure about this */ -#define P_DASHED 11 /* or this */ - -/* bold line constant */ -#define WIDTH_NORMAL 1 -#define WIDTH_BOLD 3 - -typedef struct { - unsigned char r, g, b; -} Color; - - /* static int N_pages; */ /* static point Pages; */ static double Scale; @@ -87,19 +72,6 @@ static double EdgeLen; /* length between centers of endpoints */ static double HeadHt, TailHt; /* height of arrows */ static double Fstz, Sndz; /* z values of tail and head points */ -typedef struct context_t { - unsigned char pencolor_ix, fillcolor_ix; - char *pencolor, *fillcolor; - char *fontfam, fontopt, font_was_set; - double r, g, b; /* fill color values */ - char pen, fill, penwidth; - double fontsz; -} context_t; - -#define MAXNEST 4 -static context_t cstk[MAXNEST]; -static int SP; - /* gdirname: * Returns directory pathname prefix * Code adapted from dgk @@ -158,48 +130,21 @@ static FILE *nodefile(char *filename, node_t * n) return rv; } -static void init_png(gdImagePtr im) -{ - int transparent; - - if ((transparent = gdImageGetTransparent(im)) == -1) { - transparent = gdImageColorResolve(im, 255, 255, 254); - gdImageColorTransparent(im, transparent); - } -} - -static pointf vrml_node_point(GVJ_t *job, node_t *n, point p) +static pointf vrml_node_point(GVJ_t *job, node_t *n, pointf p) { pointf rv; /* make mp relative to PNG canvas */ if (job->rotation) { - rv.x = (p.y - ND_coord_i(n).y + ND_lw_i(n)) * Scale; - rv.y = (ND_coord_i(n).x - p.x + ND_ht_i(n) / 2) * Scale; + rv.x = ( p.y - ND_coord_i(n).y + ND_lw_i(n) ) * Scale; + rv.y = (-p.x + ND_coord_i(n).x + ND_ht_i(n) / 2.) * Scale; } else { - rv.x = (p.x - ND_coord_i(n).x + ND_lw_i(n)) * Scale; - rv.y = (ND_coord_i(n).y - p.y + ND_ht_i(n) / 2) * Scale; + rv.x = ( p.x - ND_coord_i(n).x + ND_lw_i(n) ) * Scale; + rv.y = (-p.y + ND_coord_i(n).y + ND_ht_i(n) / 2.) * Scale; } return rv; } -static void vrml_font(context_t * cp) -{ -/* FIX - char *fw, *fa; - - fw = fa = "Regular"; - switch (cp->fontopt) { - case BOLD: - fw = "Bold"; - break; - case ITALIC: - fa = "Italic"; - break; - } -*/ -} - /* warmed over VRML code starts here */ static void vrml_resolve_color(GVJ_t * job, gvcolor_t * color) @@ -218,8 +163,6 @@ static void vrml_resolve_color(GVJ_t * job, gvcolor_t * color) color->type = COLOR_INDEX; } -static int white, black, transparent, basecolor; - static void vrml_begin_page(GVJ_t *job) { FILE *out = job->output_file; @@ -233,14 +176,6 @@ static void vrml_begin_page(GVJ_t *job) fprintf(out, " Transform {\n"); fprintf(out, " scale %.3f %.3f %.3f\n", .0278, .0278, .0278); fprintf(out, " children [\n"); - - SP = 0; - cstk[0].fillcolor = "white"; - cstk[0].fontfam = "times"; /* font family name */ - cstk[0].fontopt = REGULAR; /* modifier: REGULAR, BOLD or ITALIC */ - cstk[0].pen = P_SOLID; /* pen pattern style, default is solid */ - cstk[0].fill = P_NONE; - cstk[0].penwidth = WIDTH_NORMAL; } static void vrml_end_page(GVJ_t *job) @@ -271,15 +206,20 @@ static void vrml_begin_node(GVJ_t *job) node_t *n = obj->n; double z = obj->z; int width, height; + int transparent; fprintf(out, "# node %s\n", n->name); if (z < MinZ) MinZ = z; if (shapeOf(n) != SH_POINT) { PNGfile = nodefile(job->output_filename, n); + width = (ND_lw_i(n) + ND_rw_i(n)) * Scale + 3; height = (ND_ht_i(n)) * Scale + 3; im = gdImageCreate(width, height); - init_png(im); + + /* make backround transparent */ + transparent = gdImageColorResolve(im, 255, 255, 254); + gdImageColorTransparent(im, transparent); } } @@ -291,7 +231,7 @@ static void vrml_end_node(GVJ_t *job) if (shapeOf(n) != SH_POINT) { gdImagePng(im, PNGfile); gdImageDestroy(im); - im = 0; + im = NULL; fclose(PNGfile); } } @@ -355,48 +295,10 @@ static void vrml_end_edge(GVJ_t *job) fprintf(job->output_file, "] }\n"); } -static void vrml_begin_context(void) -{ - assert(SP + 1 < MAXNEST); - cstk[SP + 1] = cstk[SP]; - SP++; -} - -static void vrml_end_context(void) -{ - int psp = SP - 1; - assert(SP > 0); - if (cstk[SP].font_was_set) - vrml_font(&(cstk[psp])); - /* free(cstk[psp].fontfam); */ - SP = psp; -} - -static void vrml_set_font(char *name, double size) -{ - char *p, *q; - context_t *cp; - - cp = &(cstk[SP]); - cp->font_was_set = TRUE; - cp->fontsz = size; - p = strdup(name); - if ((q = strchr(p, '-'))) { - *q++ = 0; - if (strcasecmp(q, "italic") == 0) - cp->fontopt = ITALIC; - else if (strcasecmp(q, "bold") == 0) - cp->fontopt = BOLD; - } - cp->fontfam = p; - vrml_font(&cstk[SP]); -} - -static void vrml_textpara(GVJ_t *job, pointf pf, textpara_t * para) +static void vrml_textpara(GVJ_t *job, pointf p, textpara_t * para) { obj_state_t *obj = job->obj; char *err; - point p; pointf mp; int brect[8]; extern gdFontPtr gdFontSmall; @@ -404,7 +306,6 @@ static void vrml_textpara(GVJ_t *job, pointf pf, textpara_t * para) if (! obj->n) return; - PF2P(pf, p); switch (para->just) { case 'l': break; @@ -439,7 +340,7 @@ static void vrml_textpara(GVJ_t *job, pointf pf, textpara_t * para) * Why the special case for ranks? Is the arithmetic really correct? */ static double -interpolate_zcoord(GVJ_t *job, pointf p1, point fst, double fstz, point snd, double sndz) +interpolate_zcoord(GVJ_t *job, pointf p1, pointf fst, double fstz, pointf snd, double sndz) { obj_state_t *obj = job->obj; edge_t *e = obj->e; @@ -465,21 +366,11 @@ interpolate_zcoord(GVJ_t *job, pointf p1, point fst, double fstz, point snd, dou * Return true if the 3 points starting at A are collinear. */ static int -collinear (point * A) +collinear (pointf * A) { - Ppoint_t a, b, c; double w; - a.x = A->x; - a.y = A->y; - A++; - b.x = A->x; - b.y = A->y; - A++; - c.x = A->x; - c.y = A->y; - - w = wind(a,b,c); + w = wind(A[0],A[1],A[2]); return (fabs(w) <= 1); } @@ -488,14 +379,14 @@ collinear (point * A) * At present, just check with 4 points, the common case. */ static int -straight (point * A, int n) +straight (pointf * A, int n) { if (n != 4) return 0; return (collinear(A) && collinear(A+1)); } static void -doSegment (FILE *out, point* A, point p0, double z0, point p1, double z1) +doSegment (FILE *out, pointf* A, point p0, double z0, point p1, double z1) { double d1, d0; double delx, dely, delz; @@ -515,19 +406,18 @@ doSegment (FILE *out, point* A, point p0, double z0, point p1, double z1) fprintf(out, " Shape {\n"); fprintf(out, " geometry Cylinder {\n"); fprintf(out, " bottom FALSE top FALSE\n"); - fprintf(out, " height %f radius %d }\n", CylHt, cstk[SP].penwidth); +// fprintf(out, " height %f radius %d }\n", CylHt, cstk[SP].penwidth); fprintf(out, " appearance Appearance {\n"); fprintf(out, " material Material {\n"); fprintf(out, " ambientIntensity 0.33\n"); - fprintf(out, " diffuseColor %f %f %f\n", - cstk[SP].r,cstk[SP].g,cstk[SP].b); +// fprintf(out, " diffuseColor %f %f %f\n", cstk[SP].r,cstk[SP].g,cstk[SP].b); fprintf(out, " }\n"); fprintf(out, " }\n"); fprintf(out, " }\n"); } static void -vrml_bezier(GVJ_t *job, point * A, int n, int arrow_at_start, int arrow_at_end, int filled) +vrml_bezier(GVJ_t *job, pointf * A, int n, int arrow_at_start, int arrow_at_end, int filled) { FILE *out = job->output_file; obj_state_t *obj = job->obj; @@ -535,13 +425,9 @@ vrml_bezier(GVJ_t *job, point * A, int n, int arrow_at_start, int arrow_at_end, double fstz = obj->tail_z, sndz = obj->head_z; pointf p1, V[4]; int i, j, step; - context_t *cp; assert(obj->e); - cp = &(cstk[SP]); - if (cp->pen == P_NONE) - return; if (straight(A,n)) { doSegment (out, A, ND_coord_i(e->tail),Fstz,ND_coord_i(e->head),Sndz); return; @@ -549,32 +435,27 @@ vrml_bezier(GVJ_t *job, point * A, int n, int arrow_at_start, int arrow_at_end, fprintf(out, "Shape { geometry Extrusion {\n"); fprintf(out, " spine ["); - V[3].x = A[0].x; - V[3].y = A[0].y; + V[3] = A[0]; for (i = 0; i + 3 < n; i += 3) { V[0] = V[3]; - for (j = 1; j <= 3; j++) { - V[j].x = A[i + j].x; - V[j].y = A[i + j].y; - } + for (j = 1; j <= 3; j++) + V[j] = A[i + j]; for (step = 0; step <= BEZIERSUBDIVISION; step++) { - p1 = Bezier(V, 3, (double) step / BEZIERSUBDIVISION, NULL, - NULL); - fprintf(out, " %.3f %.3f %.3f", p1.x, p1.y, + p1 = Bezier(V, 3, (double) step / BEZIERSUBDIVISION, NULL, NULL); + fprintf(out, " %g %g %g", p1.x, p1.y, interpolate_zcoord(job, p1, A[0], fstz, A[n - 1], sndz)); } } fprintf(out, " ]\n"); - fprintf(out, " crossSection [ %d %d, %d %d, %d %d, %d %d ]\n", - (cp->penwidth), (cp->penwidth), -(cp->penwidth), - (cp->penwidth), -(cp->penwidth), -(cp->penwidth), - (cp->penwidth), -(cp->penwidth)); +// fprintf(out, " crossSection [ %d %d, %d %d, %d %d, %d %d ]\n", +// (cp->penwidth), (cp->penwidth), -(cp->penwidth), +// (cp->penwidth), -(cp->penwidth), -(cp->penwidth), +// (cp->penwidth), -(cp->penwidth)); fprintf(out, "}\n"); fprintf(out, " appearance DEF E%d Appearance {\n", e->id); fprintf(out, " material Material {\n"); fprintf(out, " ambientIntensity 0.33\n"); - fprintf(out, " diffuseColor %.3f %.3f %.3f\n", - cstk[SP].r, cstk[SP].g, cstk[SP].b); +// fprintf(out, " diffuseColor %.3f %.3f %.3f\n", cstk[SP].r, cstk[SP].g, cstk[SP].b); fprintf(out, " }\n"); fprintf(out, " }\n"); fprintf(out, "}\n"); @@ -583,8 +464,7 @@ vrml_bezier(GVJ_t *job, point * A, int n, int arrow_at_start, int arrow_at_end, /* doArrowhead: * If edge is straight, we attach a cone to the edge as a group. */ -static void -doArrowhead (GVJ_t *job, point* A) +static void doArrowhead (GVJ_t *job, pointf * A) { FILE *out = job->output_file; obj_state_t *obj = job->obj; @@ -619,7 +499,7 @@ doArrowhead (GVJ_t *job, point* A) fprintf(out, " appearance Appearance {\n"); fprintf(out, " material Material {\n"); fprintf(out, " ambientIntensity 0.33\n"); - fprintf(out, " diffuseColor %f %f %f\n", cstk[SP].r,cstk[SP].g,cstk[SP].b); +// fprintf(out, " diffuseColor %f %f %f\n", cstk[SP].r,cstk[SP].g,cstk[SP].b); fprintf(out, " }\n"); fprintf(out, " }\n"); fprintf(out, " }\n"); @@ -627,75 +507,41 @@ doArrowhead (GVJ_t *job, point* A) fprintf(out, "}\n"); } -static void vrml_polygon(GVJ_t *job, point * A, int np, int filled) +static void vrml_polygon(GVJ_t *job, pointf * A, int np, int filled) { FILE *out = job->output_file; + gvstyle_t *style = job->style; obj_state_t *obj = job->obj; graph_t *g = obj->g; node_t *n = obj->n; edge_t *e = obj->e; double z = obj->z; pointf p, mp; - int i; gdPoint *points; - int style[20]; - int pen, width; + int i, pen; gdImagePtr brush = NULL; double theta; if (g) { - fprintf(out, " Background { skyColor %.3f %.3f %.3f }\n", - cstk[SP].r, cstk[SP].g, cstk[SP].b); +// fprintf(out, " Background { skyColor %.3f %.3f %.3f }\n", +// cstk[SP].r, cstk[SP].g, cstk[SP].b); Saw_skycolor = TRUE; } else if (n) { + pen = gdgen_set_penstyle(job, im, brush); - if (cstk[SP].pen != P_NONE) { - cstk[SP].pencolor_ix = vrml_resolve_color(cstk[SP].pencolor); - cstk[SP].fillcolor_ix = vrml_resolve_color(cstk[SP].fillcolor); - if (cstk[SP].pen == P_DASHED) { - for (i = 0; i < 10; i++) - style[i] = cstk[SP].pencolor_ix; - for (; i < 20; i++) - style[i] = gdTransparent; - gdImageSetStyle(im, style, 20); - pen = gdStyled; - } else if (cstk[SP].pen == P_DOTTED) { - for (i = 0; i < 2; i++) - style[i] = cstk[SP].pencolor_ix; - for (; i < 12; i++) - style[i] = gdTransparent; - gdImageSetStyle(im, style, 12); - pen = gdStyled; - } else { - pen = cstk[SP].pencolor_ix; - } - if (cstk[SP].penwidth != WIDTH_NORMAL) { - width = cstk[SP].penwidth; - brush = gdImageCreate(width, width); - gdImagePaletteCopy(brush, im); - gdImageFilledRectangle(brush, - 0, 0, width - 1, width - 1, - cstk[SP].pencolor_ix); - gdImageSetBrush(im, brush); - if (pen == gdStyled) - pen = gdStyledBrushed; - else - pen = gdBrushed; - } - points = N_GNEW(np, gdPoint); - for (i = 0; i < np; i++) { - mp = vrml_node_point(job, n, A[i]); - points[i].x = ROUND(mp.x); - points[i].y = ROUND(mp.y); - } - if (filled) - gdImageFilledPolygon(im, points, np, cstk[SP].fillcolor_ix); - gdImagePolygon(im, points, np, pen); - free(points); - if (brush) - gdImageDestroy(brush); + points = N_GNEW(np, gdPoint); + for (i = 0; i < np; i++) { + mp = vrml_node_point(job, n, A[i]); + points[i].x = ROUND(mp.x); + points[i].y = ROUND(mp.y); } + if (filled) + gdImageFilledPolygon(im, points, np, style->fillcolor.u.index); + gdImagePolygon(im, points, np, pen); + free(points); + if (brush) + gdImageDestroy(brush); fprintf(out, "Shape {\n"); fprintf(out, " appearance Appearance {\n"); @@ -703,12 +549,11 @@ static void vrml_polygon(GVJ_t *job, point * A, int np, int filled) fprintf(out, " ambientIntensity 0.33\n"); fprintf(out, " diffuseColor 1 1 1\n"); fprintf(out, " }\n"); - fprintf(out, " texture ImageTexture { url \"node%d.png\" }\n", - n->id); + fprintf(out, " texture ImageTexture { url \"node%d.png\" }\n", n->id); fprintf(out, " }\n"); fprintf(out, " geometry Extrusion {\n"); fprintf(out, " crossSection ["); - for (i = 0; i < n; i++) { + for (i = 0; i < np; i++) { p.x = A[i].x - ND_coord_i(n).x; p.y = A[i].y - ND_coord_i(n).y; fprintf(out, " %.3f %.3f,", p.x, p.y); @@ -724,8 +569,6 @@ static void vrml_polygon(GVJ_t *job, point * A, int np, int filled) } else if (e) { - if (cstk[SP].pen == P_NONE) - return; if (np != 3) { static int flag; if (!flag) { @@ -766,9 +609,8 @@ static void vrml_polygon(GVJ_t *job, point * A, int np, int filled) fprintf(out, " rotation 0 0 1 %.3f\n", theta); fprintf(out, " children [\n"); fprintf(out, " Shape {\n"); - fprintf(out, - " geometry Cone {bottomRadius %.3f height %.3f }\n", - cstk[SP].penwidth * 2.5, cstk[SP].penwidth * 10.0); + fprintf(out, " geometry Cone {bottomRadius %.3f height %.3f }\n", + style->penwidth * 2.5, style->penwidth * 10.0); fprintf(out, " appearance USE E%d\n", e->id); fprintf(out, " }\n"); fprintf(out, " ]\n"); @@ -782,20 +624,16 @@ static void vrml_polygon(GVJ_t *job, point * A, int np, int filled) * Output sphere in VRML for point nodes. */ static void -doSphere (FILE *out, node_t *n, point p, double z, int rx, int ry) +doSphere (FILE *out, node_t *n, pointf p, double z, double rx, double ry) { - pointf mp; - if (!(strcmp(cstk[SP].fillcolor, "transparent"))) { - return; - } +// if (!(strcmp(cstk[SP].fillcolor, "transparent"))) { +// return; +// } - mp.x = ND_coord_i(n).x; - mp.y = ND_coord_i(n).y; - fprintf(out, "Transform {\n"); - fprintf(out, " translation %.3f %.3f %.3f\n", mp.x, mp.y, z); - fprintf(out, " scale %d %d %d\n", rx, rx, rx); + fprintf(out, " translation %g %g %g\n", p.x, p.y, z); + fprintf(out, " scale %g %g %g\n", rx, rx, rx); fprintf(out, " children [\n"); fprintf(out, " Transform {\n"); fprintf(out, " children [\n"); @@ -804,8 +642,8 @@ doSphere (FILE *out, node_t *n, point p, double z, int rx, int ry) fprintf(out, " appearance Appearance {\n"); fprintf(out, " material Material {\n"); fprintf(out, " ambientIntensity 0.33\n"); - fprintf(out, " diffuseColor %f %f %f\n", - cstk[SP].r,cstk[SP].g,cstk[SP].b); +// fprintf(out, " diffuseColor %f %f %f\n", +// cstk[SP].r,cstk[SP].g,cstk[SP].b); fprintf(out, " }\n"); fprintf(out, " }\n"); fprintf(out, " }\n"); @@ -815,78 +653,51 @@ doSphere (FILE *out, node_t *n, point p, double z, int rx, int ry) fprintf(out, "}\n"); } -static void vrml_ellipse(GVJ_t *job, point p, int rx, int ry, int filled) +static void vrml_ellipse(GVJ_t * job, pointf * A, int filled) { FILE *out = job->output_file; + gvstyle_t *style = job->style; obj_state_t *obj = job->obj; node_t *n = obj->n; edge_t *e = obj->e; double z = obj->z; - pointf mp; - int i; - int style[40]; /* need 2* size for arcs, I don't know why */ - int pen, width; + double rx, ry; + int dx, dy; + pointf npf, nqf, mp; + point np; + int pen; gdImagePtr brush = NULL; + rx = A[1].x - A[0].x; + ry = A[1].y - A[0].y; + if (n) { + P2PF(ND_coord_i(n), mp); + if (shapeOf(n) == SH_POINT) { - doSphere (out, n, p, z, rx, ry); + doSphere (out, n, A[0], z, rx, ry); return; } - cstk[SP].pencolor_ix = vrml_resolve_color(cstk[SP].pencolor); - cstk[SP].fillcolor_ix = vrml_resolve_color(cstk[SP].fillcolor); - if (cstk[SP].pen != P_NONE) { - if (cstk[SP].pen == P_DASHED) { - for (i = 0; i < 20; i++) - style[i] = cstk[SP].pencolor_ix; - for (; i < 40; i++) - style[i] = gdTransparent; - gdImageSetStyle(im, style, 40); - pen = gdStyled; - } else if (cstk[SP].pen == P_DOTTED) { - for (i = 0; i < 2; i++) - style[i] = cstk[SP].pencolor_ix; - for (; i < 24; i++) - style[i] = gdTransparent; - gdImageSetStyle(im, style, 24); - pen = gdStyled; - } else { - pen = cstk[SP].pencolor_ix; - } - if (cstk[SP].penwidth != WIDTH_NORMAL) { - width = cstk[SP].penwidth; - brush = gdImageCreate(width, width); - gdImagePaletteCopy(brush, im); - gdImageFilledRectangle(brush, - 0, 0, width - 1, width - 1, - cstk[SP].pencolor_ix); - gdImageSetBrush(im, brush); - if (pen == gdStyled) - pen = gdStyledBrushed; - else - pen = gdBrushed; - } - mp = vrml_node_point(job, n, p); + pen = gdgen_set_penstyle(job, im, brush); - if (filled) { - gdImageFilledEllipse(im, ROUND(mp.x), ROUND(mp.y), - ROUND(Scale * (rx + rx)), - ROUND(Scale * (ry + ry)), - cstk[SP].fillcolor_ix); - } - gdImageArc(im, ROUND(mp.x), ROUND(mp.y), - ROUND(Scale * (rx + rx)), ROUND(Scale * (ry + ry)), - 0, 360, pen); - if (brush) - gdImageDestroy(brush); - } + npf = vrml_node_point(job, n, A[0]); + nqf = vrml_node_point(job, n, A[1]); - mp.x = ND_coord_i(n).x; - mp.y = ND_coord_i(n).y; + dx = ROUND(2 * (nqf.x - npf.x)); + dy = ROUND(2 * (nqf.y - npf.y)); + + PF2P(npf, np); + + if (filled) + gdImageFilledEllipse(im, np.x, np.y, dx, dy, style->fillcolor.u.index); + gdImageArc(im, np.x, np.y, dx, dy, 0, 360, pen); + + if (brush) + gdImageDestroy(brush); fprintf(out, "Transform {\n"); - fprintf(out, " translation %.3f %.3f %.3f\n", mp.x, mp.y, z); - fprintf(out, " scale %d %d 1\n", rx, ry); + fprintf(out, " translation %g %g %g\n", mp.x, mp.y, z); + fprintf(out, " scale %g %g 1\n", rx, ry); fprintf(out, " children [\n"); fprintf(out, " Transform {\n"); fprintf(out, " rotation 1 0 0 1.57\n"); @@ -905,24 +716,19 @@ static void vrml_ellipse(GVJ_t *job, point p, int rx, int ry, int filled) fprintf(out, " }\n"); fprintf(out, " ]\n"); fprintf(out, "}\n"); - } else if (e) { - if (cstk[SP].pen == P_NONE) - return; - mp.x = (double) p.x; - mp.y = (double) p.y; /* this is gruesome, but how else can we get z coord */ - if (DIST2(mp, ND_coord_i(e->tail)) < DIST2(mp, ND_coord_i(e->head))) + if (DIST2(A[0], ND_coord_i(e->tail)) < DIST2(A[0], ND_coord_i(e->head))) z = obj->tail_z; else z = obj->head_z; fprintf(out, "Transform {\n"); - fprintf(out, " translation %.3f %.3f %.3f\n", mp.x, mp.y, z); + fprintf(out, " translation %g %g %g\n", A[0].x, A[0].y, z); fprintf(out, " children [\n"); fprintf(out, " Shape {\n"); - fprintf(out, " geometry Sphere {radius %.3f }\n", (double) rx); + fprintf(out, " geometry Sphere {radius %g }\n", (double) rx); fprintf(out, " appearance USE E%d\n", e->id); fprintf(out, " }\n"); fprintf(out, " ]\n"); @@ -930,32 +736,8 @@ static void vrml_ellipse(GVJ_t *job, point p, int rx, int ry, int filled) } } -static void vrml_polyline(point * A, int n) +static void vrml_polyline(GVJ_t *job, pointf * A, int n) { -/* - pointf p, p1; - int i; - - if (cstk[SP].pen != P_NONE) { - p.x = A[0].x; - p.y = A[0].y; - for (i = 1; i < n; i++) { - p1.x = A[i].x; - p1.y = A[i].y; -#ifdef NONEOFTHISEITHER - if (cstk[SP].pen == P_DASHED) { - gdImageDashedLine(im, ROUND(p.x), ROUND(p.y), - ROUND(p1.x), ROUND(p1.y), cstk[SP].color_ix); - } else { - gdImageLine(im, ROUND(p.x), ROUND(p.y), - ROUND(p1.x), ROUND(p1.y), cstk[SP].color_ix); - } -#endif - p.x = p1.x; - p.y = p1.y; - } - } -*/ } static gvrender_engine_t vrml_engine = { @@ -1000,10 +782,13 @@ static gvrender_features_t vrml_features = { NULL, /* gvloadimage target for usershapes */ }; #endif /* HAVE_GD_PNG */ +#endif /* HAVE_LIBGD */ -gvplugin_installed_t gvrender_gd_types[] = { +gvplugin_installed_t gvrender_vrml_types[] = { +#ifdef HAVE_LIBGD #ifdef HAVE_GD_PNG {FORMAT_VRML, "vrml", 1, &vrml_engine, &vrml_features}, +#endif #endif {0, NULL, 0, NULL, NULL} }; diff --git a/plugin/pango/gvplugin_pango.c b/plugin/pango/gvplugin_pango.c index fc3ed1198..1c4204080 100644 --- a/plugin/pango/gvplugin_pango.c +++ b/plugin/pango/gvplugin_pango.c @@ -27,4 +27,4 @@ static gvplugin_api_t apis[] = { {(api_t)0, 0}, }; -gvplugin_library_t gvplugin_pango_LTX_library = { "pango", apis }; +gvplugin_library_t gvplugin_pango_LTX_library = { "cairo", apis }; -- 2.40.0