/** * as_icon_node_insert: (skip) * @icon: a #AsIcon instance. * @parent: the parent #GNode to use.. * @ctx: the #AsNodeContext * * Inserts the icon into the DOM tree. * * Returns: (transfer none): A populated #GNode * * Since: 0.3.1 **/ GNode * as_icon_node_insert (AsIcon *icon, GNode *parent, AsNodeContext *ctx) { AsIconPrivate *priv = GET_PRIVATE (icon); GNode *n; /* embedded icon */ if (priv->kind == AS_ICON_KIND_EMBEDDED) return as_icon_node_insert_embedded (icon, parent, ctx); /* other icons */ switch (priv->kind) { case AS_ICON_KIND_REMOTE: n = as_node_insert (parent, "icon", priv->url, 0, "type", as_icon_kind_to_string (priv->kind), NULL); break; case AS_ICON_KIND_LOCAL: if (priv->filename != NULL) { n = as_node_insert (parent, "icon", priv->filename, 0, "type", as_icon_kind_to_string (priv->kind), NULL); } else { n = as_node_insert (parent, "icon", priv->name, 0, "type", as_icon_kind_to_string (priv->kind), NULL); } break; default: n = as_node_insert (parent, "icon", priv->name, 0, "type", as_icon_kind_to_string (priv->kind), NULL); break; } if (priv->kind == AS_ICON_KIND_CACHED && as_node_context_get_version (ctx) >= 0.8) { if (priv->width > 0) as_node_add_attribute_as_uint (n, "width", priv->width); if (priv->height > 0) as_node_add_attribute_as_uint (n, "height", priv->height); } return n; }
/** * as_icon_node_insert: (skip) * @icon: a #AsIcon instance. * @parent: the parent #GNode to use.. * @api_version: the AppStream API version * * Inserts the icon into the DOM tree. * * Returns: (transfer none): A populated #GNode * * Since: 0.3.1 **/ GNode * as_icon_node_insert (AsIcon *icon, GNode *parent, gdouble api_version) { AsIconPrivate *priv = GET_PRIVATE (icon); GNode *n; _cleanup_free_ gchar *data = NULL; /* normal icon */ if (priv->kind != AS_ICON_KIND_EMBEDDED) { n = as_node_insert (parent, "icon", priv->name, 0, "type", as_icon_kind_to_string (priv->kind), NULL); if (priv->kind == AS_ICON_KIND_CACHED && api_version >= 0.8) { if (priv->width > 0) as_node_add_attribute_as_int (n, "width", priv->width); if (priv->height > 0) as_node_add_attribute_as_int (n, "height", priv->height); } return n; } /* embedded icon */ n = as_node_insert (parent, "icon", NULL, 0, "type", as_icon_kind_to_string (priv->kind), NULL); if (api_version >= 0.8) { as_node_add_attribute_as_int (n, "width", priv->width); as_node_add_attribute_as_int (n, "height", priv->height); } as_node_insert (n, "name", priv->name, 0, NULL); data = g_base64_encode (g_bytes_get_data (priv->data, NULL), g_bytes_get_size (priv->data)); as_node_insert (n, "filecontent", data, AS_NODE_INSERT_FLAG_BASE64_ENCODED, NULL); return n; }
static GNode * as_icon_node_insert_embedded (AsIcon *icon, GNode *parent, AsNodeContext *ctx) { AsIconPrivate *priv = GET_PRIVATE (icon); GNode *n; g_autofree gchar *data = NULL; /* embedded icon */ n = as_node_insert (parent, "icon", NULL, 0, "type", as_icon_kind_to_string (priv->kind), NULL); if (as_node_context_get_version (ctx) >= 0.8) { as_node_add_attribute_as_uint (n, "width", priv->width); as_node_add_attribute_as_uint (n, "height", priv->height); } as_node_insert (n, "name", priv->name, 0, NULL); data = g_base64_encode (g_bytes_get_data (priv->data, NULL), g_bytes_get_size (priv->data)); as_node_insert (n, "filecontent", data, AS_NODE_INSERT_FLAG_BASE64_ENCODED, NULL); return n; }
/** * gs_refine_item_pixbuf: */ static void gs_refine_item_pixbuf (GsPlugin *plugin, GsApp *app, AsApp *item) { AsIcon *icon; gboolean ret; g_autoptr(GError) error = NULL; g_autofree gchar *fn = NULL; g_autofree gchar *cachedir = NULL; icon = as_app_get_icon_default (item); switch (as_icon_get_kind (icon)) { case AS_ICON_KIND_REMOTE: gs_app_set_icon (app, icon); if (as_icon_get_filename (icon) == NULL) { cachedir = gs_utils_get_cachedir ("icons", NULL); fn = g_build_filename (cachedir, as_icon_get_name (icon), NULL); as_icon_set_filename (icon, fn); as_icon_set_prefix (icon, cachedir); } if (g_file_test (fn, G_FILE_TEST_EXISTS)) { as_icon_set_kind (icon, AS_ICON_KIND_LOCAL); ret = gs_app_load_icon (app, plugin->scale, &error); if (!ret) { g_warning ("failed to load icon %s: %s", as_icon_get_name (icon), error->message); return; } } break; case AS_ICON_KIND_STOCK: case AS_ICON_KIND_LOCAL: gs_app_set_icon (app, icon); /* does not exist, so try to find using the icon theme */ if (as_icon_get_kind (icon) == AS_ICON_KIND_LOCAL && as_icon_get_filename (icon) == NULL) as_icon_set_kind (icon, AS_ICON_KIND_STOCK); /* load */ ret = gs_app_load_icon (app, plugin->scale, &error); if (!ret) { g_warning ("failed to load %s icon %s: %s", as_icon_kind_to_string (as_icon_get_kind (icon)), as_icon_get_name (icon), error->message); return; } break; case AS_ICON_KIND_CACHED: if (plugin->scale == 2) icon = as_app_get_icon_for_size (item, 128, 128); if (icon == NULL) icon = as_app_get_icon_for_size (item, 64, 64); if (icon == NULL) { g_warning ("failed to find cached icon %s", as_icon_get_name (icon)); return; } if (!as_icon_load (icon, AS_ICON_LOAD_FLAG_SEARCH_SIZE, &error)) { g_warning ("failed to load cached icon %s: %s", as_icon_get_name (icon), error->message); return; } gs_app_set_pixbuf (app, as_icon_get_pixbuf (icon)); break; default: g_warning ("icon kind unknown for %s", as_app_get_id (item)); break; } }
/** * as_icon_convert_to_kind: * @icon: a #AsIcon instance. * @kind: a %AsIconKind, e.g. #AS_ICON_KIND_EMBEDDED * @error: A #GError or %NULL. * * Converts the icon from one kind to another. * * Returns: %TRUE for success * * Since: 0.3.1 **/ gboolean as_icon_convert_to_kind (AsIcon *icon, AsIconKind kind, GError **error) { AsIconPrivate *priv = GET_PRIVATE (icon); /* these can't be converted */ if (priv->kind == AS_ICON_KIND_STOCK || priv->kind == AS_ICON_KIND_REMOTE) return TRUE; /* no change */ if (priv->kind == kind) return TRUE; /* cached -> embedded */ if (priv->kind == AS_ICON_KIND_CACHED && kind == AS_ICON_KIND_EMBEDDED) { gsize data_size; g_autoptr(GBytes) tmp = NULL; g_autofree gchar *data = NULL; /* load the pixbuf and save it to a PNG buffer */ if (priv->pixbuf == NULL) { if (!as_icon_load (icon, AS_ICON_LOAD_FLAG_SEARCH_SIZE, error)) return FALSE; } if (!gdk_pixbuf_save_to_buffer (priv->pixbuf, &data, &data_size, "png", error, NULL)) return FALSE; /* set the PNG buffer to a blob of data */ tmp = g_bytes_new (data, data_size); as_icon_set_data (icon, tmp); as_icon_set_kind (icon, kind); return TRUE; } /* cached -> embedded */ if (priv->kind == AS_ICON_KIND_EMBEDDED && kind == AS_ICON_KIND_CACHED) { g_autofree gchar *size_str = NULL; g_autofree gchar *path = NULL; g_autofree gchar *fn = NULL; /* ensure the parent path exists */ size_str = g_strdup_printf ("%ux%u", priv->width, priv->height); path = g_build_filename (priv->prefix, size_str, NULL); if (g_mkdir_with_parents (path, 0700) != 0) { g_set_error (error, AS_ICON_ERROR, AS_ICON_ERROR_FAILED, "Failed to create: %s", path); return FALSE; } /* save the pixbuf */ fn = g_build_filename (path, priv->name, NULL); if (!gdk_pixbuf_save (priv->pixbuf, fn, "png", error, NULL)) return FALSE; as_icon_set_kind (icon, kind); return TRUE; } /* not supported */ g_set_error (error, AS_ICON_ERROR, AS_ICON_ERROR_FAILED, "converting %s to %s is not supported", as_icon_kind_to_string (priv->kind), as_icon_kind_to_string (kind)); return FALSE; }
/** * as_icon_node_parse: * @icon: a #AsIcon instance. * @node: a #GNode. * @ctx: a #AsNodeContext. * @error: A #GError or %NULL. * * Populates the object from a DOM node. * * Returns: %TRUE for success * * Since: 0.3.1 **/ gboolean as_icon_node_parse (AsIcon *icon, GNode *node, AsNodeContext *ctx, GError **error) { AsIconPrivate *priv = GET_PRIVATE (icon); const gchar *tmp; guint size; gboolean prepend_size = TRUE; tmp = as_node_get_attribute (node, "type"); as_icon_set_kind (icon, as_icon_kind_from_string (tmp)); switch (priv->kind) { case AS_ICON_KIND_EMBEDDED: if (!as_icon_node_parse_embedded (icon, node, error)) return FALSE; break; default: /* preserve the URL for remote icons */ tmp = as_node_get_data (node); if (tmp == NULL) { g_set_error (error, AS_ICON_ERROR, AS_ICON_ERROR_FAILED, "no data for icon of type %s", as_icon_kind_to_string (priv->kind)); return FALSE; } if (priv->kind == AS_ICON_KIND_REMOTE) as_icon_set_url (icon, tmp); else if (priv->kind == AS_ICON_KIND_LOCAL) as_icon_set_filename (icon, tmp); /* store the name without any prefix */ if (g_strstr_len (tmp, -1, "/") == NULL) { as_icon_set_name (icon, tmp); } else { g_autofree gchar *basename = NULL; basename = g_path_get_basename (tmp); as_icon_set_name (icon, basename); } /* width is optional, assume 64px if missing */ size = as_node_get_attribute_as_uint (node, "width"); if (size == G_MAXUINT) { size = 64; prepend_size = FALSE; } priv->width = size; /* height is optional, assume 64px if missing */ size = as_node_get_attribute_as_uint (node, "height"); if (size == G_MAXUINT) { size = 64; prepend_size = FALSE; } priv->height = size; /* only use the size if the metadata has width and height */ if (prepend_size) { g_free (priv->prefix_private); priv->prefix_private = g_strdup_printf ("%s/%ux%u", priv->prefix, priv->width, priv->height); } break; } return TRUE; }