Esempio n. 1
0
static void vrml_textpara(GVJ_t *job, pointf p, textpara_t * para)
{
    obj_state_t *obj = job->obj;
    pointf spf, epf, q;

    if (! obj->u.n || ! im)   /* if not a node - or if no im (e.g. for cluster) */
	return;

    switch (para->just) {
    case 'l':
	break;
    case 'r':
	p.x -= para->width;
	break;
    default:
    case 'n':
	p.x -= para->width / 2;
	break;
    }
    q.x = p.x + para->width;
    q.y = p.y;

    spf = vrml_node_point(job, obj->u.n, p);
    epf = vrml_node_point(job, obj->u.n, q);

    gdgen_text(im, spf, epf,
	color_index(im, obj->pencolor),
	para->fontsize,
        DEFAULT_DPI,
	job->rotation ? (M_PI / 2) : 0,
	para->fontname,
	para->str);
}
Esempio n. 2
0
static int set_penstyle(GVJ_t * job, gdImagePtr im, gdImagePtr brush)
{
    obj_state_t *obj = job->obj;
    int i, pen, pencolor, transparent, width, dashstyle[40];

    pen = pencolor = color_index(im, obj->pencolor);
    transparent = gdImageGetTransparent(im);
    if (obj->pen == PEN_DASHED) {
        for (i = 0; i < 20; i++)
            dashstyle[i] = pencolor;
        for (; i < 40; i++)
            dashstyle[i] = transparent;
        gdImageSetStyle(im, dashstyle, 20);
        pen = gdStyled;
    } else if (obj->pen == PEN_DOTTED) {
        for (i = 0; i < 2; i++)
            dashstyle[i] = pencolor;
        for (; i < 24; i++)
            dashstyle[i] = transparent;
        gdImageSetStyle(im, dashstyle, 24);
        pen = gdStyled;
    }
    width = obj->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, pencolor);
        gdImageSetBrush(im, brush);
        if (pen == gdStyled)
            pen = gdStyledBrushed;
        else
            pen = gdBrushed;
    }
    return pen;
}
Esempio n. 3
0
static void vrml_ellipse(GVJ_t * job, pointf * A, int filled)
{
    FILE *out = job->output_file;
    obj_state_t *obj = job->obj;
    node_t *n;
    edge_t *e;
    double z = obj->z;
    double rx, ry;
    int dx, dy;
    pointf npf, nqf;
    point np;
    int pen;
    gdImagePtr brush = NULL;

    rx = A[1].x - A[0].x;
    ry = A[1].y - A[0].y;

    switch (obj->type) {
    case ROOTGRAPH_OBJTYPE:
    case CLUSTER_OBJTYPE:
	break;
    case NODE_OBJTYPE:
	n = obj->u.n;
	if (shapeOf(n) == SH_POINT) {
	    doSphere (job, n, A[0], z, rx, ry);
	    return;
	}
	pen = set_penstyle(job, im, brush);

	npf = vrml_node_point(job, n, A[0]);
	nqf = vrml_node_point(job, n, A[1]);

	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, color_index(im, obj->fillcolor));
	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", A[0].x, A[0].y, z);
	fprintf(out, "  scale %.3f %.3f 1\n", rx, ry);
	fprintf(out, "  children [\n");
	fprintf(out, "    Transform {\n");
	fprintf(out, "      rotation 1 0 0   1.57\n");
	fprintf(out, "      children [\n");
	fprintf(out, "        Shape {\n");
	fprintf(out, "          geometry Cylinder { side FALSE }\n");
	fprintf(out, "          appearance Appearance {\n");
	fprintf(out, "            material Material {\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, "          }\n");
	fprintf(out, "        }\n");
	fprintf(out, "      ]\n");
	fprintf(out, "    }\n");
	fprintf(out, "  ]\n");
	fprintf(out, "}\n");
	break;
    case EDGE_OBJTYPE:
	e = obj->u.e;
	/* this is gruesome, but how else can we get z coord */
	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", 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, "      appearance USE E%d\n", e->id);
	fprintf(out, "    }\n");
	fprintf(out, "  ]\n");
	fprintf(out, "}\n");
    }
}
Esempio n. 4
0
static void vrml_polygon(GVJ_t *job, pointf * A, int np, int filled)
{
    FILE *out = job->output_file;
    obj_state_t *obj = job->obj;
    node_t *n;
    edge_t *e;
    double z = obj->z;
    pointf p, mp;
    gdPoint *points;
    int i, pen;
    gdImagePtr brush = NULL;
    double theta;

    switch (obj->type) {
    case ROOTGRAPH_OBJTYPE:
	fprintf(out, " Background { skyColor %.3f %.3f %.3f }\n",
	    obj->fillcolor.u.rgba[0] / 255.,
	    obj->fillcolor.u.rgba[1] / 255.,
	    obj->fillcolor.u.rgba[2] / 255.);
	Saw_skycolor = TRUE;
	break;
    case CLUSTER_OBJTYPE:
	break;
    case NODE_OBJTYPE:
	n = obj->u.n;
	pen = set_penstyle(job, im, 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, color_index(im, obj->fillcolor));
	gdImagePolygon(im, points, np, pen);
	free(points);
	if (brush)
	    gdImageDestroy(brush);

	fprintf(out, "Shape {\n");
	fprintf(out, "  appearance Appearance {\n");
	fprintf(out, "    material Material {\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, "  }\n");
	fprintf(out, "  geometry Extrusion {\n");
	fprintf(out, "    crossSection [");
	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);
	}
	p.x = A[0].x - ND_coord_i(n).x;
	p.y = A[0].y - ND_coord_i(n).y;
	fprintf(out, " %.3f %.3f ]\n", p.x, p.y);
	fprintf(out, "    spine [ %d %d %.3f, %d %d %.3f ]\n",
		ND_coord_i(n).x, ND_coord_i(n).y, z - .01,
		ND_coord_i(n).x, ND_coord_i(n).y, z + .01);
	fprintf(out, "  }\n");
	fprintf(out, "}\n");
	break;
    case EDGE_OBJTYPE:
	e = obj->u.e;
	if (np != 3) {
	    static int flag;
	    if (!flag) {
		flag++;
		agerr(AGWARN,
		  "vrml_polygon: non-triangle arrowheads not supported - ignoring\n");
	    }
	}
	if (IsSegment) {
	    doArrowhead (job, A);
	    return;
	}
	p.x = p.y = 0.0;
	for (i = 0; i < np; i++) {
	    p.x += A[i].x;
	    p.y += A[i].y;
	}
	p.x = p.x / np;
	p.y = p.y / np;

	/* it is bad to know that A[1] is the aiming point, but we do */
	theta =
	    atan2((A[0].y + A[2].y) / 2.0 - A[1].y,
		  (A[0].x + A[2].x) / 2.0 - A[1].x) + M_PI / 2.0;

	/* this is gruesome, but how else can we get z coord */
	if (DIST2(p, ND_coord_i(e->tail)) < DIST2(p, ND_coord_i(e->head)))
	    z = obj->tail_z;
	else
	    z = obj->head_z;

	/* FIXME: arrow vector ought to follow z coord of bezier */
	fprintf(out, "Transform {\n");
	fprintf(out, "  translation %.3f %.3f %.3f\n", p.x, p.y, z);
	fprintf(out, "  children [\n");
	fprintf(out, "    Transform {\n");
	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",
		obj->penwidth * 2.5, obj->penwidth * 10.0);
	fprintf(out, "          appearance USE E%d\n", e->id);
	fprintf(out, "        }\n");
	fprintf(out, "      ]\n");
	fprintf(out, "    }\n");
	fprintf(out, "  ]\n");
	fprintf(out, "}\n");
	break;
    }
}
Esempio n. 5
0
/*
	long color codes look like '<yellow>', '<white>', '<hotkey>', etc.

	parsing the long color code is a slow function...
	but it makes programming with color coded strings a lot easier task

	it's more or less sorted in order of most frequent appearance to make
	it less slow

	cpos is the cursor position, which is used in <hline> and <center> tags
	for <hline>, the function recurses with Out_text()

	if dev is NULL, it produces no output
*/
int long_color_code(StringIO *dev, User *usr, char *code, int *cpos, int *lines, int max_lines, int dont_auto_color) {
int i, c, color;
char colorbuf[MAX_COLORBUF], buf[PRINT_BUF], *p;

	if (usr == NULL || code == NULL || !*code || cpos == NULL || lines == NULL)
		return 0;

	for(i = 0; i < NUM_COLORS; i++) {
		if (i == HOTKEY)
			continue;

		bufprintf(colorbuf, sizeof(colorbuf), "<%s>", color_table[i].name);

		if (!cstrnicmp(code, colorbuf, strlen(colorbuf))) {
			if (!(usr->flags & USR_ANSI))
				return strlen(colorbuf)-1;

			c = usr->color = color_table[i].key;

			color = Ansi_Color(usr, c);
			if (usr->flags & USR_BOLD)
				bufprintf(buf, sizeof(buf), "\x1b[1;%dm", color);
			else
				bufprintf(buf, sizeof(buf), "\x1b[%dm", color);
			put_StringIO(dev, buf);
			return strlen(colorbuf)-1;
		}
	}
/*
	Blinking is really irritating...

	if (!cstrnicmp(code, "<flash>", 7) || !cstrnicmp(code, "<blink>", 7)) {
		if (!(usr->flags & USR_ANSI))
			return 6;

		usr->color = KEY_CTRL('F');
		color = Ansi_Color(usr, KEY_CTRL('F'));
		if (usr->flags & USR_BOLD)
			bufprintf(buf, sizeof(buf), "\x1b[1;%dm", color);
		else
			bufprintf(buf, sizeof(buf), "\x1b[%dm", color);
		put_StringIO(dev, buf);
		return 6;
	}
*/
	if (!cstrnicmp(code, "<hotkey>", 8)) {
		c = code[8];
		if (!c)
			return 7;

		print_hotkey(usr, c, buf, sizeof(buf), cpos);
		put_StringIO(dev, buf);
		return 8;
	}
	if (!cstrnicmp(code, "<key>", 5)) {
		c = code[5];
		if (!c)
			return 4;
/*
	Don't do this; the <key> code is used in the Help files to keep this from happening

		if (usr->flags & USR_UPPERCASE_HOTKEYS)
			c = ctoupper(c);
*/
		if (usr->flags & USR_ANSI) {
			if (usr->flags & USR_BOLD)
				bufprintf(buf, sizeof(buf), "\x1b[1;%dm%c\x1b[1;%dm", color_table[usr->colors[HOTKEY]].value, c, Ansi_Color(usr, usr->color));
			else
				bufprintf(buf, sizeof(buf), "\x1b[%dm%c\x1b[%dm", color_table[usr->colors[HOTKEY]].value, c, Ansi_Color(usr, usr->color));

			(*cpos)++;
		} else {
			bufprintf(buf, sizeof(buf), "<%c>", c);
			*cpos += 3;
		}
		put_StringIO(dev, buf);
		return 5;
	}
	if (!cstrnicmp(code, "<beep>", 6)) {
		if (usr->flags & USR_BEEP)
			write_StringIO(dev, "\a", 1);
		return 5;
	}
	if (!cstrnicmp(code, "<normal>", 8)) {
		if (usr->flags & USR_ANSI) {
			bufprintf(buf, sizeof(buf), "\x1b[0;%dm", color_table[usr->colors[BACKGROUND]].value+10);
			put_StringIO(dev, buf);
		} else
			if (usr->flags & USR_BOLD)
				put_StringIO(dev, "\x1b[0m");

		if (usr->flags & USR_BOLD)
			put_StringIO(dev, "\x1b[1m");
		return 7;
	}
	if (!cstrnicmp(code, "<default>", 9)) {
		if (usr->flags & (USR_ANSI | USR_BOLD))
			put_StringIO(dev, "\x1b[0m");
		return 8;
	}
	if (!cstrnicmp(code, "<lt>", 4)) {
		if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
			auto_color(usr, colorbuf, MAX_COLORBUF);
			put_StringIO(dev, colorbuf);
		}
		write_StringIO(dev, "<", 1);
		(*cpos)++;

		if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
			restore_colorbuf(usr, usr->color, colorbuf, MAX_COLORBUF);
			put_StringIO(dev, colorbuf);
		}
		return 3;
	}
	if (!cstrnicmp(code, "<gt>", 4)) {
		if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
			auto_color(usr, colorbuf, MAX_COLORBUF);
			put_StringIO(dev, colorbuf);
		}
		write_StringIO(dev, ">", 1);
		(*cpos)++;

		if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
			restore_colorbuf(usr, usr->color, colorbuf, MAX_COLORBUF);
			put_StringIO(dev, colorbuf);
		}
		return 3;
	}

