mirror of https://github.com/GNOME/gimp.git
app: fix a few bug in text markup (de)serialization.
- g_str_equal() doesn't have the proper signature for g_slist_find_custom() so current code was never processing multiple subfonts in a markup layer text. - Escape the font name parsed from the XCF. For old XCF format, it could contain forbidden characters. And even for new XCF files (with fonts names generated such as 'font123' so there should be no escapable characters), we should not trust that the XCF/parasite contents is correct. It can be wrong for various reasons. - Search for ' font="%s"', otherwise the search-and-replace might catch other XML attributes. For instance we don't want the font "ultrabold" to match weight="ultrabold". - The backward compatibility code didn't have code to stop 2 font name replacements to chain up, i.e. if a real world font was named "gimpfont123" and another "gimpfont321" and if our replacement code were to change "gimpfont123" to "gimpfont321" then "gimpfont321" to something else. In the end, we'd have only a single font. I am fixing it by replacing " font=" to " gimpfont=" then only correcting the attribute name at the end. This intermediate attribute name acts as a "done" flag.
This commit is contained in:
parent
ed4c50ce2e
commit
e832b73e55
|
@ -137,7 +137,7 @@ gimp_text_from_parasite (const GimpParasite *parasite,
|
||||||
{
|
{
|
||||||
desc = pango_font_description_to_string (attr_font_desc->desc);
|
desc = pango_font_description_to_string (attr_font_desc->desc);
|
||||||
|
|
||||||
if (g_slist_find_custom (fonts, (gconstpointer) desc, g_str_equal) == NULL)
|
if (g_slist_find_custom (fonts, (gconstpointer) desc, (GCompareFunc) g_strcmp0) == NULL)
|
||||||
{
|
{
|
||||||
fonts = g_slist_prepend (fonts, (gpointer) desc);
|
fonts = g_slist_prepend (fonts, (gpointer) desc);
|
||||||
/*duplicate font name to making parsing easier when deserializing*/
|
/*duplicate font name to making parsing easier when deserializing*/
|
||||||
|
|
|
@ -830,7 +830,7 @@ gimp_text_serialize_property (GimpConfig *config,
|
||||||
gchar *altered_font_name = pango_font_description_to_string (attr_font_desc->desc);
|
gchar *altered_font_name = pango_font_description_to_string (attr_font_desc->desc);
|
||||||
gchar *font_name = g_strdup_printf ("gimp%s", altered_font_name);
|
gchar *font_name = g_strdup_printf ("gimp%s", altered_font_name);
|
||||||
|
|
||||||
if (g_slist_find_custom (fonts, (gconstpointer) font_name, g_str_equal) == NULL)
|
if (g_slist_find_custom (fonts, (gconstpointer) font_name, (GCompareFunc) g_strcmp0) == NULL)
|
||||||
{
|
{
|
||||||
fonts = g_slist_prepend (fonts, (gpointer) font_name);
|
fonts = g_slist_prepend (fonts, (gpointer) font_name);
|
||||||
|
|
||||||
|
@ -933,60 +933,71 @@ gimp_text_deserialize_property (GimpConfig *object,
|
||||||
|
|
||||||
/* This is for backward compatibility with older xcf files.*/
|
/* This is for backward compatibility with older xcf files.*/
|
||||||
if (g_scanner_peek_next_token (scanner) == G_TOKEN_STRING)
|
if (g_scanner_peek_next_token (scanner) == G_TOKEN_STRING)
|
||||||
while (g_scanner_peek_next_token (scanner) == G_TOKEN_STRING)
|
{
|
||||||
{
|
while (g_scanner_peek_next_token (scanner) == G_TOKEN_STRING)
|
||||||
gchar *markup_fontname;
|
{
|
||||||
gchar *escaped_markup_fontname;
|
gchar *markup_fontname;
|
||||||
gchar *actual_font_lookupname;
|
gchar *replaced_markup;
|
||||||
GimpFont *font;
|
gchar *new_markup;
|
||||||
|
GimpFont *font;
|
||||||
|
|
||||||
gimp_scanner_parse_string (scanner, &markup_fontname);
|
gimp_scanner_parse_string (scanner, &markup_fontname);
|
||||||
|
|
||||||
font = GIMP_FONT (GIMP_CONFIG_GET_IFACE (dummy_object)->deserialize_create (GIMP_TYPE_FONT,
|
font = GIMP_FONT (GIMP_CONFIG_GET_IFACE (dummy_object)->deserialize_create (GIMP_TYPE_FONT,
|
||||||
scanner,
|
scanner,
|
||||||
-1,
|
-1,
|
||||||
NULL));
|
NULL));
|
||||||
escaped_markup_fontname = g_strdup_printf ("\"%s\"", markup_fontname);
|
replaced_markup = g_markup_printf_escaped (" font=\"%s\"", markup_fontname);
|
||||||
actual_font_lookupname = g_strdup_printf ("\"%s\"", gimp_font_get_lookup_name (font));
|
new_markup = g_strdup_printf (" gimpfont=\"%s\"", gimp_font_get_lookup_name (font));
|
||||||
g_string_replace (markup_str, escaped_markup_fontname, actual_font_lookupname, 0);
|
g_string_replace (markup_str, replaced_markup, new_markup, 0);
|
||||||
|
|
||||||
g_free (markup_fontname);
|
|
||||||
g_free (escaped_markup_fontname);
|
|
||||||
g_free (actual_font_lookupname);
|
|
||||||
g_object_unref (font);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
g_free (markup_fontname);
|
||||||
|
g_free (replaced_markup);
|
||||||
|
g_free (new_markup);
|
||||||
|
g_object_unref (font);
|
||||||
|
}
|
||||||
|
/* We avoid the edge case when actual fonts are called "gimpfont%d"
|
||||||
|
* and their replacement name chains to each other by marking already
|
||||||
|
* processed font as "gimpfont=". Then we clean up this fake attribute
|
||||||
|
* name in the end.
|
||||||
|
* This is not a problem with the new format as font are stored as
|
||||||
|
* "font%d" (see comment in gimp_text_serialize_property()).
|
||||||
|
*/
|
||||||
|
g_string_replace (markup_str, " gimpfont=\"", " font=\"", 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
while (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN)
|
{
|
||||||
{
|
while (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN)
|
||||||
gchar *lookupname;
|
{
|
||||||
gchar *escaped_lookupname;
|
gchar *lookupname;
|
||||||
gchar *actual_font_lookupname;
|
gchar *replaced_markup;
|
||||||
GimpFont *font;
|
gchar *new_markup;
|
||||||
|
GimpFont *font;
|
||||||
|
|
||||||
g_scanner_get_next_token (scanner); /* ( */
|
g_scanner_get_next_token (scanner); /* ( */
|
||||||
g_scanner_get_next_token (scanner); /* "lookupname" */
|
g_scanner_get_next_token (scanner); /* "lookupname" */
|
||||||
gimp_scanner_parse_string (scanner, &lookupname);
|
gimp_scanner_parse_string (scanner, &lookupname);
|
||||||
|
|
||||||
g_scanner_get_next_token (scanner); /* ) */
|
g_scanner_get_next_token (scanner); /* ) */
|
||||||
g_scanner_get_next_token (scanner); /* font */
|
g_scanner_get_next_token (scanner); /* font */
|
||||||
|
|
||||||
font = GIMP_FONT (GIMP_CONFIG_GET_IFACE (dummy_object)->deserialize_create (GIMP_TYPE_FONT,
|
font = GIMP_FONT (GIMP_CONFIG_GET_IFACE (dummy_object)->deserialize_create (GIMP_TYPE_FONT,
|
||||||
scanner,
|
scanner,
|
||||||
-1,
|
-1,
|
||||||
NULL));
|
NULL));
|
||||||
g_scanner_get_next_token (scanner); /* ) */
|
g_scanner_get_next_token (scanner); /* ) */
|
||||||
g_scanner_get_next_token (scanner); /* ) */
|
g_scanner_get_next_token (scanner); /* ) */
|
||||||
|
|
||||||
escaped_lookupname = g_strdup_printf ("\"%s\"", lookupname);
|
replaced_markup = g_markup_printf_escaped (" font=\"%s\"", lookupname);
|
||||||
actual_font_lookupname = g_strdup_printf ("\"%s\"", gimp_font_get_lookup_name (font));
|
new_markup = g_strdup_printf (" font=\"%s\"", gimp_font_get_lookup_name (font));
|
||||||
g_string_replace (markup_str, escaped_lookupname, actual_font_lookupname, 0);
|
g_string_replace (markup_str, replaced_markup, new_markup, 0);
|
||||||
|
|
||||||
g_free (lookupname);
|
g_free (lookupname);
|
||||||
g_free (escaped_lookupname);
|
g_free (replaced_markup);
|
||||||
g_free (actual_font_lookupname);
|
g_free (new_markup);
|
||||||
g_object_unref (font);
|
g_object_unref (font);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
g_value_set_string (value, markup_str->str);
|
g_value_set_string (value, markup_str->str);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue