#include "gvplugin_render.h"
+
#ifdef HAVE_LIBGD
#include "gd.h"
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
/* 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;
}
}
-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,
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;
}
}
{
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);
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),
#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() */
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;
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
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)
color->type = COLOR_INDEX;
}
-static int white, black, transparent, basecolor;
-
static void vrml_begin_page(GVJ_t *job)
{
FILE *out = job->output_file;
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)
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);
}
}
if (shapeOf(n) != SH_POINT) {
gdImagePng(im, PNGfile);
gdImageDestroy(im);
- im = 0;
+ im = NULL;
fclose(PNGfile);
}
}
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;
if (! obj->n)
return;
- PF2P(pf, p);
switch (para->just) {
case 'l':
break;
* 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;
* 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);
}
* 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;
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;
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;
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");
/* 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;
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");
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");
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);
}
else if (e) {
- if (cstk[SP].pen == P_NONE)
- return;
if (np != 3) {
static int flag;
if (!flag) {
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");
* 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");
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");
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");
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");
}
}
-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 = {
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}
};