From e68b98ef392b488a7539944d00e7f397a57be310 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Feb 01 2008 15:14:46 +0000 Subject: - Fix svg export (bug 431184) --- diff --git a/dia-0.96.1-desktop.patch b/dia-0.96.1-desktop.patch new file mode 100644 index 0000000..3c1cb01 --- /dev/null +++ b/dia-0.96.1-desktop.patch @@ -0,0 +1,12 @@ +diff -up dia-0.96.1/dia.desktop.in.in~ dia-0.96.1/dia.desktop.in.in +--- dia-0.96.1/dia.desktop.in.in~ 2007-12-02 22:30:13.000000000 +0100 ++++ dia-0.96.1/dia.desktop.in.in 2007-12-02 22:30:13.000000000 +0100 +@@ -4,7 +4,7 @@ _Name=Dia Diagram Editor + _Comment=Edit your Diagrams + Type=Application + Exec=dia +-Icon=dia_gnome_icon.png ++Icon=dia_gnome_icon + Terminal=false + Categories=GNOME;Application;Graphics; + StartupNotify=true diff --git a/dia-0.96.1-svg-export.patch b/dia-0.96.1-svg-export.patch new file mode 100644 index 0000000..20c40c8 --- /dev/null +++ b/dia-0.96.1-svg-export.patch @@ -0,0 +1,752 @@ +diff -ur dia-0.96.1/lib/dia_svg.c dia-0.96.1.new/lib/dia_svg.c +--- dia-0.96.1/lib/dia_svg.c 2007-01-25 20:33:32.000000000 +0100 ++++ dia-0.96.1.new/lib/dia_svg.c 2008-02-01 14:59:10.000000000 +0100 +@@ -137,10 +137,11 @@ + * @param node An XML node to parse a style from. + * @param s The SVG style object to fill out. This should previously be + * initialized to some default values. ++ * @param user_scale, if >0 scalable values (font-size, stroke-width, ...) are divided by this, otherwise ignored + * @bug This function is way too long (213 lines). So dont touch it :) + */ + void +-dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s) ++dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s, real user_scale) + { + xmlChar *str; + gchar temp[FONT_NAME_LENGTH_MAX+1]; /* font-family names will be limited to 40 characters */ +@@ -214,6 +215,8 @@ + + if (!over) { + s->font_height = g_ascii_strtod(temp, NULL); ++ if (user_scale > 0) ++ s->font_height /= user_scale; + } + } else if (!strncmp("text-anchor:", ptr, 12)) { + ptr += 12; +@@ -228,6 +231,8 @@ + } else if (!strncmp("stroke-width:", ptr, 13)) { + ptr += 13; + s->line_width = g_ascii_strtod(ptr, &ptr); ++ if (user_scale > 0) ++ s->line_width /= user_scale; + } else if (!strncmp("stroke:", ptr, 7)) { + ptr += 7; + while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++; +@@ -293,6 +298,8 @@ + s->dashlength = 1.0; + else { + s->dashlength = g_ascii_strtod(ptr, &ptr); ++ if (user_scale > 0) ++ s->dashlength /= user_scale; + } + } else if (!strncmp("stroke-dasharray:", ptr, 17)) { + /* FIXME? do we need to read an array here (not clear from +@@ -308,6 +315,8 @@ + s->dashlength = 1.0; + else { + s->dashlength = g_ascii_strtod(ptr, &ptr); ++ if (user_scale > 0) ++ s->dashlength /= user_scale; + } + } + +@@ -335,6 +344,8 @@ + if (str) { + s->line_width = g_ascii_strtod(str, NULL); + xmlFree(str); ++ if (user_scale > 0) ++ s->line_width /= user_scale; + } + + if (family || style || weight) { +Only in dia-0.96.1.new/lib: dia_svg.c.orig +diff -ur dia-0.96.1/lib/dia_svg.h dia-0.96.1.new/lib/dia_svg.h +--- dia-0.96.1/lib/dia_svg.h 2007-01-06 23:28:26.000000000 +0100 ++++ dia-0.96.1.new/lib/dia_svg.h 2008-02-01 14:59:12.000000000 +0100 +@@ -57,7 +57,7 @@ + + void dia_svg_style_init (DiaSvgStyle *gs, DiaSvgStyle *parent_style); + void dia_svg_style_copy (DiaSvgStyle *dest, DiaSvgStyle *src); +-void dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s); ++void dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s, real user_scale); + /* parse the svg sub format for pathes int an array of BezPoint */ + GArray* dia_svg_parse_path(const gchar *path_str, gchar **unparsed, gboolean *closed); + +diff -ur dia-0.96.1/lib/diasvgrenderer.c dia-0.96.1.new/lib/diasvgrenderer.c +--- dia-0.96.1/lib/diasvgrenderer.c 2007-01-14 14:39:12.000000000 +0100 ++++ dia-0.96.1.new/lib/diasvgrenderer.c 2008-02-01 15:05:15.000000000 +0100 +@@ -49,8 +49,8 @@ + #include "textline.h" + + #define DTOSTR_BUF_SIZE G_ASCII_DTOSTR_BUF_SIZE +-#define dia_svg_dtostr(buf,d) \ +- g_ascii_formatd(buf,sizeof(buf),"%g",d) ++#define dia_svg_dtostr(buf,d) \ ++ g_ascii_formatd(buf,sizeof(buf),"%g",(d)*renderer->scale) + static void + draw_text_line(DiaRenderer *self, TextLine *text_line, + Point *pos, Color *colour); +@@ -761,6 +761,7 @@ + DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self); + xmlNodePtr node; + gchar d_buf[DTOSTR_BUF_SIZE]; ++ gchar *uri; + + node = xmlNewChild(renderer->root, NULL, "image", NULL); + +@@ -772,13 +773,23 @@ + xmlSetProp(node, "width", d_buf); + dia_svg_dtostr(d_buf, height); + xmlSetProp(node, "height", d_buf); +- xmlSetProp(node, "xlink:href", dia_image_filename(image)); ++ ++ 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); + } + + /* constructor */ + static void +-dia_svg_renderer_init (GTypeInstance *instance, gpointer g_class) ++dia_svg_renderer_init (GTypeInstance *self, gpointer g_class) + { ++ DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self); ++ ++ renderer->scale = 1.0; ++ + } + + static gpointer parent_class = NULL; +Only in dia-0.96.1.new/lib: diasvgrenderer.c.orig +Only in dia-0.96.1.new/lib: diasvgrenderer.c.rej +Only in dia-0.96.1.new/lib: diasvgrenderer.c~ +diff -ur dia-0.96.1/lib/diasvgrenderer.h dia-0.96.1.new/lib/diasvgrenderer.h +--- dia-0.96.1/lib/diasvgrenderer.h 2007-01-06 23:28:26.000000000 +0100 ++++ dia-0.96.1.new/lib/diasvgrenderer.h 2008-02-01 14:59:16.000000000 +0100 +@@ -33,6 +33,7 @@ + const char *linecap; + const char *linejoin; + char *linestyle; /* not const -- must free */ ++ real scale; /* 1.0 for shape output, more for svg output, */ + }; + + struct _DiaSvgRendererClass +diff -ur dia-0.96.1/objects/custom/shape_info.c dia-0.96.1.new/objects/custom/shape_info.c +--- dia-0.96.1/objects/custom/shape_info.c 2007-01-06 23:28:09.000000000 +0100 ++++ dia-0.96.1.new/objects/custom/shape_info.c 2008-02-01 15:00:00.000000000 +0100 +@@ -172,7 +172,7 @@ + if (node->type != XML_ELEMENT_NODE || node->ns != svg_ns) + continue; + dia_svg_style_init (&s, style); +- dia_svg_parse_style(node, &s); ++ dia_svg_parse_style(node, &s, -1); + if (!strcmp(node->name, "line")) { + GraphicElementLine *line = g_new0(GraphicElementLine, 1); + +@@ -665,7 +665,7 @@ + DIA_SVG_LINECAPS_DEFAULT, DIA_SVG_LINEJOIN_DEFAULT, DIA_SVG_LINESTYLE_DEFAULT, 1.0 + }; + +- dia_svg_parse_style(node, &s); ++ dia_svg_parse_style(node, &s, -1); + parse_svg_node(info, node, svg_ns, &s, filename); + update_bounds(info); + } +Only in dia-0.96.1.new/objects/custom: shape_info.c.orig +Only in dia-0.96.1.new/objects/custom: shape_info.c.rej +Only in dia-0.96.1.new/objects/custom: shape_info.c~ +diff -ur dia-0.96.1/plug-ins/shape/shape-export.c dia-0.96.1.new/plug-ins/shape/shape-export.c +--- dia-0.96.1/plug-ins/shape/shape-export.c 2007-03-18 20:49:15.000000000 +0100 ++++ dia-0.96.1.new/plug-ins/shape/shape-export.c 2008-02-01 14:59:20.000000000 +0100 +@@ -147,6 +147,8 @@ + renderer->dash_length = 1.0; + renderer->dot_length = 0.2; + renderer->saved_line_style = LINESTYLE_SOLID; ++ /* keep everything unscaled, i.e. in Dia's scale default */ ++ renderer->scale = 1.0; + + /* set up the root node */ + renderer->doc = xmlNewDoc("1.0"); +Only in dia-0.96.1.new/plug-ins/shape: shape-export.c.orig +diff -ur dia-0.96.1/plug-ins/svg/render_svg.c dia-0.96.1.new/plug-ins/svg/render_svg.c +--- dia-0.96.1/plug-ins/svg/render_svg.c 2007-03-18 20:49:15.000000000 +0100 ++++ dia-0.96.1.new/plug-ins/svg/render_svg.c 2008-02-01 14:36:42.000000000 +0100 +@@ -61,6 +61,9 @@ + struct _SvgRenderer + { + DiaSvgRenderer parent_instance; ++ ++ /* track the parents while grouping in draw_object() */ ++ GQueue *parents; + }; + + struct _SvgRendererClass +@@ -85,6 +88,15 @@ + + static gpointer parent_class = NULL; + ++/* constructor */ ++static void ++svg_renderer_init (GTypeInstance *self, gpointer g_class) ++{ ++ SvgRenderer *renderer = SVG_RENDERER (self); ++ ++ renderer->parents = g_queue_new (); ++} ++ + GType + svg_renderer_get_type (void) + { +@@ -102,7 +114,7 @@ + NULL, /* class_data */ + sizeof (SvgRenderer), + 0, /* n_preallocs */ +- NULL /* init */ ++ svg_renderer_init /* init */ + }; + + object_type = g_type_register_static (DIA_TYPE_SVG_RENDERER, +@@ -114,9 +126,30 @@ + } + + static void ++begin_render (DiaRenderer *self) ++{ ++ SvgRenderer *renderer = SVG_RENDERER (self); ++ g_assert (g_queue_is_empty (renderer->parents)); ++ DIA_RENDERER_CLASS (parent_class)->begin_render (DIA_RENDERER (self)); ++} ++ ++static void ++end_render (DiaRenderer *self) ++{ ++ SvgRenderer *renderer = SVG_RENDERER (self); ++ g_assert (g_queue_is_empty (renderer->parents)); ++ DIA_RENDERER_CLASS (parent_class)->end_render (DIA_RENDERER (self)); ++} ++ ++/* destructor */ ++static void + svg_renderer_finalize (GObject *object) + { +- G_OBJECT_CLASS (parent_class)->finalize (object); ++ SvgRenderer *svg_renderer = SVG_RENDERER (object); ++ ++ g_queue_free (svg_renderer->parents); ++ ++ G_OBJECT_CLASS (parent_class)->finalize (object); + } + + static void +@@ -129,6 +162,8 @@ + + object_class->finalize = svg_renderer_finalize; + ++ renderer_class->begin_render = begin_render; ++ renderer_class->end_render = end_render; + renderer_class->draw_object = draw_object; + renderer_class->draw_rounded_rect = draw_rounded_rect; + renderer_class->fill_rounded_rect = fill_rounded_rect; +@@ -139,6 +174,7 @@ + new_svg_renderer(DiagramData *data, const char *filename) + { + DiaSvgRenderer *renderer; ++ SvgRenderer *svg_renderer; + FILE *file; + gchar buf[512]; + time_t time_now; +@@ -163,32 +199,40 @@ + renderer->dash_length = 1.0; + renderer->dot_length = 0.2; + renderer->saved_line_style = LINESTYLE_SOLID; ++ /* apparently most svg readers don't like small values, especially not in the viewBox attribute */ ++ renderer->scale = 20.0; + + /* set up the root node */ +- renderer->doc = xmlNewDoc("1.0"); +- renderer->doc->encoding = xmlStrdup("UTF-8"); ++ renderer->doc = xmlNewDoc((const xmlChar *)"1.0"); ++ renderer->doc->encoding = xmlStrdup((const xmlChar *)"UTF-8"); + renderer->doc->standalone = FALSE; +- dtd = xmlCreateIntSubset(renderer->doc, "svg", +- "-//W3C//DTD SVG 1.0//EN", +- "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd"); ++ dtd = xmlCreateIntSubset(renderer->doc, (const xmlChar *)"svg", ++ (const xmlChar *)"-//W3C//DTD SVG 1.0//EN", ++ (const xmlChar *)"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd"); + xmlAddChild((xmlNodePtr) renderer->doc, (xmlNodePtr) dtd); +- renderer->root = xmlNewDocNode(renderer->doc, NULL, "svg", NULL); ++ renderer->root = xmlNewDocNode(renderer->doc, NULL, (const xmlChar *)"svg", NULL); + xmlAddSibling(renderer->doc->children, (xmlNodePtr) renderer->root); + ++ /* add namespaces to make strict parsers happy, e.g. Firefox */ ++ svg_renderer = SVG_RENDERER (renderer); ++ + /* set the extents of the SVG document */ + extent = &data->extents; + g_snprintf(buf, sizeof(buf), "%dcm", + (int)ceil((extent->right - extent->left))); +- xmlSetProp(renderer->root, "width", buf); ++ xmlSetProp(renderer->root, (const xmlChar *)"width", (xmlChar *) buf); + g_snprintf(buf, sizeof(buf), "%dcm", + (int)ceil((extent->bottom - extent->top))); +- xmlSetProp(renderer->root, "height", buf); ++ xmlSetProp(renderer->root, (const xmlChar *)"height", (xmlChar *) buf); + g_snprintf(buf, sizeof(buf), "%d %d %d %d", +- (int)floor(extent->left), (int)floor(extent->top), +- (int)ceil(extent->right - extent->left), +- (int)ceil(extent->bottom - extent->top)); +- xmlSetProp(renderer->root, "viewBox", buf); +- ++ (int)floor(extent->left * renderer->scale), (int)floor(extent->top * renderer->scale), ++ (int)ceil((extent->right - extent->left) * renderer->scale), ++ (int)ceil((extent->bottom - extent->top) * renderer->scale)); ++ xmlSetProp(renderer->root, (const xmlChar *)"viewBox", (xmlChar *) buf); ++ xmlSetProp(renderer->root,(const xmlChar *)"xmlns", (const xmlChar *)"http://www.w3.org/2000/svg"); ++ xmlSetProp(renderer->root,(const xmlChar *)"xmlns", (const xmlChar *)"http://www.w3.org/2000/svg"); ++ xmlSetProp(renderer->root,(const xmlChar *)"xmlns:xlink", (const xmlChar *)"http://www.w3.org/1999/xlink"); ++ + time_now = time(NULL); + name = g_get_user_name(); + +@@ -215,11 +259,39 @@ + } + + static void +-draw_object(DiaRenderer *renderer, ++draw_object(DiaRenderer *self, + DiaObject *object) + { +- /* TODO: wrap in */ +- object->ops->draw(object, renderer); ++ /* wrap in ++ * We could try to be smart and count the objects we using for the object. ++ * If it is only one the grouping is superfluous and should be removed. ++ */ ++ DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self); ++ SvgRenderer *svg_renderer = SVG_RENDERER (self); ++ int n_children = 0; ++ xmlNodePtr child, group; ++ ++ g_queue_push_tail (svg_renderer->parents, renderer->root); ++ /* modifying the root pointer so everything below us gets into the new node */ ++ renderer->root = group = xmlNewNode (renderer->svg_name_space, (const xmlChar *)"g"); ++ ++ object->ops->draw(object, DIA_RENDERER (renderer)); ++ ++ /* no easy way to count? */ ++ child = renderer->root->children; ++ while (child != NULL) { ++ child = child->next; ++ ++n_children; ++ } ++ renderer->root = g_queue_pop_tail (svg_renderer->parents); ++ /* if there is only one element added to the group node unpack it again */ ++ if (1 == n_children) { ++ xmlAddChild (renderer->root, group->children); ++ xmlUnlinkNode (group); /* dont free the children */ ++ xmlFree (group); ++ } else { ++ xmlAddChild (renderer->root, group); ++ } + } + + static void +@@ -231,22 +303,22 @@ + xmlNodePtr node; + gchar buf[G_ASCII_DTOSTR_BUF_SIZE]; + +- node = xmlNewChild(renderer->root, NULL, "rect", NULL); ++ node = xmlNewChild(renderer->root, NULL, (const xmlChar *)"rect", NULL); + +- xmlSetProp(node, "style", +- DIA_SVG_RENDERER_GET_CLASS(self)->get_draw_style(renderer, colour)); ++ xmlSetProp(node, (const xmlChar *)"style", ++ (const xmlChar *) DIA_SVG_RENDERER_GET_CLASS(self)->get_draw_style(renderer, colour)); + +- g_ascii_formatd(buf, sizeof(buf), "%g", ul_corner->x); +- xmlSetProp(node, "x", buf); +- g_ascii_formatd(buf, sizeof(buf), "%g", ul_corner->y); +- xmlSetProp(node, "y", buf); +- g_ascii_formatd(buf, sizeof(buf), "%g", lr_corner->x - ul_corner->x); +- xmlSetProp(node, "width", buf); +- g_ascii_formatd(buf, sizeof(buf), "%g", lr_corner->y - ul_corner->y); +- xmlSetProp(node, "height", buf); +- g_ascii_formatd(buf, sizeof(buf),"%g", rounding); +- xmlSetProp(node, "rx", buf); +- xmlSetProp(node, "ry", buf); ++ g_ascii_formatd(buf, sizeof(buf), "%g", ul_corner->x * renderer->scale); ++ xmlSetProp(node, (const xmlChar *)"x", (xmlChar *) buf); ++ g_ascii_formatd(buf, sizeof(buf), "%g", ul_corner->y * renderer->scale); ++ xmlSetProp(node, (const xmlChar *)"y", (xmlChar *) buf); ++ g_ascii_formatd(buf, sizeof(buf), "%g", (lr_corner->x - ul_corner->x) * renderer->scale); ++ xmlSetProp(node, (const xmlChar *)"width", (xmlChar *) buf); ++ g_ascii_formatd(buf, sizeof(buf), "%g", (lr_corner->y - ul_corner->y) * renderer->scale); ++ xmlSetProp(node, (const xmlChar *)"height", (xmlChar *) buf); ++ g_ascii_formatd(buf, sizeof(buf),"%g", (rounding * renderer->scale)); ++ xmlSetProp(node, (const xmlChar *)"rx", (xmlChar *) buf); ++ xmlSetProp(node, (const xmlChar *)"ry", (xmlChar *) buf); + } + + static void +@@ -258,22 +330,22 @@ + xmlNodePtr node; + gchar buf[G_ASCII_DTOSTR_BUF_SIZE]; + +- node = xmlNewChild(renderer->root, NULL, "rect", NULL); ++ node = xmlNewChild(renderer->root, NULL, (const xmlChar *)"rect", NULL); + +- xmlSetProp(node, "style", +- DIA_SVG_RENDERER_GET_CLASS(self)->get_fill_style(renderer, colour)); ++ xmlSetProp(node, (const xmlChar *)"style", ++ (const xmlChar *) DIA_SVG_RENDERER_GET_CLASS(self)->get_fill_style(renderer, colour)); + +- g_ascii_formatd(buf, sizeof(buf), "%g", ul_corner->x); +- xmlSetProp(node, "x", buf); +- g_ascii_formatd(buf, sizeof(buf), "%g", ul_corner->y); +- xmlSetProp(node, "y", buf); +- g_ascii_formatd(buf, sizeof(buf), "%g", lr_corner->x - ul_corner->x); +- xmlSetProp(node, "width", buf); +- g_ascii_formatd(buf, sizeof(buf), "%g", lr_corner->y - ul_corner->y); +- xmlSetProp(node, "height", buf); +- g_ascii_formatd(buf, sizeof(buf),"%g", rounding); +- xmlSetProp(node, "rx", buf); +- xmlSetProp(node, "ry", buf); ++ g_ascii_formatd(buf, sizeof(buf), "%g", (ul_corner->x * renderer->scale)); ++ xmlSetProp(node, (const xmlChar *)"x", (xmlChar *) buf); ++ g_ascii_formatd(buf, sizeof(buf), "%g", (ul_corner->y * renderer->scale)); ++ xmlSetProp(node, (const xmlChar *)"y", (xmlChar *) buf); ++ g_ascii_formatd(buf, sizeof(buf), "%g", (lr_corner->x - ul_corner->x) * renderer->scale); ++ xmlSetProp(node, (const xmlChar *)"width", (xmlChar *) buf); ++ g_ascii_formatd(buf, sizeof(buf), "%g", (lr_corner->y - ul_corner->y) * renderer->scale); ++ xmlSetProp(node, (const xmlChar *)"height", (xmlChar *) buf); ++ g_ascii_formatd(buf, sizeof(buf),"%g", (rounding * renderer->scale)); ++ xmlSetProp(node, (const xmlChar *)"rx", (xmlChar *) buf); ++ xmlSetProp(node, (const xmlChar *)"ry", (xmlChar *) buf); + } + + static void +diff -ur dia-0.96.1/plug-ins/svg/svg-import.c dia-0.96.1.new/plug-ins/svg/svg-import.c +--- dia-0.96.1/plug-ins/svg/svg-import.c 2007-01-06 23:39:30.000000000 +0100 ++++ dia-0.96.1.new/plug-ins/svg/svg-import.c 2008-02-01 15:03:33.000000000 +0100 +@@ -70,6 +70,46 @@ + return colour; + } + ++/* Dia default scale is 20px per cm; the user scale *should* be dynamic but this would involve a ++ * much more complicated approach than implemented in this imported (transformations!) ++ */ ++const gdouble DEFAULT_SVG_SCALE = 20.0; ++static gdouble user_scale = 20.0; ++ ++/*! ++ * Read a numeric value from a string taking unit into account. The signature is the same as ++ * g_ascii_strtod but also reads the unit if there is one ++ */ ++static gdouble ++get_value_as_cm (const gchar *nptr, ++ gchar **endptr) ++{ ++ gchar *endp = NULL; ++ gdouble val = 0.0; ++ ++ g_return_val_if_fail (nptr != NULL, 0.0); ++ ++ val = g_ascii_strtod (nptr, &endp); ++ if (!endp || '\0' == *endp || ' ' == *endp || ',' == *endp || ';' == *endp) ++ val /= user_scale; ++ else if (strncmp(endp, "px", 2) == 0) ++ val /= user_scale, endp+=2; ++ else if (strncmp(endp, "cm", 2) == 0) ++ val *= 1.0, endp+=2; /* nothing to scale */ ++ else if (strncmp(endp, "mm", 2) == 0) ++ val /= 10.0, endp+=2; ++ else if (strncmp(endp, "in", 2) == 0) ++ val /= 2.54, endp+=2; ++ else if (strncmp(endp, "pt", 2) == 0) ++ val /= 0.03528, endp+=2; ++ /* the rest can't really be resolved here, passing unit to caller (who will just ignore at the moment) */ ++ ++ if (endptr) ++ *endptr = endp; ++ ++ return val; ++} ++ + static PropDescription svg_line_prop_descs[] = { + { "start_point", PROP_TYPE_POINT }, + { "end_point", PROP_TYPE_POINT }, +@@ -136,7 +176,7 @@ + /* SVG defaults */ + dia_svg_style_init (gs, parent_style); + +- dia_svg_parse_style(node, gs); ++ dia_svg_parse_style(node, gs, user_scale); + props = prop_list_from_descs(svg_style_prop_descs, pdtpp_true); + g_assert(props->len == 5); + +@@ -185,6 +225,7 @@ + gchar *str, *pathdata, *unparsed = NULL; + GArray *bezpoints = NULL; + gboolean closed = FALSE; ++ guint i; + + pathdata = str = xmlGetProp(node, "d"); + do { +@@ -206,7 +247,17 @@ + } + bcd = g_new(BezierCreateData, 1); + bcd->num_points = bezpoints->len; +- bcd->points = &(g_array_index(bezpoints, BezPoint, 0)); ++ bcd->points = &(g_array_index(bezpoints, BezPoint, 0)); ++ /* dia_svg_parse_path does not scale to the user coordinate system, do it here */ ++ for (i = 0; i < bcd->num_points; ++i) { ++ bcd->points[i].p1.x /= user_scale; ++ bcd->points[i].p1.y /= user_scale; ++ if (bcd->points[i].type != BEZ_CURVE_TO) continue; /* don't scale unintitialized */ ++ bcd->points[i].p2.x /= user_scale; ++ bcd->points[i].p2.y /= user_scale; ++ bcd->points[i].p3.x /= user_scale; ++ bcd->points[i].p3.y /= user_scale; ++ } + new_obj = otype->ops->create(NULL, bcd, &h1, &h2); + g_free(bcd); + apply_style(new_obj, node, parent_style); +@@ -220,6 +271,7 @@ + + if (bezpoints) + g_array_free (bezpoints, TRUE); ++ + xmlFree (str); + + return list; +@@ -241,20 +293,20 @@ + gs = g_new(DiaSvgStyle, 1); + gs->font = NULL; + gs->font_height = 1.0; +- gs->alignment = ALIGN_CENTER; ++ gs->alignment = ALIGN_LEFT; + + point.x = 0; + point.y = 0; + + str = xmlGetProp(node, "x"); + if (str) { +- point.x = g_ascii_strtod(str, NULL); ++ point.x = get_value_as_cm(str, NULL); + xmlFree(str); + } + + str = xmlGetProp(node, "y"); + if (str) { +- point.y = g_ascii_strtod(str, NULL); ++ point.y = get_value_as_cm(str, NULL); + xmlFree(str); + } + +@@ -267,8 +319,7 @@ + props = prop_list_from_descs(svg_text_prop_descs, pdtpp_true); + g_assert(props->len == 1); + +- dia_svg_parse_style(node, gs); +- ++ dia_svg_parse_style(node, gs, user_scale); + if(gs->font == NULL) { + gs->font = dia_font_new_from_legacy_name("Courier"); + } +@@ -281,6 +332,7 @@ + prop->attr.position.y = point.y; + prop->attr.font = gs->font; + prop->attr.height = gs->font_height; ++ prop->attr.color = get_colour (gs->fill); + new_obj->ops->set_props(new_obj, props); + prop_list_free(props); + } +@@ -312,7 +364,7 @@ + while (tmp[0] != '\0' && !g_ascii_isdigit(tmp[0]) && tmp[0]!='.'&&tmp[0]!='-') + tmp++; + if (tmp[0] == '\0') break; +- val = g_ascii_strtod(tmp, &tmp); ++ val = get_value_as_cm(tmp, &tmp); + g_array_append_val(arr, val); + } + xmlFree(str); +@@ -354,34 +406,34 @@ + + str = xmlGetProp(node, "cx"); + if (str) { +- start.x = g_ascii_strtod(str, NULL); ++ start.x = get_value_as_cm(str, NULL); + xmlFree(str); + } + else return list; + str = xmlGetProp(node, "cy"); + if (str) { +- start.y = g_ascii_strtod(str, NULL); ++ start.y = get_value_as_cm(str, NULL); + xmlFree(str); + } + else return list; + str = xmlGetProp(node, "rx"); + if (str) { +- width = g_ascii_strtod(str, NULL)*2; ++ width = get_value_as_cm(str, NULL)*2; + xmlFree(str); + } + str = xmlGetProp(node, "ry"); + if (str) { +- height = g_ascii_strtod(str, NULL)*2; ++ height = get_value_as_cm(str, NULL)*2; + xmlFree(str); + } + str = xmlGetProp(node, "ry"); + if (str) { +- height = g_ascii_strtod(str, NULL)*2; ++ height = get_value_as_cm(str, NULL)*2; + xmlFree(str); + } + str = xmlGetProp(node, "r"); + if (str) { +- width = height = g_ascii_strtod(str, NULL)*2; ++ width = height = get_value_as_cm(str, NULL)*2; + xmlFree(str); + } + if (width <= 0.0 || height <= 0.0) +@@ -411,25 +463,25 @@ + + str = xmlGetProp(node, "x1"); + if (str) { +- start.x = g_ascii_strtod(str, NULL); ++ start.x = get_value_as_cm(str, NULL); + xmlFree(str); + } + else return list; + str = xmlGetProp(node, "y1"); + if (str) { +- start.y = g_ascii_strtod(str, NULL); ++ start.y = get_value_as_cm(str, NULL); + xmlFree(str); + } + else return list; + str = xmlGetProp(node, "x2"); + if (str) { +- end.x = g_ascii_strtod(str, NULL); ++ end.x = get_value_as_cm(str, NULL); + xmlFree(str); + } + else return list; + str = xmlGetProp(node, "y2"); + if (str) { +- end.y = g_ascii_strtod(str, NULL); ++ end.y = get_value_as_cm(str, NULL); + xmlFree(str); + } + else return list; +@@ -472,40 +524,40 @@ + + str = xmlGetProp(node, "x"); + if (str) { +- start.x = g_ascii_strtod(str, NULL); ++ start.x = get_value_as_cm(str, NULL); + xmlFree(str); + } + else return list; + str = xmlGetProp(node, "y"); + if (str) { +- start.y = g_ascii_strtod(str, NULL); ++ start.y = get_value_as_cm(str, NULL); + xmlFree(str); + } + else return list; + str = xmlGetProp(node, "width"); + if (str) { +- width = g_ascii_strtod(str, NULL); ++ width = get_value_as_cm(str, NULL); + xmlFree(str); + } + else return list; + str = xmlGetProp(node, "height"); + if (str) { +- height = g_ascii_strtod(str, NULL); ++ height = get_value_as_cm(str, NULL); + xmlFree(str); + } + else return list; + str = xmlGetProp(node, "rx"); + if (str) { +- corner_radius = g_ascii_strtod(str, NULL); ++ corner_radius = get_value_as_cm(str, NULL); + xmlFree(str); + } + str = xmlGetProp(node, "ry"); + if (str) { + if(corner_radius != 0.0) { + /* calculate the mean value of rx and ry */ +- corner_radius = (corner_radius+g_ascii_strtod(str, NULL))/2; ++ corner_radius = (corner_radius+get_value_as_cm(str, NULL))/2; + } else { +- corner_radius = g_ascii_strtod(str, NULL); ++ corner_radius = get_value_as_cm(str, NULL); + } + xmlFree(str); + } +@@ -560,7 +612,7 @@ + /* We need to have/apply the groups style before the objects style */ + group_gs = g_new0 (DiaSvgStyle, 1); + dia_svg_style_init (group_gs, parent_gs); +- dia_svg_parse_style (node, group_gs); ++ dia_svg_parse_style (node, group_gs, user_scale); + + moreitems = read_items (node->xmlChildrenNode, group_gs); + +@@ -659,6 +711,44 @@ + return FALSE; + } + ++ /* the following calls rely on the fact that noone messed with the original scale */ ++ user_scale = DEFAULT_SVG_SCALE; ++ /* if the svg root element contains width, height and viewBox calculate our user scale from it */ ++ { ++ xmlChar *swidth = xmlGetProp(root, (const xmlChar *)"width"); ++ xmlChar *sheight = xmlGetProp(root, (const xmlChar *)"height"); ++ xmlChar *sviewbox = xmlGetProp(root, (const xmlChar *)"viewBox"); ++ ++ if (swidth && sheight && sviewbox) { ++ real width = get_value_as_cm (swidth, NULL); ++ real height = get_value_as_cm (sheight, NULL); ++ gint x1 = 0, y1 = 0, x2 = 0, y2 = 0; ++ ++ if (4 == sscanf (sviewbox, "%d %d %d %d", &x1, &y1, &x2, &y2)) { ++ real xs, ys; ++ g_print ("viewBox(%d %d %d %d) = (%f,%f)\n", x1, y1, x2, y2, width, height); ++ /* some basic sanity check */ ++ if (x2 > x1 && y2 > y1 && width > 0 && height > 0) ++ xs = ((real)x2 - x1) / width; ++ ys = ((real)y2 - y1) / height; ++ /* plausibility check, strictly speaking these are not required to be the same ++ * /or/ are they and Dia is writting a bogus viewBox? ++ */ ++ if (fabs((fabs (xs/ys) - 1.0) < 0.1)) { ++ user_scale = xs; ++ g_print ("viewBox(%d %d %d %d) scaling (%f,%f) -> %f\n", x1, y1, x2, y2, xs, ys, user_scale); ++ } ++ } ++ } ++ ++ if (swidth) ++ xmlFree (swidth); ++ if (sheight) ++ xmlFree (sheight); ++ if (sviewbox) ++ xmlFree (sviewbox); ++ } ++ + items = read_items (root->xmlChildrenNode, NULL); + for (item = items; item != NULL; item = g_list_next (item)) { + DiaObject *obj = (DiaObject *)item->data; +Only in dia-0.96.1.new/plug-ins/svg: svg-import.c.orig +Only in dia-0.96.1.new/plug-ins/svg: svg-import.c.rej +Only in dia-0.96.1.new/plug-ins/svg: svg-import.c~ diff --git a/dia.spec b/dia.spec index ac14384..d15daa0 100644 --- a/dia.spec +++ b/dia.spec @@ -1,6 +1,6 @@ Name: dia Version: 0.96.1 -Release: 4%{?dist} +Release: 6%{?dist} Epoch: 1 Summary: Diagram drawing program Group: Applications/Multimedia @@ -12,6 +12,8 @@ Patch2: dia-0.95-pre6-help.patch Patch3: dia-0.94-fallbacktoxpmicons.patch Patch4: dia-0.96-python-detect.patch Patch5: dia-0.96.1-64bit.patch +Patch6: dia-0.96.1-desktop.patch +Patch7: dia-0.96.1-svg-export.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: libgnomeui-devel python-devel pygtk2-devel desktop-file-utils BuildRequires: intltool docbook-utils docbook-style-dsssl docbook-style-xsl @@ -34,6 +36,8 @@ and can export to PostScript(TM). %patch3 -p1 -b .fallbacktoxpmicons %patch4 -p1 -b .py-detect %patch5 -p1 -b .64bit +%patch6 -p1 +%patch7 -p1 sed -i 's|libdia_la_LDFLAGS = -avoid-version|libdia_la_LDFLAGS = -avoid-version $(shell pkg-config gtk+-2.0 libxml-2.0 libart-2.0 libgnome-2.0 --libs)|' \ lib/Makefile.* chmod -x `find objects/AADL -type f` @@ -63,7 +67,6 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/%{name}/libcairo* # below is the desktop file and icon stuff. desktop-file-install --vendor fedora --delete-original \ --dir $RPM_BUILD_ROOT%{_datadir}/applications \ - --add-category Office \ --remove-category Application \ $RPM_BUILD_ROOT%{_datadir}/applications/%{name}.desktop mkdir -p $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/48x48/apps @@ -102,12 +105,18 @@ rm -fr $RPM_BUILD_ROOT %dir %{_datadir}/gnome %dir %{_datadir}/gnome/help %{_datadir}/gnome/help/%{name} -%dir %{_datadir}/mime-info %{_datadir}/mime-info/* %{_datadir}/icons/hicolor/48x48/apps/*.png %changelog +* Fri Feb 1 2008 Hans de Goede 1:0.96.1-6 +- Fix svg export (bug 431184) + +* Sun Dec 2 2007 Hans de Goede 1:0.96.1-5 +- Do not put dia in both the Office and the Graphics application menus + (bz 408041) + * Tue Nov 27 2007 Hans de Goede 1:0.96.1-4 - Fix help not showing due to an encoding error (bz 401291)