[Freeciv-Dev] (PR#11507) use pixbufs for gtk2 sprites
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=11507 >
Seems crop_sprite completely didn't work with a mask, meaning isotrident
basically didn't work at all. Dunno how I missed that, I guess I only
tested it in trident.
Anyway, here is a new patch with a new-and-cool implementation of
crop_sprite. The new implementation allows alpha levels in the cropping
mask as well. This means alpha levels can be used for the blending mask.
At some point we should introduce a cleanup_sprite() function. This
function should remove and unreference the pixbuf if there is a pixmap
present (i.e., if there's no alpha). sprite_get_pixbuf is used for
small sprites which is fine, but it's also used inside crop_sprite which
means we end up with duplicate copies for each base tileset sprite.
-jason
Index: client/gui-gtk-2.0/dialogs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/dialogs.c,v
retrieving revision 1.88
diff -u -r1.88 dialogs.c
--- client/gui-gtk-2.0/dialogs.c 22 Jan 2005 19:45:40 -0000 1.88
+++ client/gui-gtk-2.0/dialogs.c 1 Feb 2005 00:59:15 -0000
@@ -1652,10 +1652,9 @@
gtk_list_store_append(store, &it);
s = crop_blankspace(nation->flag_sprite);
- img = gdk_pixbuf_new_from_sprite(s);
- free_sprite(s);
+ img = sprite_get_pixbuf(s);
gtk_list_store_set(store, &it, 0, i, 1, FALSE, 2, img, -1);
- g_object_unref(img);
+ free_sprite(s);
g_value_init(&value, G_TYPE_STRING);
g_value_set_static_string(&value, nation->name);
Index: client/gui-gtk-2.0/diplodlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/diplodlg.c,v
retrieving revision 1.26
diff -u -r1.26 diplodlg.c
--- client/gui-gtk-2.0/diplodlg.c 22 Jan 2005 20:31:11 -0000 1.26
+++ client/gui-gtk-2.0/diplodlg.c 1 Feb 2005 00:59:15 -0000
@@ -640,12 +640,10 @@
gtk_list_store_set(store, &it, 0, buf, -1);
} clause_list_iterate_end;
- gtk_image_set_from_pixmap(GTK_IMAGE(pdialog->image0),
- get_thumb_pixmap(pdialog->treaty.accept0),
- NULL);
- gtk_image_set_from_pixmap(GTK_IMAGE(pdialog->image1),
- get_thumb_pixmap(pdialog->treaty.accept1),
- NULL);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(pdialog->image0),
+ get_thumb_pixbuf(pdialog->treaty.accept0));
+ gtk_image_set_from_pixbuf(GTK_IMAGE(pdialog->image1),
+ get_thumb_pixbuf(pdialog->treaty.accept1));
}
/****************************************************************
Index: client/gui-gtk-2.0/graphics.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/graphics.c,v
retrieving revision 1.31
diff -u -r1.31 graphics.c
--- client/gui-gtk-2.0/graphics.c 25 Dec 2004 19:50:29 -0000 1.31
+++ client/gui-gtk-2.0/graphics.c 1 Feb 2005 00:59:15 -0000
@@ -49,8 +49,8 @@
#include "patrol_cursor.xbm"
#include "patrol_cursor_mask.xbm"
-SPRITE * intro_gfx_sprite;
-SPRITE * radar_gfx_sprite;
+SPRITE * intro_gfx_sprite;
+SPRITE * radar_gfx_sprite;
GdkCursor * goto_cursor;
GdkCursor * drop_cursor;
@@ -102,38 +102,65 @@
struct Sprite *mask,
int mask_offset_x, int mask_offset_y)
{
- GdkPixmap *mypixmap, *mymask = NULL;
-
- mypixmap = gdk_pixmap_new(root_window, width, height, -1);
-
- gdk_draw_drawable(mypixmap, civ_gc, source->pixmap, x, y, 0, 0,
- width, height);
-
- if (source->mask) {
- mymask = gdk_pixmap_new(NULL, width, height, 1);
- gdk_draw_rectangle(mymask, mask_bg_gc, TRUE, 0, 0, -1, -1);
-
- gdk_draw_drawable(mymask, mask_fg_gc, source->mask,
- x, y, 0, 0, width, height);
- }
+ GdkPixbuf *mypixbuf, *sub, *mask_pixbuf;
+ /* First just crop the image. */
+ if (x < 0) {
+ width += x;
+ x = 0;
+ }
+ if (y < 0) {
+ height += y;
+ y = 0;
+ }
+ width = CLIP(0, width, source->width - x);
+ height = CLIP(0, height, source->height - y);
+ sub = gdk_pixbuf_new_subpixbuf(sprite_get_pixbuf(source), x, y,
+ width, height);
+ mypixbuf = gdk_pixbuf_copy(sub);
+ g_object_unref(sub);
+
+ /* Now mask. This reduces the alpha of the final image proportional to the
+ * alpha of the mask. Thus if the mask has 50% alpha the final image will
+ * be reduced by 50% alpha. Note that the mask offset is in coordinates
+ * relative to the clipped image not the final image. */
if (mask) {
- if (mymask) {
- gdk_gc_set_function(mask_fg_gc, GDK_AND);
- gdk_draw_drawable(mymask, mask_fg_gc, mask->mask,
- x - mask_offset_x, y - mask_offset_y,
- 0, 0, width, height);
- gdk_gc_set_function(mask_fg_gc, GDK_OR);
- } else {
- mymask = gdk_pixmap_new(NULL, width, height, 1);
- gdk_draw_rectangle(mymask, mask_bg_gc, TRUE, 0, 0, -1, -1);
+ int x1, y1;
- gdk_draw_drawable(mymask, mask_fg_gc, source->mask,
- x, y, 0, 0, width, height);
+ /* The mask offset is the offset into the mask relative to the origin
+ * of the original source image. For instance when cropping with
+ * blending sprites the offset is always 0. Here we convert the
+ * coordinates so that they are relative to the origin of the new
+ * (cropped) image. */
+ mask_offset_x += x;
+ mask_offset_y += y;
+
+ width = CLIP(0, width, mask->width - mask_offset_x);
+ height = CLIP(0, height, mask->height - mask_offset_y);
+
+ mask_pixbuf = sprite_get_pixbuf(mask);
+
+ gdk_pixbuf_add_alpha(mypixbuf, FALSE, 0, 0, 0);
+ gdk_pixbuf_add_alpha(mask_pixbuf, FALSE, 0, 0, 0);
+
+ for (x1 = 0; x1 < width; x1++) {
+ for (y1 = 0; y1 < height; y1++) {
+ int mask_x = x1 + mask_offset_x, mask_y = y1 + mask_offset_y;
+ guchar *alpha = gdk_pixbuf_get_pixels(mypixbuf)
+ + y1 * gdk_pixbuf_get_rowstride(mypixbuf)
+ + x1 * gdk_pixbuf_get_n_channels(mypixbuf)
+ + 3;
+ guchar *mask_alpha = gdk_pixbuf_get_pixels(mask_pixbuf)
+ + mask_y * gdk_pixbuf_get_rowstride(mask_pixbuf)
+ + mask_x * gdk_pixbuf_get_n_channels(mask_pixbuf)
+ + 3;
+
+ *alpha = (*alpha) * (*mask_alpha) / 255;
+ }
}
}
- return ctor_sprite_mask(mypixmap, mymask, width, height);
+ return ctor_sprite(mypixbuf);
}
/****************************************************************************
@@ -213,21 +240,51 @@
Create a new sprite with the given pixmap, dimensions, and
(optional) mask.
***************************************************************************/
-SPRITE *ctor_sprite_mask( GdkPixmap *mypixmap, GdkPixmap *mask,
- int width, int height )
+SPRITE *ctor_sprite(GdkPixbuf *pixbuf)
{
- SPRITE *mysprite = fc_malloc(sizeof(SPRITE));
+ struct Sprite *sprite = fc_malloc(sizeof(*sprite));
+ bool has_alpha = FALSE, has_mask = FALSE;
- mysprite->pixmap = mypixmap;
- mysprite->fogged = NULL;
- mysprite->mask = mask;
+ sprite->width = gdk_pixbuf_get_width(pixbuf);
+ sprite->height = gdk_pixbuf_get_height(pixbuf);
- mysprite->width = width;
- mysprite->height = height;
+ /* Check to see if this pixbuf has an alpha layer. */
+ if (gdk_pixbuf_get_has_alpha(pixbuf)) {
+ guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);
+ int x, y, rowstride = gdk_pixbuf_get_rowstride(pixbuf);
+
+ for (y = 0; y < sprite->height; y++) {
+ for (x = 0; x < sprite->width; x++) {
+ int i = y * rowstride + 4 * x + 3;
+ guchar pixel = pixels[i];
- mysprite->pixbuf = NULL;
+ if (pixel > 0 && pixel < 255) {
+ has_alpha = TRUE;
+ }
+ if (pixel == 0) {
+ has_mask = TRUE;
+ }
+ }
+ }
+ }
- return mysprite;
+ sprite->pixbuf_fogged = NULL;
+ sprite->pixmap_fogged = NULL;
+ if (has_alpha) {
+ sprite->pixbuf = pixbuf;
+ sprite->pixmap = NULL;
+ sprite->mask = NULL;
+ } else {
+ gdk_pixbuf_render_pixmap_and_mask(pixbuf, &sprite->pixmap,
+ &sprite->mask, 1);
+ if (!has_mask && sprite->mask) {
+ g_object_unref(sprite->mask);
+ sprite->mask = NULL;
+ }
+ g_object_unref(pixbuf);
+ sprite->pixbuf = NULL;
+ }
+ return sprite;
}
@@ -264,28 +321,13 @@
struct Sprite *load_gfxfile(const char *filename)
{
GdkPixbuf *im;
- SPRITE *mysprite;
- int w, h;
if (!(im = gdk_pixbuf_new_from_file(filename, NULL))) {
freelog(LOG_FATAL, "Failed reading graphics file: %s", filename);
exit(EXIT_FAILURE);
}
- mysprite=fc_malloc(sizeof(struct Sprite));
-
- w = gdk_pixbuf_get_width(im); h = gdk_pixbuf_get_height(im);
- gdk_pixbuf_render_pixmap_and_mask(im, &mysprite->pixmap, &mysprite->mask, 1);
-
- mysprite->width = w;
- mysprite->height = h;
-
- mysprite->pixbuf = NULL;
- mysprite->fogged = NULL;
-
- g_object_unref(im);
-
- return mysprite;
+ return ctor_sprite(im);
}
/***************************************************************************
@@ -303,9 +345,13 @@
}
if (s->pixbuf) {
g_object_unref(s->pixbuf);
+ s->pixbuf = NULL;
}
- if (s->fogged) {
- g_object_unref(s->fogged);
+ if (s->pixmap_fogged) {
+ g_object_unref(s->pixmap_fogged);
+ }
+ if (s->pixbuf_fogged) {
+ g_object_unref(s->pixbuf_fogged);
}
free(s);
}
@@ -376,24 +422,9 @@
***************************************************************************/
SPRITE* sprite_scale(SPRITE *src, int new_w, int new_h)
{
- GdkPixbuf *original, *im;
- SPRITE *mysprite;
-
- original = sprite_get_pixbuf(src);
- im = gdk_pixbuf_scale_simple(original, new_w, new_h, GDK_INTERP_BILINEAR);
-
- mysprite=fc_malloc(sizeof(struct Sprite));
-
- gdk_pixbuf_render_pixmap_and_mask(im, &mysprite->pixmap, &mysprite->mask, 1);
-
- mysprite->width = new_w;
- mysprite->height = new_h;
-
- mysprite->pixbuf = NULL;
- mysprite->fogged = NULL;
- g_object_unref(im);
-
- return mysprite;
+ return ctor_sprite(gdk_pixbuf_scale_simple(sprite_get_pixbuf(src),
+ new_w, new_h,
+ GDK_INTERP_BILINEAR));
}
/***************************************************************************
@@ -405,9 +436,10 @@
int *start_y, int *end_x, int *end_y)
{
GdkImage *mask_image;
+ GdkBitmap *mask = sprite_get_mask(sprite);
int i, j;
- if (!sprite->mask) {
+ if (!mask) {
*start_x = 0;
*start_y = 0;
*end_x = sprite->width - 1;
@@ -416,7 +448,7 @@
}
mask_image =
- gdk_drawable_get_image(sprite->mask, 0, 0, sprite->width, sprite->height);
+ gdk_drawable_get_image(mask, 0, 0, sprite->width, sprite->height);
/* parses mask image for the first column that contains a visible pixel */
@@ -522,9 +554,11 @@
}
/********************************************************************
+ Render a pixbuf from the sprite.
+
NOTE: the pixmap and mask of a sprite must not change after this
function is called!
- ********************************************************************/
+********************************************************************/
GdkPixbuf *sprite_get_pixbuf(SPRITE *sprite)
{
if (!sprite) {
@@ -537,3 +571,18 @@
return sprite->pixbuf;
}
+/****************************************************************************
+ Render a mask from the sprite.
+
+ NOTE: the pixbuf of a sprite must not change after this function is called!
+****************************************************************************/
+GdkBitmap *sprite_get_mask(struct Sprite *sprite)
+{
+ if (!sprite->pixmap && !sprite->mask) {
+ /* If we're not in pixmap mode and we don't yet have a mask, render
+ * the pixbuf to a mask. */
+ gdk_pixbuf_render_pixmap_and_mask(sprite->pixbuf, NULL,
+ &sprite->mask, 1);
+ }
+ return sprite->mask;
+}
Index: client/gui-gtk-2.0/graphics.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/graphics.h,v
retrieving revision 1.10
diff -u -r1.10 graphics.h
--- client/gui-gtk-2.0/graphics.h 25 Dec 2004 19:50:29 -0000 1.10
+++ client/gui-gtk-2.0/graphics.h 1 Feb 2005 00:59:15 -0000
@@ -20,13 +20,17 @@
struct Sprite
{
- GdkPixmap *pixmap;
- GdkPixmap *fogged;
+ /* A pixmap + mask is used if there's a 1-bit alpha channel. mask may be
+ * NULL if there's no alpha. For multi-bit alpha levels, a pixbuf will be
+ * used instead. For consistency a pixbuf may be generated on-demand when
+ * doing drawing (into a gtkpixcomm or gtkimage), so it's important that
+ * the sprite data not be changed after the sprite is loaded. */
+ GdkPixmap *pixmap, *pixmap_fogged;
GdkBitmap *mask;
+ GdkPixbuf *pixbuf, *pixbuf_fogged;
+
int width;
int height;
-
- GdkPixbuf *pixbuf;
};
typedef struct Sprite SPRITE;
@@ -45,8 +49,7 @@
GdkGC *white_gc,
gint x, gint y, PangoLayout *layout);
-SPRITE *ctor_sprite_mask(GdkPixmap *mypixmap, GdkPixmap *mask,
- int width, int height);
+SPRITE *ctor_sprite(GdkPixbuf *pixbuf);
SPRITE* sprite_scale(SPRITE *src, int new_w, int new_h);
void sprite_get_bounding_box(SPRITE * sprite, int *start_x,
int *start_y, int *end_x, int *end_y);
@@ -55,10 +58,10 @@
GdkPixbuf *gdk_pixbuf_new_from_sprite(SPRITE *src);
/********************************************************************
- NOTE: the pixmap and mask of a sprite must not change after this
- function is called!
+ Note: a sprite cannot be changed after these functions are called!
********************************************************************/
GdkPixbuf *sprite_get_pixbuf(SPRITE *sprite);
+GdkBitmap *sprite_get_mask(struct Sprite *sprite);
#endif /* FC__GRAPHICS_H */
Index: client/gui-gtk-2.0/gtkpixcomm.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gtkpixcomm.c,v
retrieving revision 1.13
diff -u -r1.13 gtkpixcomm.c
--- client/gui-gtk-2.0/gtkpixcomm.c 15 Dec 2004 23:18:18 -0000 1.13
+++ client/gui-gtk-2.0/gtkpixcomm.c 1 Feb 2005 00:59:15 -0000
@@ -246,24 +246,33 @@
break;
case OP_COPY:
- if (rop->src->mask) {
- gdk_gc_set_clip_mask(civ_gc, rop->src->mask);
- gdk_gc_set_clip_origin(civ_gc, x + rop->x, y + rop->y);
-
- gdk_draw_drawable(widget->window, civ_gc,
- rop->src->pixmap,
- 0, 0,
- x + rop->x, y + rop->y,
- rop->src->width, rop->src->height);
-
- gdk_gc_set_clip_origin(civ_gc, 0, 0);
- gdk_gc_set_clip_mask(civ_gc, NULL);
- } else {
- gdk_draw_drawable(widget->window, civ_gc,
- rop->src->pixmap,
- 0, 0,
- x + rop->x, y + rop->y,
- rop->src->width, rop->src->height);
+ if (rop->src->pixmap) {
+ if (rop->src->mask) {
+ gdk_gc_set_clip_mask(civ_gc, rop->src->mask);
+ gdk_gc_set_clip_origin(civ_gc, x + rop->x, y + rop->y);
+
+ gdk_draw_drawable(widget->window, civ_gc,
+ rop->src->pixmap,
+ 0, 0,
+ x + rop->x, y + rop->y,
+ rop->src->width, rop->src->height);
+
+ gdk_gc_set_clip_origin(civ_gc, 0, 0);
+ gdk_gc_set_clip_mask(civ_gc, NULL);
+ } else {
+ gdk_draw_drawable(widget->window, civ_gc,
+ rop->src->pixmap,
+ 0, 0,
+ x + rop->x, y + rop->y,
+ rop->src->width, rop->src->height);
+ }
+ } else {
+ gdk_draw_pixbuf(widget->window, civ_gc,
+ rop->src->pixbuf,
+ 0, 0,
+ x + rop->x, y + rop->y,
+ rop->src->width, rop->src->height,
+ GDK_RGB_DITHER_NONE, 0, 0);
}
break;
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_main.c,v
retrieving revision 1.103
diff -u -r1.103 gui_main.c
--- client/gui-gtk-2.0/gui_main.c 28 Jan 2005 19:57:09 -0000 1.103
+++ client/gui-gtk-2.0/gui_main.c 1 Feb 2005 00:59:16 -0000
@@ -621,8 +621,8 @@
gtk_pixcomm_clear(GTK_PIXCOMM(unit_below_pixmap[i]));
}
- more_arrow_pixmap = gtk_image_new_from_pixmap(sprites.right_arrow->pixmap,
- NULL);
+ more_arrow_pixmap
+ = gtk_image_new_from_pixbuf(sprite_get_pixbuf(sprites.right_arrow));
gtk_widget_ref(more_arrow_pixmap);
gtk_table_attach_defaults(GTK_TABLE(table), more_arrow_pixmap, 4, 5, 1, 2);
@@ -826,14 +826,16 @@
G_CALLBACK(taxrates_callback), GINT_TO_POINTER(i));
sprite = i < 5 ? sprites.tax_science : sprites.tax_gold;
- econ_label[i] = gtk_image_new_from_pixmap(sprite->pixmap, sprite->mask);
+ econ_label[i] = gtk_image_new_from_pixbuf(sprite_get_pixbuf(sprite));
gtk_container_add(GTK_CONTAINER(ebox), econ_label[i]);
}
/* science, environmental, govt, timeout */
- bulb_label = gtk_image_new_from_pixmap(sprites.bulb[0]->pixmap, NULL);
- sun_label = gtk_image_new_from_pixmap(sprites.warming[0]->pixmap, NULL);
- flake_label = gtk_image_new_from_pixmap(sprites.cooling[0]->pixmap, NULL);
+ bulb_label = gtk_image_new_from_pixbuf(sprite_get_pixbuf(sprites.bulb[0]));
+ sun_label
+ = gtk_image_new_from_pixbuf(sprite_get_pixbuf(sprites.warming[0]));
+ flake_label
+ = gtk_image_new_from_pixbuf(sprite_get_pixbuf(sprites.cooling[0]));
{
/* HACK: the UNHAPPY citizen is used for the government
* when we don't know any better. */
@@ -841,7 +843,7 @@
sprite = get_citizen_sprite(c, 0, NULL);
}
- government_label = gtk_image_new_from_pixmap(sprite->pixmap, sprite->mask);
+ government_label = gtk_image_new_from_pixbuf(sprite_get_pixbuf(sprite));
for (i = 0; i < 4; i++) {
GtkWidget *w;
Index: client/gui-gtk-2.0/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapview.c,v
retrieving revision 1.155
diff -u -r1.155 mapview.c
--- client/gui-gtk-2.0/mapview.c 21 Jan 2005 03:36:26 -0000 1.155
+++ client/gui-gtk-2.0/mapview.c 1 Feb 2005 00:59:16 -0000
@@ -128,23 +128,23 @@
for (; d < game.player_ptr->economic.luxury /10; d++) {
struct Sprite *sprite = sprites.tax_luxury;
- gtk_image_set_from_pixmap(GTK_IMAGE(econ_label[d]),
- sprite->pixmap, sprite->mask);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(econ_label[d]),
+ sprite_get_pixbuf(sprite));
}
for (; d < (game.player_ptr->economic.science
+ game.player_ptr->economic.luxury) / 10; d++) {
struct Sprite *sprite = sprites.tax_science;
- gtk_image_set_from_pixmap(GTK_IMAGE(econ_label[d]),
- sprite->pixmap, sprite->mask);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(econ_label[d]),
+ sprite_get_pixbuf(sprite));
}
for (; d < 10; d++) {
struct Sprite *sprite = sprites.tax_gold;
- gtk_image_set_from_pixmap(GTK_IMAGE(econ_label[d]),
- sprite->pixmap, sprite->mask);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(econ_label[d]),
+ sprite_get_pixbuf(sprite));
}
update_timeout_label();
@@ -216,9 +216,9 @@
/**************************************************************************
...
**************************************************************************/
-GdkPixmap *get_thumb_pixmap(int onoff)
+GdkPixbuf *get_thumb_pixbuf(int onoff)
{
- return sprites.treaty_thumb[BOOL_VAL(onoff)]->pixmap;
+ return sprite_get_pixbuf(sprites.treaty_thumb[BOOL_VAL(onoff)]);
}
/**************************************************************************
@@ -232,12 +232,12 @@
sol = CLIP(0, sol, NUM_TILES_PROGRESS-1);
flake = CLIP(0, flake, NUM_TILES_PROGRESS-1);
- gtk_image_set_from_pixmap(GTK_IMAGE(bulb_label),
- sprites.bulb[bulb]->pixmap, NULL);
- gtk_image_set_from_pixmap(GTK_IMAGE(sun_label),
- sprites.warming[sol]->pixmap, NULL);
- gtk_image_set_from_pixmap(GTK_IMAGE(flake_label),
- sprites.cooling[flake]->pixmap, NULL);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(bulb_label),
+ sprite_get_pixbuf(sprites.bulb[bulb]));
+ gtk_image_set_from_pixbuf(GTK_IMAGE(sun_label),
+ sprite_get_pixbuf(sprites.warming[sol]));
+ gtk_image_set_from_pixbuf(GTK_IMAGE(flake_label),
+ sprite_get_pixbuf(sprites.cooling[flake]));
if (game.government_count==0) {
/* HACK: the UNHAPPY citizen is used for the government
@@ -248,8 +248,8 @@
} else {
gov_sprite = get_government(gov)->sprite;
}
- gtk_image_set_from_pixmap(GTK_IMAGE(government_label),
- gov_sprite->pixmap, NULL);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(government_label),
+ sprite_get_pixbuf(gov_sprite));
}
/**************************************************************************
@@ -639,15 +639,23 @@
if (!ssprite) {
return;
}
-
- gdk_gc_set_clip_origin(civ_gc, canvas_x, canvas_y);
- gdk_gc_set_clip_mask(civ_gc, ssprite->mask);
- gdk_draw_drawable(pixmap, civ_gc, ssprite->pixmap,
+ if (ssprite->pixmap) {
+ gdk_gc_set_clip_origin(civ_gc, canvas_x, canvas_y);
+ gdk_gc_set_clip_mask(civ_gc, ssprite->mask);
+
+ gdk_draw_drawable(pixmap, civ_gc, ssprite->pixmap,
+ 0, 0,
+ canvas_x, canvas_y,
+ ssprite->width, ssprite->height);
+ gdk_gc_set_clip_mask(civ_gc, NULL);
+ } else {
+ gdk_draw_pixbuf(pixmap, civ_gc, ssprite->pixbuf,
0, 0,
- canvas_x, canvas_y,
- ssprite->width, ssprite->height);
- gdk_gc_set_clip_mask(civ_gc, NULL);
+ canvas_x, canvas_y,
+ ssprite->width, ssprite->height,
+ GDK_RGB_DITHER_NONE, 0, 0);
+ }
}
/**************************************************************************
@@ -659,18 +667,27 @@
int offset_x, int offset_y,
int width, int height)
{
- if (ssprite->mask) {
- gdk_gc_set_clip_origin(civ_gc, pixmap_x, pixmap_y);
- gdk_gc_set_clip_mask(civ_gc, ssprite->mask);
- }
+ if (ssprite->pixmap) {
+ if (ssprite->mask) {
+ gdk_gc_set_clip_origin(civ_gc, pixmap_x, pixmap_y);
+ gdk_gc_set_clip_mask(civ_gc, ssprite->mask);
+ }
- gdk_draw_drawable(pixmap, civ_gc, ssprite->pixmap,
+ gdk_draw_drawable(pixmap, civ_gc, ssprite->pixmap,
+ offset_x, offset_y,
+ pixmap_x + offset_x, pixmap_y + offset_y,
+ MIN(width, MAX(0, ssprite->width - offset_x)),
+ MIN(height, MAX(0, ssprite->height - offset_y)));
+
+ gdk_gc_set_clip_mask(civ_gc, NULL);
+ } else {
+ gdk_draw_pixbuf(pixmap, civ_gc, ssprite->pixbuf,
offset_x, offset_y,
pixmap_x + offset_x, pixmap_y + offset_y,
MIN(width, MAX(0, ssprite->width - offset_x)),
- MIN(height, MAX(0, ssprite->height - offset_y)));
-
- gdk_gc_set_clip_mask(civ_gc, NULL);
+ MIN(height, MAX(0, ssprite->height - offset_y)),
+ GDK_RGB_DITHER_NONE, 0, 0);
+ }
}
/**************************************************************************
@@ -783,7 +800,7 @@
{
if (pcanvas->type == CANVAS_PIXMAP) {
gdk_gc_set_clip_origin(fill_bg_gc, canvas_x, canvas_y);
- gdk_gc_set_clip_mask(fill_bg_gc, psprite->mask);
+ gdk_gc_set_clip_mask(fill_bg_gc, sprite_get_mask(psprite));
gdk_gc_set_foreground(fill_bg_gc, colors_standard[color]);
gdk_draw_rectangle(pcanvas->v.pixmap, fill_bg_gc, TRUE,
@@ -801,7 +818,7 @@
{
if (pcanvas->type == CANVAS_PIXMAP) {
gdk_gc_set_clip_origin(fill_tile_gc, canvas_x, canvas_y);
- gdk_gc_set_clip_mask(fill_tile_gc, psprite->mask);
+ gdk_gc_set_clip_mask(fill_tile_gc, sprite_get_mask(psprite));
gdk_gc_set_foreground(fill_tile_gc, colors_standard[COLOR_STD_BLACK]);
gdk_gc_set_stipple(fill_tile_gc, black50);
gdk_gc_set_ts_origin(fill_tile_gc, canvas_x, canvas_y);
@@ -870,10 +887,14 @@
guchar *pixel;
const int bright = 65; /* Brightness percentage */
- fogged = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
- sprite->width, sprite->height);
- gdk_pixbuf_get_from_drawable(fogged, sprite->pixmap, NULL,
- 0, 0, 0, 0, sprite->width, sprite->height);
+ if (sprite->pixmap) {
+ fogged = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
+ sprite->width, sprite->height);
+ gdk_pixbuf_get_from_drawable(fogged, sprite->pixmap, NULL,
+ 0, 0, 0, 0, sprite->width, sprite->height);
+ } else {
+ fogged = gdk_pixbuf_copy(sprite->pixbuf);
+ }
/* Iterate over all pixels, reducing brightness by 50%. */
for (x = 0; x < sprite->width; x++) {
@@ -888,9 +909,13 @@
}
}
- gdk_pixbuf_render_pixmap_and_mask(fogged, &sprite->fogged,
- NULL, 0);
- g_object_unref(fogged);
+ if (sprite->pixmap) {
+ gdk_pixbuf_render_pixmap_and_mask(fogged, &sprite->pixmap_fogged,
+ NULL, 0);
+ g_object_unref(fogged);
+ } else {
+ sprite->pixbuf_fogged = fogged;
+ }
}
/**************************************************************************
@@ -905,9 +930,12 @@
return;
}
- if (fog && better_fog && !ssprite->fogged) {
+ if (fog && better_fog
+ && ((ssprite->pixmap && !ssprite->pixmap_fogged)
+ || (!ssprite->pixmap && !ssprite->pixbuf_fogged))) {
fog_sprite(ssprite);
- if (!ssprite->fogged) {
+ if ((ssprite->pixmap && !ssprite->pixmap_fogged)
+ || (!ssprite->pixmap && !ssprite->pixbuf_fogged)) {
freelog(LOG_NORMAL,
_("Better fog will only work in truecolor. Disabling it"));
better_fog = FALSE;
@@ -915,16 +943,23 @@
}
if (fog && better_fog) {
- gdk_gc_set_clip_origin(fill_tile_gc, canvas_x, canvas_y);
- gdk_gc_set_clip_mask(fill_tile_gc, ssprite->mask);
-
- gdk_draw_drawable(pixmap, fill_tile_gc,
- ssprite->fogged,
- 0, 0,
- canvas_x, canvas_y,
- ssprite->width, ssprite->height);
- gdk_gc_set_clip_mask(fill_tile_gc, NULL);
-
+ if (ssprite->pixmap) {
+ if (ssprite->mask) {
+ gdk_gc_set_clip_origin(civ_gc, canvas_x, canvas_y);
+ gdk_gc_set_clip_mask(civ_gc, ssprite->mask);
+ }
+ gdk_draw_drawable(pixmap, civ_gc,
+ ssprite->pixmap_fogged,
+ 0, 0,
+ canvas_x, canvas_y,
+ ssprite->width, ssprite->height);
+ gdk_gc_set_clip_mask(civ_gc, NULL);
+ } else {
+ gdk_draw_pixbuf(pixmap, civ_gc, ssprite->pixbuf_fogged,
+ 0, 0, canvas_x, canvas_y,
+ ssprite->width, ssprite->height,
+ GDK_RGB_DITHER_NONE, 0, 0);
+ }
return;
}
@@ -936,7 +971,7 @@
faster to just draw every second pixel black in the first place. */
if (fog) {
gdk_gc_set_clip_origin(fill_tile_gc, canvas_x, canvas_y);
- gdk_gc_set_clip_mask(fill_tile_gc, ssprite->mask);
+ gdk_gc_set_clip_mask(fill_tile_gc, sprite_get_mask(ssprite));
gdk_gc_set_foreground(fill_tile_gc, colors_standard[COLOR_STD_BLACK]);
gdk_gc_set_ts_origin(fill_tile_gc, canvas_x, canvas_y);
gdk_gc_set_stipple(fill_tile_gc, black50);
@@ -970,6 +1005,8 @@
enum color_std color, enum city_tile_type worker,
int canvas_x, int canvas_y)
{
+ GdkBitmap *mask;
+
if (pcanvas->type == CANVAS_PIXMAP) {
if (worker == C_TILE_EMPTY) {
gdk_gc_set_stipple(fill_tile_gc, gray25);
@@ -982,9 +1019,9 @@
gdk_gc_set_ts_origin(fill_tile_gc, canvas_x, canvas_y);
gdk_gc_set_foreground(fill_tile_gc, colors_standard[color]);
- if (sprites.black_tile && sprites.black_tile->mask) {
+ if (sprites.black_tile && (mask = sprite_get_mask(sprites.black_tile))) {
gdk_gc_set_clip_origin(fill_tile_gc, canvas_x, canvas_y);
- gdk_gc_set_clip_mask(fill_tile_gc, sprites.black_tile->mask);
+ gdk_gc_set_clip_mask(fill_tile_gc, mask);
}
gdk_draw_rectangle(pcanvas->v.pixmap, fill_tile_gc, TRUE,
Index: client/gui-gtk-2.0/mapview.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapview.h,v
retrieving revision 1.18
diff -u -r1.18 mapview.h
--- client/gui-gtk-2.0/mapview.h 22 Jul 2004 05:42:47 -0000 1.18
+++ client/gui-gtk-2.0/mapview.h 1 Feb 2005 00:59:16 -0000
@@ -26,7 +26,7 @@
struct unit;
struct city;
-GdkPixmap *get_thumb_pixmap(int onoff);
+GdkPixbuf *get_thumb_pixbuf(int onoff);
gboolean overview_canvas_expose(GtkWidget *w, GdkEventExpose *ev, gpointer
data);
gboolean map_canvas_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data);
Index: client/gui-gtk-2.0/menu.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/menu.c,v
retrieving revision 1.57
diff -u -r1.57 menu.c
--- client/gui-gtk-2.0/menu.c 25 Nov 2004 06:57:17 -0000 1.57
+++ client/gui-gtk-2.0/menu.c 1 Feb 2005 00:59:17 -0000
@@ -1204,7 +1204,7 @@
item = gtk_image_menu_item_new_with_label(buf);
gsprite = get_government(g->index)->sprite;
- image = gtk_image_new_from_pixmap(gsprite->pixmap, gsprite->mask);
+ image = gtk_image_new_from_pixbuf(sprite_get_pixbuf(gsprite));
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
gtk_widget_show(image);
Index: client/gui-gtk-2.0/pages.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/pages.c,v
retrieving revision 1.14
diff -u -r1.14 pages.c
--- client/gui-gtk-2.0/pages.c 22 Jan 2005 19:45:40 -0000 1.14
+++ client/gui-gtk-2.0/pages.c 1 Feb 2005 00:59:17 -0000
@@ -1386,7 +1386,7 @@
static GdkPixbuf *get_flag(char *flag_str)
{
int x0, y0, x1, y1, w, h;
- GdkPixbuf *im;
+ GdkPixbuf *im, *im2;
SPRITE *flag;
flag = load_sprite(flag_str);
@@ -1410,14 +1410,13 @@
assert(w >= MIN_DIMENSION && h >= MIN_DIMENSION);
/* get the pixbuf and crop*/
- im = gdk_pixbuf_get_from_drawable(NULL, flag->pixmap,
- gdk_colormap_get_system(),
- x0, y0, 0, 0, w, h);
-
+ im = gdk_pixbuf_new_subpixbuf(sprite_get_pixbuf(flag), x0, y0, w, h);
+ im2 = gdk_pixbuf_copy(im);
+ g_object_unref(im);
unload_sprite(flag_str);
/* and finaly store the scaled flag pixbuf in the static flags array */
- return im;
+ return im2;
}
/**************************************************************************
Index: client/gui-gtk-2.0/plrdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/plrdlg.c,v
retrieving revision 1.48
diff -u -r1.48 plrdlg.c
--- client/gui-gtk-2.0/plrdlg.c 17 Dec 2004 16:25:18 -0000 1.48
+++ client/gui-gtk-2.0/plrdlg.c 1 Feb 2005 00:59:17 -0000
@@ -496,12 +496,9 @@
assert(w >= MIN_DIMENSION && h >= MIN_DIMENSION);
/* croping */
- im = gdk_pixbuf_get_from_drawable(NULL,
- flag->pixmap,
- gdk_colormap_get_system(),
- x0, y0,
- 0, 0,
- w, h);
+ im = gdk_pixbuf_new_subpixbuf(sprite_get_pixbuf(flag), x0, y0, w, h);
+ g_object_unref(im);
+ im = gdk_pixbuf_copy(im);
/* and finaly store the scaled flag pixbuf in the static flags array */
return im;
Index: client/gui-gtk-2.0/spaceshipdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/spaceshipdlg.c,v
retrieving revision 1.14
diff -u -r1.14 spaceshipdlg.c
--- client/gui-gtk-2.0/spaceshipdlg.c 22 Jan 2005 19:45:40 -0000 1.14
+++ client/gui-gtk-2.0/spaceshipdlg.c 1 Feb 2005 00:59:17 -0000
@@ -300,13 +300,10 @@
sprite = (k==0 ? sprites.spaceship.habitation :
k==1 ? sprites.spaceship.life_support :
sprites.spaceship.solar_panels);
- gdk_gc_set_clip_origin(civ_gc, x, y);
- gdk_gc_set_clip_mask(civ_gc, sprite->mask);
- gdk_draw_drawable(pdialog->image_canvas->window, civ_gc, sprite->pixmap,
- 0, 0,
- x, y,
- sprite->width, sprite->height);
- gdk_gc_set_clip_mask(civ_gc,NULL);
+ gdk_draw_pixbuf(pdialog->image_canvas->window, civ_gc,
+ sprite_get_pixbuf(sprite),
+ 0, 0, x, y, sprite->width, sprite->height,
+ GDK_RGB_DITHER_NONE, 0, 0);
}
for (i=0; i < NUM_SS_COMPONENTS; i++) {
@@ -321,13 +318,10 @@
sprite = (k==0) ? sprites.spaceship.fuel : sprites.spaceship.propulsion;
- gdk_gc_set_clip_origin(civ_gc, x, y);
- gdk_gc_set_clip_mask(civ_gc, sprite->mask);
- gdk_draw_drawable(pdialog->image_canvas->window, civ_gc, sprite->pixmap,
- 0, 0,
- x, y,
- sprite->width, sprite->height);
- gdk_gc_set_clip_mask(civ_gc,NULL);
+ gdk_draw_pixbuf(pdialog->image_canvas->window, civ_gc,
+ sprite_get_pixbuf(sprite),
+ 0, 0, x, y, sprite->width, sprite->height,
+ GDK_RGB_DITHER_NONE, 0, 0);
}
sprite = sprites.spaceship.structural;
@@ -338,13 +332,10 @@
x = structurals_info[i].x * sprite->width / 4 - sprite->width / 2;
y = structurals_info[i].y * sprite->height / 4 - sprite->height / 2;
- gdk_gc_set_clip_origin(civ_gc, x, y);
- gdk_gc_set_clip_mask(civ_gc, sprite->mask);
- gdk_draw_drawable(pdialog->image_canvas->window, civ_gc, sprite->pixmap,
- 0, 0,
- x, y,
- sprite->width, sprite->height);
- gdk_gc_set_clip_mask(civ_gc,NULL);
+ gdk_draw_pixbuf(pdialog->image_canvas->window, civ_gc,
+ sprite_get_pixbuf(sprite),
+ 0, 0, x, y, sprite->width, sprite->height,
+ GDK_RGB_DITHER_NONE, 0, 0);
}
}
|
|