gnome-control-center/capplets/background/gnome-wp-utils.c
Rodney Dawes 00006d7745 Regenerate the thumbnail in the list when we change scaling type now
2004-04-05  Rodney Dawes  <dobey@ximian.com>

	* gnome-wp-capplet.c (gnome_wp_scale_type_changed): Regenerate the
	thumbnail in the list when we change scaling type now
	(wallpaper_properties_init): Add GtkFileFilter support (needs love)
	TreeView is buggy, so we need to not set the vertical-separator
	style property for it
	* gnome-wp-item.c: Include <config.h> and <gnome.h> here
	(collect_save_options): Add a function to set all of the pixbuf options
	for the thumbnail pixbuf properly, so we can save them back out
	(gnome_wp_item_get_thumbnail): Fix up the code to
	generate the thumbnails for the list a bit, so that we have sexy
	thumbnails that look exactly like how the image would, on-screen
	Initialize all of the width/height variables to 0
	Add a new pixbuf variable for loading the original image to get the
	dimensions of it, so we can do thumbnailing more properly
	Use a LIST_IMAGE_WIDTH define, for the width of the images in the list
	Just return the bgpixbuf if we are creating the "No Wallpaper" thumb
	Save the thumbnail back out with the dimensions for the original image
	If our image is smaller than the list thumbnail, then just use 1.0 as
	the ratio for scaling the image for tiling/etc...
	Use the new API to do scaling inside the center/tile functions
	Reload the thumbnail pixbuf after generating it with the thumbnail
	system, so that we get all of the pixbuf options set correctly
	* gnome-wp-item.h (GnomeWPItem): store the original image's width
	and height in the item, so we can avoid reopening the original image
	every time we generate the thumbnail, on systems where the thumbnail
	doesn't contain the appropriate information
	* gnome-wp-utils.c (gnome_wp_pixbuf_tile):
	(gnome_wp_pixbuf_center): Add API to do the scaling inside these calls

	Fixes #136691
2004-04-05 21:32:02 +00:00

198 lines
4.9 KiB
C

/*
* Authors: Rodney Dawes <dobey@ximian.com>
*
* Copyright 2003 Novell, Inc. (www.novell.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
*
*/
#include "gnome-wp-utils.h"
#include <string.h>
GdkPixbuf * gnome_wp_pixbuf_new_gradient (GtkOrientation orientation,
GdkColor * c1,
GdkColor * c2,
gint width, gint height) {
GdkPixbuf * pixbuf;
gint i, j;
gint dr, dg, db;
gint gs1;
gint vc = ((orientation == GTK_ORIENTATION_HORIZONTAL) || (c1 == c2));
guchar * b, * row, * d;
int rowstride;
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
d = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
dr = c2->red - c1->red;
dg = c2->green - c1->green;
db = c2->blue - c1->blue;
gs1 = (orientation == GTK_ORIENTATION_VERTICAL) ? height - 1 : width - 1;
row = g_new (unsigned char, rowstride);
if (vc) {
b = row;
for (j = 0; j < width; j++) {
*b++ = (c1->red + (j * dr) / gs1) >> 8;
*b++ = (c1->green + (j * dg) / gs1) >> 8;
*b++ = (c1->blue + (j * db) / gs1) >> 8;
}
}
for (i = 0; i < height; i++) {
if (!vc) {
unsigned char cr, cg, cb;
cr = (c1->red + (i * dr) / gs1) >> 8;
cg = (c1->green + (i * dg) / gs1) >> 8;
cb = (c1->blue + (i * db) / gs1) >> 8;
b = row;
for (j = 0; j < width; j++) {
*b++ = cr;
*b++ = cg;
*b++ = cb;
}
}
memcpy (d, row, width * 3);
d += rowstride;
}
g_free (row);
return pixbuf;
}
GdkPixbuf * gnome_wp_pixbuf_new_solid (GdkColor * color,
gint width, gint height) {
GdkPixbuf * pixbuf;
gint j, rowstride;
guchar * b, * d, * row;
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
d = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
row = g_new (unsigned char, rowstride);
b = row;
for (j = 0; j < width; j++) {
*b++ = color->red >> 8;
*b++ = color->green >> 8;
*b++ = color->blue >> 8;
}
for (j = 0; j < height; j++) {
memcpy (d, row, width * 3);
d += rowstride;
}
g_free (row);
return pixbuf;
}
GdkPixbuf * gnome_wp_pixbuf_tile (GdkPixbuf * src_pixbuf,
GdkPixbuf * dest_pixbuf,
gint scaled_width,
gint scaled_height) {
GdkPixbuf * tmpbuf;
gdouble cx, cy;
gint dwidth, dheight;
gint swidth, sheight;
guint alpha = 255;
if (dest_pixbuf == NULL) {
return gdk_pixbuf_copy (src_pixbuf);
}
tmpbuf = gdk_pixbuf_scale_simple (src_pixbuf, scaled_width, scaled_height,
GDK_INTERP_BILINEAR);
swidth = gdk_pixbuf_get_width (tmpbuf);
sheight = gdk_pixbuf_get_height (tmpbuf);
dwidth = gdk_pixbuf_get_width (dest_pixbuf);
dheight = gdk_pixbuf_get_height (dest_pixbuf);
for (cy = 0; cy < dheight; cy += sheight) {
for (cx = 0; cx < dwidth; cx += swidth) {
gdk_pixbuf_composite (tmpbuf, dest_pixbuf, cx, cy,
MIN (swidth, dwidth - cx),
MIN (sheight, dheight - cy),
cx, cy, 1.0, 1.0,
GDK_INTERP_BILINEAR, alpha);
}
}
g_object_unref (tmpbuf);
return gdk_pixbuf_copy (dest_pixbuf);
}
GdkPixbuf * gnome_wp_pixbuf_center (GdkPixbuf * src_pixbuf,
GdkPixbuf * dest_pixbuf,
gint scaled_width,
gint scaled_height) {
GdkPixbuf * tmpbuf;
gint ox, oy, cx, cy;
gint dwidth, dheight;
gint swidth, sheight;
gint cwidth, cheight;
guint alpha = 255;
if (dest_pixbuf == NULL) {
return gdk_pixbuf_copy (src_pixbuf);
}
ox = cx = oy = cy = 0;
tmpbuf = gdk_pixbuf_scale_simple (src_pixbuf, scaled_width, scaled_height,
GDK_INTERP_BILINEAR);
swidth = gdk_pixbuf_get_width (tmpbuf);
sheight = gdk_pixbuf_get_height (tmpbuf);
dwidth = gdk_pixbuf_get_width (dest_pixbuf);
dheight = gdk_pixbuf_get_height (dest_pixbuf);
if (dwidth > swidth) {
ox = (dwidth - swidth) / 2;
cx = 0;
cwidth = swidth;
} else {
cx = (swidth - dwidth) / 2;
oy = 0;
cwidth = dwidth;
}
if (dheight > sheight) {
oy = ((dheight - sheight) / 2);
cy = 0;
cheight = sheight;
} else {
cy = (sheight - dheight) / 2;
oy = 0;
cheight = dheight;
}
gdk_pixbuf_composite (tmpbuf, dest_pixbuf, ox, oy,
cwidth, cheight,
ox - cx, oy - cy, 1.0, 1.0,
GDK_INTERP_BILINEAR, alpha);
g_object_unref (tmpbuf);
return gdk_pixbuf_copy (dest_pixbuf);
}