Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2004:
[Freeciv-Dev] Re: (PR#11507) use pixbufs for gtk2 sprites
Home

[Freeciv-Dev] Re: (PR#11507) use pixbufs for gtk2 sprites

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] Re: (PR#11507) use pixbufs for gtk2 sprites
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 14 Dec 2004 11:54:06 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=11507 >

Here's a patch that does things what I consider the "right way".  I 
really don't know why gdkpixbuf doesn't do it this way!  In gdkpixbuf 
there is no way to have a 1-bit alpha channel; you must have 8-bit or no 
alpha.  Also whoever thought gdk_pixbuf_get_pixels was a good idea 
should be fired.

Anyway, the right way is to track a 0-bit, 1-bit, or 8-bit alpha channel 
as needed.  This patch does this inside the sprite struct by tracking a 
pixmap if there is no alpha or a pixbuf if there is.  However to make 
the interface consistent pixbufs are used for most non-mapview graphics 
(this should make no difference in speed, and fixes some bugs where the 
masks were ignored).

With the current tileset this patch makes no difference in speed. 
However it allows you to add alpha levels to individual sprites in the 
tileset, giving you better graphics but at a cost in speed.  Using just 
alpha fog in the trident tileset (easy to do - just drop tiles.png into 
the trident directory) gives a 10% drop in speed.

This highlights the next problem with using alpha levels in tilesets: 
the other clients can't handle it.  The gtk and xaw clients will not 
work at all with this (the XAW client can't even handle RGB PNGs, much 
less RGBA).  I don't know if the win32 client will work.  Honestly I'd 
say if the gtk2 and win32 clients work with RGBA graphics then the 
others can either be obsoleted or simply have their users told not to 
use those tilesets.

-jason


? vgcore.pid4735
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.85
diff -u -r1.85 dialogs.c
--- client/gui-gtk-2.0/dialogs.c        8 Dec 2004 20:48:33 -0000       1.85
+++ client/gui-gtk-2.0/dialogs.c        14 Dec 2004 19:26:26 -0000
@@ -1642,10 +1642,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.24
diff -u -r1.24 diplodlg.c
--- client/gui-gtk-2.0/diplodlg.c       8 Dec 2004 20:48:33 -0000       1.24
+++ client/gui-gtk-2.0/diplodlg.c       14 Dec 2004 19:26:26 -0000
@@ -654,12 +654,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.28
diff -u -r1.28 graphics.c
--- client/gui-gtk-2.0/graphics.c       23 Nov 2004 15:44:10 -0000      1.28
+++ client/gui-gtk-2.0/graphics.c       14 Dec 2004 19:26:26 -0000
@@ -49,8 +49,7 @@
 #include "patrol_cursor.xbm"
 #include "patrol_cursor_mask.xbm"
 
-SPRITE *               intro_gfx_sprite;
-SPRITE *               radar_gfx_sprite;
+GdkPixmap *intro_gfx, *radar_gfx;
 
 GdkCursor *            goto_cursor;
 GdkCursor *            drop_cursor;
@@ -104,6 +103,7 @@
   PangoContext *context;
   PangoLayout *layout;
   PangoRectangle rect;
+  struct Sprite *sprite;
 
   context = gdk_pango_context_get();
   layout = pango_layout_new(context);
@@ -116,32 +116,37 @@
   face_gc = gdk_gc_new(root_window);
 
   /* Main graphic */
-  intro_gfx_sprite = load_gfxfile(main_intro_filename);
-  tot=intro_gfx_sprite->width;
+  sprite = load_gfxfile(main_intro_filename);
+  gdk_pixbuf_render_pixmap_and_mask(sprite_get_pixbuf(sprite),
+                                   &intro_gfx, NULL, 1);
+  tot = sprite->width;
+  y = sprite->height - 45;
+  free_sprite(sprite);
 
   pango_layout_set_text(layout, freeciv_motto(), -1);
   pango_layout_get_pixel_extents(layout, &rect, NULL);
 
-  y = intro_gfx_sprite->height-45;
-
   gdk_gc_set_rgb_fg_color(face_gc, &face);
-  gdk_draw_layout(intro_gfx_sprite->pixmap, face_gc,
+  gdk_draw_layout(intro_gfx, face_gc,
                  (tot-rect.width) / 2, y, layout);
   g_object_unref(face_gc);
 
   /* Minimap graphic */
-  radar_gfx_sprite = load_gfxfile(minimap_intro_filename);
-  tot=radar_gfx_sprite->width;
-
   my_snprintf(s, sizeof(s), "%d.%d.%d%s",
              MAJOR_VERSION, MINOR_VERSION,
              PATCH_VERSION, VERSION_LABEL);
   pango_layout_set_text(layout, s, -1);
   pango_layout_get_pixel_extents(layout, &rect, NULL);
 
-  y = radar_gfx_sprite->height - (rect.height + 6);
+  sprite = load_gfxfile(minimap_intro_filename);
+  gdk_pixbuf_render_pixmap_and_mask(sprite_get_pixbuf(sprite),
+                                   &radar_gfx, NULL, 1);
+  tot = sprite->width;
+  y = sprite->height - (rect.height + 6);
+
+  free_sprite(sprite);
 
-  gtk_draw_shadowed_string(radar_gfx_sprite->pixmap,
+  gtk_draw_shadowed_string(radar_gfx,
                        toplevel->style->black_gc,
                        toplevel->style->white_gc,
                        (tot - rect.width) / 2, y,
@@ -151,7 +156,7 @@
   pango_layout_get_pixel_extents(layout, &rect, NULL);
   y-=rect.height+3;
 
-  gtk_draw_shadowed_string(radar_gfx_sprite->pixmap,
+  gtk_draw_shadowed_string(radar_gfx,
                        toplevel->style->black_gc,
                        toplevel->style->white_gc,
                        (tot - rect.width) / 2, y,
@@ -173,38 +178,24 @@
                           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);
+  GdkPixbuf *mypixbuf, *sub;
 
-  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);
-  }
-
-  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);
+  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);
 
-      gdk_draw_drawable(mymask, mask_fg_gc, source->mask,
-                       x, y, 0, 0, width, height);
-    }
-  }
-
-  return ctor_sprite_mask(mypixmap, mymask, width, height);
+  return ctor_sprite(mypixbuf);
 }
 
 /****************************************************************************
@@ -284,21 +275,49 @@
  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));
-
-    mysprite->pixmap   = mypixmap;
+  struct Sprite *sprite = fc_malloc(sizeof(*sprite));
+  bool has_alpha = FALSE, has_mask = FALSE;
 
-    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;
+  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;
 }
 
 
@@ -335,27 +354,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;
-
-  g_object_unref(im);
-
-  return mysprite;
+  return ctor_sprite(im);
 }
 
 /***************************************************************************
@@ -373,6 +378,7 @@
   }
   if (s->pixbuf) {
     g_object_unref(s->pixbuf);
+    s->pixbuf = NULL;
   }
   free(s);
 }
@@ -427,13 +433,13 @@
 ***************************************************************************/
 void free_intro_radar_sprites(void)
 {
-  if (intro_gfx_sprite) {
-    free_sprite(intro_gfx_sprite);
-    intro_gfx_sprite=NULL;
-  }
-  if (radar_gfx_sprite) {
-    free_sprite(radar_gfx_sprite);
-    radar_gfx_sprite=NULL;
+  if (intro_gfx) {
+    g_object_unref(intro_gfx);
+    intro_gfx = NULL;
+  }
+  if (radar_gfx) {
+    g_object_unref(radar_gfx);
+    radar_gfx = NULL;
   }
 }
 
@@ -443,24 +449,8 @@
 ***************************************************************************/
 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;
-
-  g_object_unref(im);
-
-  return mysprite;
+  return ctor_sprite(gdk_pixbuf_scale_simple(src->pixbuf, new_w, new_h,
+                                            GDK_INTERP_BILINEAR));
 }
 
 /***************************************************************************
@@ -472,9 +462,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;
@@ -483,7 +474,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 */
@@ -603,3 +594,14 @@
   return sprite->pixbuf;
 }
 
