#ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "debug.h" #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; }