示例#1
0
static void
draw_polygon (DiaRenderer *self, 
	      Point *points, int num_points, 
	      Color *fill, Color *stroke)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  int i;
  xmlNodePtr node;
  GString *str;
  gchar px_buf[DTOSTR_BUF_SIZE];
  gchar py_buf[DTOSTR_BUF_SIZE];

  node = xmlNewChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"polygon", NULL);

  xmlSetProp(node, (const xmlChar *)"style", (xmlChar *) get_draw_style (renderer, fill, stroke));

  if (fill)
    xmlSetProp(node, (const xmlChar *)"fill-rule", (const xmlChar *) "evenodd");

  str = g_string_new(NULL);
  for (i = 0; i < num_points; i++)
    g_string_append_printf(str, "%s,%s ",
		      dia_svg_dtostr(px_buf, points[i].x),
		      dia_svg_dtostr(py_buf, points[i].y) );
  xmlSetProp(node, (const xmlChar *)"points", (xmlChar *) str->str);
  g_string_free(str, TRUE);
}
示例#2
0
static void
draw_text (DiaRenderer *self, Text *text)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  Point pos = text->position;
  int i;
  xmlNodePtr node_text, node_tspan;
  gchar d_buf[G_ASCII_DTOSTR_BUF_SIZE];

  node_text = xmlNewChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"text", NULL);
  /* text 'global' properties  */
  node_set_text_style(node_text, renderer, text->font, text->height, text->alignment, &text->color);
  dia_svg_dtostr(d_buf, pos.x);
  xmlSetProp(node_text, (const xmlChar *)"x", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, pos.y);
  xmlSetProp(node_text, (const xmlChar *)"y", (xmlChar *) d_buf);
  
  pos = text->position;
  for (i=0;i<text->numlines;i++) {
    TextLine *text_line = text->lines[i];

    node_tspan = xmlNewTextChild(node_text, renderer->svg_name_space, (const xmlChar *)"tspan",
                                 (const xmlChar *)text_line_get_string(text_line));
    dia_svg_dtostr(d_buf, pos.x);
    xmlSetProp(node_tspan, (const xmlChar *)"x", (xmlChar *) d_buf);
    dia_svg_dtostr(d_buf, pos.y);
    xmlSetProp(node_tspan, (const xmlChar *)"y", (xmlChar *) d_buf);
    
    pos.y += text->height;
  }
}
示例#3
0
static void
draw_image(DiaRenderer *self,
	   Point *point,
	   real width, real height,
	   DiaImage *image)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  xmlNodePtr node;
  gchar d_buf[DTOSTR_BUF_SIZE];
  gchar *uri;

  node = xmlNewChild(renderer->root, NULL, (const xmlChar *)"image", NULL);

  dia_svg_dtostr(d_buf, point->x);
  xmlSetProp(node, (const xmlChar *)"x", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, point->y);
  xmlSetProp(node, (const xmlChar *)"y", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, width);
  xmlSetProp(node, (const xmlChar *)"width", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, height);
  xmlSetProp(node, (const xmlChar *)"height", (xmlChar *) d_buf);
  
  uri = g_filename_to_uri(dia_image_filename(image), NULL, NULL);
  if (uri)
    xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) uri);
  else /* not sure if this fallbach is better than nothing */
    xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) dia_image_filename(image));
  g_free (uri);
}
示例#4
0
static void
draw_text_line(DiaRenderer *self, TextLine *text_line,
	       Point *pos, Alignment alignment, Color *colour)
{    
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  xmlNodePtr node;
  char *style, *tmp;
  real saved_width;
  gchar d_buf[DTOSTR_BUF_SIZE];
  DiaFont *font;

  node = xmlNewTextChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"text", 
		         (xmlChar *) text_line_get_string(text_line));
 
  saved_width = renderer->linewidth;
  renderer->linewidth = 0.001;
  style = (char*)get_fill_style(renderer, colour);
  /* return value must not be freed */
  renderer->linewidth = saved_width;
  tmp = g_strdup_printf("%s; font-size: %s", style,
			dia_svg_dtostr(d_buf, text_line_get_height(text_line)));
  style = tmp;
  /* This is going to break for non-LTR texts, as SVG thinks 'start' is
   * 'right' for those. */
  switch (alignment) {
  case ALIGN_LEFT:
    tmp = g_strconcat(style, "; text-anchor:start", NULL);
    break;
  case ALIGN_CENTER:
    tmp = g_strconcat(style, "; text-anchor:middle", NULL);
    break;
  case ALIGN_RIGHT:
    tmp = g_strconcat(style, "; text-anchor:end", NULL);
    break;
  }
  g_free (style);
  style = tmp;

  font = text_line_get_font(text_line);
  tmp = g_strdup_printf("%s; font-family: %s; font-style: %s; "
			"font-weight: %s",style,
			dia_font_get_family(font),
			dia_font_get_slant_string(font),
			dia_font_get_weight_string(font));
  g_free(style);
  style = tmp;

  /* have to do something about fonts here ... */

  xmlSetProp(node, (const xmlChar *)"style", (xmlChar *) style);
  g_free(style);

  dia_svg_dtostr(d_buf, pos->x);
  xmlSetProp(node, (const xmlChar *)"x", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, pos->y);
  xmlSetProp(node, (const xmlChar *)"y", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, text_line_get_width(text_line));
  xmlSetProp(node, (const xmlChar*)"textLength", (xmlChar *) d_buf);
}
示例#5
0
static void
set_linestyle(DiaRenderer *self, LineStyle mode)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  real hole_width;
  gchar dash_length_buf[DTOSTR_BUF_SIZE];
  gchar dot_length_buf[DTOSTR_BUF_SIZE];
  gchar hole_width_buf[DTOSTR_BUF_SIZE];

  renderer->saved_line_style = mode;

  g_free(renderer->linestyle);
  switch(mode) {
  case LINESTYLE_SOLID:
    renderer->linestyle = NULL;
    break;
  case LINESTYLE_DASHED:
    dia_svg_dtostr(dash_length_buf, renderer->dash_length);
    renderer->linestyle = g_strdup_printf("%s", dash_length_buf);
    break;
  case LINESTYLE_DASH_DOT:
    hole_width = (renderer->dash_length - renderer->dot_length) / 2.0;

    dia_svg_dtostr(dash_length_buf, renderer->dash_length);
    dia_svg_dtostr(dot_length_buf, renderer->dot_length);
    dia_svg_dtostr(hole_width_buf, hole_width);

    renderer->linestyle = g_strdup_printf("%s %s %s %s",
					  dash_length_buf,
					  hole_width_buf,
					  dot_length_buf,
					  hole_width_buf );
    break;
  case LINESTYLE_DASH_DOT_DOT:
    hole_width = (renderer->dash_length - 2.0*renderer->dot_length) / 3.0;

    dia_svg_dtostr(dash_length_buf, renderer->dash_length);
    dia_svg_dtostr(dot_length_buf, renderer->dot_length);
    dia_svg_dtostr(hole_width_buf, hole_width);

    renderer->linestyle = g_strdup_printf("%s %s %s %s %s %s",
					  dash_length_buf,
					  hole_width_buf,
					  dot_length_buf,
					  hole_width_buf,
					  dot_length_buf,
					  hole_width_buf );
    break;
  case LINESTYLE_DOTTED:

    dia_svg_dtostr(dot_length_buf, renderer->dot_length);

    renderer->linestyle = g_strdup_printf("%s", dot_length_buf);
    break;
  default:
    renderer->linestyle = NULL;
  }
}
示例#6
0
/* the return value of this function should not be saved anywhere */
static const gchar *
get_draw_style(DiaSvgRenderer *renderer,
	       Color *colour)
{
  static GString *str = NULL;
  gchar linewidth_buf[DTOSTR_BUF_SIZE];

  if (!str) str = g_string_new(NULL);
  g_string_truncate(str, 0);

  /* TODO(CHECK): the shape-export didn't have 'fill: none' here */
  g_string_printf(str, "fill: none; fill-opacity:0; stroke-width: %s", dia_svg_dtostr(linewidth_buf, renderer->linewidth) );
  if (strcmp(renderer->linecap, "butt"))
    g_string_append_printf(str, "; stroke-linecap: %s", renderer->linecap);
  if (strcmp(renderer->linejoin, "miter"))
    g_string_append_printf(str, "; stroke-linejoin: %s", renderer->linejoin);
  if (renderer->linestyle)
    g_string_append_printf(str, "; stroke-dasharray: %s", renderer->linestyle);

  if (colour)
    g_string_append_printf(str, "; stroke: #%02x%02x%02x",
		      (int)(255*colour->red), 
			  (int)(255*colour->green),
		      (int)(255*colour->blue));

  return str->str;
}
示例#7
0
static void
draw_string(DiaRenderer *self,
	    const char *text,
	    Point *pos, Alignment alignment,
	    Color *colour)
{    
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  xmlNodePtr node;
  gchar d_buf[G_ASCII_DTOSTR_BUF_SIZE];

  node = xmlNewChild(renderer->root, renderer->svg_name_space, (xmlChar *)"text", (xmlChar *)text);

  node_set_text_style(node, renderer, self->font, self->font_height, alignment, colour);
  
  dia_svg_dtostr(d_buf, pos->x);
  xmlSetProp(node, (xmlChar *)"x", (xmlChar *)d_buf);
  dia_svg_dtostr(d_buf, pos->y);
  xmlSetProp(node, (xmlChar *)"y", (xmlChar *)d_buf);
}
示例#8
0
static void
draw_image(DiaRenderer *self,
	   Point *point,
	   real width, real height,
	   DiaImage *image)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  xmlNodePtr node;
  gchar d_buf[DTOSTR_BUF_SIZE];
  gchar *uri = NULL;

  node = xmlNewChild(renderer->root, NULL, (const xmlChar *)"image", NULL);

  dia_svg_dtostr(d_buf, point->x);
  xmlSetProp(node, (const xmlChar *)"x", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, point->y);
  xmlSetProp(node, (const xmlChar *)"y", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, width);
  xmlSetProp(node, (const xmlChar *)"width", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, height);
  xmlSetProp(node, (const xmlChar *)"height", (xmlChar *) d_buf);

  /* if the image file location is relative to the SVG file's store 
   * a relative path - if it does not have a path: inline it */
  if (strcmp (dia_image_filename(image), "(null)") == 0) {
    gchar *b64 = pixbuf_encode_base64 (dia_image_pixbuf (image));
    gchar *uri;

    if (b64)
      uri = g_strdup_printf ("data:image/png;base64,%s", b64);
    else
      uri = g_strdup ("(null)");
    xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) uri);
    g_free (b64);    
  } else if ((uri = dia_relativize_filename (renderer->filename, dia_image_filename(image))) != NULL)
    xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) uri);
  else if ((uri = g_filename_to_uri(dia_image_filename(image), NULL, NULL)) != NULL)
    xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) uri);
  else /* not sure if this fallback is better than nothing */
    xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) dia_image_filename(image));
  g_free (uri);
}
示例#9
0
static void
draw_line(DiaRenderer *self, 
	  Point *start, Point *end, 
	  Color *line_colour)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  xmlNodePtr node;
  gchar d_buf[DTOSTR_BUF_SIZE];

  node = xmlNewChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"line", NULL);

  xmlSetProp(node, (const xmlChar *)"style", (xmlChar *) get_draw_style(renderer, NULL, line_colour));

  dia_svg_dtostr(d_buf, start->x);
  xmlSetProp(node, (const xmlChar *)"x1", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, start->y);
  xmlSetProp(node, (const xmlChar *)"y1", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, end->x);
  xmlSetProp(node, (const xmlChar *)"x2", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, end->y);
  xmlSetProp(node, (const xmlChar *)"y2", (xmlChar *) d_buf);
}
示例#10
0
static void
draw_rect(DiaRenderer *self, 
	  Point *ul_corner, Point *lr_corner,
	  Color *fill, Color *stroke)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  xmlNodePtr node;
  gchar d_buf[DTOSTR_BUF_SIZE];

  node = xmlNewChild(renderer->root, NULL, (const xmlChar *)"rect", NULL);

  xmlSetProp(node, (const xmlChar *)"style", (xmlChar *) get_draw_style (renderer, fill, stroke));

  dia_svg_dtostr(d_buf, ul_corner->x);
  xmlSetProp(node, (const xmlChar *)"x", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, ul_corner->y);
  xmlSetProp(node, (const xmlChar *)"y", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, lr_corner->x - ul_corner->x);
  xmlSetProp(node, (const xmlChar *)"width", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, lr_corner->y - ul_corner->y);
  xmlSetProp(node, (const xmlChar *)"height", (xmlChar *) d_buf);
}
示例#11
0
static void
draw_ellipse(DiaRenderer *self, 
	     Point *center,
	     real width, real height,
	     Color *fill, Color *stroke)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  xmlNodePtr node;
  gchar d_buf[DTOSTR_BUF_SIZE];

  node = xmlNewChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"ellipse", NULL);

  xmlSetProp(node, (const xmlChar *)"style", (xmlChar *) get_draw_style (renderer, fill, stroke));

  dia_svg_dtostr(d_buf, center->x);
  xmlSetProp(node, (const xmlChar *)"cx", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, center->y);
  xmlSetProp(node, (const xmlChar *)"cy", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, width / 2);
  xmlSetProp(node, (const xmlChar *)"rx", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, height / 2);
  xmlSetProp(node, (const xmlChar *)"ry", (xmlChar *) d_buf);
}
示例#12
0
static void
draw_text_line(DiaRenderer *self, TextLine *text_line,
	       Point *pos, Alignment alignment, Color *colour)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  xmlNodePtr node;
  DiaFont *font = text_line_get_font(text_line); /* no reference? */
  real font_height = text_line_get_height(text_line);
  gchar d_buf[G_ASCII_DTOSTR_BUF_SIZE];
  
  node = xmlNewChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"text", 
		     (xmlChar *) text_line_get_string(text_line));

  /* not using the renderers font but the textlines */
  node_set_text_style(node, renderer, font, font_height, alignment, colour);

  dia_svg_dtostr(d_buf, pos->x);
  xmlSetProp(node, (const xmlChar *)"x", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, pos->y);
  xmlSetProp(node, (const xmlChar *)"y", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, text_line_get_width(text_line));
  xmlSetProp(node, (const xmlChar*)"textLength", (xmlChar *) d_buf);
}
示例#13
0
/* the return value of this function should not be saved anywhere */
static const gchar *
get_draw_style(DiaSvgRenderer *renderer,
	       Color *fill,
	       Color *stroke)
{
  static GString *str = NULL;
  gchar linewidth_buf[DTOSTR_BUF_SIZE];
  gchar alpha_buf[DTOSTR_BUF_SIZE];

  if (!str)
    str = g_string_new(NULL);
  g_string_truncate(str, 0);

  /* we only append a semicolon with the second attribute */
  if (fill) {
    if (renderer->active_pattern) {
      gchar *key = _make_pattern_key (renderer->active_pattern);
      g_string_printf(str, "fill:url(#%s)", key);
      g_free (key);
    } else {
      g_string_printf(str, "fill: #%02x%02x%02x; fill-opacity: %s",
		      (int)(255*fill->red), (int)(255*fill->green),
		      (int)(255*fill->blue), 
		      g_ascii_formatd(alpha_buf, sizeof(alpha_buf), "%g", fill->alpha));
    }
  } else {
    g_string_printf(str, "fill: none");
  }

  if (stroke) {
    g_string_append_printf(str, "; stroke-opacity: %s; stroke-width: %s",
			   g_ascii_formatd (alpha_buf, sizeof(alpha_buf), "%g", stroke->alpha), 
			   dia_svg_dtostr(linewidth_buf, renderer->linewidth) );
    if (strcmp(renderer->linecap, "butt"))
      g_string_append_printf(str, "; stroke-linecap: %s", renderer->linecap);
    if (strcmp(renderer->linejoin, "miter"))
      g_string_append_printf(str, "; stroke-linejoin: %s", renderer->linejoin);
    if (renderer->linestyle)
      g_string_append_printf(str, "; stroke-dasharray: %s", renderer->linestyle);

    g_string_append_printf(str, "; stroke: #%02x%02x%02x",
			   (int)(255*stroke->red), 
			   (int)(255*stroke->green),
			   (int)(255*stroke->blue));
  } else {
    g_string_append_printf(str, "; stroke: none");
  }
  return str->str;
}
示例#14
0
static void
fill_arc(DiaRenderer *self, 
	 Point *center,
	 real width, real height,
	 real angle1, real angle2,
	 Color *colour)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  xmlNodePtr node;
  char buf[512];
  real rx = width / 2, ry = height / 2;
  real sx=center->x + rx*cos(angle1*G_PI/180);
  real sy=center->y - ry*sin(angle1*G_PI/180);
  real ex=center->x + rx*cos(angle2*G_PI/180);
  real ey=center->y - ry*sin(angle2*G_PI/180);
  int swp = (angle2 > angle1) ? 0 : 1; /* preserve direction */
  int large_arc = (fabs(angle2 - angle1) >= 180);
  gchar sx_buf[DTOSTR_BUF_SIZE];
  gchar sy_buf[DTOSTR_BUF_SIZE];
  gchar rx_buf[DTOSTR_BUF_SIZE];
  gchar ry_buf[DTOSTR_BUF_SIZE];
  gchar ex_buf[DTOSTR_BUF_SIZE];
  gchar ey_buf[DTOSTR_BUF_SIZE];
  gchar cx_buf[DTOSTR_BUF_SIZE];
  gchar cy_buf[DTOSTR_BUF_SIZE];

  node = xmlNewChild(renderer->root, NULL, (const xmlChar *)"path", NULL);
  
  xmlSetProp(node, (const xmlChar *)"style", (xmlChar *)get_draw_style(renderer, colour, NULL));

  g_snprintf(buf, sizeof(buf), "M %s,%s A %s,%s 0 %d %d %s,%s L %s,%s z",
	     dia_svg_dtostr(sx_buf, sx), dia_svg_dtostr(sy_buf, sy),
	     dia_svg_dtostr(rx_buf, rx), dia_svg_dtostr(ry_buf, ry),
	     large_arc, swp,
	     dia_svg_dtostr(ex_buf, ex), dia_svg_dtostr(ey_buf, ey),
	     dia_svg_dtostr(cx_buf, center->x),
	     dia_svg_dtostr(cy_buf, center->y) );

  xmlSetProp(node, (const xmlChar *)"d", (xmlChar *) buf);
}
示例#15
0
static void
node_set_text_style (xmlNodePtr      node,
                     DiaSvgRenderer *renderer,
		     const DiaFont  *font,
		     real            font_height,
                     Alignment       alignment,
		     Color          *colour)
{
  char *style, *tmp;
  real saved_width;
  gchar d_buf[G_ASCII_DTOSTR_BUF_SIZE];
  DiaSvgRendererClass *svg_renderer_class = DIA_SVG_RENDERER_GET_CLASS (renderer);
  /* SVG font-size is the (line-) height, from SVG Spec:
   * ... property refers to the size of the font from baseline to baseline when multiple lines of text are set ...
  so we should be able to use font_height directly instead of:
   */
  real font_size = dia_font_get_size (font) * (font_height / dia_font_get_height (font));
  /* ... but at least Inkscape and Firefox would produce the wrong font-size */
  const gchar *family = dia_font_get_family(font);

  saved_width = renderer->linewidth;
  renderer->linewidth = 0.001;
  style = (char*)svg_renderer_class->get_fill_style(renderer, colour);
  /* return value must not be freed */
  renderer->linewidth = saved_width;
  /* This is going to break for non-LTR texts, as SVG thinks 'start' is
   * 'right' for those.
   */
  switch (alignment) {
  case ALIGN_LEFT:
    style = g_strconcat(style, ";text-anchor:start", NULL);
    break;
  case ALIGN_CENTER:
    style = g_strconcat(style, ";text-anchor:middle", NULL);
    break;
  case ALIGN_RIGHT:
    style = g_strconcat(style, ";text-anchor:end", NULL);
    break;
  }
#if 0 /* would need a unit according to https://bugzilla.mozilla.org/show_bug.cgi?id=707071#c4 */
  tmp = g_strdup_printf("%s;font-size:%s", style,
			dia_svg_dtostr(d_buf, font_size) );
  g_free (style);
  style = tmp;
#else
  /* font-size as attribute can work like the other length w/o unit */
  dia_svg_dtostr(d_buf, font_size);
  xmlSetProp(node, (const xmlChar *)"font-size", (xmlChar *) d_buf);
#endif

  if (font) {
     tmp = g_strdup_printf("%s;font-family:%s;font-style:%s;"
                           "font-weight:%s",style,
                           strcmp(family, "sans") == 0 ? "sans-serif" : family,
                           dia_font_get_slant_string(font),
                           dia_font_get_weight_string(font));
     g_free(style);
     style = tmp;
  }

  /* have to do something about fonts here ... */

  xmlSetProp(node, (xmlChar *)"style", (xmlChar *)style);
  g_free(style);
}
示例#16
0
static void
draw_text_line(DiaRenderer *self, TextLine *text_line,
	       Point *pos, Alignment alignment, Color *colour)
{    
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  xmlNodePtr node;
  real saved_width;
  gchar d_buf[DTOSTR_BUF_SIZE];
  DiaFont *font;
  GString *style;

  node = xmlNewTextChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"text", 
		         (xmlChar *) text_line_get_string(text_line));

  saved_width = renderer->linewidth;
  renderer->linewidth = 0.001;
  /* return value must not be freed */
  renderer->linewidth = saved_width;
