2005-10-09 10:53:36 +02:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2005-11-06 17:00:53 +01:00
|
|
|
#include "../config.h"
|
2005-10-09 10:53:36 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <glib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <strings.h>
|
|
|
|
|
2005-11-06 17:24:28 +01:00
|
|
|
#include "gm-debug.h"
|
2005-10-09 10:53:36 +02:00
|
|
|
#include "gm-pixbuf.h"
|
|
|
|
|
|
|
|
static GList *gm_pixbuf_directories = NULL;
|
|
|
|
static GList *gm_pixbufs = NULL;
|
|
|
|
|
|
|
|
GdkPixbuf *gm_pixbuf_create(const gchar * filename, int width, int height);
|
|
|
|
|
|
|
|
void
|
|
|
|
gm_pixbuf_add_directory(const gchar *directory) {
|
|
|
|
gm_pixbuf_directories =
|
|
|
|
g_list_prepend(gm_pixbuf_directories, g_strdup(directory));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gm_pixbuf_init() {
|
|
|
|
gm_pixbuf_add_directory(PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gm_pixbuf_fini() {
|
|
|
|
GList *l;
|
|
|
|
GmPixbufInfo *i;
|
|
|
|
|
|
|
|
for (l = gm_pixbuf_directories; l; l = l->next) {
|
|
|
|
g_free(l->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_list_free(gm_pixbuf_directories);
|
|
|
|
|
|
|
|
for (l = gm_pixbufs; l; l = l->next) {
|
|
|
|
i = (GmPixbufInfo *)(l->data);
|
|
|
|
g_free(i->name);
|
|
|
|
g_object_unref(i->pixbuf);
|
|
|
|
g_free(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_list_free(gm_pixbufs);
|
|
|
|
}
|
|
|
|
|
|
|
|
gchar *
|
|
|
|
gm_pixbuf_find(const gchar *filename) {
|
|
|
|
GList *elem;
|
|
|
|
|
|
|
|
if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
|
|
|
|
return g_strdup(filename);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (elem = gm_pixbuf_directories; elem; elem = elem->next) {
|
|
|
|
gchar *pathname =
|
|
|
|
g_strdup_printf("%s%s%s", (gchar *) elem->data,
|
|
|
|
G_DIR_SEPARATOR_S, filename);
|
|
|
|
|
|
|
|
if (g_file_test(pathname, G_FILE_TEST_EXISTS)) {
|
|
|
|
return pathname;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(pathname);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
GdkPixbuf *
|
|
|
|
gm_pixbuf_create(const gchar * filename, int width, int height) {
|
|
|
|
gchar *pathname = NULL, *ext;
|
|
|
|
GdkPixbuf *pixbuf = NULL;
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
if (!filename || strlen(filename) == 0) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pathname = gm_pixbuf_find(filename);
|
|
|
|
|
|
|
|
if (!pathname) {
|
|
|
|
debug_msg(1, "gm_pixbuf_create: couldn't find pixbuf file: %s", filename);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ext = rindex(pathname, '.');
|
|
|
|
|
|
|
|
if (width < 1 || height < 1) {
|
|
|
|
pixbuf = gdk_pixbuf_new_from_file(pathname, &error);
|
|
|
|
} else {
|
|
|
|
pixbuf = gdk_pixbuf_new_from_file_at_size(pathname, width, height, &error);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pixbuf) {
|
|
|
|
debug_msg(1, "gm_pixbuf_create: failed to load pixbuf from file: %s: %s\n",
|
|
|
|
pathname, error->message);
|
|
|
|
g_error_free(error);
|
|
|
|
error = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(pathname);
|
|
|
|
return pixbuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
GdkPixbuf *
|
|
|
|
gm_pixbuf_get_at_size(const gchar *filename, int width, int height) {
|
|
|
|
GdkPixbuf *pix;
|
|
|
|
GList *elem;
|
|
|
|
GmPixbufInfo *i;
|
|
|
|
|
|
|
|
for (elem = gm_pixbufs; elem; elem = elem->next) {
|
|
|
|
i = (GmPixbufInfo *) (elem->data);
|
|
|
|
|
|
|
|
if (strcmp(i->name, filename) == 0 &&
|
|
|
|
i->width == width && i->height == height) {
|
|
|
|
return i->pixbuf;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Not found, so create it
|
|
|
|
pix = gm_pixbuf_create(filename, width, height);
|
|
|
|
|
|
|
|
if (pix) {
|
|
|
|
i = g_new(GmPixbufInfo, 1);
|
|
|
|
i->name = g_strdup(filename);
|
|
|
|
i->width = width;
|
|
|
|
i->height = height;
|
|
|
|
i->pixbuf = pix;
|
|
|
|
gm_pixbufs = g_list_append(gm_pixbufs, i);
|
|
|
|
return pix;
|
|
|
|
} else {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns pixbuf if it is already loaded in pixmaps
|
|
|
|
GdkPixbuf *
|
|
|
|
gm_pixbuf_get(const gchar *filename) {
|
|
|
|
return gm_pixbuf_get_at_size(filename, -1, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void gm_pixbuf_set_alpha(GdkPixbuf **pixs, guchar alpha) {
|
|
|
|
int width, height, n_channels, rowstride, y, x;
|
|
|
|
GdkPixbuf *pix;
|
|
|
|
guchar *pixels, *p;
|
|
|
|
|
|
|
|
if (!gdk_pixbuf_get_has_alpha(*pixs)) {
|
|
|
|
pix = gdk_pixbuf_add_alpha(*pixs, FALSE, 0, 0, 0);
|
|
|
|
gdk_pixbuf_unref(*pixs);
|
|
|
|
} else {
|
|
|
|
pix = *pixs;
|
|
|
|
}
|
|
|
|
|
|
|
|
n_channels = gdk_pixbuf_get_n_channels(pix);
|
|
|
|
|
|
|
|
if (gdk_pixbuf_get_colorspace(pix) != GDK_COLORSPACE_RGB ||
|
|
|
|
gdk_pixbuf_get_bits_per_sample(pix) != 8 ||
|
|
|
|
!gdk_pixbuf_get_has_alpha(pix) ||
|
|
|
|
n_channels != 4) {
|
|
|
|
*pixs = pix;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
width = gdk_pixbuf_get_width(pix);
|
|
|
|
height = gdk_pixbuf_get_height(pix);
|
|
|
|
rowstride = gdk_pixbuf_get_rowstride(pix);
|
|
|
|
pixels = gdk_pixbuf_get_pixels(pix);
|
|
|
|
p = pixels;
|
|
|
|
|
|
|
|
for (y = 0; y < height; y++) {
|
|
|
|
for (x = 0; x < width; x++) {
|
|
|
|
p[3] = alpha;
|
|
|
|
p = p + n_channels;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*pixs = pix;
|
|
|
|
}
|