Import newer upstream.
This commit is contained in:
@ -63,6 +63,20 @@
|
||||
|
||||
#define DEBUGPRINT(x) /* g_print x */
|
||||
|
||||
enum
|
||||
{
|
||||
PIKA_FONT_SYMBOL_FONTHASH,
|
||||
PIKA_FONT_SYMBOL_FULLNAME,
|
||||
PIKA_FONT_SYMBOL_FAMILY,
|
||||
PIKA_FONT_SYMBOL_STYLE,
|
||||
PIKA_FONT_SYMBOL_PSNAME,
|
||||
PIKA_FONT_SYMBOL_INDEX,
|
||||
PIKA_FONT_SYMBOL_WEIGHT,
|
||||
PIKA_FONT_SYMBOL_SLANT,
|
||||
PIKA_FONT_SYMBOL_WIDTH,
|
||||
PIKA_FONT_SYMBOL_FONTVERSION
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
@ -231,18 +245,21 @@ pika_font_deserialize_create (GType type,
|
||||
gint most_similar_font_index = -1;
|
||||
gint font_count = pika_container_get_n_children (fonts_container);
|
||||
gint largest_similarity = 0;
|
||||
gint similar_fonts = 0;
|
||||
GList *similar_fonts = NULL;
|
||||
GList *iter;
|
||||
gint i;
|
||||
gchar *fonthash;
|
||||
gchar *fullname;
|
||||
gchar *family;
|
||||
gchar *psname;
|
||||
gchar *style;
|
||||
gint index;
|
||||
gint weight;
|
||||
gint slant;
|
||||
gint width;
|
||||
gint fontversion;
|
||||
gchar *fonthash = NULL;
|
||||
gchar *fullname = NULL;
|
||||
gchar *family = NULL;
|
||||
gchar *psname = NULL;
|
||||
gchar *style = NULL;
|
||||
gint index = -1;
|
||||
gint weight = -1;
|
||||
gint slant = -1;
|
||||
gint width = -1;
|
||||
gint fontversion = -1;
|
||||
guint scope_id;
|
||||
guint old_scope_id;
|
||||
|
||||
/* This is for backward compatibility with older xcf files.
|
||||
* The font used to be serialized as a string containing
|
||||
@ -250,7 +267,7 @@ pika_font_deserialize_create (GType type,
|
||||
*/
|
||||
if (g_scanner_peek_next_token (scanner) == G_TOKEN_STRING)
|
||||
{
|
||||
gchar* font_name;
|
||||
gchar* font_name = NULL;
|
||||
|
||||
pika_scanner_parse_string (scanner, &font_name);
|
||||
|
||||
@ -269,61 +286,119 @@ pika_font_deserialize_create (GType type,
|
||||
else
|
||||
g_object_ref (font);
|
||||
|
||||
g_free (font_name);
|
||||
|
||||
return PIKA_CONFIG (PIKA_FONT (font));
|
||||
}
|
||||
|
||||
if (g_scanner_peek_next_token (scanner) == G_TOKEN_RIGHT_PAREN)
|
||||
return PIKA_CONFIG (PIKA_FONT (pika_font_get_standard ()));
|
||||
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
g_scanner_get_next_token (scanner); /* "fonthash" */
|
||||
pika_scanner_parse_string (scanner, &fonthash);
|
||||
g_scanner_get_next_token (scanner); /* ) */
|
||||
scope_id = g_type_qname (type);
|
||||
old_scope_id = g_scanner_set_scope (scanner, scope_id);
|
||||
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
g_scanner_get_next_token (scanner); /* "fullname" */
|
||||
pika_scanner_parse_string (scanner, &fullname);
|
||||
g_scanner_get_next_token (scanner); /* ) */
|
||||
g_scanner_scope_add_symbol (scanner, scope_id, "fonthash",
|
||||
GINT_TO_POINTER (PIKA_FONT_SYMBOL_FONTHASH));
|
||||
g_scanner_scope_add_symbol (scanner, scope_id, "fullname",
|
||||
GINT_TO_POINTER (PIKA_FONT_SYMBOL_FULLNAME));
|
||||
g_scanner_scope_add_symbol (scanner, scope_id, "family",
|
||||
GINT_TO_POINTER (PIKA_FONT_SYMBOL_FAMILY));
|
||||
g_scanner_scope_add_symbol (scanner, scope_id, "style",
|
||||
GINT_TO_POINTER (PIKA_FONT_SYMBOL_STYLE));
|
||||
g_scanner_scope_add_symbol (scanner, scope_id, "psname",
|
||||
GINT_TO_POINTER (PIKA_FONT_SYMBOL_PSNAME));
|
||||
g_scanner_scope_add_symbol (scanner, scope_id, "index",
|
||||
GINT_TO_POINTER (PIKA_FONT_SYMBOL_INDEX));
|
||||
g_scanner_scope_add_symbol (scanner, scope_id, "weight",
|
||||
GINT_TO_POINTER (PIKA_FONT_SYMBOL_WEIGHT));
|
||||
g_scanner_scope_add_symbol (scanner, scope_id, "slant",
|
||||
GINT_TO_POINTER (PIKA_FONT_SYMBOL_SLANT));
|
||||
g_scanner_scope_add_symbol (scanner, scope_id, "width",
|
||||
GINT_TO_POINTER (PIKA_FONT_SYMBOL_WIDTH));
|
||||
g_scanner_scope_add_symbol (scanner, scope_id, "fontversion",
|
||||
GINT_TO_POINTER (PIKA_FONT_SYMBOL_FONTVERSION));
|
||||
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
g_scanner_get_next_token (scanner); /* "family" */
|
||||
pika_scanner_parse_string (scanner, &family);
|
||||
g_scanner_get_next_token (scanner); /* ) */
|
||||
while (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
GTokenType token;
|
||||
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
g_scanner_get_next_token (scanner); /* "style" */
|
||||
pika_scanner_parse_string (scanner, &style);
|
||||
g_scanner_get_next_token (scanner); /* ) */
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
g_scanner_get_next_token (scanner); /* "psname" */
|
||||
pika_scanner_parse_string (scanner, &psname);
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
g_scanner_get_next_token (scanner); /* "font index" */
|
||||
pika_scanner_parse_int (scanner, &index);
|
||||
g_scanner_get_next_token (scanner); /* ) */
|
||||
if (token != G_TOKEN_SYMBOL)
|
||||
{
|
||||
/* When encountering an unknown symbol, we simply ignore its contents
|
||||
* (up to the next closing parenthese). This would allow us to load
|
||||
* future XCF files in case we add new fields to recognize fonts
|
||||
* without having to bump the XCF version (just ignoring unknown
|
||||
* fields). We still output a small message on stderr.
|
||||
*/
|
||||
if (token == G_TOKEN_IDENTIFIER)
|
||||
g_printerr ("%s: ignoring unknown symbol '%s'.\n", G_STRFUNC, scanner->value.v_string);
|
||||
else
|
||||
g_printerr ("%s: ignoring unknown token %d.\n", G_STRFUNC, token);
|
||||
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
g_scanner_get_next_token (scanner); /* "weight" */
|
||||
pika_scanner_parse_int (scanner, &weight);
|
||||
g_scanner_get_next_token (scanner); /* ) */
|
||||
while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF)
|
||||
{
|
||||
if (token == G_TOKEN_RIGHT_PAREN)
|
||||
break;
|
||||
}
|
||||
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
g_scanner_get_next_token (scanner); /* "slant" */
|
||||
pika_scanner_parse_int (scanner, &slant);
|
||||
g_scanner_get_next_token (scanner); /* ) */
|
||||
continue;
|
||||
}
|
||||
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
g_scanner_get_next_token (scanner); /* "width" */
|
||||
pika_scanner_parse_int (scanner, &width);
|
||||
g_scanner_get_next_token (scanner); /* ) */
|
||||
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
|
||||
{
|
||||
case PIKA_FONT_SYMBOL_FONTHASH:
|
||||
pika_scanner_parse_string (scanner, &fonthash);
|
||||
break;
|
||||
case PIKA_FONT_SYMBOL_FULLNAME:
|
||||
pika_scanner_parse_string (scanner, &fullname);
|
||||
break;
|
||||
case PIKA_FONT_SYMBOL_FAMILY:
|
||||
pika_scanner_parse_string (scanner, &family);
|
||||
break;
|
||||
case PIKA_FONT_SYMBOL_STYLE:
|
||||
pika_scanner_parse_string (scanner, &style);
|
||||
break;
|
||||
case PIKA_FONT_SYMBOL_PSNAME:
|
||||
pika_scanner_parse_string (scanner, &psname);
|
||||
break;
|
||||
case PIKA_FONT_SYMBOL_INDEX:
|
||||
pika_scanner_parse_int (scanner, &index);
|
||||
break;
|
||||
case PIKA_FONT_SYMBOL_WEIGHT:
|
||||
pika_scanner_parse_int (scanner, &weight);
|
||||
break;
|
||||
case PIKA_FONT_SYMBOL_SLANT:
|
||||
pika_scanner_parse_int (scanner, &slant);
|
||||
break;
|
||||
case PIKA_FONT_SYMBOL_WIDTH:
|
||||
pika_scanner_parse_int (scanner, &width);
|
||||
break;
|
||||
case PIKA_FONT_SYMBOL_FONTVERSION:
|
||||
pika_scanner_parse_int (scanner, &fontversion);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_scanner_get_next_token (scanner); /* ( */
|
||||
g_scanner_get_next_token (scanner); /* "fontversion" */
|
||||
pika_scanner_parse_int (scanner, &fontversion);
|
||||
g_scanner_get_next_token (scanner); /* ) */
|
||||
if (g_scanner_get_next_token (scanner) != G_TOKEN_RIGHT_PAREN)
|
||||
break;
|
||||
}
|
||||
|
||||
g_scanner_scope_remove_symbol (scanner, scope_id, "fonthash");
|
||||
g_scanner_scope_remove_symbol (scanner, scope_id, "fullname");
|
||||
g_scanner_scope_remove_symbol (scanner, scope_id, "family");
|
||||
g_scanner_scope_remove_symbol (scanner, scope_id, "style");
|
||||
g_scanner_scope_remove_symbol (scanner, scope_id, "psname");
|
||||
g_scanner_scope_remove_symbol (scanner, scope_id, "index");
|
||||
g_scanner_scope_remove_symbol (scanner, scope_id, "weight");
|
||||
g_scanner_scope_remove_symbol (scanner, scope_id, "slant");
|
||||
g_scanner_scope_remove_symbol (scanner, scope_id, "width");
|
||||
g_scanner_scope_remove_symbol (scanner, scope_id, "fontversion");
|
||||
g_scanner_set_scope (scanner, old_scope_id);
|
||||
|
||||
for (i = 0; i < font_count; i++)
|
||||
{
|
||||
@ -331,10 +406,10 @@ pika_font_deserialize_create (GType type,
|
||||
|
||||
font = PIKA_FONT (pika_container_get_child_by_index (fonts_container, i));
|
||||
|
||||
if (font->hash != NULL && !g_strcmp0 (font->hash, fonthash))
|
||||
if (fonthash != NULL && font->hash != NULL && !g_strcmp0 (font->hash, fonthash))
|
||||
{
|
||||
most_similar_font_index = i;
|
||||
similar_fonts = 1;
|
||||
g_clear_pointer (&similar_fonts, g_list_free);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -342,19 +417,19 @@ pika_font_deserialize_create (GType type,
|
||||
* hence their higher importance in measuring similarity.
|
||||
*/
|
||||
|
||||
if (!g_strcmp0 (font->fullname, fullname))
|
||||
if (fullname != NULL && !g_strcmp0 (font->fullname, fullname))
|
||||
current_font_similarity += 5;
|
||||
|
||||
if (!g_strcmp0 (font->family, family))
|
||||
if (family != NULL && !g_strcmp0 (font->family, family))
|
||||
current_font_similarity += 5;
|
||||
|
||||
if (font->psname != NULL && !g_strcmp0 (font->psname, psname))
|
||||
if (psname != NULL && font->psname != NULL && !g_strcmp0 (font->psname, psname))
|
||||
current_font_similarity += 5;
|
||||
|
||||
if (current_font_similarity < 5)
|
||||
continue;
|
||||
|
||||
if (font->style != NULL && !g_strcmp0 (font->style, style))
|
||||
if (style != NULL && font->style != NULL && !g_strcmp0 (font->style, style))
|
||||
current_font_similarity++;
|
||||
|
||||
if (font->weight != -1 && font->weight == weight)
|
||||
@ -376,63 +451,31 @@ pika_font_deserialize_create (GType type,
|
||||
{
|
||||
largest_similarity = current_font_similarity;
|
||||
most_similar_font_index = i;
|
||||
similar_fonts = 1;
|
||||
g_clear_pointer (&similar_fonts, g_list_free);
|
||||
similar_fonts = g_list_prepend (similar_fonts, GINT_TO_POINTER (i));
|
||||
}
|
||||
else if (current_font_similarity == largest_similarity)
|
||||
{
|
||||
similar_fonts++;
|
||||
similar_fonts = g_list_prepend (similar_fonts, GINT_TO_POINTER (i));
|
||||
}
|
||||
}
|
||||
|
||||
/* In case there are multiple font with identical info,
|
||||
* the font file hash should be used for comparison.
|
||||
*/
|
||||
if (similar_fonts > 1)
|
||||
for (i = 0; i < font_count && similar_fonts > 0; i++)
|
||||
/* In case there are multiple font with identical info,
|
||||
* the font file hash should be used for comparison.
|
||||
*/
|
||||
if (g_list_length (similar_fonts) == 1)
|
||||
g_clear_pointer (&similar_fonts, g_list_free);
|
||||
for (iter = similar_fonts; iter; iter = iter->next)
|
||||
{
|
||||
i = GPOINTER_TO_INT (iter->data);
|
||||
font = PIKA_FONT (pika_container_get_child_by_index (fonts_container, i));
|
||||
|
||||
if (g_strcmp0 (pika_font_get_hash (font), fonthash) == 0)
|
||||
{
|
||||
gint current_font_similarity = 0;
|
||||
font = PIKA_FONT (pika_container_get_child_by_index (fonts_container, i));
|
||||
|
||||
if (!g_strcmp0 (font->fullname, fullname))
|
||||
current_font_similarity += 5;
|
||||
|
||||
if (!g_strcmp0 (font->family, family))
|
||||
current_font_similarity += 5;
|
||||
|
||||
if (font->psname != NULL && !g_strcmp0 (font->psname, psname))
|
||||
current_font_similarity += 5;
|
||||
|
||||
if (current_font_similarity < 5)
|
||||
continue;
|
||||
|
||||
if (font->style != NULL && !g_strcmp0 (font->style, style))
|
||||
current_font_similarity++;
|
||||
|
||||
if (font->weight != -1 && font->weight == weight)
|
||||
current_font_similarity++;
|
||||
|
||||
if (font->width != -1 && font->width == width)
|
||||
current_font_similarity++;
|
||||
|
||||
if (font->slant != -1 && font->slant == slant)
|
||||
current_font_similarity++;
|
||||
|
||||
if (font->index != -1 && font->index == index)
|
||||
current_font_similarity++;
|
||||
|
||||
if (font->fontversion != -1 && font->fontversion == fontversion)
|
||||
current_font_similarity++;
|
||||
|
||||
if (current_font_similarity == largest_similarity)
|
||||
{
|
||||
if (g_strcmp0 (pika_font_get_hash (font), fonthash) == 0)
|
||||
{
|
||||
most_similar_font_index = i;
|
||||
break;
|
||||
}
|
||||
similar_fonts--;
|
||||
}
|
||||
most_similar_font_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (most_similar_font_index > -1)
|
||||
{
|
||||
@ -444,6 +487,7 @@ pika_font_deserialize_create (GType type,
|
||||
font = PIKA_FONT (pika_font_get_standard ());
|
||||
}
|
||||
|
||||
g_list_free (similar_fonts);
|
||||
g_free (fonthash);
|
||||
g_free (fullname);
|
||||
g_free (family);
|
||||
|
@ -424,13 +424,13 @@ pika_font_factory_recursive_add_fontdir (FcConfig *config,
|
||||
GFileType file_type;
|
||||
GFile *child;
|
||||
|
||||
if (g_file_info_get_is_hidden (info))
|
||||
if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN))
|
||||
{
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
|
||||
file_type = g_file_info_get_file_type (info);
|
||||
file_type = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE);
|
||||
child = g_file_enumerator_get_child (enumerator, info);
|
||||
|
||||
if (file_type == G_FILE_TYPE_DIRECTORY)
|
||||
@ -896,4 +896,4 @@ pika_font_factory_load_names (PikaContainer *container,
|
||||
FcFontSetDestroy (fontset);
|
||||
|
||||
pika_font_class_set_font_factory (container);
|
||||
}
|
||||
}
|
||||
|
@ -927,7 +927,7 @@ pika_text_deserialize_property (PikaConfig *object,
|
||||
}
|
||||
else if (property_id == PROP_MARKUP)
|
||||
{
|
||||
gchar *markup;
|
||||
gchar *markup = NULL;
|
||||
GString *markup_str;
|
||||
PikaFont *dummy_object = g_object_new (PIKA_TYPE_FONT, NULL);
|
||||
|
||||
@ -940,7 +940,7 @@ pika_text_deserialize_property (PikaConfig *object,
|
||||
{
|
||||
while (g_scanner_peek_next_token (scanner) == G_TOKEN_STRING)
|
||||
{
|
||||
gchar *markup_fontname;
|
||||
gchar *markup_fontname = NULL;
|
||||
gchar *replaced_markup;
|
||||
gchar *new_markup;
|
||||
PikaFont *font;
|
||||
@ -973,7 +973,7 @@ pika_text_deserialize_property (PikaConfig *object,
|
||||
{
|
||||
while (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
gchar *lookupname;
|
||||
gchar *lookupname = NULL;
|
||||
gchar *replaced_markup;
|
||||
gchar *new_markup;
|
||||
PikaFont *font;
|
||||
@ -1007,6 +1007,7 @@ pika_text_deserialize_property (PikaConfig *object,
|
||||
|
||||
g_object_unref (dummy_object);
|
||||
g_string_free (markup_str, TRUE);
|
||||
g_free (markup);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
Reference in New Issue
Block a user