X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=libchimara%2Fgraphics.c;h=1ab5a359b68ba304bf3d0a1c5ec90d357bc13ff0;hb=cdb84c7c776f214f41ba1a509efb2494e7ed1baf;hp=7f59915dafb3402ea94b1e7b32a408e0b705151c;hpb=4884a6e823e53b0d0e61ae122cd1083ea10aebea;p=projects%2Fchimara%2Fchimara.git diff --git a/libchimara/graphics.c b/libchimara/graphics.c index 7f59915..1ab5a35 100644 --- a/libchimara/graphics.c +++ b/libchimara/graphics.c @@ -13,25 +13,12 @@ static gboolean image_loaded; static gboolean size_determined; static struct image_info* -load_image_in_cache(glui32 image, gint width, gint height) +load_image_from_blorb(giblorb_result_t resource, glui32 image, gint width, gint height) { ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key); - giblorb_err_t blorb_error = 0; - giblorb_result_t resource; GError *pixbuf_error = NULL; guchar *buffer; - /* Lookup the proper resource */ - if(!glk_data->resource_map) { - WARNING("No resource map has been loaded yet."); - return NULL; - } - blorb_error = giblorb_load_resource(glk_data->resource_map, giblorb_method_FilePos, &resource, giblorb_ID_Pict, image); - if(blorb_error != giblorb_err_None) { - WARNING_S( "Error loading resource", giblorb_get_error_message(blorb_error) ); - return NULL; - } - struct image_info *info = g_new0(struct image_info, 1); info->resource_number = image; @@ -75,24 +62,84 @@ load_image_in_cache(glui32 image, gint width, gint height) } g_mutex_unlock(glk_data->resource_lock); + info->pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); + g_object_ref(info->pixbuf); + + g_object_unref(loader); + return info; +} + +static struct image_info * +load_image_from_file(const gchar *filename, glui32 image, gint width, gint height) +{ + GError *err = NULL; + + struct image_info *info = g_new0(struct image_info, 1); + info->resource_number = image; + + if(width > 0 && height > 0) { + info->scaled = TRUE; + info->pixbuf = gdk_pixbuf_new_from_file_at_size(filename, width, height, &err); + } else { + info->pixbuf = gdk_pixbuf_new_from_file(filename, &err); + } + if(!info->pixbuf) { + IO_WARNING("Error loading resource from alternative location", filename, err->message); + g_error_free(err); + g_free(info); + return NULL; + } + g_object_ref(info->pixbuf); + + return info; +} + +static struct image_info* +load_image_in_cache(glui32 image, gint width, gint height) +{ + ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key); + struct image_info *info = NULL; + + /* Lookup the proper resource */ + if(!glk_data->resource_map) { + if(!glk_data->resource_load_callback) { + WARNING("No resource map has been loaded yet."); + return NULL; + } + gchar *filename = glk_data->resource_load_callback(CHIMARA_RESOURCE_IMAGE, image, glk_data->resource_load_callback_data); + if(!filename) { + WARNING("Error loading resource from alternative location"); + return NULL; + } + info = load_image_from_file(filename, image, width, height); + g_free(filename); + } else { + giblorb_result_t resource; + giblorb_err_t blorb_error = giblorb_load_resource(glk_data->resource_map, giblorb_method_FilePos, &resource, giblorb_ID_Pict, image); + if(blorb_error != giblorb_err_None) { + WARNING_S( "Error loading resource", giblorb_get_error_message(blorb_error) ); + return NULL; + } + info = load_image_from_blorb(resource, image, width, height); + } + + if(info == NULL) + return NULL; + /* Store the image in the cache */ gdk_threads_enter(); if( g_slist_length(glk_data->image_cache) >= IMAGE_CACHE_MAX_NUM ) { struct image_info *head = (struct image_info*) glk_data->image_cache->data; - gdk_pixbuf_unref(head->pixbuf); + g_object_unref(head->pixbuf); g_free(head); glk_data->image_cache = g_slist_remove_link(glk_data->image_cache, glk_data->image_cache); } - info->pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); - gdk_pixbuf_ref(info->pixbuf); info->width = gdk_pixbuf_get_width(info->pixbuf); info->height = gdk_pixbuf_get_height(info->pixbuf); glk_data->image_cache = g_slist_prepend(glk_data->image_cache, info); gdk_threads_leave(); - - g_object_unref(loader); return info; } @@ -128,7 +175,7 @@ on_pixbuf_closed(GdkPixbufLoader *loader, gpointer data) void clear_image_cache(struct image_info *data, gpointer user_data) { - gdk_pixbuf_unref(data->pixbuf); + g_object_unref(data->pixbuf); g_free(data); } @@ -185,11 +232,11 @@ image_cache_find(struct image_info* to_find) * @height: Pointer to a location at which to store the image's height. * * This gets information about the image resource with the given identifier. It - * returns %TRUE if there is such an image, and %FALSE if not. You can also pass - * pointers to width and height variables; if the image exists, the variables - * will be filled in with the width and height of the image, in pixels. (You can - * pass %NULL for either width or height if you don't care about that - * information.) + * returns %TRUE (1) if there is such an image, and %FALSE (0) if not. You can + * also pass pointers to width and height variables; if the image exists, the + * variables will be filled in with the width and height of the image, in + * pixels. (You can pass %NULL for either width or height if you don't care + * about that information.) * * * You should always use this function to measure the size of images when you @@ -220,7 +267,7 @@ glk_image_get_info(glui32 image, glui32 *width, glui32 *height) if(width != NULL) *width = found->width; - if(width != NULL) + if(height != NULL) *height = found->height; return TRUE; } @@ -343,12 +390,13 @@ glk_image_draw_scaled(winid_t win, glui32 image, glsi32 val1, glsi32 val2, glui3 glui32 draw_image_common(winid_t win, GdkPixbuf *pixbuf, glsi32 val1, glsi32 val2) { - GdkPixmap *canvas; - gdk_threads_enter(); - switch(win->type) { case wintype_Graphics: { + GdkPixmap *canvas; + + gdk_threads_enter(); + gtk_image_get_pixmap( GTK_IMAGE(win->widget), &canvas, NULL ); if(canvas == NULL) { WARNING("Could not get pixmap"); @@ -359,18 +407,23 @@ draw_image_common(winid_t win, GdkPixbuf *pixbuf, glsi32 val1, glsi32 val2) /* Update the screen */ gtk_widget_queue_draw(win->widget); + + gdk_threads_leave(); } break; case wintype_TextBuffer: { + flush_window_buffer(win); + + gdk_threads_enter(); + GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) ); GtkTextIter end, start; gtk_text_buffer_get_end_iter(buffer, &end); - start = end; - flush_window_buffer(win); gtk_text_buffer_insert_pixbuf(buffer, &end, pixbuf); + start = end; gtk_text_iter_forward_char(&end); gint height = 0; @@ -390,12 +443,11 @@ draw_image_common(winid_t win, GdkPixbuf *pixbuf, glsi32 val1, glsi32 val2) GtkTextTag *tag = gtk_text_buffer_create_tag(buffer, NULL, "rise", PANGO_SCALE * (-height), NULL); gtk_text_buffer_apply_tag(buffer, tag, &start, &end); } + + gdk_threads_leave(); } break; - } - - gdk_threads_leave(); return TRUE; }