Exemplo n.º 1
0
static GdkPixbuf *
photos_base_item_create_placeholder_icon (const gchar *icon_name)
{
  GApplication *app;
  GdkPixbuf *centered_pixbuf = NULL;
  GdkPixbuf *pixbuf = NULL;
  GdkPixbuf *ret_val = NULL;
  GError *error;
  GIcon *icon = NULL;
  GList *windows;
  GtkIconInfo *info = NULL;
  GtkIconTheme *theme;
  GtkStyleContext *context;
  gint icon_size;
  gint scale;

  app = g_application_get_default ();
  windows = gtk_application_get_windows (GTK_APPLICATION (app));
  if (windows == NULL)
    goto out;

  icon = g_themed_icon_new (icon_name);
  scale = photos_application_get_scale_factor (PHOTOS_APPLICATION (app));
  theme = gtk_icon_theme_get_default ();
  info = gtk_icon_theme_lookup_by_gicon_for_scale (theme,
                                                   icon,
                                                   16,
                                                   scale,
                                                   GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_FORCE_SYMBOLIC);
  if (info == NULL)
    goto out;

  context = gtk_widget_get_style_context (GTK_WIDGET (windows->data));

  error = NULL;
  pixbuf = gtk_icon_info_load_symbolic_for_context (info, context, NULL, &error);
  if (error != NULL)
    {
      g_warning ("Unable to load icon '%s': %s", icon_name, error->message);
      g_error_free (error);
      goto out;
    }

  icon_size = photos_utils_get_icon_size ();
  centered_pixbuf = photos_utils_center_pixbuf (pixbuf, icon_size);
  photos_utils_border_pixbuf (centered_pixbuf);

  ret_val = centered_pixbuf;
  centered_pixbuf = NULL;

 out:
  g_clear_object (&centered_pixbuf);
  g_clear_object (&pixbuf);
  g_clear_object (&info);
  g_clear_object (&icon);
  return ret_val;
}
Exemplo n.º 2
0
GdkPixbuf *
photos_utils_create_placeholder_icon_for_scale (const gchar *name, gint size, gint scale)
{
  GApplication *app;
  g_autoptr (GdkPixbuf) centered_pixbuf = NULL;
  g_autoptr (GdkPixbuf) pixbuf = NULL;
  GdkPixbuf *ret_val = NULL;
  g_autoptr (GIcon) icon = NULL;
  GList *windows;
  g_autoptr (GtkIconInfo) info = NULL;
  GtkIconTheme *theme;
  GtkStyleContext *context;
  gint size_scaled;

  app = g_application_get_default ();
  windows = gtk_application_get_windows (GTK_APPLICATION (app));
  if (windows == NULL)
    goto out;

  icon = g_themed_icon_new (name);
  theme = gtk_icon_theme_get_default ();
  info = gtk_icon_theme_lookup_by_gicon_for_scale (theme,
                                                   icon,
                                                   16,
                                                   scale,
                                                   GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_FORCE_SYMBOLIC);
  if (info == NULL)
    goto out;

  context = gtk_widget_get_style_context (GTK_WIDGET (windows->data));

  {
    g_autoptr (GError) error = NULL;

    pixbuf = gtk_icon_info_load_symbolic_for_context (info, context, NULL, &error);
    if (error != NULL)
      {
        g_warning ("Unable to load icon '%s': %s", name, error->message);
        goto out;
      }
  }

  size_scaled = size * scale;
  centered_pixbuf = photos_utils_center_pixbuf (pixbuf, size_scaled);

  ret_val = centered_pixbuf;
  centered_pixbuf = NULL;

 out:
  return ret_val;
}
Exemplo n.º 3
0
static void
ensure_surface_for_icon_name_or_gicon (GtkIconHelper *self,
				       GtkStyleContext *context)
{
  GtkIconTheme *icon_theme;
  gint width, height, scale;
  GtkIconInfo *info;
  GtkIconLookupFlags flags;

  if (!check_invalidate_surface (self, context))
    return;

  icon_theme = gtk_icon_theme_get_default ();
  flags = get_icon_lookup_flags (self);

  ensure_icon_size (self, context, &width, &height);
  scale = get_scale_factor (self, context);

  if (self->priv->storage_type == GTK_IMAGE_ICON_NAME &&
      self->priv->icon_name != NULL)
    {
      info = gtk_icon_theme_lookup_icon_for_scale (icon_theme,
						   self->priv->icon_name,
						   MIN (width, height),
						   scale, flags);
    }
  else if (self->priv->storage_type == GTK_IMAGE_GICON &&
           self->priv->gicon != NULL)
    {
      info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme,
						       self->priv->gicon,
						       MIN (width, height),
						       scale, flags);
    }
  else
    {
      g_assert_not_reached ();
      return;
    }

  ensure_stated_surface_from_info (self, context, info, scale);

  if (info)
    g_object_unref (info);
}
Exemplo n.º 4
0
static GdkPaintable *
ensure_paintable_for_gicon (GtkIconHelper    *self,
                            GtkCssStyle      *style,
                            GtkTextDirection  dir,
                            gint              scale,
                            GIcon            *gicon,
                            gboolean         *symbolic)
{
  GtkIconTheme *icon_theme;
  gint width, height;
  GtkIconInfo *info;
  GtkIconLookupFlags flags;
  GdkPaintable *paintable;

  icon_theme = gtk_css_icon_theme_value_get_icon_theme
    (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_THEME));
  flags = get_icon_lookup_flags (self, style, dir);

  width = height = gtk_icon_helper_get_size (self);

  info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme,
                                                   gicon,
                                                   MIN (width, height),
                                                   scale, flags);
  if (info == NULL)
    info = gtk_icon_theme_lookup_icon (icon_theme,
                                       "image-missing",
                                       width,
                                       flags | GTK_ICON_LOOKUP_USE_BUILTIN | GTK_ICON_LOOKUP_GENERIC_FALLBACK);

  *symbolic = gtk_icon_info_is_symbolic (info);
  paintable = GDK_PAINTABLE (gtk_icon_info_load_texture (info));
  g_object_unref (info);

  if (paintable && scale != 1)
    {
      GdkPaintable *orig = paintable;

      paintable = gtk_scaler_new (orig, scale);
      g_object_unref (orig);
    }

  return paintable;
}
Exemplo n.º 5
0
/**
 * st_texture_cache_load_gicon:
 * @cache: The texture cache instance
 * @theme_node: (nullable): The #StThemeNode to use for colors, or NULL
 *                            if the icon must not be recolored
 * @icon: the #GIcon to load
 * @size: Size of themed
 * @scale: Scale factor of display
 *
 * This method returns a new #ClutterActor for a given #GIcon. If the
 * icon isn't loaded already, the texture will be filled
 * asynchronously.
 *
 * Return Value: (transfer none): A new #ClutterActor for the icon, or %NULL if not found
 */