/*
	there are two special codes for use in help files and stuff...
	<hline> and <center>

	especially the code for hline is cryptic, but the idea is that
	it fills the line to the width of the terminal
*/
	if (!cstrnicmp(code, "<hline>", 7)) {
		int l;

		code += 7;
		if (!*code)
			return 6;

		c = ((usr->display->term_width-1) > PRINT_BUF) ? PRINT_BUF : (usr->display->term_width-1);
		cstrncpy(buf, code, c);
/*
	it stinks, but you have to remove all chars that can reset the cursor pos
*/
		p = buf;
		while(*p) {
			if (*p == KEY_CTRL('X') || *p == '\b')
				memmove(p, p+1, strlen(p+1)+1);
			else {
				if (*p == '\n') {		/* don't go over newlines */
					*p = 0;
					break;
				}
				p++;
			}
		}
		l = strlen(buf);
		i = color_strlen(buf);

		while(*cpos + i < usr->display->term_width-1)
			Out_text(dev, usr, buf, cpos, lines, max_lines, AUTO_COLOR_FORCED);	/* recurse */

		if (*cpos + i >= usr->display->term_width-1) {			/* 'partial put' of the remainder */
			buf[color_index(buf, c - *cpos)] = 0;
			Out_text(dev, usr, buf, cpos, lines, max_lines, AUTO_COLOR_FORCED);
		}
		return 6+l;
	}
	if (!cstrnicmp(code, "<center>", 8)) {
		code += 8;
		if (!*code)
			return 7;

		c = strlen(code);
		c = (c > PRINT_BUF) ? PRINT_BUF : c;
		cstrncpy(buf, code, c);
		buf[c-1] = 0;

		if ((p = cstrchr(buf, '\n')) != NULL)		/* don't go over newlines */
			*p = 0;

		i = (usr->display->term_width-1)/2 - color_strlen(buf)/2 - *cpos;
		while(i > 0) {
			write_StringIO(dev, " ", 1);
			(*cpos)++;
			i--;
		}
		return 7;
	}
	if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
		auto_color(usr, colorbuf, MAX_COLORBUF);
		put_StringIO(dev, colorbuf);
	}
	write_StringIO(dev, "<", 1);
	(*cpos)++;

	if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
		restore_colorbuf(usr, usr->color, colorbuf, MAX_COLORBUF);
		put_StringIO(dev, colorbuf);
	}
	return 0;
}