Import newer upstream.

This commit is contained in:
2023-09-25 16:54:03 -07:00
parent a8611b8b16
commit 098531073c
66 changed files with 13399 additions and 10203 deletions

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;
}