ClutterActor *
st_texture_cache_load_gicon (StTextureCache    *cache,
                             StThemeNode       *theme_node,
                             GIcon             *icon,
                             gint               size,
                             gint               scale)
{
  AsyncTextureLoadData *request;
  ClutterActor *texture;
  char *gicon_string;
  char *key;
  GtkIconTheme *theme;
  GtkIconInfo *info;
  StTextureCachePolicy policy;
  StIconColors *colors = NULL;
  StIconStyle icon_style = ST_ICON_STYLE_REQUESTED;
  GtkIconLookupFlags lookup_flags;

  if (theme_node)
    {
      colors = st_theme_node_get_icon_colors (theme_node);
      icon_style = st_theme_node_get_icon_style (theme_node);
    }

  /* Do theme lookups in the main thread to avoid thread-unsafety */
  theme = cache->priv->icon_theme;

  lookup_flags = GTK_ICON_LOOKUP_USE_BUILTIN;

  if (icon_style == ST_ICON_STYLE_REGULAR)
    lookup_flags |= GTK_ICON_LOOKUP_FORCE_REGULAR;
  else if (icon_style == ST_ICON_STYLE_SYMBOLIC)
    lookup_flags |= GTK_ICON_LOOKUP_FORCE_SYMBOLIC;

  if (clutter_get_default_text_direction () == CLUTTER_TEXT_DIRECTION_RTL)
    lookup_flags |= GTK_ICON_LOOKUP_DIR_RTL;
  else
    lookup_flags |= GTK_ICON_LOOKUP_DIR_LTR;

  info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, size, scale, lookup_flags);
  if (info == NULL)
    return NULL;

  gicon_string = g_icon_to_string (icon);
  /* A return value of NULL indicates that the icon can not be serialized,
   * so don't have a unique identifier for it as a cache key, and thus can't
   * be cached. If it is cachable, we hardcode a policy of FOREVER here for
   * now; we should actually blow this away on icon theme changes probably */
  policy = gicon_string != NULL ? ST_TEXTURE_CACHE_POLICY_FOREVER
                                : ST_TEXTURE_CACHE_POLICY_NONE;
  if (colors)
    {
      /* This raises some doubts about the practice of using string keys */
      key = g_strdup_printf (CACHE_PREFIX_ICON "%s,size=%d,scale=%d,style=%d,colors=%2x%2x%2x%2x,%2x%2x%2x%2x,%2x%2x%2x%2x,%2x%2x%2x%2x",
                             gicon_string, size, scale, icon_style,
                             colors->foreground.red, colors->foreground.blue, colors->foreground.green, colors->foreground.alpha,
                             colors->warning.red, colors->warning.blue, colors->warning.green, colors->warning.alpha,
                             colors->error.red, colors->error.blue, colors->error.green, colors->error.alpha,
                             colors->success.red, colors->success.blue, colors->success.green, colors->success.alpha);
    }
  else
    {
      key = g_strdup_printf (CACHE_PREFIX_ICON "%s,size=%d,scale=%d,style=%d",
                             gicon_string, size, scale, icon_style);
    }
  g_free (gicon_string);

  texture = (ClutterActor *) create_default_texture ();
  clutter_actor_set_size (texture, size * scale, size * scale);

  if (ensure_request (cache, key, policy, &request, texture))
    {
      /* If there's an outstanding request, we've just added ourselves to it */
      g_object_unref (info);
      g_free (key);
    }
  else
    {
      /* Else, make a new request */

      request->cache = cache;
      /* Transfer ownership of key */
      request->key = key;
      request->policy = policy;
      request->colors = colors ? st_icon_colors_ref (colors) : NULL;
      request->icon_info = info;
      request->width = request->height = size;
      request->scale = scale;

      load_texture_async (cache, request);
    }

  return CLUTTER_ACTOR (texture);
}
Exemplo n.º 6
0
static CoglHandle
cinnamon_app_create_faded_icon_cpu (StTextureCache *cache,
                                 const char     *key,
                                 void           *datap,
                                 GError        **error)
{
  CreateFadedIconData *data = datap;
  CinnamonApp *app;
  GdkPixbuf *pixbuf;
  int size;
  int scale;
  CoglHandle texture;
  gint width, height, rowstride;
  guint8 n_channels;
  gboolean have_alpha;
  gint fade_start;
  gint fade_range;
  guint i, j;
  guint pixbuf_byte_size;
  guint8 *orig_pixels;
  guint8 *pixels;
  GIcon *icon;
  GtkIconInfo *info;

  app = data->app;
  size = data->size;
  scale = data->scale;

  info = NULL;

  icon = g_app_info_get_icon (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry)));
  if (icon != NULL)
    {
      info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (),
                                                       icon, size, scale,
                                                       GTK_ICON_LOOKUP_FORCE_SIZE);
    }

  if (info == NULL)
    {
      icon = g_themed_icon_new ("application-x-executable");
      info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (),
                                                       icon, size, scale,
                                                       GTK_ICON_LOOKUP_FORCE_SIZE);
      g_object_unref (icon);
    }

  if (info == NULL)
    return COGL_INVALID_HANDLE;

  pixbuf = gtk_icon_info_load_icon (info, NULL);
  g_object_unref (info);

  if (pixbuf == NULL)
    return COGL_INVALID_HANDLE;

  width = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
  n_channels = gdk_pixbuf_get_n_channels (pixbuf);
  orig_pixels = gdk_pixbuf_get_pixels (pixbuf);
  have_alpha = gdk_pixbuf_get_has_alpha (pixbuf);

  pixbuf_byte_size = (height - 1) * rowstride +
    + width * ((n_channels * gdk_pixbuf_get_bits_per_sample (pixbuf) + 7) / 8);

  pixels = g_malloc0 (rowstride * height);
  memcpy (pixels, orig_pixels, pixbuf_byte_size);

  fade_start = width / 2;
  fade_range = width - fade_start;
  for (i = fade_start; i < width; i++)
    {
      for (j = 0; j < height; j++)
        {
          guchar *pixel = &pixels[j * rowstride + i * n_channels];
          float fade = 1.0 - ((float) i - fade_start) / fade_range;
          pixel[0] = 0.5 + pixel[0] * fade;
          pixel[1] = 0.5 + pixel[1] * fade;
          pixel[2] = 0.5 + pixel[2] * fade;
          if (have_alpha)
            pixel[3] = 0.5 + pixel[3] * fade;
        }
    }

    texture = st_cogl_texture_new_from_data_wrapper (width, height,
                                                     COGL_TEXTURE_NONE,
                                                     have_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
                                                     COGL_PIXEL_FORMAT_ANY,
                                                     rowstride, pixels);

  g_free (pixels);
  g_object_unref (pixbuf);

  return texture;
}
Exemplo n.º 7
0
static gboolean
gtk_color_swatch_render_overlay (GtkCssGadget *gadget,
                                 cairo_t      *cr,
                                 int           x,
                                 int           y,
                                 int           width,
                                 int           height,
                                 gpointer      data)
{
    GtkWidget *widget;
    GtkColorSwatch *swatch;
    GtkStyleContext *context;
    GtkStateFlags state;
    GtkIconTheme *theme;
    GtkIconInfo *icon_info = NULL;
    gint scale;

    widget = gtk_css_gadget_get_owner (gadget);
    swatch = GTK_COLOR_SWATCH (widget);

    theme = gtk_icon_theme_get_default ();
    context = gtk_widget_get_style_context (widget);
    state = gtk_style_context_get_state (context);

    scale = gtk_widget_get_scale_factor (widget);
    if (swatch->priv->icon)
    {
        icon_info = gtk_icon_theme_lookup_icon_for_scale (theme, swatch->priv->icon, PIXBUF_SIZE,
                    scale,
                    GTK_ICON_LOOKUP_GENERIC_FALLBACK
                    | GTK_ICON_LOOKUP_USE_BUILTIN);
    }
    else if ((state & GTK_STATE_FLAG_SELECTED) != 0)
    {
        GIcon *gicon;

        gicon = g_themed_icon_new ("object-select-symbolic");
        /* fallback for themes that don't have object-select-symbolic */
        g_themed_icon_append_name (G_THEMED_ICON (gicon), "gtk-apply");

        icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, gicon, PIXBUF_SIZE,
                    scale,
                    GTK_ICON_LOOKUP_USE_BUILTIN);
        g_object_unref (gicon);
    }

    /* now draw the overlay image */
    if (icon_info != NULL)
    {
        GdkPixbuf *pixbuf;

        pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, context, NULL, NULL);
        if (pixbuf != NULL)
        {
            cairo_surface_t *surface;

            surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, gtk_widget_get_window (widget));
            gtk_render_icon_surface (context, cr, surface, x, y);
            cairo_surface_destroy (surface);
            g_object_unref (pixbuf);
        }

        g_object_unref (icon_info);
    }

    return FALSE;
}
Exemplo n.º 8
0
static gboolean
swatch_draw (GtkWidget *widget,
             cairo_t   *cr)
{
  GtkColorSwatch *swatch = (GtkColorSwatch*)widget;
  gdouble width, height;
  GtkStyleContext *context;
  GtkStateFlags state;
  GtkIconTheme *theme;
  GtkBorder border, padding;
  GdkRectangle rect;
  GtkIconInfo *icon_info = NULL;
  gint scale;

  theme = gtk_icon_theme_get_default ();
  context = gtk_widget_get_style_context (widget);
  state = gtk_style_context_get_state (context);
  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  gtk_render_background (context, cr, 0, 0, width, height);

  if (swatch->priv->has_color)
    {
      cairo_pattern_t *pattern;
      cairo_matrix_t matrix;

      gtk_render_content_path (context, cr, 0, 0, width, height);

      if (swatch->priv->use_alpha)
        {
          cairo_save (cr);

          cairo_clip_preserve (cr);

          cairo_set_source_rgb (cr, 0.33, 0.33, 0.33);
          cairo_fill_preserve (cr);

          pattern = _gtk_color_chooser_get_checkered_pattern ();
          cairo_matrix_init_scale (&matrix, 0.125, 0.125);
          cairo_pattern_set_matrix (pattern, &matrix);

          cairo_set_source_rgb (cr, 0.66, 0.66, 0.66);
          cairo_mask (cr, pattern);
          cairo_pattern_destroy (pattern);

          cairo_restore (cr);

          gdk_cairo_set_source_rgba (cr, &swatch->priv->color);
        }
      else
        {
          cairo_set_source_rgb (cr,
                                swatch->priv->color.red,
                                swatch->priv->color.green,
                                swatch->priv->color.blue);
        }

      cairo_fill (cr);
    }

  gtk_render_frame (context, cr, 0, 0, width, height);

  scale = gtk_widget_get_scale_factor (widget);
  if (swatch->priv->icon)
    {
      icon_info = gtk_icon_theme_lookup_icon_for_scale (theme, swatch->priv->icon, PIXBUF_SIZE,
                                                        scale,
                                                        GTK_ICON_LOOKUP_GENERIC_FALLBACK
                                                        | GTK_ICON_LOOKUP_USE_BUILTIN);
    }
  else if ((state & GTK_STATE_FLAG_SELECTED) != 0)
    {
      GIcon *gicon;

      gicon = g_themed_icon_new ("object-select-symbolic");
      /* fallback for themes that don't have object-select-symbolic */
      g_themed_icon_append_name (G_THEMED_ICON (gicon), "gtk-apply");

      icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, gicon, PIXBUF_SIZE,
                                                            scale,
                                                            GTK_ICON_LOOKUP_GENERIC_FALLBACK
                                                            | GTK_ICON_LOOKUP_USE_BUILTIN);
      g_object_unref (gicon);
    }

  /* now draw the overlay image */
  gtk_style_context_get_border (context, state, &border);
  gtk_style_context_get_padding (context, state, &padding);
  rect.width = width - (border.left + border.right + padding.left + padding.right);
  rect.height = height - (border.top + border.bottom + padding.top + padding.bottom);
  rect.x = border.left + padding.left;
  rect.y = border.top + padding.top;

  gtk_style_context_save_to_node (context, swatch->priv->overlay_node);

  gtk_render_background (context, cr, rect.x, rect.y, rect.width, rect.height);
  gtk_render_frame (context, cr, rect.x, rect.y, rect.width, rect.height);

  if (icon_info != NULL)
    {
      GdkPixbuf *pixbuf;

      pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, context, NULL, NULL);
      if (pixbuf != NULL)
        {
          cairo_surface_t *surface;

          surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, gtk_widget_get_window (widget));
          gtk_render_icon_surface (context, cr, surface,
                                   rect.x + (rect.width - (gdk_pixbuf_get_width (pixbuf) / scale)) / 2,
                                   rect.y + (rect.height - (gdk_pixbuf_get_height (pixbuf) / scale)) / 2);
          cairo_surface_destroy (surface);
          g_object_unref (pixbuf);
        }

      g_object_unref (icon_info);
    }

  if (gtk_widget_has_visible_focus (widget))
    gtk_render_focus (context, cr, 0, 0, width, height);

  gtk_style_context_restore (context);

  return FALSE;
}
Exemplo n.º 9
0
static cairo_surface_t *
ensure_surface_for_gicon (GtkIconHelper    *self,
                          GtkCssStyle      *style,
                          GtkTextDirection  dir,
                          gint              scale,
                          GIcon            *gicon)
{
  GtkIconHelperPrivate *priv = self->priv;
  GtkIconTheme *icon_theme;
  gint width, height;
  GtkIconInfo *info;
  GtkIconLookupFlags flags;
  cairo_surface_t *surface;
  GdkPixbuf *destination;
  gboolean symbolic;

  icon_theme = gtk_css_icon_theme_value_get_icon_theme
    (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_THEME));
  flags = get_icon_lookup_flags (self, style, dir);

  ensure_icon_size (self, &width, &height);

  info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme,
                                                   gicon,
                                                   MIN (width, height),
                                                   scale, flags);
  if (info)
    {
      symbolic = gtk_icon_info_is_symbolic (info);

      if (symbolic)
        {
          GdkRGBA fg, success_color, warning_color, error_color;

          gtk_icon_theme_lookup_symbolic_colors (style, &fg, &success_color, &warning_color, &error_color);

          destination = gtk_icon_info_load_symbolic (info,
                                                     &fg, &success_color,
                                                     &warning_color, &error_color,
                                                     NULL,
                                                     NULL);
        }
      else
        {
          destination = gtk_icon_info_load_icon (info, NULL);
        }

      g_object_unref (info);
    }
  else
    {
      destination = NULL;
    }

  if (destination == NULL)
    {
      destination = gtk_icon_theme_load_icon (icon_theme,
                                              "image-missing",
                                              width,
                                              flags | GTK_ICON_LOOKUP_USE_BUILTIN | GTK_ICON_LOOKUP_GENERIC_FALLBACK,
                                              NULL);
      /* We include this image as resource, so we always have it available or
       * the icontheme code is broken */
      g_assert (destination);
      symbolic = FALSE;
    }

  surface = gdk_cairo_surface_create_from_pixbuf (destination, scale, gtk_widget_get_window (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))));

  if (!symbolic)
    {
      GtkCssIconEffect icon_effect;

      icon_effect = _gtk_css_icon_effect_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_EFFECT));
      gtk_css_icon_effect_apply (icon_effect, surface);
    }
  else
    {
      priv->rendered_surface_is_symbolic = TRUE;
    }

  g_object_unref (destination);

  return surface;
}
Exemplo n.º 10
0
GIcon *
photos_utils_create_symbolic_icon_for_scale (const gchar *name, gint base_size, gint scale)
{
  g_autoptr (GIcon) icon = NULL;
  GIcon *ret_val = NULL;
  g_autoptr (GdkPixbuf) pixbuf = NULL;
  g_autoptr (GtkIconInfo) info = NULL;
  GtkIconTheme *theme;
  g_autoptr (GtkStyleContext) style = NULL;
  g_autoptr (GtkWidgetPath) path = NULL;
  cairo_surface_t *icon_surface = NULL; /* TODO: use g_autoptr */
  cairo_surface_t *surface; /* TODO: use g_autoptr */
  cairo_t *cr; /* TODO: use g_autoptr */
  g_autofree gchar *symbolic_name = NULL;
  const gint bg_size = 24;
  const gint emblem_margin = 4;
  gint emblem_pos;
  gint emblem_size;
  gint total_size;
  gint total_size_scaled;

  total_size = base_size / 2;
  total_size_scaled = total_size * scale;
  emblem_size = bg_size - emblem_margin * 2;

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, total_size_scaled, total_size_scaled);
  cairo_surface_set_device_scale (surface, (gdouble) scale, (gdouble) scale);
  cr = cairo_create (surface);

  style = gtk_style_context_new ();

  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
  gtk_style_context_set_path (style, path);

  gtk_style_context_add_class (style, "photos-icon-bg");

  gtk_render_background (style, cr, total_size - bg_size, total_size - bg_size, bg_size, bg_size);

  symbolic_name = g_strconcat (name, "-symbolic", NULL);
  icon = g_themed_icon_new_with_default_fallbacks (symbolic_name);

  theme = gtk_icon_theme_get_default();
  info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, emblem_size, scale, GTK_ICON_LOOKUP_FORCE_SIZE);
  if (info == NULL)
    goto out;

  pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL);
  if (pixbuf == NULL)
    goto out;

  icon_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL);

  emblem_pos = total_size - emblem_size - emblem_margin;
  gtk_render_icon_surface (style, cr, icon_surface, emblem_pos, emblem_pos);

  ret_val = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, total_size_scaled, total_size_scaled));

 out:
  cairo_surface_destroy (icon_surface);
  cairo_surface_destroy (surface);
  cairo_destroy (cr);

  return ret_val;
}
Exemplo n.º 11
0
/**
 * gd_create_symbolic_icon_for_scale:
 * @name:
 * @base_size:
 * @scale:
 *
 * Returns: (transfer full):
 */
