static void cairo_gradient_fill (cairo_t* cr, obj_state_t* obj, int filled, pointf* A, int n) { cairo_pattern_t* pat; float angle = obj->gradient_angle * M_PI / 180; float r1,r2; pointf G[2],c1; if (filled == GRADIENT) { 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 { get_gradient_points(A, G, n, 0, 1); //r1 is inner radius, r2 is outer radius r1 = G[1].x; /* Set a r2/4 in get_gradient_points */ r2 = G[1].y; if (angle == 0) { c1.x = G[0].x; c1.y = G[0].y; } else { c1.x = G[0].x + r1 * cos(angle); c1.y = G[0].y - r1 * sin(angle); } pat = cairo_pattern_create_radial(c1.x,c1.y,r1,G[0].x,G[0].y,r2); } if (obj->gradient_frac > 0) { cairogen_add_color_stop_rgba(pat,obj->gradient_frac - 0.001,&(obj->fillcolor)); cairogen_add_color_stop_rgba(pat,obj->gradient_frac,&(obj->stopcolor)); } else { 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); }
/* svg_gradstyle * Outputs the SVG statements that define the gradient pattern */ static int svg_gradstyle(GVJ_t * job, pointf * A, int n) { pointf G[2]; float angle; static int gradId; 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); if (obj->gradient_frac > 0) gvprintf(job, "<stop offset=\"%.03f\" style=\"stop-color:", obj->gradient_frac - 0.001); else 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"); if (obj->gradient_frac > 0) gvprintf(job, "<stop offset=\"%.03f\" style=\"stop-color:", obj->gradient_frac); else 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; }
static void xdot_gradient_fillcolor (GVJ_t* job, int filled, pointf* A, int n) { unsigned char buf0[BUFSIZ]; agxbuf xbuf; obj_state_t* obj = job->obj; float angle = obj->gradient_angle * M_PI / 180; float r1,r2; pointf G[2],c1,c2; if (xd->version < 14) { xdot_fillcolor (job); return; } agxbinit(&xbuf, BUFSIZ, buf0); if (filled == GRADIENT) { get_gradient_points(A, G, n, angle, 2); agxbputc (&xbuf, '['); xdot_point (&xbuf, G[0]); xdot_point (&xbuf, G[1]); } else { get_gradient_points(A, G, n, 0, 3); //r1 is inner radius, r2 is outer radius r1 = G[1].x; r2 = G[1].y; if (angle == 0) { c1.x = G[0].x; c1.y = G[0].y; } else { c1.x = G[0].x + (r2/4) * cos(angle); c1.y = G[0].y + (r2/4) * sin(angle); } c2.x = G[0].x; c2.y = G[0].y; r1 = r2/4; agxbputc(&xbuf, '('); xdot_point (&xbuf, c1); xdot_num (&xbuf, r1); xdot_point (&xbuf, c2); xdot_num (&xbuf, r2); } agxbput(&xbuf, "2 "); if (obj->gradient_frac > 0) { xdot_color_stop (&xbuf, obj->gradient_frac, &obj->fillcolor); xdot_color_stop (&xbuf, obj->gradient_frac, &obj->stopcolor); } else { xdot_color_stop (&xbuf, 0, &obj->fillcolor); xdot_color_stop (&xbuf, 1, &obj->stopcolor); } agxbpop(&xbuf); if (filled == GRADIENT) agxbputc(&xbuf, ']'); else agxbputc(&xbuf, ')'); xdot_str (job, "C ", agxbuse(&xbuf)); agxbfree(&xbuf); }