#if 0 /* would need a unit: https://bugzilla.mozilla.org/show_bug.cgi?id=707071#c4 */
  style = g_strdup_printf("%s; font-size: %s", get_draw_style(renderer, colour, NULL),
			dia_svg_dtostr(d_buf, text_line_get_height(text_line)));
#else
  /* get_draw_style: the return value of this function must not be saved 
   * anywhere. And of course it must not be free'd */
  style = g_string_new (get_draw_style(renderer, colour, NULL));
#endif
  /* This is going to break for non-LTR texts, as SVG thinks 'start' is
   * 'right' for those. */
  switch (alignment) {
  case ALIGN_LEFT:
    g_string_append (style, "; text-anchor:start");
    break;
  case ALIGN_CENTER:
    g_string_append (style, "; text-anchor:middle");
    break;
  case ALIGN_RIGHT:
    g_string_append (style, "; text-anchor:end");
    break;
  default:
    break;
  }

  font = text_line_get_font(text_line);
  g_string_append_printf (style, "font-family: %s; font-style: %s; font-weight: %s",
			  dia_font_get_family(font),
			  dia_font_get_slant_string(font),
			  dia_font_get_weight_string(font));

  xmlSetProp(node, (const xmlChar *)"style", (xmlChar *) style->str);
  g_string_free (style, TRUE);

  dia_svg_dtostr(d_buf, pos->x);
  xmlSetProp(node, (const xmlChar *)"x", (xmlChar *) d_buf);
  dia_svg_dtostr(d_buf, pos->y);
  xmlSetProp(node, (const xmlChar *)"y", (xmlChar *) d_buf);

  /* font-size as single attribute can work like the other length w/o unit */
  dia_svg_dtostr(d_buf, text_line_get_height(text_line));
  xmlSetProp(node, (const xmlChar *)"font-size", (xmlChar *) d_buf);

  dia_svg_dtostr(d_buf, text_line_get_width(text_line));
  xmlSetProp(node, (const xmlChar*)"textLength", (xmlChar *) d_buf);
}
示例#17
0
static void
_bezier(DiaRenderer *self, 
	BezPoint *points,
	int numpoints,
	Color *fill,
	Color *stroke,
	gboolean closed)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  int i;
  xmlNodePtr node;
  GString *str;
  gchar p1x_buf[DTOSTR_BUF_SIZE];
  gchar p1y_buf[DTOSTR_BUF_SIZE];
  gchar p2x_buf[DTOSTR_BUF_SIZE];
  gchar p2y_buf[DTOSTR_BUF_SIZE];
  gchar p3x_buf[DTOSTR_BUF_SIZE];
  gchar p3y_buf[DTOSTR_BUF_SIZE];

  node = xmlNewChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"path", NULL);

  if (fill || stroke)
    xmlSetProp(node, (const xmlChar *)"style", (xmlChar *)get_draw_style(renderer, fill, stroke));

  str = g_string_new(NULL);

  if (points[0].type != BEZ_MOVE_TO)
    g_warning("first BezPoint must be a BEZ_MOVE_TO");

  g_string_printf(str, "M %s %s",
		   dia_svg_dtostr(p1x_buf, (gdouble) points[0].p1.x),
		   dia_svg_dtostr(p1y_buf, (gdouble) points[0].p1.y) );

  for (i = 1; i < numpoints; i++)
    switch (points[i].type) {
    case BEZ_MOVE_TO:
      if (!DIA_RENDERER_GET_CLASS (self)->is_capable_to(self, RENDER_HOLES)) {
        g_warning("only first BezPoint should be a BEZ_MOVE_TO");
        g_string_printf(str, "M %s %s",
		        dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
		        dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
      } else {
        g_string_append_printf(str, "M %s %s",
		        dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
		        dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
      }
      break;
    case BEZ_LINE_TO:
      g_string_append_printf(str, " L %s,%s",
			dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
			dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
      break;
    case BEZ_CURVE_TO:
      g_string_append_printf(str, " C %s,%s %s,%s %s,%s",
			dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
			dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y),
			dia_svg_dtostr(p2x_buf, (gdouble) points[i].p2.x),
			dia_svg_dtostr(p2y_buf, (gdouble) points[i].p2.y),
			dia_svg_dtostr(p3x_buf, (gdouble) points[i].p3.x),
			dia_svg_dtostr(p3y_buf, (gdouble) points[i].p3.y) );
      break;
    }
  if (fill) {
    xmlSetProp(node, (const xmlChar *)"fill-rule", (const xmlChar *) "evenodd");
    g_string_append(str, "z");
  }
  xmlSetProp(node, (const xmlChar *)"d", (xmlChar *) str->str);
  g_string_free(str, TRUE);
}
示例#18
0
static void
fill_bezier(DiaRenderer *self, 
	    BezPoint *points, /* Last point must be same as first point */
	    int numpoints,
	    Color *colour)
{
  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
  int i;
  xmlNodePtr node;
  GString *str;
  gchar p1x_buf[DTOSTR_BUF_SIZE];
  gchar p1y_buf[DTOSTR_BUF_SIZE];
  gchar p2x_buf[DTOSTR_BUF_SIZE];
  gchar p2y_buf[DTOSTR_BUF_SIZE];
  gchar p3x_buf[DTOSTR_BUF_SIZE];
  gchar p3y_buf[DTOSTR_BUF_SIZE];

  node = xmlNewChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"path", NULL);
  
  xmlSetProp(node, (const xmlChar *)"style", (xmlChar *) get_fill_style(renderer, colour));

  str = g_string_new(NULL);

  if (points[0].type != BEZ_MOVE_TO)
    g_warning("first BezPoint must be a BEZ_MOVE_TO");

  g_string_printf(str, "M %s %s",
		   dia_svg_dtostr(p1x_buf, (gdouble) points[0].p1.x),
		   dia_svg_dtostr(p1y_buf, (gdouble) points[0].p1.y) );
 
  for (i = 1; i < numpoints; i++)
    switch (points[i].type) {
    case BEZ_MOVE_TO:
      g_warning("only first BezPoint should be a BEZ_MOVE_TO");
      g_string_printf(str, "M %s %s",
		      dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
		      dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
      break;
    case BEZ_LINE_TO:
      g_string_append_printf(str, " L %s,%s",
			dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
			dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
      break;
    case BEZ_CURVE_TO:
      g_string_append_printf(str, " C %s,%s %s,%s %s,%s",
			dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
			dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y),
			dia_svg_dtostr(p2x_buf, (gdouble) points[i].p2.x),
			dia_svg_dtostr(p2y_buf, (gdouble) points[i].p2.y),
			dia_svg_dtostr(p3x_buf, (gdouble) points[i].p3.x),
			dia_svg_dtostr(p3y_buf, (gdouble) points[i].p3.y) );
      break;
    }
  g_string_append(str, "z");
  xmlSetProp(node, (const xmlChar *)"d", (xmlChar *) str->str);
  g_string_free(str, TRUE);
}