GIcon *
gd_create_symbolic_icon_for_scale (const gchar *name,
                                   gint base_size,
                                   gint scale)
{
  gchar *symbolic_name;
  GIcon *icon, *retval = NULL;
  cairo_surface_t *icon_surface;
  cairo_surface_t *surface;
  cairo_t *cr;
  GtkStyleContext *style;
  GtkWidgetPath *path;
  GdkPixbuf *pixbuf;
  GtkIconTheme *theme;
  GtkIconInfo *info;
  gint bg_size;
  gint emblem_size;
  gint total_size;
  gint total_size_scaled;

  total_size = base_size / 2;
  total_size_scaled = total_size * scale;

  bg_size = MAX (total_size / 2, _BG_MIN_SIZE);
  emblem_size = MAX (bg_size - 8, _EMBLEM_MIN_SIZE);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, total_size_scaled, total_size_scaled);
  cairo_surface_set_device_scale (surface, (gdouble) scale, (gdouble) scale);
  cr = cairo_create (surface);

  style = gtk_style_context_new ();

  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
  gtk_style_context_set_path (style, path);
  gtk_widget_path_unref (path);

  gtk_style_context_add_class (style, "documents-icon-bg");

  gtk_render_background (style, cr, (total_size - bg_size) / 2, (total_size - bg_size) / 2, bg_size, bg_size);

  symbolic_name = g_strconcat (name, "-symbolic", NULL);
  icon = g_themed_icon_new_with_default_fallbacks (symbolic_name);
  g_free (symbolic_name);

  theme = gtk_icon_theme_get_default();
  info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, emblem_size, scale,
                                                   GTK_ICON_LOOKUP_FORCE_SIZE);
  g_object_unref (icon);

  if (info == NULL)
    goto out;

  pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL);
  g_object_unref (info);

  if (pixbuf == NULL)
    goto out;

  icon_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL);
  g_object_unref (pixbuf);

  gtk_render_icon_surface (style, cr, icon_surface, (total_size - emblem_size) / 2,  (total_size - emblem_size) / 2);
  cairo_surface_destroy (icon_surface);

  retval = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, total_size_scaled, total_size_scaled));

 out:
  g_object_unref (style);
  cairo_surface_destroy (surface);
  cairo_destroy (cr);

  return retval;
}
NautilusIconInfo *
nautilus_icon_info_lookup (GIcon *icon,
			   int size,
			   int scale)
{
	NautilusIconInfo *icon_info;
	GdkPixbuf *pixbuf;
	
	if (G_IS_LOADABLE_ICON (icon)) {
		LoadableIconKey lookup_key;
		LoadableIconKey *key;
		GInputStream *stream;
		
		if (loadable_icon_cache == NULL) {
			loadable_icon_cache =
				g_hash_table_new_full ((GHashFunc)loadable_icon_key_hash,
						       (GEqualFunc)loadable_icon_key_equal,
						       (GDestroyNotify) loadable_icon_key_free,
						       (GDestroyNotify) g_object_unref);
		}
		
		lookup_key.icon = icon;
		lookup_key.size = size;

		icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key);
		if (icon_info) {
			return g_object_ref (icon_info);
		}

		pixbuf = NULL;
		stream = g_loadable_icon_load (G_LOADABLE_ICON (icon),
					       size * scale,
					       NULL, NULL, NULL);
		if (stream) {
			pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream,
								      size * scale, size * scale,
								      TRUE,
								      NULL, NULL);
			g_input_stream_close (stream, NULL, NULL);
			g_object_unref (stream);
		}

		icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf, scale);

		key = loadable_icon_key_new (icon, size);
		g_hash_table_insert (loadable_icon_cache, key, icon_info);

		return g_object_ref (icon_info);
	} else if (G_IS_THEMED_ICON (icon)) {
		const char * const *names;
		ThemedIconKey lookup_key;
		ThemedIconKey *key;
		GtkIconTheme *icon_theme;
		GtkIconInfo *gtkicon_info;
		const char *filename;

		if (themed_icon_cache == NULL) {
			themed_icon_cache =
				g_hash_table_new_full ((GHashFunc)themed_icon_key_hash,
						       (GEqualFunc)themed_icon_key_equal,
						       (GDestroyNotify) themed_icon_key_free,
						       (GDestroyNotify) g_object_unref);
		}
		
		names = g_themed_icon_get_names (G_THEMED_ICON (icon));

		icon_theme = gtk_icon_theme_get_default ();
		gtkicon_info = gtk_icon_theme_choose_icon_for_scale (icon_theme, (const char **)names,
								     size, scale, GTK_ICON_LOOKUP_FORCE_SIZE);

		if (gtkicon_info == NULL) {
			return nautilus_icon_info_new_for_pixbuf (NULL, scale);
		}

		filename = gtk_icon_info_get_filename (gtkicon_info);
		if (filename == NULL) {
			g_object_unref (gtkicon_info);
			return nautilus_icon_info_new_for_pixbuf (NULL, scale);
		}

		lookup_key.filename = (char *)filename;
		lookup_key.size = size;

		icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key);
		if (icon_info) {
			g_object_unref (gtkicon_info);
			return g_object_ref (icon_info);
		}
		
		icon_info = nautilus_icon_info_new_for_icon_info (gtkicon_info, scale);
		
		key = themed_icon_key_new (filename, size);
		g_hash_table_insert (themed_icon_cache, key, icon_info);

		g_object_unref (gtkicon_info);

		return g_object_ref (icon_info);
	} else {
                GdkPixbuf *pixbuf;
                GtkIconInfo *gtk_icon_info;

                gtk_icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (),
									  icon,
									  size,
									  scale,
									  GTK_ICON_LOOKUP_FORCE_SIZE);
                if (gtk_icon_info != NULL) {
                        pixbuf = gtk_icon_info_load_icon (gtk_icon_info, NULL);
                        g_object_unref (gtk_icon_info);
                } else {
                        pixbuf = NULL;
                }

		icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf, scale);

		if (pixbuf != NULL) {
			g_object_unref (pixbuf);
		}

		return icon_info;
        }
}