+GdkBitmap *sprite_get_mask(struct Sprite *sprite)
+{
+  GdkPixmap *pixmap;
+
+  if (sprite->pixbuf && !sprite->mask) {
+    gdk_pixbuf_render_pixmap_and_mask(sprite->pixbuf, &pixmap,
+                                     &sprite->mask, 1);
+    g_object_unref(pixmap);
+  }
+  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.9
diff -u -r1.9 graphics.h
--- client/gui-gtk-2.0/graphics.h       20 Nov 2004 08:17:37 -0000      1.9
+++ client/gui-gtk-2.0/graphics.h       14 Dec 2004 19:26:26 -0000
@@ -20,20 +20,18 @@
 
 struct Sprite
 {
+  GdkPixbuf *pixbuf;
   GdkPixmap *pixmap;
   GdkBitmap *mask;
   int       width;
   int       height;
-
-  GdkPixbuf *pixbuf;
 };
 
 typedef struct Sprite SPRITE;
 
 void create_overlay_unit(struct canvas *pcanvas, int i);
 
-extern SPRITE *    intro_gfx_sprite;
-extern SPRITE *    radar_gfx_sprite;
+extern GdkPixmap *intro_gfx, *radar_gfx;
 extern GdkCursor * goto_cursor;
 extern GdkCursor * drop_cursor;
 extern GdkCursor * nuke_cursor;
@@ -44,8 +42,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);
@@ -54,10 +51,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.12
diff -u -r1.12 gtkpixcomm.c
--- client/gui-gtk-2.0/gtkpixcomm.c     20 Nov 2004 08:17:37 -0000      1.12
+++ client/gui-gtk-2.0/gtkpixcomm.c     14 Dec 2004 19:26:26 -0000
@@ -243,25 +243,12 @@
         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);
