Пример #1
0
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");
  }
}
Пример #2
0
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;
}