/* style flags */
#define FILLED (1 << 0)
-#define ROUNDED (1 << 1)
-#define DIAGONALS (1 << 2)
-#define AUXLABELS (1 << 3)
-#define INVISIBLE (1 << 4)
-#define DOGEAR (1 << 5)
-#define TAB (1 << 6)
-#define FOLDER (1 << 7)
-#define BOX3D (1 << 8)
-#define COMPONENT (1 << 9)
-#define GRADIENT (1 << 10)
-#define RGRADIENT GRADIENT + 1 /*radial gradient */
+#define RADIAL (1 << 1)
+#define ROUNDED (1 << 2)
+#define DIAGONALS (1 << 3)
+#define AUXLABELS (1 << 4)
+#define INVISIBLE (1 << 5)
+#define DOGEAR (1 << 6)
+#define TAB (1 << 7)
+#define FOLDER (1 << 8)
+#define BOX3D (1 << 9)
+#define COMPONENT (1 << 10)
+
+/* fill types */
+#define FILL 1
+#define GRADIENT 2
+#define RGRADIENT 3
/* label types */
#define LT_NONE (0 << 1)
obj->pen = parent->pen;
obj->fill = parent->fill;
obj->penwidth = parent->penwidth;
- obj->gradient.angle = parent->gradient.angle;
- obj->gradient.startcolor = parent->gradient.startcolor;
- obj->gradient.stopcolor = parent->gradient.stopcolor;
+ obj->gradient_angle = parent->gradient_angle;
+ obj->stopcolor = parent->stopcolor;
}
else {
/* obj->pencolor = NULL */
}
}
+static char **checkClusterStyle(graph_t* sg, int *flagp)
+{
+ char *style;
+ char **pstyle = 0;
+ int istyle = 0;
+
+ if (((style = agget(sg, "style")) != 0) && style[0]) {
+ char **pp;
+ char **qp;
+ char *p;
+ pp = pstyle = parse_style(style);
+ while ((p = *pp)) {
+ if (strcmp(p, "filled") == 0) {
+ istyle |= FILLED;
+ pp++;
+ }else if (strcmp(p, "radial") == 0) {
+ istyle |= (FILLED | RADIAL);
+ pp++;
+ }else if (strcmp(p, "rounded") == 0) {
+ istyle |= ROUNDED;
+ qp = pp; /* remove rounded from list passed to renderer */
+ do {
+ qp++;
+ *(qp-1) = *qp;
+ } while (*qp);
+ } else pp++;
+ }
+ }
+
+ *flagp = istyle;
+ return pstyle;
+}
+
void emit_map_rect(GVJ_t *job, boxf b)
{
obj_state_t *obj = job->obj;
free (pts);
}
+static boolean findStopColor (char* colorlist, char* clrs[2])
+{
+ char* p = strchr(colorlist,':');
+
+ if (p) {
+ char* s;
+ *p = '\0';
+ clrs[0] = strdup (colorlist);
+ *p++ = ':';
+ if (*p == '\0')
+ clrs[1] = NULL;
+ else if ((s = strchr(p,':'))) {
+ *s = '\0';
+ clrs[0] = strdup (p);
+ *s++ = ':';
+ }
+ else
+ clrs[1] = strdup (p);
+ return TRUE;
+ }
+ else return FALSE;
+}
+
static void emit_background(GVJ_t * job, graph_t *g)
{
xdot* xd;
- char *str,*fillcolor;
- int dfltColor,gradient;
+ char *str;
+ int dfltColor;
/* if no bgcolor specified - first assume default of "white" */
if (! ((str = agget(g, "bgcolor")) && str[0])) {
/* except for "transparent" on truecolor, or default "white" on (assumed) white paper, paint background */
if (!( ((job->flags & GVDEVICE_DOES_TRUECOLOR) && streq(str, "transparent"))
|| ((job->flags & GVRENDER_NO_WHITE_BG) && dfltColor))) {
- gvrender_set_fillcolor(job, str);
- gvrender_set_pencolor(job, str);
- gradient = findGradient(g,G_gradient);
- if(gradient > 0){
- if (! ((fillcolor = agget(g, "fillcolor")) && str[0]))
- fillcolor = str;
- gvrender_set_gradient(job,g,fillcolor,findGradientAngle(g,G_gradientangle));
- gvrender_box(job, job->clip,gradient); /* linear or radial gradient */
+ char* clrs[2];
+
+ if ((findStopColor (str, clrs))) {
+ int filled, istyle = 0;
+ gvrender_set_fillcolor(job, clrs[0]);
+ gvrender_set_pencolor(job, "transparent");
+ checkClusterStyle(g, &istyle);
+ if (clrs[1])
+ gvrender_set_gradient_vals(job,clrs[1],findGradientAngle(g,G_gradientangle));
+ else
+ gvrender_set_gradient_vals(job,DEFAULT_COLOR,findGradientAngle(g,G_gradientangle));
+ if (istyle & RADIAL)
+ filled = RGRADIENT;
+ else
+ filled = GRADIENT;
+ gvrender_box(job, job->clip, filled);
+ free (clrs[0]);
+ free (clrs[1]);
+ }
+ else {
+ gvrender_set_fillcolor(job, str);
+ gvrender_set_pencolor(job, str);
+ gvrender_box(job, job->clip, FILL); /* filled */
}
- else
- gvrender_box(job, job->clip, TRUE); /* filled */
}
if ((xd = (xdot*)GD_drawing(g)->xdots))
}
}
-static char **checkClusterStyle(graph_t* sg, int *flagp)
-{
- char *style;
- char **pstyle = 0;
- int istyle = 0;
-
- if (((style = agget(sg, "style")) != 0) && style[0]) {
- char **pp;
- char **qp;
- char *p;
- pp = pstyle = parse_style(style);
- while ((p = *pp)) {
- if (strcmp(p, "filled") == 0) {
- istyle |= FILLED;
- pp++;
- }else if (strcmp(p, "rounded") == 0) {
- istyle |= ROUNDED;
- qp = pp; /* remove rounded from list passed to renderer */
- do {
- qp++;
- *(qp-1) = *qp;
- } while (*qp);
- } else pp++;
- }
- }
-
- *flagp = istyle;
- return pstyle;
-}
-
static void emit_begin_cluster(GVJ_t * job, Agraph_t * sg)
{
obj_state_t *obj;
}
-/* cairogen_get_gradient_points
+/* get_gradient_points
* Evaluates the extreme points of an ellipse or polygon
* Determines the point at the center of the extreme points
- * Uses the angle parameter to identify two points on a line that defines the gradient direction
- *
+ * If isRadial is true,sets the inner radius to half the distance to the min point;
+ * else uses the angle parameter to identify two points on a line that defines the
+ * gradient direction
*/
-void cairogen_get_gradient_points(pointf * A, pointf * G, int n, float angle)
+void get_gradient_points(pointf * A, pointf * G, int n, float angle, boolean isRadial)
{
int i;
double rx, ry;
pointf min,max,center;
- if ( n == 2) {
+ if (n == 2) {
rx = A[1].x - A[0].x;
ry = A[1].y - A[0].y;
min.x = A[0].x - rx;
min.x = max.x = A[0].x;
min.y = max.y = A[0].y;
for (i = 0; i < n; i++){
- min.x = (A[i].x < min.x ? A[i].x : min.x);
- min.y = (A[i].y < min.y ? A[i].y : min.y);
- max.x = (A[i].x > max.x ? A[i].x : max.x);
- max.y = (A[i].y > max.y ? A[i].y : max.y);
- }
- }
- center.x = min.x + (max.x - min.x)/2;
- center.y = min.y + (max.y - min.y)/2;
- G[0].x = center.x - (max.x - center.x) * cos(angle);
- G[0].y = -center.y + (max.y - center.y) * sin(angle);
- G[1].x = center.x + (center.x - min.x) * cos(angle);
- G[1].y = -center.y - (center.y - min.y) * sin(angle);
-}
-
-/* cairogen_get_rgradient_points
- * Evaluates the extreme points of an ellipse or polygon
- * Determines the point at the center of the extreme points
- * Sets the inner radius to half the distance to the min point
- *
- */
-void cairogen_get_rgradient_points(pointf * A, pointf * G, int n)
-{
- int i;
- double rx, ry,inner_r,outer_r;
- pointf min,max,center;
-
- if ( n == 2) {
- rx = A[1].x - A[0].x;
- ry = A[1].y - A[0].y;
- min.x = A[0].x - rx;
- max.x = A[0].x + rx;
- min.y = A[0].y - ry;
- max.y = A[0].y + ry;
- }
- else {
- min.x = max.x = A[0].x;
- min.y = max.y = A[0].y;
- for (i = 0; i < n; i++){
- min.x = (A[i].x < min.x ? A[i].x : min.x);
- min.y = (A[i].y < min.y ? A[i].y : min.y);
- max.x = (A[i].x > max.x ? A[i].x : max.x);
- max.y = (A[i].y > max.y ? A[i].y : max.y);
+ min.x = MIN(A[i].x,min.x);
+ min.y = MIN(A[i].y,min.y);
+ max.x = MAX(A[i].x,max.x);
+ max.y = MAX(A[i].y,max.y);
}
}
center.x = min.x + (max.x - min.x)/2;
center.y = min.y + (max.y - min.y)/2;
+ if (isRadial) {
+ double inner_r, outer_r;
outer_r = sqrt((center.x - min.x)*(center.x - min.x) +
(center.y - min.y)*(center.y - min.y));
inner_r = outer_r /4.;
G[0].y = -center.y;
G[1].x = inner_r;
G[1].y = outer_r;
-
+ }
+ else {
+ G[0].x = center.x - (max.x - center.x) * cos(angle);
+ G[0].y = -center.y + (max.y - center.y) * sin(angle);
+ G[1].x = center.x + (center.x - min.x) * cos(angle);
+ G[1].y = -center.y - (center.y - min.y) * sin(angle);
+ }
}
#ifndef WIN32_STATIC
extern boolean overlap_label(textlabel_t *lp, boxf b);
extern boolean overlap_edge(edge_t *e, boxf b);
+ extern void get_gradient_points(pointf * A, pointf * G, int n, float angle, boolean isRadial);
+
extern int processClusterEdges(graph_t * g);
extern char *latin1ToUTF8(char *);
int alloc;
} gv_argvlist_t;
- typedef struct gv_gradient_s {
- int angle;
- gvcolor_t startcolor, stopcolor;
- int id;
- } gv_gradient_t;
-
typedef struct gvdevice_callbacks_s {
void (*refresh) (GVJ_t * job);
void (*button_press) (GVJ_t * job, int button, pointf pointer);
emit_state_t emit_state;
- gvcolor_t pencolor, fillcolor;
- gv_gradient_t gradient;
+ gvcolor_t pencolor, fillcolor, stopcolor;
+ int gradient_angle;
pen_type pen;
fill_type fill;
double penwidth;
extern void gvrender_set_pencolor(GVJ_t * job, char *name);
extern void gvrender_set_penwidth(GVJ_t * job, double penwidth);
extern void gvrender_set_fillcolor(GVJ_t * job, char *name);
- extern void gvrender_set_gradientcolor(GVJ_t * job, char *gr_color_ptr[2]);
- extern void gvrender_set_gradientAngle(GVJ_t * job, int angle);
- extern void gvrender_set_gradientId(GVJ_t * job);
extern void gvrender_set_gradient_attr(GVJ_t * job, void *g_obj, attrsym_t * color_attr, attrsym_t * angle_attr);
extern void gvrender_set_gradient(GVJ_t * job, void *g_obj, char *color, int angle);
extern char *gvrender_set_gradient_values(GVJ_t* job, char* gradcolor, int angle);
+ extern void gvrender_set_gradient_vals (GVJ_t * job, char *stopcolor, int angle);
extern void gvrender_set_style(GVJ_t * job, char **s);
extern void gvrender_ellipse(GVJ_t * job, pointf * AF, int n, int filled);
extern int emit_once(char *str);
extern shape_desc *find_user_shape(char *name);
-extern char *findGradientColor(void * n, char *pos, char *color, char *dflt);
-extern char *findAttrColor(void *obj, attrsym_t *colorattr, char *dflt);
-extern int findGradientAngle(void * n, attrsym_t * attr);
+extern char *findGradientColor(void *n, char *pos, char *color,
+ char *dflt);
+extern char *findAttrColor(void *obj, attrsym_t * colorattr, char *dflt);
+extern int findGradientAngle(void *n, attrsym_t * attr);
extern boolean mapbool(char *s);
#ifndef HAVE_STRCASECMP
/* job->flags = 0; */
plugin = gvc->api[API_device];
if (plugin) {
- typeptr = plugin->typeptr;
- job->device.engine = (gvdevice_engine_t *) (typeptr->engine);
- job->device.features = (gvdevice_features_t *) (typeptr->features);
- job->device.id = typeptr->id;
- job->device.type = plugin->typestr;
+ typeptr = plugin->typeptr;
+ job->device.engine = (gvdevice_engine_t *) (typeptr->engine);
+ job->device.features = (gvdevice_features_t *) (typeptr->features);
+ job->device.id = typeptr->id;
+ job->device.type = plugin->typestr;
+
+ job->flags |= job->device.features->flags;
+ } else
+ return NO_SUPPORT; /* FIXME - should differentiate problem */
- job->flags |= job->device.features->flags;
- }
- else
- return NO_SUPPORT; /* FIXME - should differentiate problem */
-
/* The device plugin has a dependency on a render plugin,
* so the render plugin should be available as well now */
plugin = gvc->api[API_render];
if (plugin) {
- typeptr = plugin->typeptr;
- job->render.engine = (gvrender_engine_t *) (typeptr->engine);
- job->render.features = (gvrender_features_t *) (typeptr->features);
- job->render.type = plugin->typestr;
+ typeptr = plugin->typeptr;
+ job->render.engine = (gvrender_engine_t *) (typeptr->engine);
+ job->render.features = (gvrender_features_t *) (typeptr->features);
+ job->render.type = plugin->typestr;
- job->flags |= job->render.features->flags;
+ job->flags |= job->render.features->flags;
- if (job->device.engine)
- job->render.id = typeptr->id;
+ if (job->device.engine)
+ job->render.id = typeptr->id;
else
/* A null device engine indicates that the device id is also the renderer id
* and that the renderer doesn't need "device" functions.
* Device "features" settings are still available */
- job->render.id = job->device.id;
- return GVRENDER_PLUGIN;
+ job->render.id = job->device.id;
+ return GVRENDER_PLUGIN;
}
job->render.engine = NULL;
- return NO_SUPPORT; /* FIXME - should differentiate problem */
+ return NO_SUPPORT; /* FIXME - should differentiate problem */
}
int gvrender_features(GVJ_t * job)
if (gvdevice_initialize(job))
return 1;
if (gvre) {
- if (gvre->begin_job)
+ if (gvre->begin_job)
gvre->begin_job(job);
}
return 0;
gvrender_engine_t *gvre = job->render.engine;
if (gvre) {
- if (gvre->end_job)
+ if (gvre->end_job)
gvre->end_job(job);
}
- job->gvc->common.lib = NULL; /* FIXME - minimally this doesn't belong here */
+ job->gvc->common.lib = NULL; /* FIXME - minimally this doesn't belong here */
gvdevice_finalize(job);
}
#define BOLD 1
#define ITALIC 2
-pointf gvrender_ptf(GVJ_t *job, pointf p)
+pointf gvrender_ptf(GVJ_t * job, pointf p)
{
pointf rv, translation, scale;
scale.y = job->zoom * job->devscale.y;
if (job->rotation) {
- rv.x = -(p.y + translation.y) * scale.x;
- rv.y = (p.x + translation.x) * scale.y;
+ rv.x = -(p.y + translation.y) * scale.x;
+ rv.y = (p.x + translation.x) * scale.y;
} else {
- rv.x = (p.x + translation.x) * scale.x;
- rv.y = (p.y + translation.y) * scale.y;
+ rv.x = (p.x + translation.x) * scale.x;
+ rv.y = (p.y + translation.y) * scale.y;
}
return rv;
}
/* transform an array of n points */
/* *AF and *af must be preallocated */
/* *AF can be the same as *af for inplace transforms */
-pointf* gvrender_ptf_A(GVJ_t *job, pointf *af, pointf *AF, int n)
+pointf *gvrender_ptf_A(GVJ_t * job, pointf * af, pointf * AF, int n)
{
int i;
double t;
scale.y = job->zoom * job->devscale.y;
if (job->rotation) {
- for (i = 0; i < n; i++) {
- t = -(af[i].y + translation.y) * scale.x;
- AF[i].y = (af[i].x + translation.x) * scale.y;
+ for (i = 0; i < n; i++) {
+ t = -(af[i].y + translation.y) * scale.x;
+ AF[i].y = (af[i].x + translation.x) * scale.y;
AF[i].x = t;
}
- }
- else {
- for (i = 0; i < n; i++) {
- AF[i].x = (af[i].x + translation.x) * scale.x;
- AF[i].y = (af[i].y + translation.y) * scale.y;
+ } else {
+ for (i = 0; i < n; i++) {
+ AF[i].x = (af[i].x + translation.x) * scale.x;
+ AF[i].y = (af[i].y + translation.y) * scale.y;
}
}
return AF;
color->u.string = name;
color->type = COLOR_STRING;
tok = canontoken(name);
- if (!features->knowncolors || (bsearch(&tok, features->knowncolors, features->sz_knowncolors,
- sizeof(char *), gvrender_comparestr)) == NULL) {
+ if (!features->knowncolors
+ ||
+ (bsearch
+ (&tok, features->knowncolors, features->sz_knowncolors,
+ sizeof(char *), gvrender_comparestr)) == NULL) {
/* if tok was not found in known_colors */
rc = colorxlate(name, color, features->color_type);
if (rc != COLOR_OK) {
if (emit_once(missedcolor))
agerr(AGWARN, "%s is not a known color.\n", name);
free(missedcolor);
- }
- else {
+ } else {
agerr(AGERR, "error in colxlate()\n");
}
}
void gvrender_begin_graph(GVJ_t * job, graph_t * g)
{
- GVC_t *gvc = job->gvc;
+ /* GVC_t *gvc = job->gvc; */
gvrender_engine_t *gvre = job->render.engine;
- char *s;
+ /* char *s; */
if (gvre) {
/* render specific init */
if (gvre->begin_graph)
gvre->begin_graph(job);
+#if 0
/* background color */
if (((s = agget(g, "bgcolor")) != 0) && s[0]) {
- gvrender_resolve_color(job->render.features, s, &(gvc->bgcolor));
+ gvrender_resolve_color(job->render.features, s,
+ &(gvc->bgcolor));
if (gvre->resolve_color)
gvre->resolve_color(job, &(gvc->bgcolor));
}
+#endif
}
}
gvrender_engine_t *gvre = job->render.engine;
if (gvre) {
- if (gvre->end_graph)
+ if (gvre->end_graph)
gvre->end_graph(job);
}
gvdevice_format(job);
gvrender_engine_t *gvre = job->render.engine;
if (gvre) {
- if (gvre->begin_page)
+ if (gvre->begin_page)
gvre->begin_page(job);
}
}
gvrender_engine_t *gvre = job->render.engine;
if (gvre) {
- if (gvre->end_page)
+ if (gvre->end_page)
gvre->end_page(job);
}
}
if (gvre) {
if (gvre->begin_layer)
- gvre->begin_layer(job, job->gvc->layerIDs[job->layerNum], job->layerNum, job->numLayers);
+ gvre->begin_layer(job, job->gvc->layerIDs[job->layerNum],
+ job->layerNum, job->numLayers);
}
}
gvrender_engine_t *gvre = job->render.engine;
if (gvre) {
- if (gvre->end_layer)
+ if (gvre->end_layer)
gvre->end_layer(job);
}
}
}
}
-void gvrender_end_cluster(GVJ_t * job, graph_t *g)
+void gvrender_end_cluster(GVJ_t * job, graph_t * g)
{
gvrender_engine_t *gvre = job->render.engine;
if (gvre) {
- if (gvre->end_cluster)
+ if (gvre->end_cluster)
gvre->end_cluster(job);
}
}
}
}
-void gvrender_begin_anchor(GVJ_t * job, char *href, char *tooltip, char *target, char *id)
+void gvrender_begin_anchor(GVJ_t * job, char *href, char *tooltip,
+ char *target, char *id)
{
gvrender_engine_t *gvre = job->render.engine;
void gvrender_begin_label(GVJ_t * job, label_type type)
{
gvrender_engine_t *gvre = job->render.engine;
-
+
if (gvre) {
- if (gvre->begin_label)
- gvre->begin_label(job, type);
+ if (gvre->begin_label)
+ gvre->begin_label(job, type);
}
}
void gvrender_end_label(GVJ_t * job)
{
gvrender_engine_t *gvre = job->render.engine;
-
+
if (gvre) {
- if (gvre->end_label)
- gvre->end_label(job);
+ if (gvre->end_label)
+ gvre->end_label(job);
}
}
pointf PF;
if (para->str && para->str[0]
- && ( ! job->obj /* because of xdgen non-conformity */
- || job->obj->pen != PEN_NONE)) {
+ && (!job->obj /* because of xdgen non-conformity */
+ || job->obj->pen != PEN_NONE)) {
if (job->flags & GVRENDER_DOES_TRANSFORM)
PF = p;
else
gvcolor_t *color = &(job->obj->pencolor);
char *cp = NULL;
- if ((cp = strstr(name, ":"))) /* if its a color list, then use only first */
+ if ((cp = strstr(name, ":"))) /* if its a color list, then use only first */
*cp = '\0';
if (gvre) {
gvrender_resolve_color(job->render.features, name, color);
if (gvre->resolve_color)
gvre->resolve_color(job, color);
}
- if (cp) /* restore color list */
+ if (cp) /* restore color list */
*cp = ':';
}
gvcolor_t *color = &(job->obj->fillcolor);
char *cp = NULL;
- if ((cp = strstr(name, ":"))) /* if its a color list, then use only first */
+ if ((cp = strstr(name, ":"))) /* if its a color list, then use only first */
*cp = '\0';
if (gvre) {
gvrender_resolve_color(job->render.features, name, color);
*cp = ':';
}
-void gvrender_set_gradientcolor(GVJ_t * job, char *gr_color_ptr[2])
+static void gvrender_set_gradientcolor(GVJ_t * job, char *colors[2])
{
gvrender_engine_t *gvre = job->render.engine;
gvcolor_t *color;
- char * start_color, * stop_color;
-
- start_color = gr_color_ptr[0];
- stop_color = gr_color_ptr[1];
- if (gvre && gr_color_ptr[0] != NULL && gr_color_ptr[1] != NULL) {
- color = &(job->obj->gradient.startcolor);
- gvrender_resolve_color(job->render.features, start_color, color);
- if (gvre->resolve_color)
- gvre->resolve_color(job, color);
- color = &(job->obj->gradient.stopcolor);
- gvrender_resolve_color(job->render.features, stop_color, color);
- if (gvre->resolve_color)
- gvre->resolve_color(job, color);
- }
-}
-
-void gvrender_set_gradientAngle(GVJ_t * job, int angle)
-{
- obj_state_t *obj = job->obj;
- obj->gradient.angle = angle;
-
-}
-static int gradientId;
-void gvrender_set_gradientId(GVJ_t * job){
-
- obj_state_t *obj = job->obj;
- obj->gradient.id = gradientId++;
-}
-
-void gvrender_set_gradient_attr(GVJ_t * job, void *g_obj, attrsym_t * color_attr, attrsym_t * angle_attr){
- char *color;
- int angle;
-
- if(color_attr != NULL) {
- color = N_GNEW(GR_SZ,char);
- strcpy(color,findAttrColor(g_obj, color_attr, ""));
- if ( angle_attr != NULL )
- angle = findGradientAngle(g_obj,angle_attr);
- else
- angle = 0;
- gvrender_set_gradient(job, g_obj, color, angle);
- free(color);
- }
-
-}
-
-void gvrender_set_gradient(GVJ_t * job, void *g_obj, char * color, int angle){
-char *gradcolor = NULL,*startcolor,*stopcolor;
-
- if(color != NULL) {
- gradcolor = N_GNEW((2 * GR_SZ)+1,char);
- startcolor = strdup(color);
- stopcolor = strdup(color);
- findGradientColor(g_obj,GR_START,startcolor,DEFAULT_FILL);
- strcpy(gradcolor,startcolor);
- strcat(gradcolor,":");
- strcat(gradcolor,findGradientColor(g_obj,GR_STOP, stopcolor, startcolor)); /* use start color as stop color if : missing */
- gvrender_set_gradient_values(job,gradcolor,angle);
- free(startcolor);
- free(stopcolor);
- free(gradcolor);
- }
-
+
+ if (gvre && colors[0]) {
+ color = &(job->obj->fillcolor);
+ gvrender_resolve_color(job->render.features, colors[0], color);
+ if (gvre->resolve_color)
+ gvre->resolve_color(job, color);
+ }
+ if (gvre && colors[1]) {
+ color = &(job->obj->stopcolor);
+ gvrender_resolve_color(job->render.features, colors[1], color);
+ if (gvre->resolve_color)
+ gvre->resolve_color(job, color);
+ }
+}
+
+void gvrender_set_gradient_attr(GVJ_t * job, void *g_obj,
+ attrsym_t * color_attr,
+ attrsym_t * angle_attr)
+{
+ char *color;
+ int angle;
+
+ if (color_attr != NULL) {
+ color = N_GNEW(GR_SZ, char);
+ strcpy(color, findAttrColor(g_obj, color_attr, ""));
+ if (angle_attr != NULL)
+ angle = findGradientAngle(g_obj, angle_attr);
+ else
+ angle = 0;
+ gvrender_set_gradient(job, g_obj, color, angle);
+ free(color);
+ }
+
+}
+
+void gvrender_set_gradient(GVJ_t * job, void *g_obj, char *color,
+ int angle)
+{
+ char *gradcolor = NULL, *startcolor, *stopcolor;
+
+ if (color != NULL) {
+ gradcolor = N_GNEW((2 * GR_SZ) + 1, char);
+ startcolor = strdup(color);
+ stopcolor = strdup(color);
+ findGradientColor(g_obj, GR_START, startcolor, DEFAULT_FILL);
+ strcpy(gradcolor, startcolor);
+ strcat(gradcolor, ":");
+ strcat(gradcolor, findGradientColor(g_obj, GR_STOP, stopcolor, startcolor)); /* use start color as stop color if : missing */
+ gvrender_set_gradient_values(job, gradcolor, angle);
+ free(startcolor);
+ free(stopcolor);
+ free(gradcolor);
+ }
+
}
static char gradientcolor[2][GR_SZ];
-char *gvrender_set_gradient_values(GVJ_t* job, char* gradcolor, int angle){
+char *gvrender_set_gradient_values(GVJ_t * job, char *gradcolor, int angle)
+{
char *gr_color_ptr[2], *ptr;
gr_color_ptr[0] = gradientcolor[0];
gr_color_ptr[1] = gradientcolor[1];
gr_color_ptr[0][GR_SZ - 1] = gr_color_ptr[0][0] = 0;
gr_color_ptr[1][GR_SZ - 1] = gr_color_ptr[1][0] = 0;
- if(gradcolor != NULL && gradcolor[0]){
- ptr= strstr(gradcolor,":");
- if(ptr != NULL){
- *ptr = '\0';
- ++ptr;
- if(ptr[0])
- strncpy(gr_color_ptr[1],ptr,GR_SZ - 1);
- else
- strncpy(gr_color_ptr[1],gradcolor,GR_SZ - 1); //use start color as stop color
- }
- else
- strncpy(gr_color_ptr[1],gradcolor,GR_SZ - 1); //use start color as stop color
- strncpy(gr_color_ptr[0],gradcolor,GR_SZ - 1);
- gvrender_set_gradientcolor(job, gr_color_ptr);
- gvrender_set_gradientAngle(job,angle);
- gvrender_set_gradientId(job);
+ if (gradcolor != NULL && gradcolor[0]) {
+ ptr = strstr(gradcolor, ":");
+ if (ptr != NULL) {
+ *ptr = '\0';
+ ++ptr;
+ if (ptr[0])
+ strncpy(gr_color_ptr[1], ptr, GR_SZ - 1);
+ else
+ strncpy(gr_color_ptr[1], gradcolor, GR_SZ - 1); //use start color as stop color
+ } else
+ strncpy(gr_color_ptr[1], gradcolor, GR_SZ - 1); //use start color as stop color
+ strncpy(gr_color_ptr[0], gradcolor, GR_SZ - 1);
+ gvrender_set_gradientcolor(job, gr_color_ptr);
+ job->obj->gradient_angle = angle;
}
return gr_color_ptr[1];
}
+void gvrender_set_gradient_vals (GVJ_t * job, char *stopcolor, int angle)
+{
+ gvrender_engine_t *gvre = job->render.engine;
+ gvcolor_t *color = &(job->obj->stopcolor);
+
+ if (gvre) {
+ gvrender_resolve_color(job->render.features, stopcolor, color);
+ if (gvre->resolve_color)
+ gvre->resolve_color(job, color);
+ }
+ job->obj->gradient_angle = angle;
+}
void gvrender_set_style(GVJ_t * job, char **s)
{
obj->rawstyle = s;
if (gvre) {
- if (s) while ((p = line = *s++)) {
- if (streq(line, "solid"))
- obj->pen = PEN_SOLID;
- else if (streq(line, "dashed"))
- obj->pen = PEN_DASHED;
- else if (streq(line, "dotted"))
- obj->pen = PEN_DOTTED;
- else if (streq(line, "invis") || streq(line, "invisible"))
- obj->pen = PEN_NONE;
- else if (streq(line, "bold"))
- obj->penwidth = PENWIDTH_BOLD;
- else if (streq(line, "setlinewidth")) {
- while (*p)
+ if (s)
+ while ((p = line = *s++)) {
+ if (streq(line, "solid"))
+ obj->pen = PEN_SOLID;
+ else if (streq(line, "dashed"))
+ obj->pen = PEN_DASHED;
+ else if (streq(line, "dotted"))
+ obj->pen = PEN_DOTTED;
+ else if (streq(line, "invis") || streq(line, "invisible"))
+ obj->pen = PEN_NONE;
+ else if (streq(line, "bold"))
+ obj->penwidth = PENWIDTH_BOLD;
+ else if (streq(line, "setlinewidth")) {
+ while (*p)
+ p++;
p++;
- p++;
- obj->penwidth = atof(p);
- } else if (streq(line, "filled"))
- obj->fill = FILL_SOLID;
- else if (streq(line, "unfilled"))
- obj->fill = FILL_NONE;
- else if (streq(line, "tapered"))
- ;
- else {
- agerr(AGWARN,
- "gvrender_set_style: unsupported style %s - ignoring\n",
- line);
+ obj->penwidth = atof(p);
+ } else if (streq(line, "filled"))
+ obj->fill = FILL_SOLID;
+ else if (streq(line, "unfilled"))
+ obj->fill = FILL_NONE;
+ else if (streq(line, "tapered"));
+ else {
+ agerr(AGWARN,
+ "gvrender_set_style: unsupported style %s - ignoring\n",
+ line);
+ }
}
- }
}
}
pointf af[2];
/* center */
- af[0].x = (pf[0].x + pf[1].x)/2.;
- af[0].y = (pf[0].y + pf[1].y)/2.;
+ af[0].x = (pf[0].x + pf[1].x) / 2.;
+ af[0].y = (pf[0].y + pf[1].y) / 2.;
/* corner */
af[1] = pf[1];
- if (! (job->flags & GVRENDER_DOES_TRANSFORM))
- gvrender_ptf_A(job, af, af, 2);
+ if (!(job->flags & GVRENDER_DOES_TRANSFORM))
+ gvrender_ptf_A(job, af, af, 2);
gvre->ellipse(job, af, filled);
}
}
if (job->flags & GVRENDER_DOES_TRANSFORM)
gvre->polygon(job, af, n, filled);
else {
- if (sizeAF < n) {
- sizeAF = n+10;
+ if (sizeAF < n) {
+ sizeAF = n + 10;
AF = grealloc(AF, sizeAF * sizeof(pointf));
- }
- gvrender_ptf_A(job, af, AF, n);
- gvre->polygon(job, AF, n, filled);
+ }
+ gvrender_ptf_A(job, af, AF, n);
+ gvre->polygon(job, AF, n, filled);
}
}
}
A[1].y = A[2].y;
A[3].x = A[2].x;
A[3].y = A[0].y;
-
+
gvrender_polygon(job, A, 4, filled);
}
void gvrender_beziercurve(GVJ_t * job, pointf * af, int n,
- int arrow_at_start, int arrow_at_end, boolean filled)
+ int arrow_at_start, int arrow_at_end,
+ boolean filled)
{
gvrender_engine_t *gvre = job->render.engine;
if (gvre) {
if (gvre->beziercurve && job->obj->pen != PEN_NONE) {
if (job->flags & GVRENDER_DOES_TRANSFORM)
- gvre->beziercurve(job, af, n, arrow_at_start, arrow_at_end,filled);
+ gvre->beziercurve(job, af, n, arrow_at_start, arrow_at_end,
+ filled);
else {
- if (sizeAF < n) {
- sizeAF = n+10;
+ if (sizeAF < n) {
+ sizeAF = n + 10;
AF = grealloc(AF, sizeAF * sizeof(pointf));
- }
- gvrender_ptf_A(job, af, AF, n);
- gvre->beziercurve(job, AF, n, arrow_at_start, arrow_at_end,filled);
+ }
+ gvrender_ptf_A(job, af, AF, n);
+ gvre->beziercurve(job, AF, n, arrow_at_start, arrow_at_end,
+ filled);
}
}
}
if (gvre) {
if (gvre->polyline && job->obj->pen != PEN_NONE) {
if (job->flags & GVRENDER_DOES_TRANSFORM)
- gvre->polyline(job, af, n);
- else {
- if (sizeAF < n) {
- sizeAF = n+10;
+ gvre->polyline(job, af, n);
+ else {
+ if (sizeAF < n) {
+ sizeAF = n + 10;
AF = grealloc(AF, sizeAF * sizeof(pointf));
- }
- gvrender_ptf_A(job, af, AF, n);
- gvre->polyline(job, AF, n);
+ }
+ gvrender_ptf_A(job, af, AF, n);
+ gvre->polyline(job, AF, n);
}
}
}
static imagescale_t get_imagescale(char *s)
{
- if (*s == '\0') return IMAGESCALE_FALSE;
- if (!strcasecmp(s, "width")) return IMAGESCALE_WIDTH;
- if (!strcasecmp(s, "height")) return IMAGESCALE_HEIGHT;
- if (!strcasecmp(s, "both")) return IMAGESCALE_BOTH;
- if (mapbool(s)) return IMAGESCALE_TRUE;
- return IMAGESCALE_FALSE;
+ if (*s == '\0')
+ return IMAGESCALE_FALSE;
+ if (!strcasecmp(s, "width"))
+ return IMAGESCALE_WIDTH;
+ if (!strcasecmp(s, "height"))
+ return IMAGESCALE_HEIGHT;
+ if (!strcasecmp(s, "both"))
+ return IMAGESCALE_BOTH;
+ if (mapbool(s))
+ return IMAGESCALE_TRUE;
+ return IMAGESCALE_FALSE;
}
/* gvrender_usershape:
* Scale image to fill polygon bounding box according to "imagescale"
*/
-void gvrender_usershape(GVJ_t * job, char *name, pointf * a, int n,
- boolean filled, char *imagescale)
+void gvrender_usershape(GVJ_t * job, char *name, pointf * a, int n,
+ boolean filled, char *imagescale)
{
gvrender_engine_t *gvre = job->render.engine;
usershape_t *us;
double iw, ih, pw, ph;
- double scalex, scaley; /* scale factors */
- boxf b; /* target box */
+ double scalex, scaley; /* scale factors */
+ boxf b; /* target box */
int i;
- point isz;
+ point isz;
- if (! (us = gvusershape_find(name))) {
+ if (!(us = gvusershape_find(name))) {
if (find_user_shape(name)) {
if (gvre && gvre->library_shape)
- gvre->library_shape(job, name, a, n, filled);
+ gvre->library_shape(job, name, a, n, filled);
}
- return;
+ return;
}
- isz = gvusershape_size_dpi (us, job->dpi);
- if ((isz.x <= 0) && (isz.y <= 0)) return;
+ isz = gvusershape_size_dpi(us, job->dpi);
+ if ((isz.x <= 0) && (isz.y <= 0))
+ return;
/* compute bb of polygon */
b.LL = b.UR = a[0];
pw = b.UR.x - b.LL.x;
ph = b.UR.y - b.LL.y;
- ih = (double)isz.y;
- iw = (double)isz.x;
+ ih = (double) isz.y;
+ iw = (double) isz.x;
scalex = pw / iw;
scaley = ph / ih;
switch (get_imagescale(imagescale)) {
case IMAGESCALE_TRUE:
- /* keep aspect ratio fixed by just using the smaller scale */
+ /* keep aspect ratio fixed by just using the smaller scale */
if (scalex < scaley) {
iw *= scalex;
ih *= scalex;
/* if image is smaller than target area then center it */
if (iw < pw) {
- b.LL.x += (pw - iw) / 2.0;
- b.UR.x -= (pw - iw) / 2.0;
+ b.LL.x += (pw - iw) / 2.0;
+ b.UR.x -= (pw - iw) / 2.0;
}
if (ih < ph) {
- b.LL.y += (ph - ih) / 2.0;
- b.UR.y -= (ph - ih) / 2.0;
+ b.LL.y += (ph - ih) / 2.0;
+ b.UR.y -= (ph - ih) / 2.0;
}
/* convert from graph to device coordinates */
gvrender_engine_t *gvre = job->render.engine;
if (gvre) {
- job->obj->penwidth = penwidth;
- /*if (gvre->set_penwidth) gvre->set_penwidth(job, penwidth);*/
+ job->obj->penwidth = penwidth;
+ /*if (gvre->set_penwidth) gvre->set_penwidth(job, penwidth); */
}
}
#include "const.h"
#include "gvplugin_render.h"
+#include "agxbuf.h"
+#include "utils.h"
#include "gvplugin_device.h"
#include "gvio.h"
#include "gvcint.h"
-extern char *strdup_and_subst_obj(char *str, void *obj);
-
typedef enum { FORMAT_SVG, FORMAT_SVGZ, } format_type;
-extern char *xml_string(char *str);
-extern char *xml_url_string(char *str);
-extern void cairogen_get_gradient_points(pointf * A, pointf * G, int n, float angle);
-extern void cairogen_get_rgradient_points(pointf * A, pointf * G, int n);
-
/* SVG dash array */
static char *sdasharray = "5,2";
/* SVG dot array */
gvputs(job, color.u.string);
break;
case RGBA_BYTE:
- if (color.u.rgba[3] == 0) /* transparent */
+ 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]);
+ color.u.rgba[0], color.u.rgba[1], color.u.rgba[2]);
break;
default:
assert(0); /* internal error */
}
}
-static void svg_grstyle(GVJ_t * job, int filled)
+static void svg_grstyle(GVJ_t * job, int filled, int gid)
{
obj_state_t *obj = job->obj;
- char sgid[11];
gvputs(job, " fill=\"");
- if (filled == GRADIENT){
- sprintf(sgid,"%d",obj->gradient.id);
- gvprintf(job,"url(#l_%s)",sgid);
- }
- else if (filled == RGRADIENT){
- sprintf(sgid,"%d",obj->gradient.id);
- gvprintf(job,"url(#r_%s)",sgid);
- }
- else if (filled) {
+ if (filled == GRADIENT) {
+ gvprintf(job, "url(#l_%d)", gid);
+ } else if (filled == RGRADIENT) {
+ gvprintf(job, "url(#r_%d)", gid);
+ } else if (filled) {
svg_print_color(job, obj->fillcolor);
- if (obj->fillcolor.type == RGBA_BYTE && obj->fillcolor.u.rgba[3] > 0 && obj->fillcolor.u.rgba[3] < 255 )
- gvprintf(job, "\" fill-opacity=\"%f", ((float)obj->fillcolor.u.rgba[3]/255.0));
+ if (obj->fillcolor.type == RGBA_BYTE
+ && obj->fillcolor.u.rgba[3] > 0
+ && obj->fillcolor.u.rgba[3] < 255)
+ gvprintf(job, "\" fill-opacity=\"%f",
+ ((float) obj->fillcolor.u.rgba[3] / 255.0));
gvputs(job, "\" stroke=\"");
svg_print_color(job, obj->pencolor);
- }
- else {
+ } else {
gvputs(job, "none");
gvputs(job, "\" stroke=\"");
svg_print_color(job, obj->pencolor);
} else if (obj->pen == PEN_DOTTED) {
gvprintf(job, "\" stroke-dasharray=\"%s", sdotarray);
}
- if (obj->pencolor.type == RGBA_BYTE && obj->pencolor.u.rgba[3] > 0 && obj->pencolor.u.rgba[3] < 255)
- gvprintf(job, "\" stroke-opacity=\"%f", ((float)obj->pencolor.u.rgba[3]/255.0));
+ if (obj->pencolor.type == RGBA_BYTE && obj->pencolor.u.rgba[3] > 0
+ && obj->pencolor.u.rgba[3] < 255)
+ gvprintf(job, "\" stroke-opacity=\"%f",
+ ((float) obj->pencolor.u.rgba[3] / 255.0));
gvputs(job, "\"");
}
static void svg_begin_job(GVJ_t * job)
{
char *s;
- gvputs(job, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
+ gvputs(job,
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
if ((s = agget(job->gvc->g, "stylesheet")) && s[0]) {
- gvputs(job, "<?xml-stylesheet href=\"");
- gvputs(job, s);
- gvputs(job, "\" type=\"text/css\"?>\n");
+ gvputs(job, "<?xml-stylesheet href=\"");
+ gvputs(job, s);
+ gvputs(job, "\" type=\"text/css\"?>\n");
}
#if 0
gvputs(job, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n");
- gvputs(job, " \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"");
+ gvputs(job,
+ " \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"");
/* This is to work around a bug in the SVG 1.0 DTD */
- gvputs(job, " [\n <!ATTLIST svg xmlns:xlink CDATA #FIXED \"http://www.w3.org/1999/xlink\">\n]");
+ gvputs(job,
+ " [\n <!ATTLIST svg xmlns:xlink CDATA #FIXED \"http://www.w3.org/1999/xlink\">\n]");
#else
- gvputs(job, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
- gvputs(job, " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
+ gvputs(job, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
+ gvputs(job,
+ " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
#endif
gvputs(job, "<!-- Generated by ");
gvputs(job, "<!--");
if (agnameof(obj->u.g)[0]) {
- gvputs(job, " Title: ");
+ gvputs(job, " Title: ");
gvputs(job, xml_string(agnameof(obj->u.g)));
}
- gvprintf(job, " Pages: %d -->\n", job->pagesArraySize.x * job->pagesArraySize.y);
+ gvprintf(job, " Pages: %d -->\n",
+ job->pagesArraySize.x * job->pagesArraySize.y);
gvprintf(job, "<svg width=\"%dpt\" height=\"%dpt\"\n",
- job->width, job->height);
+ job->width, job->height);
gvprintf(job, " viewBox=\"%.2f %.2f %.2f %.2f\"",
- job->canvasBox.LL.x, job->canvasBox.LL.y,
- job->canvasBox.UR.x, job->canvasBox.UR.y);
+ job->canvasBox.LL.x, job->canvasBox.LL.y,
+ job->canvasBox.UR.x, job->canvasBox.UR.y);
/* namespace of svg */
gvputs(job, " xmlns=\"http://www.w3.org/2000/svg\"");
/* namespace of xlink */
gvputs(job, "</svg>\n");
}
-static void svg_begin_layer(GVJ_t * job, char *layername, int layerNum, int numLayers)
+static void svg_begin_layer(GVJ_t * job, char *layername, int layerNum,
+ int numLayers)
{
gvputs(job, "<g id=\"");
gvputs(job, xml_string(layername));
gvputs(job, "<g id=\"");
gvputs(job, xml_string(obj->id));
gvputs(job, "\" class=\"graph\"");
- gvprintf(job, " transform=\"scale(%g %g) rotate(%d) translate(%g %g)\">\n",
- job->scale.x, job->scale.y, -job->rotation,
- job->translation.x, -job->translation.y);
+ gvprintf(job,
+ " transform=\"scale(%g %g) rotate(%d) translate(%g %g)\">\n",
+ job->scale.x, job->scale.y, -job->rotation,
+ job->translation.x, -job->translation.y);
/* default style */
if (agnameof(obj->u.g)[0]) {
- gvputs(job, "<title>");
- gvputs(job, xml_string(agnameof(obj->u.g)));
- gvputs(job, "</title>\n");
+ gvputs(job, "<title>");
+ gvputs(job, xml_string(agnameof(obj->u.g)));
+ gvputs(job, "</title>\n");
}
}
gvputs(job, "</g>\n");
}
-static void
-svg_begin_edge(GVJ_t * job)
+static void svg_begin_edge(GVJ_t * job)
{
obj_state_t *obj = job->obj;
char *ename;
gvputs(job, "<g id=\"");
gvputs(job, xml_string(obj->id));
gvputs(job, "\" class=\"edge\">");
-
+
gvputs(job, "<title>");
- ename = strdup_and_subst_obj("\\E", (void*)(obj->u.e));
+ ename = strdup_and_subst_obj("\\E", (void *) (obj->u.e));
gvputs(job, xml_string(ename));
free(ename);
gvputs(job, "</title>\n");
}
static void
-svg_begin_anchor(GVJ_t * job, char *href, char *tooltip, char *target, char *id)
+svg_begin_anchor(GVJ_t * job, char *href, char *tooltip, char *target,
+ char *id)
{
gvputs(job, "<a");
#if 0
* it changes the behavior in browsers, the link apears in the bottom information bar
*/
else {
- assert (id && id[0]); /* there should always be an id available */
+ assert(id && id[0]); /* there should always be an id available */
gvputs(job, " xlink:href=\"#");
- gvputs(job, xml_url_string(href));
- gvputs(job, "\"");
+ gvputs(job, xml_url_string(href));
+ gvputs(job, "\"");
}
#endif
if (tooltip && tooltip[0]) {
- gvputs(job, " xlink:title=\"");
+ gvputs(job, " xlink:title=\"");
gvputs(job, xml_string(tooltip));
gvputs(job, "\"");
}
{
obj_state_t *obj = job->obj;
PostscriptAlias *pA;
- char *family=NULL, *weight=NULL, *stretch=NULL, *style=NULL;
+ char *family = NULL, *weight = NULL, *stretch = NULL, *style = NULL;
int flags;
gvputs(job, "<text");
gvprintf(job, " x=\"%g\" y=\"%g\"", p.x, -p.y);
pA = para->postscript_alias;
if (pA) {
- switch(GD_fontnames(job->gvc->g)) {
- case PSFONTS:
- family = pA->name;
- weight = pA->weight;
- style = pA->style;
- break;
- case SVGFONTS:
- family = pA->svg_font_family;
- weight = pA->svg_font_weight;
- style = pA->svg_font_style;
- break;
- default:
- case NATIVEFONTS:
- family = pA->family;
- weight = pA->weight;
- style = pA->style;
- break;
+ switch (GD_fontnames(job->gvc->g)) {
+ case PSFONTS:
+ family = pA->name;
+ weight = pA->weight;
+ style = pA->style;
+ break;
+ case SVGFONTS:
+ family = pA->svg_font_family;
+ weight = pA->svg_font_weight;
+ style = pA->svg_font_style;
+ break;
+ default:
+ case NATIVEFONTS:
+ family = pA->family;
+ weight = pA->weight;
+ style = pA->style;
+ break;
}
stretch = pA->stretch;
- gvprintf(job, " font-family=\"%s", family);
- if (pA->svg_font_family) gvprintf(job, ",%s", pA->svg_font_family);
- gvputs(job, "\"");
- if (weight) gvprintf(job, " font-weight=\"%s\"", weight);
- if (stretch) gvprintf(job, " font-stretch=\"%s\"", stretch);
- if (style) gvprintf(job, " font-style=\"%s\"", style);
- }
- else
+ gvprintf(job, " font-family=\"%s", family);
+ if (pA->svg_font_family)
+ gvprintf(job, ",%s", pA->svg_font_family);
+ gvputs(job, "\"");
+ if (weight)
+ gvprintf(job, " font-weight=\"%s\"", weight);
+ if (stretch)
+ gvprintf(job, " font-stretch=\"%s\"", stretch);
+ if (style)
+ gvprintf(job, " font-style=\"%s\"", style);
+ } else
gvprintf(job, " font-family=\"%s\"", para->fontname);
if ((para->font) && (flags = para->font->flags)) {
- if ((flags & HTML_BF) && !weight) gvprintf(job, " font-weight=\"bold\"");
- if ((flags & HTML_IF) && !style) gvprintf(job, " font-style=\"italic\"");
- if ((flags & HTML_UL)) gvprintf(job, " text-decoration=\"underline\"");
- if ((flags & HTML_SUP)) gvprintf(job, " baseline-shift=\"super\"");
- if ((flags & HTML_SUB)) gvprintf(job, " baseline-shift=\"sub\"");
+ if ((flags & HTML_BF) && !weight)
+ gvprintf(job, " font-weight=\"bold\"");
+ if ((flags & HTML_IF) && !style)
+ gvprintf(job, " font-style=\"italic\"");
+ if ((flags & HTML_UL))
+ gvprintf(job, " text-decoration=\"underline\"");
+ if ((flags & HTML_SUP))
+ gvprintf(job, " baseline-shift=\"super\"");
+ if ((flags & HTML_SUB))
+ gvprintf(job, " baseline-shift=\"sub\"");
}
gvprintf(job, " font-size=\"%.2f\"", para->fontsize);
break;
case RGBA_BYTE:
gvprintf(job, " fill=\"#%02x%02x%02x\"",
- obj->pencolor.u.rgba[0], obj->pencolor.u.rgba[1], obj->pencolor.u.rgba[2]);
+ obj->pencolor.u.rgba[0], obj->pencolor.u.rgba[1],
+ obj->pencolor.u.rgba[2]);
break;
default:
assert(0); /* internal error */
gvputs(job, "</text>\n");
}
+static int gradId;
+
/* svg_gradstyle
* Outputs the SVG statements that define the gradient pattern
*/
-static void svg_gradstyle(GVJ_t * job, pointf * A, int n)
+static int svg_gradstyle(GVJ_t * job, pointf * A, int n)
{
- pointf G[2];
- float angle;
- char sgid[11];
-
- obj_state_t *obj = job->obj;
- angle = obj->gradient.angle * M_PI / 180; //angle of gradient line
- G[0].x = G[0].y = G[1].x = G[1].y = 0.;
- cairogen_get_gradient_points(A, G, n, angle); //get points on gradient line
- sprintf(sgid,"%d",obj->gradient.id);
-
- gvprintf(job, "<defs>\n<linearGradient id=\"l_%s\" gradientUnits=\"userSpaceOnUse\" ",sgid);
- gvprintf(job,"x1=\"%g\" y1=\"%g\" x2=\"%g\" y2=\"%g\" >\n", G[0].x,G[0].y,G[1].x,G[1].y);
- gvputs(job,"<stop offset=\"0\" style=\"stop-color:");
- svg_print_color(job, obj->gradient.startcolor);
- gvputs(job,";stop-opacity:");
- if (obj->gradient.startcolor.type == RGBA_BYTE && obj->gradient.startcolor.u.rgba[3] > 0 && obj->gradient.startcolor.u.rgba[3] < 255 )
- gvprintf(job, "%f", ((float)obj->gradient.startcolor.u.rgba[3]/255.0));
- else gvputs(job,"1.");
- gvputs(job,";\"/>\n");
- gvputs(job,"<stop offset=\"1\" style=\"stop-color:");
- svg_print_color(job, obj->gradient.stopcolor);
- gvputs(job,";stop-opacity:");
- if (obj->gradient.stopcolor.type == RGBA_BYTE && obj->gradient.stopcolor.u.rgba[3] > 0 && obj->gradient.stopcolor.u.rgba[3] < 255 )
- gvprintf(job, "%f", ((float)obj->gradient.stopcolor.u.rgba[3]/255.0));
- else gvputs(job,"1.");
- gvputs(job,";\"/>\n</linearGradient>\n</defs>\n");
+ pointf G[2];
+ float angle;
+ int id = gradId++;
+
+ obj_state_t *obj = job->obj;
+ angle = obj->gradient_angle * M_PI / 180; //angle of gradient line
+ G[0].x = G[0].y = G[1].x = G[1].y = 0.;
+ get_gradient_points(A, G, n, angle, 0); //get points on gradient line
+
+ gvprintf(job,
+ "<defs>\n<linearGradient id=\"l_%d\" gradientUnits=\"userSpaceOnUse\" ", id);
+ gvprintf(job, "x1=\"%g\" y1=\"%g\" x2=\"%g\" y2=\"%g\" >\n", G[0].x,
+ G[0].y, G[1].x, G[1].y);
+ gvputs(job, "<stop offset=\"0\" style=\"stop-color:");
+ svg_print_color(job, obj->fillcolor);
+ gvputs(job, ";stop-opacity:");
+ if (obj->fillcolor.type == RGBA_BYTE && obj->fillcolor.u.rgba[3] > 0
+ && obj->fillcolor.u.rgba[3] < 255)
+ gvprintf(job, "%f", ((float) obj->fillcolor.u.rgba[3] / 255.0));
+ else
+ gvputs(job, "1.");
+ gvputs(job, ";\"/>\n");
+ gvputs(job, "<stop offset=\"1\" style=\"stop-color:");
+ svg_print_color(job, obj->stopcolor);
+ gvputs(job, ";stop-opacity:");
+ if (obj->stopcolor.type == RGBA_BYTE && obj->stopcolor.u.rgba[3] > 0
+ && obj->stopcolor.u.rgba[3] < 255)
+ gvprintf(job, "%f", ((float) obj->stopcolor.u.rgba[3] / 255.0));
+ else
+ gvputs(job, "1.");
+ gvputs(job, ";\"/>\n</linearGradient>\n</defs>\n");
+ return id;
}
-/* svg_gradstyle
+/* svg_rgradstyle
* Outputs the SVG statements that define the radial gradient pattern
*/
-static void svg_rgradstyle(GVJ_t * job, pointf * A, int n)
+static int svg_rgradstyle(GVJ_t * job, pointf * A, int n)
{
- pointf G[2];
- float angle;
- char fx[5],fy[5],sgid[11];
- int ifx,ify;
-
- obj_state_t *obj = job->obj;
- angle = obj->gradient.angle * M_PI / 180; //angle of gradient line
- G[0].x = G[0].y = G[1].x = G[1].y = G[2].x = G[2].y= 0.;
- cairogen_get_rgradient_points(A, G, n);
- if(angle == 0.){
+ pointf G[2];
+ float angle;
+ int ifx, ify;
+ int id = gradId++;
+
+ obj_state_t *obj = job->obj;
+ angle = obj->gradient_angle * M_PI / 180; //angle of gradient line
+ G[0].x = G[0].y = G[1].x = G[1].y;
+ get_gradient_points(A, G, n, 0, 1);
+ if (angle == 0.) {
ifx = ify = 50;
- }
- else {
- ifx = 50*(1 + cos(angle));
- ify = 50*(1 - sin(angle));
- }
- sprintf(sgid,"%d",obj->gradient.id);
- sprintf(fx,"%d%%",ifx);
- sprintf(fy,"%d%%",ify);
- gvprintf(job, "<defs>\n<radialGradient id=\"r_%s\" cx=\"50%\" cy=\"50%\" r=\"75%\" fx=",sgid);
- gvprintf(job,"\"%s\"",fx);
- gvputs(job," fy=");
- gvprintf(job,"\"%s\">\n",fy);
- gvputs(job,"<stop offset=\"0\" style=\"stop-color:");
- svg_print_color(job, obj->gradient.startcolor);
- gvputs(job,";stop-opacity:");
- if (obj->gradient.startcolor.type == RGBA_BYTE && obj->gradient.startcolor.u.rgba[3] > 0 && obj->gradient.startcolor.u.rgba[3] < 255 )
- gvprintf(job, "%f", ((float)obj->gradient.startcolor.u.rgba[3]/255.0));
- else gvputs(job,"1.");
- gvputs(job,";\"/>\n");
- gvputs(job,"<stop offset=\"1\" style=\"stop-color:");
- svg_print_color(job, obj->gradient.stopcolor);
- gvputs(job,";stop-opacity:");
- if (obj->gradient.stopcolor.type == RGBA_BYTE && obj->gradient.stopcolor.u.rgba[3] > 0 && obj->gradient.stopcolor.u.rgba[3] < 255 )
- gvprintf(job, "%f", ((float)obj->gradient.stopcolor.u.rgba[3]/255.0));
- else gvputs(job,"1.");
- gvputs(job,";\"/>\n</radialGradient>\n</defs>\n");
+ } else {
+ ifx = 50 * (1 + cos(angle));
+ ify = 50 * (1 - sin(angle));
+ }
+ gvprintf(job,
+ "<defs>\n<radialGradient id=\"r_%d\" cx=\"50%%\" cy=\"50%%\" r=\"75%%\" fx=\"%d%%\" fy=\"%d%%\">\n",
+ id, ifx, ify);
+ gvputs(job, "<stop offset=\"0\" style=\"stop-color:");
+ svg_print_color(job, obj->fillcolor);
+ gvputs(job, ";stop-opacity:");
+ if (obj->fillcolor.type == RGBA_BYTE && obj->fillcolor.u.rgba[3] > 0
+ && obj->fillcolor.u.rgba[3] < 255)
+ gvprintf(job, "%f", ((float) obj->fillcolor.u.rgba[3] / 255.0));
+ else
+ gvputs(job, "1.");
+ gvputs(job, ";\"/>\n");
+ gvputs(job, "<stop offset=\"1\" style=\"stop-color:");
+ svg_print_color(job, obj->stopcolor);
+ gvputs(job, ";stop-opacity:");
+ if (obj->stopcolor.type == RGBA_BYTE && obj->stopcolor.u.rgba[3] > 0
+ && obj->stopcolor.u.rgba[3] < 255)
+ gvprintf(job, "%f", ((float) obj->stopcolor.u.rgba[3] / 255.0));
+ else
+ gvputs(job, "1.");
+ gvputs(job, ";\"/>\n</radialGradient>\n</defs>\n");
+ return id;
}
static void svg_ellipse(GVJ_t * job, pointf * A, int filled)
{
+ int gid = 0;
+
/* A[] contains 2 points: the center and corner. */
if (filled == GRADIENT) {
- svg_gradstyle(job,A,2);
- }
- else if (filled == (RGRADIENT)){
- svg_rgradstyle(job,A,2);
+ gid = svg_gradstyle(job, A, 2);
+ } else if (filled == (RGRADIENT)) {
+ gid = svg_rgradstyle(job, A, 2);
}
gvputs(job, "<ellipse");
- svg_grstyle(job, filled);
+ svg_grstyle(job, filled, gid);
gvprintf(job, " cx=\"%g\" cy=\"%g\"", A[0].x, -A[0].y);
gvprintf(job, " rx=\"%g\" ry=\"%g\"",
- A[1].x - A[0].x, A[1].y - A[0].y);
+ A[1].x - A[0].x, A[1].y - A[0].y);
gvputs(job, "/>\n");
}
static void
svg_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
- int arrow_at_end, int filled)
+ int arrow_at_end, int filled)
{
gvputs(job, "<path");
- svg_grstyle(job, filled);
+ svg_grstyle(job, filled, 0);
gvputs(job, " d=\"");
svg_bzptarray(job, A, n);
gvputs(job, "\"/>\n");
static void svg_polygon(GVJ_t * job, pointf * A, int n, int filled)
{
- int i;
+ int i, gid = 0;
if (filled == GRADIENT) {
- svg_gradstyle(job,A,n);
- }
- else if (filled == (RGRADIENT)){
- svg_rgradstyle(job,A,n);
+ gid = svg_gradstyle(job, A, n);
+ } else if (filled == (RGRADIENT)) {
+ gid = svg_rgradstyle(job, A, n);
}
gvputs(job, "<polygon");
- svg_grstyle(job, filled);
+ svg_grstyle(job, filled, gid);
gvputs(job, " points=\"");
for (i = 0; i < n; i++)
gvprintf(job, "%g,%g ", A[i].x, -A[i].y);
int i;
gvputs(job, "<polyline");
- svg_grstyle(job, 0);
+ svg_grstyle(job, 0, 0);
gvputs(job, " points=\"");
for (i = 0; i < n; i++)
gvprintf(job, "%g,%g ", A[i].x, -A[i].y);
svg_begin_anchor,
svg_end_anchor,
0, /* svg_begin_anchor */
- 0, /* svg_end_anchor */
+ 0, /* svg_end_anchor */
svg_textpara,
0, /* svg_resolve_color */
svg_ellipse,
};
gvrender_features_t render_features_svg = {
- GVRENDER_Y_GOES_DOWN
- | GVRENDER_DOES_TRANSFORM
- | GVRENDER_DOES_LABELS
- | GVRENDER_DOES_MAPS
- | GVRENDER_DOES_TARGETS
- | GVRENDER_DOES_TOOLTIPS, /* flags */
- 4., /* default pad - graph units */
+ GVRENDER_Y_GOES_DOWN | GVRENDER_DOES_TRANSFORM | GVRENDER_DOES_LABELS | GVRENDER_DOES_MAPS | GVRENDER_DOES_TARGETS | GVRENDER_DOES_TOOLTIPS, /* flags */
+ 4., /* default pad - graph units */
svg_knowncolors, /* knowncolors */
sizeof(svg_knowncolors) / sizeof(char *), /* sizeof knowncolors */
RGBA_BYTE, /* color_type */
gvdevice_features_t device_features_svg = {
GVDEVICE_DOES_TRUECOLOR, /* flags */
- {0.,0.}, /* default margin - points */
- {0.,0.}, /* default page width, height - points */
- {72.,72.}, /* default dpi */
+ {0., 0.}, /* default margin - points */
+ {0., 0.}, /* default page width, height - points */
+ {72., 72.}, /* default dpi */
};
gvdevice_features_t device_features_svgz = {
- GVDEVICE_BINARY_FORMAT
- | GVDEVICE_COMPRESSED_FORMAT
- | GVDEVICE_DOES_TRUECOLOR,/* flags */
- {0.,0.}, /* default margin - points */
- {0.,0.}, /* default page width, height - points */
- {72.,72.}, /* default dpi */
+ GVDEVICE_BINARY_FORMAT | GVDEVICE_COMPRESSED_FORMAT | GVDEVICE_DOES_TRUECOLOR, /* flags */
+ {0., 0.}, /* default margin - points */
+ {0., 0.}, /* default page width, height - points */
+ {72., 72.}, /* default dpi */
};
gvplugin_installed_t gvrender_svg_types[] = {
#include "const.h"
#include "gvplugin_render.h"
+#include "agxbuf.h"
+#include "utils.h"
#include "gvplugin_device.h"
#include "gvio.h"
#ifdef HAVE_PANGOCAIRO
#include <pango/pangocairo.h>
-extern void cairogen_get_gradient_points(pointf * A, pointf * G, int n, float angle);
-extern void cairogen_get_rgradient_points(pointf * A, pointf * G, int n);
typedef enum {
FORMAT_CAIRO,
cairo_set_matrix(cr, &matrix);
if (filled == GRADIENT || filled == (RGRADIENT)) {
- angle = obj->gradient.angle * M_PI / 180;
+ angle = obj->gradient_angle * M_PI / 180;
if(filled == GRADIENT) {
- angle = obj->gradient.angle * M_PI / 180;
- cairogen_get_gradient_points(A, G, 2, angle);
+ get_gradient_points(A, G, 2, angle, 0);
pat = cairo_pattern_create_linear (G[0].x,G[0].y,G[1].x,G[1].y);
}
else {
- cairogen_get_rgradient_points(A, G, 2);
+ get_gradient_points(A, G, 2, 0, 1);
//r1 is inner radius, r2 is outter radius
r1 = G[1].x;
r2 = G[1].y;
//r1 is inner radius, r2 is outter radius
pat = cairo_pattern_create_radial(c1.x,c1.y,r1,c2.x,c2.y,r2);
}
- cairogen_add_color_stop_rgba(pat,0,&(obj->gradient.startcolor));
- cairogen_add_color_stop_rgba(pat,1,&(obj->gradient.stopcolor));
+ cairogen_add_color_stop_rgba(pat,0,&(obj->fillcolor));
+ cairogen_add_color_stop_rgba(pat,1,&(obj->stopcolor));
cairo_set_source (cr, pat);
cairo_fill_preserve (cr);
cairo_pattern_destroy (pat);
cairo_line_to(cr, A[i].x, -A[i].y);
cairo_close_path(cr);
if (filled == GRADIENT || filled == (RGRADIENT)) {
- angle = obj->gradient.angle * M_PI / 180;
+ angle = obj->gradient_angle * M_PI / 180;
if(filled == GRADIENT) {
- cairogen_get_gradient_points(A, G, n, angle);
+ get_gradient_points(A, G, n, angle, 0);
pat = cairo_pattern_create_linear (G[0].x,G[0].y,G[1].x,G[1].y);
}
else {
- cairogen_get_rgradient_points(A, G, n);
+ get_gradient_points(A, G, n, 0, 1);
r1 = G[1].x;
r2 = G[1].y;
if (angle == 0) {
//r1 is inner radius, r2 is outter radius
pat = cairo_pattern_create_radial(c1.x,c1.y,r1,c2.x,c2.y,r2);
}
- cairogen_add_color_stop_rgba(pat,0,&(obj->gradient.startcolor));
- cairogen_add_color_stop_rgba(pat,1,&(obj->gradient.stopcolor));
+ cairogen_add_color_stop_rgba(pat,0,&(obj->fillcolor));
+ cairogen_add_color_stop_rgba(pat,1,&(obj->stopcolor));
cairo_set_source (cr, pat);
cairo_fill_preserve (cr);
cairo_pattern_destroy (pat);