static void _gradient_do (gpointer key, gpointer value, gpointer user_data) { DiaPattern *pattern = (DiaPattern *)value; GradientData *gd = (GradientData *)user_data; DiaSvgRenderer *renderer = gd->renderer; xmlNodePtr parent = gd->node; xmlNodePtr gradient; DiaPatternType pt; guint flags; Point p1, p2; gchar vbuf[DTOSTR_BUF_SIZE]; real scale = renderer->scale; dia_pattern_get_settings (pattern, &pt, &flags); if ((flags & DIA_PATTERN_USER_SPACE)==0) scale = 1.0; dia_pattern_get_points (pattern, &p1, &p2); if (pt == DIA_LINEAR_GRADIENT) { gradient = xmlNewChild (parent, parent->ns, (const xmlChar *)"linearGradient", NULL); xmlSetProp (gradient, (const xmlChar *)"x1", (const xmlChar *)g_ascii_formatd(vbuf,sizeof(vbuf),"%g", p1.x * scale)); xmlSetProp (gradient, (const xmlChar *)"y1", (const xmlChar *)g_ascii_formatd(vbuf,sizeof(vbuf),"%g", p1.y * scale)); xmlSetProp (gradient, (const xmlChar *)"x2", (const xmlChar *)g_ascii_formatd(vbuf,sizeof(vbuf),"%g", p2.x * scale)); xmlSetProp (gradient, (const xmlChar *)"y2", (const xmlChar *)g_ascii_formatd(vbuf,sizeof(vbuf),"%g", p2.y * scale)); } else if (pt == DIA_RADIAL_GRADIENT) { real r; dia_pattern_get_radius (pattern, &r); gradient = xmlNewChild (parent, parent->ns, (const xmlChar *)"radialGradient", NULL); xmlSetProp (gradient, (const xmlChar *)"cx", (const xmlChar *)g_ascii_formatd(vbuf,sizeof(vbuf),"%g", p1.x * scale)); xmlSetProp (gradient, (const xmlChar *)"cy", (const xmlChar *)g_ascii_formatd(vbuf,sizeof(vbuf),"%g", p1.y * scale)); xmlSetProp (gradient, (const xmlChar *)"fx", (const xmlChar *)g_ascii_formatd(vbuf,sizeof(vbuf),"%g", p2.x * scale)); xmlSetProp (gradient, (const xmlChar *)"fy", (const xmlChar *)g_ascii_formatd(vbuf,sizeof(vbuf),"%g", p2.y * scale)); xmlSetProp (gradient, (const xmlChar *)"r", (const xmlChar *)g_ascii_formatd(vbuf,sizeof(vbuf),"%g", r * scale)); } else { gradient = xmlNewChild (parent, parent->ns, (const xmlChar *)"pattern", NULL); } /* don't miss to set the id */ { gchar *id = _make_pattern_key (pattern); xmlSetProp (gradient, (const xmlChar *)"id", (const xmlChar *)id); g_free (id); } if (flags & DIA_PATTERN_USER_SPACE) xmlSetProp (gradient, (const xmlChar *)"gradientUnits", (const xmlChar *)"userSpaceOnUse"); if (flags & DIA_PATTERN_EXTEND_REPEAT) xmlSetProp (gradient, (const xmlChar *)"spreadMethod", (const xmlChar *)"repeat"); else if (flags & DIA_PATTERN_EXTEND_REFLECT) xmlSetProp (gradient, (const xmlChar *)"spreadMethod", (const xmlChar *)"reflect"); else if (flags & DIA_PATTERN_EXTEND_PAD) xmlSetProp (gradient, (const xmlChar *)"spreadMethod", (const xmlChar *)"pad"); if (pt == DIA_LINEAR_GRADIENT || pt == DIA_RADIAL_GRADIENT) { dia_pattern_foreach (pattern, _color_stop_do, gradient); } else { g_warning ("SVG pattern data not implemented"); } }
static cairo_pattern_t * _pattern_build_for_cairo (DiaPattern *pattern, const Rectangle *ext) { cairo_pattern_t *pat; gsize i; real x, y; DiaPatternType type; guint flags; Point p1, p2; real r; g_return_val_if_fail (pattern != NULL, NULL); dia_pattern_get_settings (pattern, &type, &flags); dia_pattern_get_points (pattern, &p1, &p2); dia_pattern_get_radius (pattern, &r); switch (type ) { case DIA_LINEAR_GRADIENT : pat = cairo_pattern_create_linear (p1.x, p1.y, p2.x, p2.y); break; case DIA_RADIAL_GRADIENT : pat = cairo_pattern_create_radial (p2.x, p2.y, 0.0, p1.x, p1.y, r); break; default : g_warning ("_pattern_build_for_cairo non such."); return NULL; } /* this must only be optionally done */ if ((flags & DIA_PATTERN_USER_SPACE)==0) { cairo_matrix_t matrix; real w = ext->right - ext->left; real h = ext->bottom - ext->top; cairo_matrix_init (&matrix, w, 0.0, 0.0, h, ext->left, ext->top); cairo_matrix_invert (&matrix); cairo_pattern_set_matrix (pat, &matrix); } if (flags & DIA_PATTERN_EXTEND_PAD) cairo_pattern_set_extend (pat, CAIRO_EXTEND_PAD); else if (flags & DIA_PATTERN_EXTEND_REPEAT) cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT); else if (flags & DIA_PATTERN_EXTEND_REFLECT) cairo_pattern_set_extend (pat, CAIRO_EXTEND_REFLECT); dia_pattern_foreach (pattern, _add_color_stop, pat); return pat; }