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
This commit is contained in:
parent
dba02f8f08
commit
4208078750
@ -777,6 +777,7 @@ typedef struct {
|
|||||||
char *key;
|
char *key;
|
||||||
char *uri;
|
char *uri;
|
||||||
gboolean thumbnail;
|
gboolean thumbnail;
|
||||||
|
gboolean enforced_square;
|
||||||
char *mimetype;
|
char *mimetype;
|
||||||
GtkRecentInfo *recent_info;
|
GtkRecentInfo *recent_info;
|
||||||
char *checksum;
|
char *checksum;
|
||||||
@ -788,15 +789,47 @@ typedef struct {
|
|||||||
} AsyncTextureLoadData;
|
} AsyncTextureLoadData;
|
||||||
|
|
||||||
static CoglHandle
|
static CoglHandle
|
||||||
pixbuf_to_cogl_handle (GdkPixbuf *pixbuf)
|
pixbuf_to_cogl_handle (GdkPixbuf *pixbuf,
|
||||||
|
gboolean add_padding)
|
||||||
{
|
{
|
||||||
return cogl_texture_new_from_data (gdk_pixbuf_get_width (pixbuf),
|
CoglHandle texture, offscreen;
|
||||||
gdk_pixbuf_get_height (pixbuf),
|
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,
|
COGL_TEXTURE_NONE,
|
||||||
gdk_pixbuf_get_has_alpha (pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
|
gdk_pixbuf_get_has_alpha (pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
|
||||||
COGL_PIXEL_FORMAT_ANY,
|
COGL_PIXEL_FORMAT_ANY,
|
||||||
gdk_pixbuf_get_rowstride (pixbuf),
|
gdk_pixbuf_get_rowstride (pixbuf),
|
||||||
gdk_pixbuf_get_pixels (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 *
|
static cairo_surface_t *
|
||||||
@ -882,7 +915,7 @@ on_pixbuf_loaded (GObject *source,
|
|||||||
if (pixbuf == NULL)
|
if (pixbuf == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
texdata = pixbuf_to_cogl_handle (pixbuf);
|
texdata = pixbuf_to_cogl_handle (pixbuf, data->enforced_square);
|
||||||
|
|
||||||
g_object_unref (pixbuf);
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
@ -956,7 +989,7 @@ st_texture_cache_reset_texture (StTextureCachePropertyBind *bind,
|
|||||||
|
|
||||||
if (pixbuf != NULL)
|
if (pixbuf != NULL)
|
||||||
{
|
{
|
||||||
texdata = pixbuf_to_cogl_handle (pixbuf);
|
texdata = pixbuf_to_cogl_handle (pixbuf, FALSE);
|
||||||
g_object_unref (pixbuf);
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
clutter_texture_set_cogl_texture (bind->texture, texdata);
|
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 = g_object_ref (icon);
|
||||||
request->icon_info = info;
|
request->icon_info = info;
|
||||||
request->width = request->height = size;
|
request->width = request->height = size;
|
||||||
|
request->enforced_square = TRUE;
|
||||||
|
|
||||||
load_icon_pixbuf_async (cache, icon, info, size, colors, NULL, on_pixbuf_loaded, request);
|
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);
|
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);
|
set_texture_cogl_texture (texture, texdata);
|
||||||
|
|
||||||
@ -1574,7 +1608,7 @@ st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache,
|
|||||||
if (!pixbuf)
|
if (!pixbuf)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
texdata = pixbuf_to_cogl_handle (pixbuf);
|
texdata = pixbuf_to_cogl_handle (pixbuf, FALSE);
|
||||||
g_object_unref (pixbuf);
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
|
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
|
||||||
@ -1825,7 +1859,7 @@ st_texture_cache_load_from_data (StTextureCache *cache,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
texdata = pixbuf_to_cogl_handle (pixbuf);
|
texdata = pixbuf_to_cogl_handle (pixbuf, TRUE);
|
||||||
g_object_unref (pixbuf);
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
set_texture_cogl_texture (texture, texdata);
|
set_texture_cogl_texture (texture, texdata);
|
||||||
@ -1949,6 +1983,7 @@ st_texture_cache_load_thumbnail (StTextureCache *cache,
|
|||||||
data->thumbnail = TRUE;
|
data->thumbnail = TRUE;
|
||||||
data->width = size;
|
data->width = size;
|
||||||
data->height = size;
|
data->height = size;
|
||||||
|
data->enforced_square = TRUE;
|
||||||
data->textures = g_slist_prepend (data->textures, g_object_ref (texture));
|
data->textures = g_slist_prepend (data->textures, g_object_ref (texture));
|
||||||
load_thumbnail_async (cache, uri, mimetype, size, NULL, on_pixbuf_loaded, data);
|
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->recent_info = gtk_recent_info_ref (info);
|
||||||
data->width = size;
|
data->width = size;
|
||||||
data->height = size;
|
data->height = size;
|
||||||
|
data->enforced_square = TRUE;
|
||||||
data->textures = g_slist_prepend (data->textures, g_object_ref (texture));
|
data->textures = g_slist_prepend (data->textures, g_object_ref (texture));
|
||||||
load_recent_thumbnail_async (cache, info, size, NULL, on_pixbuf_loaded, data);
|
load_recent_thumbnail_async (cache, info, size, NULL, on_pixbuf_loaded, data);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user