app/path: Add <title> to SVG import/export
In 84ff512c, we made the SVG id attribute
conform to SVG standards by using a
generic ID. However, we also relied on
that field to rename the path when copying
and pasting in GIMP. As a result, the path
name was lost.
This patch adds a <title> element inside the
<path> element, per David Gowers.
This allows us to retain the original
path name when copying and pasting
paths within GIMP itself, as this also adds
a check to see if there's a title element and
uses that as the path name.
This commit is contained in:
parent
4e2463b688
commit
0da5e56a7b
2 changed files with 65 additions and 9 deletions
|
|
@ -215,21 +215,27 @@ gimp_path_export_path (GimpPath *path,
|
|||
GString *str,
|
||||
gint path_id)
|
||||
{
|
||||
gchar *name;
|
||||
gchar *data = gimp_path_export_path_data (path);
|
||||
const gchar *name = gimp_object_get_name (path);
|
||||
gchar *data = gimp_path_export_path_data (path);
|
||||
gchar *id;
|
||||
gchar *esc_name;
|
||||
|
||||
/* SVG specification states the id attribute must not contain whitespace.
|
||||
* Rather than filter user names, we'll just define a generic,
|
||||
* auto-incrementing id. */
|
||||
name = g_strdup_printf ("path%d", path_id);
|
||||
id = g_strdup_printf ("path%d", path_id);
|
||||
esc_name = g_markup_escape_text (name, strlen (name));
|
||||
|
||||
g_string_append_printf (str,
|
||||
" <path id=\"%s\"\n"
|
||||
" fill=\"none\" stroke=\"black\" stroke-width=\"1\"\n"
|
||||
" d=\"%s\" />\n",
|
||||
name, data);
|
||||
" d=\"%s\">\n"
|
||||
" <title>%s</title>\n"
|
||||
" </path>\n",
|
||||
id, data, esc_name);
|
||||
|
||||
g_free (name);
|
||||
g_free (id);
|
||||
g_free (esc_name);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,11 @@ static void svg_parser_start_element (GMarkupParseContext *context,
|
|||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
static void svg_parser_text (GMarkupParseContext *context,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
static void svg_parser_end_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
gpointer user_data,
|
||||
|
|
@ -143,7 +148,7 @@ static const GMarkupParser markup_parser =
|
|||
{
|
||||
svg_parser_start_element,
|
||||
svg_parser_end_element,
|
||||
NULL, /* characters */
|
||||
svg_parser_text,
|
||||
NULL, /* passthrough */
|
||||
NULL /* error */
|
||||
};
|
||||
|
|
@ -190,7 +195,8 @@ static const SvgHandler svg_handlers[] =
|
|||
{ "ellipse", svg_handler_ellipse_start, NULL },
|
||||
{ "line", svg_handler_line_start, NULL },
|
||||
{ "polyline", svg_handler_poly_start, NULL },
|
||||
{ "polygon", svg_handler_poly_start, NULL }
|
||||
{ "polygon", svg_handler_poly_start, NULL },
|
||||
{ "title", NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -480,6 +486,50 @@ svg_parser_start_element (GMarkupParseContext *context,
|
|||
handler->start (handler, attribute_names, attribute_values, parser);
|
||||
}
|
||||
|
||||
static void
|
||||
svg_parser_text (GMarkupParseContext *context,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
SvgParser *parser = user_data;
|
||||
SvgHandler *handler;
|
||||
|
||||
handler = g_queue_pop_head (parser->stack);
|
||||
|
||||
if (handler &&
|
||||
handler->name &&
|
||||
strcmp (handler->name, "title") == 0)
|
||||
{
|
||||
gchar *title = g_markup_escape_text (text, text_len);
|
||||
SvgHandler *prior_handler;
|
||||
GList *paths;
|
||||
|
||||
prior_handler = g_queue_pop_head (parser->stack);
|
||||
|
||||
/* Replace path ID with title name if imported */
|
||||
if (prior_handler && prior_handler->paths)
|
||||
{
|
||||
for (paths = prior_handler->paths; paths; paths = paths->next)
|
||||
{
|
||||
SvgPath *svg_path = paths->data;
|
||||
|
||||
if (svg_path->id)
|
||||
g_free (svg_path->id);
|
||||
|
||||
svg_path->id = g_strdup (title);
|
||||
}
|
||||
g_list_free (paths);
|
||||
}
|
||||
|
||||
g_queue_push_head (parser->stack, prior_handler);
|
||||
g_free (title);
|
||||
}
|
||||
g_queue_push_head (parser->stack, handler);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
svg_parser_end_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
|
|
@ -1761,7 +1811,7 @@ parse_number (ParsePathContext *ctx,
|
|||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
fraction *= 0.1;
|
||||
value += fraction * (c - '0');
|
||||
value += fraction * (c - '0');
|
||||
}
|
||||
else if (c == 'e' || c == 'E')
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue