Beispiel #1
0
void
_gtk_icon_helper_get_size (GtkIconHelper *self,
                           GtkStyleContext *context,
                           gint *width_out,
                           gint *height_out)
{
  cairo_surface_t *surface;
  gint width, height;

  width = height = 0;
  surface = _gtk_icon_helper_ensure_surface (self, context);

  if (surface != NULL)
    {
      width = self->priv->rendered_surface_width;
      height = self->priv->rendered_surface_height;
      cairo_surface_destroy (surface);
    }
  else if (self->priv->storage_type == GTK_IMAGE_ANIMATION)
    {
      width = gdk_pixbuf_animation_get_width (self->priv->animation);
      height = gdk_pixbuf_animation_get_height (self->priv->animation);
    }
  else if (self->priv->icon_size != -1)
    {
      ensure_icon_size (self, context, &width, &height);
    }

  if (width_out)
    *width_out = width;
  if (height_out)
    *height_out = height;
}
Beispiel #2
0
static void
ensure_pixbuf_for_gicon (GtkIconHelper *self,
                         GtkStyleContext *context)
{
  GtkIconTheme *icon_theme;
  gint width, height;
  GtkIconInfo *info;
  GtkIconLookupFlags flags;

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

  icon_theme = gtk_icon_theme_get_for_screen (gtk_style_context_get_screen (context));
  flags = get_icon_lookup_flags (self, context);

  ensure_icon_size (self, context, &width, &height);

  if (self->priv->gicon != NULL)
    {
      info = gtk_icon_theme_lookup_by_gicon (icon_theme,
                                             self->priv->gicon,
                                             MIN (width, height), flags);
    }
  else
    {
      g_assert_not_reached ();
      return;
    }

  self->priv->rendered_pixbuf = ensure_stated_icon_from_info (self, context, info);

  if (info)
    g_object_unref (info);
}
Beispiel #3
0
static void
get_surface_size (GtkIconHelper   *self,
		  GtkStyleContext *context,
		  cairo_surface_t *surface,
		  int *width,
		  int *height)
{
  double x_scale, y_scale;

  if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE)
    {
      x_scale = y_scale = 1;

#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
      cairo_surface_get_device_scale (surface, &x_scale, &y_scale);
#endif

      /* Assume any set scaling is icon scale */
      *width =
	ceil (cairo_image_surface_get_width (surface) / x_scale);
      *height =
	ceil (cairo_image_surface_get_height (surface) / y_scale);
    }
  else
    ensure_icon_size (self, context, width, height);
}
Beispiel #4
0
static void
get_surface_size (GtkIconHelper   *self,
		  cairo_surface_t *surface,
		  int *width,
		  int *height)
{
  GdkRectangle clip;
  cairo_t *cr;

  cr = cairo_create (surface);
  if (gdk_cairo_get_clip_rectangle (cr, &clip))
    {
      if (clip.x != 0 || clip.y != 0)
        {
          g_warning ("origin of surface is %d %d, not supported", clip.x, clip.y);
        }
      *width = clip.width;
      *height = clip.height;
    }
  else
    {
      g_warning ("infinite surface size not supported");
      ensure_icon_size (self, width, height);
    }

  cairo_destroy (cr);
}
Beispiel #5
0
void
_gtk_icon_helper_get_size (GtkIconHelper *self,
                           GtkStyleContext *context,
                           gint *width_out,
                           gint *height_out)
{
  GdkPixbuf *pix;
  gint width, height;

  width = height = 0;
  pix = _gtk_icon_helper_ensure_pixbuf (self, context);

  if (pix != NULL)
    {
      width = gdk_pixbuf_get_width (pix);
      height = gdk_pixbuf_get_height (pix);

      g_object_unref (pix);
    }
  else if (self->priv->storage_type == GTK_IMAGE_ANIMATION)
    {
      width = gdk_pixbuf_animation_get_width (self->priv->animation);
      height = gdk_pixbuf_animation_get_height (self->priv->animation);
    }
  else if (self->priv->icon_size != -1)
    {
      ensure_icon_size (self, context, &width, &height);
    }

  if (width_out)
    *width_out = width;
  if (height_out)
    *height_out = height;
}
Beispiel #6
0
static void
ensure_surface_from_pixbuf (GtkIconHelper   *self,
			    GtkStyleContext *context)
{
  gint width, height;
  GdkPixbuf *pixbuf;
  int scale;

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

  if (self->priv->rendered_surface)
    return;

  scale = get_scale_factor (self, context);

  if (self->priv->force_scale_pixbuf &&
      (self->priv->pixel_size != -1 ||
       self->priv->icon_size != GTK_ICON_SIZE_INVALID))
    {
      ensure_icon_size (self, context, &width, &height);

      if (scale != self->priv->orig_pixbuf_scale ||
	  width < gdk_pixbuf_get_width (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale ||
          height < gdk_pixbuf_get_height (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale)
	{
	  width = MIN (width * scale, gdk_pixbuf_get_width (self->priv->orig_pixbuf) * scale / self->priv->orig_pixbuf_scale);
	  height = MIN (height * scale, gdk_pixbuf_get_height (self->priv->orig_pixbuf) * scale / self->priv->orig_pixbuf_scale);

	  pixbuf = gdk_pixbuf_scale_simple (self->priv->orig_pixbuf,
					    width, height,
					    GDK_INTERP_BILINEAR);
	}
      else
	{
	  pixbuf = g_object_ref (self->priv->orig_pixbuf); 
	  scale = self->priv->orig_pixbuf_scale;
	}
    }
  else
    {
      pixbuf = g_object_ref (self->priv->orig_pixbuf);
      scale = self->priv->orig_pixbuf_scale;
    }

  self->priv->rendered_surface_width = (gdk_pixbuf_get_width (pixbuf) + scale - 1) / scale;
  self->priv->rendered_surface_height = (gdk_pixbuf_get_height (pixbuf) + scale - 1) / scale;

  self->priv->rendered_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, self->priv->window);
  g_object_unref (pixbuf);
}
Beispiel #7
0
static void
ensure_pixbuf_at_size (GtkIconHelper   *self,
                       GtkStyleContext *context)
{
  gint width, height;
  GdkPixbuf *stated;

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

  if (self->priv->rendered_pixbuf)
    return;

  if (self->priv->force_scale_pixbuf &&
      (self->priv->pixel_size != -1 ||
       self->priv->icon_size != GTK_ICON_SIZE_INVALID))
    {
      ensure_icon_size (self, context, &width, &height);

      if (self->priv->orig_pixbuf_scale > 1 ||
	  /* These should divide the orig_pixbuf size by scale, but need not 
	     due to the above scale > 1 check */
	  width < gdk_pixbuf_get_width (self->priv->orig_pixbuf) ||
          height < gdk_pixbuf_get_height (self->priv->orig_pixbuf))
	{
	  width = MIN (width, gdk_pixbuf_get_width (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale);
	  height = MIN (height, gdk_pixbuf_get_height (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale);
	  self->priv->rendered_pixbuf =
	    gdk_pixbuf_scale_simple (self->priv->orig_pixbuf,
				     width, height,
				     GDK_INTERP_BILINEAR);
	}
    }
  else if (self->priv->orig_pixbuf_scale > 1)
    {
	  width = gdk_pixbuf_get_width (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale;
	  height =gdk_pixbuf_get_height (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale;
	  self->priv->rendered_pixbuf =
	    gdk_pixbuf_scale_simple (self->priv->orig_pixbuf,
				     width, height,
				     GDK_INTERP_BILINEAR);
    }

  if (!self->priv->rendered_pixbuf)
    self->priv->rendered_pixbuf = g_object_ref (self->priv->orig_pixbuf);

  stated = ensure_stated_pixbuf_from_pixbuf (self, context, self->priv->rendered_pixbuf);
  g_object_unref (self->priv->rendered_pixbuf);
  self->priv->rendered_pixbuf = stated;
}
Beispiel #8
0
static gboolean
get_pixbuf_size (GtkIconHelper   *self,
                 GtkStyleContext *context,
                 gint *width_out,
                 gint *height_out,
                 gint *scale_out)
{
  gboolean scale_pixmap;
  gint width, height;
  int scale;

  scale = get_scale_factor (self, context);
  scale_pixmap = FALSE;

  if (self->priv->force_scale_pixbuf &&
      (self->priv->pixel_size != -1 ||
       self->priv->icon_size != GTK_ICON_SIZE_INVALID))
    {
      ensure_icon_size (self, context, &width, &height);

      if (scale != self->priv->orig_pixbuf_scale ||
	  width < gdk_pixbuf_get_width (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale ||
          height < gdk_pixbuf_get_height (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale)
	{
	  width = MIN (width * scale, gdk_pixbuf_get_width (self->priv->orig_pixbuf) * scale / self->priv->orig_pixbuf_scale);
	  height = MIN (height * scale, gdk_pixbuf_get_height (self->priv->orig_pixbuf) * scale / self->priv->orig_pixbuf_scale);

          scale_pixmap = TRUE;
	}
      else
	{
	  width = gdk_pixbuf_get_width (self->priv->orig_pixbuf);
	  height = gdk_pixbuf_get_height (self->priv->orig_pixbuf);
	  scale = self->priv->orig_pixbuf_scale;
	}
    }
  else
    {
      width = gdk_pixbuf_get_width (self->priv->orig_pixbuf);
      height = gdk_pixbuf_get_height (self->priv->orig_pixbuf);
      scale = self->priv->orig_pixbuf_scale;
    }

  *width_out = width;
  *height_out = height;
  *scale_out = scale;

  return scale_pixmap;
}
Beispiel #9
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);
}
Beispiel #10
0
void
_gtk_icon_helper_get_size (GtkIconHelper *self,
                           GtkStyleContext *context,
                           gint *width_out,
                           gint *height_out)
{
  cairo_surface_t *surface;
  gint width, height, scale;

  width = height = 0;

  /* Certain kinds of images are easy to calculate the size for, these
     we do immediately to avoid having to potentially load the image
     data for something that may not yet be visible */
  switch (self->priv->storage_type)
    {
    case GTK_IMAGE_SURFACE:
      get_surface_size (self, context, self->priv->orig_surface,
                        &width,
                        &height);
      break;

    case GTK_IMAGE_PIXBUF:
      get_pixbuf_size (self, context, &width, &height, &scale);
      width = (width + scale - 1) / scale;
      height = (height + scale - 1) / scale;
      break;

    case GTK_IMAGE_ICON_NAME:
    case GTK_IMAGE_GICON:
      if (self->priv->pixel_size != -1 || self->priv->force_scale_pixbuf)
        ensure_icon_size (self, context, &width, &height);

      break;

    case GTK_IMAGE_STOCK:
    case GTK_IMAGE_ICON_SET:
    case GTK_IMAGE_ANIMATION:
    case GTK_IMAGE_EMPTY:
    default:
      break;
    }

  /* Otherwise we load the surface to guarantee we get a size */
  if (width == 0)
    {
      surface = _gtk_icon_helper_ensure_surface (self, context);

      if (surface != NULL)
        {
          width = self->priv->rendered_surface_width;
          height = self->priv->rendered_surface_height;
          cairo_surface_destroy (surface);
        }
      else if (self->priv->storage_type == GTK_IMAGE_ANIMATION)
        {
          width = gdk_pixbuf_animation_get_width (self->priv->animation);
          height = gdk_pixbuf_animation_get_height (self->priv->animation);
        }
      else if (self->priv->icon_size != GTK_ICON_SIZE_INVALID)
        {
          ensure_icon_size (self, context, &width, &height);
        }
    }

  if (width_out)
    *width_out = width;
  if (height_out)
    *height_out = height;
}
Beispiel #11
0
void
_gtk_icon_helper_get_size (GtkIconHelper *self,
                           gint *width_out,
                           gint *height_out)
{
  gint width, height, scale;

  width = height = 0;

  /* Certain kinds of images are easy to calculate the size for, these
     we do immediately to avoid having to potentially load the image
     data for something that may not yet be visible */
  switch (gtk_image_definition_get_storage_type (self->priv->def))
    {
    case GTK_IMAGE_SURFACE:
      get_surface_size (self,
                        gtk_image_definition_get_surface (self->priv->def),
                        &width,
                        &height);
      break;

    case GTK_IMAGE_PIXBUF:
      get_pixbuf_size (self,
                       gtk_widget_get_scale_factor (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))),
                       gtk_image_definition_get_pixbuf (self->priv->def),
                       gtk_image_definition_get_scale (self->priv->def),
                       &width, &height, &scale);
      width = (width + scale - 1) / scale;
      height = (height + scale - 1) / scale;
      break;

    case GTK_IMAGE_ANIMATION:
      {
        GdkPixbufAnimation *animation = gtk_image_definition_get_animation (self->priv->def);
        width = gdk_pixbuf_animation_get_width (animation);
        height = gdk_pixbuf_animation_get_height (animation);
        break;
      }

    case GTK_IMAGE_ICON_NAME:
    case GTK_IMAGE_GICON:
      if (self->priv->pixel_size != -1 || self->priv->force_scale_pixbuf)
        ensure_icon_size (self, &width, &height);

      break;

    case GTK_IMAGE_STOCK:
    case GTK_IMAGE_ICON_SET:
    case GTK_IMAGE_EMPTY:
    default:
      break;
    }

  /* Otherwise we load the surface to guarantee we get a size */
  if (width == 0)
    {
      gtk_icon_helper_ensure_surface (self);

      if (self->priv->rendered_surface != NULL)
        {
          get_surface_size (self, self->priv->rendered_surface, &width, &height);
        }
      else if (self->priv->icon_size != GTK_ICON_SIZE_INVALID)
        {
          ensure_icon_size (self, &width, &height);
        }
    }

  if (width_out)
    *width_out = width;
  if (height_out)
    *height_out = height;
}
Beispiel #12
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;
}