[gnome-shell] st-texture-cache: Fix stretched images



commit 4208078750e56c34da451a2a0bfe66de7a6fab63
Author: Florian Müllner <fmuellner gnome org>
Date:   Tue Mar 22 04:47:43 2011 +0100

    st-texture-cache: Fix stretched images
    
    Some functions in StTextureCache enforce square ClutterTextures,
    even in cases where the underlying CoglTexture has a different
    width:height ratio.
    Add padding in those cases to keep the resulting image from being
    stretched.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=643866

 src/st/st-texture-cache.c |   62 +++++++++++++++++++++++++++++++++++---------
 1 files changed, 49 insertions(+), 13 deletions(-)
---
diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c
index a87f495..182851b 100644
--- a/src/st/st-texture-cache.c
+++ b/src/st/st-texture-cache.c
@@ -777,6 +777,7 @@ typedef struct {
   char *key;
   char *uri;
   gboolean thumbnail;
+  gboolean enforced_square;
   char *mimetype;
   GtkRecentInfo *recent_info;
   char *checksum;
@@ -788,15 +789,47 @@ typedef struct {
 } AsyncTextureLoadData;
 
 static CoglHandle
-pixbuf_to_cogl_handle (GdkPixbuf *pixbuf)
-{
-  return cogl_texture_new_from_data (gdk_pixbuf_get_width (pixbuf),
-                                     gdk_pixbuf_get_height (pixbuf),
-                                     COGL_TEXTURE_NONE,
-                                     gdk_pixbuf_get_has_alpha (pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
-                                     COGL_PIXEL_FORMAT_ANY,
-                                     gdk_pixbuf_get_rowstride (pixbuf),
-                                     gdk_pixbuf_get_pixels (pixbuf));
+pixbuf_to_cogl_handle (GdkPixbuf *pixbuf,
+                       gboolean   add_padding)
+{
+  CoglHandle texture, offscreen;
+  CoglColor clear_color;
+  int width, height;
+  guint size;
+
+  width = gdk_pixbuf_get_width (pixbuf);
+  height = gdk_pixbuf_get_height (pixbuf);
+  size = MAX (width, height);
+
+  if (!add_padding || width == height)
+    return cogl_texture_new_from_data (width,
+                                       height,
+                                       COGL_TEXTURE_NONE,
+                                       gdk_pixbuf_get_has_alpha (pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
+                                       COGL_PIXEL_FORMAT_ANY,
+                                       gdk_pixbuf_get_rowstride (pixbuf),
+                                       gdk_pixbuf_get_pixels (pixbuf));
+
+  texture = cogl_texture_new_with_size (size, size,
+                                        COGL_TEXTURE_NO_SLICING,
+                                        COGL_PIXEL_FORMAT_ANY);
+
+  offscreen = cogl_offscreen_new_to_texture (texture);
+  cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
+  cogl_push_framebuffer (offscreen);
+  cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
+  cogl_pop_framebuffer ();
+  cogl_handle_unref (offscreen);
+
+  cogl_texture_set_region (texture,
+                           0, 0,
+                           (size - width) / 2, (size - height) / 2,
+                           width, height,
+                           width, height,
+                           gdk_pixbuf_get_has_alpha (pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
+                           gdk_pixbuf_get_rowstride (pixbuf),
+                           gdk_pixbuf_get_pixels (pixbuf));
+  return texture;
 }
 
 static cairo_surface_t *
@@ -882,7 +915,7 @@ on_pixbuf_loaded (GObject      *source,
   if (pixbuf == NULL)
     goto out;
 
-  texdata = pixbuf_to_cogl_handle (pixbuf);
+  texdata = pixbuf_to_cogl_handle (pixbuf, data->enforced_square);
 
   g_object_unref (pixbuf);
 
@@ -956,7 +989,7 @@ st_texture_cache_reset_texture (StTextureCachePropertyBind *bind,
 
   if (pixbuf != NULL)
     {
-      texdata = pixbuf_to_cogl_handle (pixbuf);
+      texdata = pixbuf_to_cogl_handle (pixbuf, FALSE);
       g_object_unref (pixbuf);
 
       clutter_texture_set_cogl_texture (bind->texture, texdata);
@@ -1183,6 +1216,7 @@ load_gicon_with_colors (StTextureCache    *cache,
       request->icon = g_object_ref (icon);
       request->icon_info = info;
       request->width = request->height = size;
+      request->enforced_square = TRUE;
 
       load_icon_pixbuf_async (cache, icon, info, size, colors, NULL, on_pixbuf_loaded, request);
     }
@@ -1247,7 +1281,7 @@ load_from_pixbuf (GdkPixbuf *pixbuf)
 
   clutter_actor_set_size (CLUTTER_ACTOR (texture), width, height);
 
-  texdata = pixbuf_to_cogl_handle (pixbuf);
+  texdata = pixbuf_to_cogl_handle (pixbuf, FALSE);
 
   set_texture_cogl_texture (texture, texdata);
 
@@ -1574,7 +1608,7 @@ st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache,
       if (!pixbuf)
         goto out;
 
-      texdata = pixbuf_to_cogl_handle (pixbuf);
+      texdata = pixbuf_to_cogl_handle (pixbuf, FALSE);
       g_object_unref (pixbuf);
 
       if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
@@ -1825,7 +1859,7 @@ st_texture_cache_load_from_data (StTextureCache    *cache,
           return NULL;
         }
 
-      texdata = pixbuf_to_cogl_handle (pixbuf);
+      texdata = pixbuf_to_cogl_handle (pixbuf, TRUE);
       g_object_unref (pixbuf);
 
       set_texture_cogl_texture (texture, texdata);
@@ -1949,6 +1983,7 @@ st_texture_cache_load_thumbnail (StTextureCache    *cache,
       data->thumbnail = TRUE;
       data->width = size;
       data->height = size;
+      data->enforced_square = TRUE;
       data->textures = g_slist_prepend (data->textures, g_object_ref (texture));
       load_thumbnail_async (cache, uri, mimetype, size, NULL, on_pixbuf_loaded, data);
     }
@@ -2025,6 +2060,7 @@ st_texture_cache_load_recent_thumbnail (StTextureCache    *cache,
       data->recent_info = gtk_recent_info_ref (info);
       data->width = size;
       data->height = size;
+      data->enforced_square = TRUE;
       data->textures = g_slist_prepend (data->textures, g_object_ref (texture));
       load_recent_thumbnail_async (cache, info, size, NULL, on_pixbuf_loaded, data);
     }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]