-       }
+       gdk_draw_pixbuf(widget->window, civ_gc,
+                       sprite_get_pixbuf(rop->src),
+                       0, 0,
+                       x + rop->x, y + rop->y,
+                       rop->src->width, rop->src->height,
+                       GDK_RGB_DITHER_NONE, 0, 0);
         break;
 
       default:
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.98
diff -u -r1.98 gui_main.c
--- client/gui-gtk-2.0/gui_main.c       7 Dec 2004 22:38:59 -0000       1.98
+++ client/gui-gtk-2.0/gui_main.c       14 Dec 2004 19:26:26 -0000
@@ -610,8 +610,7 @@
     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(sprites.right_arrow->pixbuf);
   gtk_widget_ref(more_arrow_pixmap);
   gtk_table_attach_defaults(GTK_TABLE(table), more_arrow_pixmap, 4, 5, 1, 2);
 
@@ -814,14 +813,14 @@
                      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->pixbuf);
     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(sprites.bulb[0]->pixbuf);
+  sun_label = gtk_image_new_from_pixbuf(sprites.warming[0]->pixbuf);
+  flake_label = gtk_image_new_from_pixbuf(sprites.cooling[0]->pixbuf);
   {
     /* HACK: the UNHAPPY citizen is used for the government
      * when we don't know any better. */
@@ -829,7 +828,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->pixbuf);
 
   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.147
diff -u -r1.147 mapview.c
--- client/gui-gtk-2.0/mapview.c        1 Nov 2004 03:39:45 -0000       1.147
+++ client/gui-gtk-2.0/mapview.c        14 Dec 2004 19:26:27 -0000
@@ -64,7 +64,7 @@
 
 /* the intro picture is held in this pixmap, which is scaled to
    the screen size */
-static SPRITE *scaled_intro_sprite = NULL;
+static GdkPixmap *scaled_intro_sprite;
 
 static GtkObject *map_hadj, *map_vadj;
 
@@ -130,23 +130,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();
@@ -218,9 +218,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)]);
 }
 
 /**************************************************************************
@@ -234,12 +234,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
@@ -250,8 +250,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));
 }
 
 /**************************************************************************
@@ -304,9 +304,9 @@
 gboolean overview_canvas_expose(GtkWidget *w, GdkEventExpose *ev, gpointer 
data)
 {
   if (!can_client_change_view()) {
-    if (radar_gfx_sprite) {
+    if (radar_gfx) {
       gdk_draw_drawable(overview_canvas->window, civ_gc,
-                       radar_gfx_sprite->pixmap, ev->area.x, ev->area.y,
+                       radar_gfx, ev->area.x, ev->area.y,
                        ev->area.x, ev->area.y,
                        ev->area.width, ev->area.height);
     }
@@ -343,22 +343,21 @@
   if (!can_client_change_view()) {
     if (map_configure || !scaled_intro_sprite) {
 
-      if (!intro_gfx_sprite) {
+      if (!intro_gfx) {
         load_intro_gfx();
       }
 
       if (scaled_intro_sprite) {
-        free_sprite(scaled_intro_sprite);
+       g_object_unref(scaled_intro_sprite);
       }
 
-      scaled_intro_sprite = sprite_scale(intro_gfx_sprite,
-                                        w->allocation.width,
-                                        w->allocation.height);
+      scaled_intro_sprite = intro_gfx;
+      g_object_ref(scaled_intro_sprite);
     }
 
     if (scaled_intro_sprite) {
       gdk_draw_drawable(map_canvas->window, civ_gc,
-                       scaled_intro_sprite->pixmap,
+                       scaled_intro_sprite,
                        ev->area.x, ev->area.y, ev->area.x, ev->area.y,
                        ev->area.width, ev->area.height);
       gtk_widget_queue_draw(overview_canvas);
@@ -374,7 +373,7 @@
   else
   {
     if (scaled_intro_sprite) {
-      free_sprite(scaled_intro_sprite);
+      g_object_unref(scaled_intro_sprite);
       scaled_intro_sprite = NULL;
     }
 
@@ -667,15 +666,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);
+  }
 }
 
 /**************************************************************************
@@ -687,18 +694,31 @@
                              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);
-  }
+  static int pixmaps = 0, pixbufs = 0;
+
+  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);
+    }
+
+    pixmaps++;
+    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_draw_drawable(pixmap, civ_gc, ssprite->pixmap,
+    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);
+    pixbufs++;
+  }
 }
 
 /**************************************************************************
@@ -744,7 +764,6 @@
                            int canvas_x, int canvas_y,
                            struct Sprite *sprite)
 {
-  assert(sprite->pixmap);
   canvas_put_sprite(pcanvas, canvas_x, canvas_y, sprite,
                    0, 0, sprite->width, sprite->height);
 }
@@ -798,7 +817,7 @@
                             int canvas_x, int canvas_y)
 {
   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,
@@ -814,7 +833,7 @@
                            int canvas_x, int canvas_y)
 {
   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);
@@ -885,7 +904,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);
@@ -932,7 +951,7 @@
 
   if (is_isometric) {
     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, sprite_get_mask(sprites.black_tile));
   }
 
   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        14 Dec 2004 19:26:27 -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   14 Dec 2004 19:26:27 -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(gsprite->pixbuf);
           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.13
diff -u -r1.13 pages.c
--- client/gui-gtk-2.0/pages.c  23 Nov 2004 15:39:01 -0000      1.13
+++ client/gui-gtk-2.0/pages.c  14 Dec 2004 19:26:27 -0000
@@ -1383,7 +1383,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);
@@ -1407,14 +1407,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.47
diff -u -r1.47 plrdlg.c
--- client/gui-gtk-2.0/plrdlg.c 25 Nov 2004 06:57:17 -0000      1.47
+++ client/gui-gtk-2.0/plrdlg.c 14 Dec 2004 19:26:27 -0000
@@ -470,12 +470,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(flag->pixbuf, 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.13
diff -u -r1.13 spaceshipdlg.c
--- client/gui-gtk-2.0/spaceshipdlg.c   31 Oct 2004 20:45:55 -0000      1.13
+++ client/gui-gtk-2.0/spaceshipdlg.c   14 Dec 2004 19:26:27 -0000
@@ -290,13 +290,9 @@
     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->pixbuf, 
+                   0, 0, x, y, sprite->width, sprite->height,
+                   GDK_RGB_DITHER_NONE, 0, 0);
   }
 
   for (i=0; i < NUM_SS_COMPONENTS; i++) {
@@ -311,13 +307,9 @@
 
     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->pixbuf,
+                   0, 0, x, y, sprite->width, sprite->height,
+                   GDK_RGB_DITHER_NONE, 0, 0);
   }
 
   sprite = sprites.spaceship.structural;
@@ -328,13 +320,9 @@
     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->pixbuf,
+                   0, 0, x, y, sprite->width, sprite->height,
+                   GDK_RGB_DITHER_NONE, 0, 0);
   }
 }
 
Index: data/trident/tiles.png
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/trident/tiles.png,v
retrieving revision 1.7
diff -u -r1.7 tiles.png
Binary files /tmp/cvs1dkhEe and tiles.png differ

PNG image


[Prev in Thread] Current Thread [Next in Thread]