Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2005:
[Freeciv-Dev] (PR#12042) cairo for mapview drawing
Home

[Freeciv-Dev] (PR#12042) cairo for mapview drawing

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#12042) cairo for mapview drawing
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 28 Jan 2005 21:18:56 -0800
Reply-to: bugs@xxxxxxxxxxx

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

Using cairo for the mapview (canvas) drawing is an idea.  It allows a 
fairly transparent canvas system very similar to what the mapview code 
uses now but more powerful.  However it may not be stable enough for use 
yet (or ever).

Just to play around I started implementing this.  The idea is to replace 
most of the canvas functions with cairo functions.  Cairo objects thus 
get put into the canvas structures (maybe someday the canvas struct may 
be dropped entirely).

Only gui-xaw is supported, and only a small amount of the drawing is 
currently done with cairo.  But for the record here is the patch.

-jason

Index: configure.ac
===================================================================
RCS file: /home/freeciv/CVS/freeciv/configure.ac,v
retrieving revision 1.92
diff -u -r1.92 configure.ac
--- configure.ac        27 Jan 2005 02:14:40 -0000      1.92
+++ configure.ac        29 Jan 2005 05:05:29 -0000
@@ -416,6 +416,21 @@
   FC_CHECK_SOUND()
 
   gui_sources="gui-$client"
+
+
+  cairo="cairo"
+  AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+  if test "$PKG_CONFIG" = "no"; then
+    AC_MSG_ERROR([pkg-config is missing.])
+  fi
+  if $PKG_CONFIG --atleast-version 0.3 $cairo; then
+    :
+  else
+    AC_MSG_ERROR([Cairo version 0.3 or higher is required])
+  fi
+  CAIRO_LIBS=`$PKG_CONFIG --libs $cairo`
+  CAIRO_CFLAGS=`$PKG_CONFIG --cflags $cairo`
+  CLIENT_CFLAGS="$CLIENT_CFLAGS $CAIRO_CFLAGS"
 fi
 
 AC_SUBST(gui_sources)
@@ -424,6 +439,8 @@
 AC_SUBST(CLIENT_LDFLAGS)
 AC_SUBST(SOUND_CFLAGS)
 AC_SUBST(SOUND_LIBS)
+AC_SUBST(CAIRO_LIBS)
+AC_SUBST(CAIRO_CFLAGS)
 AC_SUBST(VERSION_WITHOUT_LABEL)
 AC_SUBST(VERSION_LABEL)
 AM_CONDITIONAL(ESD, test "x$ESD" = "xyes")
Index: client/Makefile.am
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/Makefile.am,v
retrieving revision 1.61
diff -u -r1.61 Makefile.am
--- client/Makefile.am  24 Sep 2004 15:33:31 -0000      1.61
+++ client/Makefile.am  29 Jan 2005 05:05:29 -0000
@@ -138,7 +138,7 @@
 
 bin_PROGRAMS = civclient
 
-AM_CPPFLAGS = -I$(top_srcdir)/utility -I$(srcdir)/include 
-I$(top_srcdir)/common -I$(top_srcdir)/common/aicore -I../intl 
-I$(srcdir)/agents @SOUND_CFLAGS@
+AM_CPPFLAGS = -I$(top_srcdir)/utility -I$(srcdir)/include 
-I$(top_srcdir)/common -I$(top_srcdir)/common/aicore -I../intl 
-I$(srcdir)/agents @SOUND_CFLAGS@ @CAIRO_CFLAGS@
 
 ## Above, note -I../intl instead of -I$(top_srdir/intl) is deliberate.
 
@@ -201,7 +201,7 @@
                        @gui_sources@/libguiclient.a
 civclient_DEPENDENCIES = $(fc_civclient_libs)
 civclient_LDADD        = $(fc_civclient_libs) $(fc_civclient_libs) \
-       @INTLLIBS@ @CLIENT_LIBS@ @SOUND_LIBS@
+       @INTLLIBS@ @CLIENT_LIBS@ @SOUND_LIBS@ @CAIRO_LIBS@
 desktopfiledir = $(prefix)/share/applications
 desktopfile_DATA = \
        freeciv.desktop
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.171
diff -u -r1.171 mapview_common.c
--- client/mapview_common.c     5 Jan 2005 23:24:24 -0000       1.171
+++ client/mapview_common.c     29 Jan 2005 05:05:30 -0000
@@ -428,6 +428,7 @@
      * rectangle) is copied.  Then the remaining areas (two rectangles)
      * are updated through update_map_canvas. */
     struct canvas *target = mapview_canvas.tmp_store;
+    struct canvas *source = mapview_canvas.store;
 
     if (old_gui_x0 < gui_x0) {
       update_x0 = MAX(old_gui_x0 + width, gui_x0);
@@ -445,11 +446,15 @@
     }
 
     dirty_all();
-    canvas_copy(target, mapview_canvas.store,
-               common_x0 - old_gui_x0,
-               common_y0 - old_gui_y0,
-               common_x0 - gui_x0, common_y0 - gui_y0,
-               common_x1 - common_x0, common_y1 - common_y0);
+
+    cairo_set_operator(target->cr, CAIRO_OPERATOR_SRC);
+    cairo_translate(target->cr, -dx, -dy);
+    cairo_show_surface(target->cr, source->surf, width, height);
+    cairo_identity_matrix(target->cr);
+    if (cairo_status(target->cr) != CAIRO_STATUS_SUCCESS) {
+      freelog(LOG_NORMAL, "Cairo error %s!",
+             cairo_status_string(target->cr));
+    }
     mapview_canvas.tmp_store = mapview_canvas.store;
     mapview_canvas.store = target;
 
@@ -522,7 +527,7 @@
     } while (mytime < timing_sec);
 
     mytime = read_timer_seconds(anim_timer);
-    freelog(LOG_DEBUG, "Got %d frames in %f seconds: %f FPS.",
+    freelog(LOG_NORMAL, "Got %d frames in %f seconds: %f FPS.",
            frames, mytime, (double)frames / mytime);
   } else {
     base_set_mapview_origin(gui_x0, gui_y0);
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.85
diff -u -r1.85 mapview_common.h
--- client/mapview_common.h     25 Dec 2004 20:38:14 -0000      1.85
+++ client/mapview_common.h     29 Jan 2005 05:05:30 -0000
@@ -14,6 +14,8 @@
 #ifndef FC__MAPVIEW_COMMON_H
 #define FC__MAPVIEW_COMMON_H
 
+#include <cairo.h>
+
 #include "shared.h"            /* bool type */
 
 #include "fc_types.h"
@@ -23,7 +25,18 @@
 
 #include "tilespec.h"
 
-struct canvas_store;           /* opaque type, real type is gui-dep */
+struct canvas {
+  cairo_t *cr;
+  cairo_surface_t *surf;
+  int width, height;
+  struct gui_canvas *gui;
+};
+
+struct Sprite {
+  cairo_surface_t *pix, *mask;
+  int width, height;
+  struct gui_sprite *gui;
+};
 
 struct mapview_decoration {
   /* For client Area Selection */
Index: client/gui-xaw/citydlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/citydlg.c,v
retrieving revision 1.131
diff -u -r1.131 citydlg.c
--- client/gui-xaw/citydlg.c    22 Jan 2005 19:45:41 -0000      1.131
+++ client/gui-xaw/citydlg.c    29 Jan 2005 05:05:30 -0000
@@ -98,7 +98,8 @@
   Widget storage_label;
   Widget pollution_label;
   Widget sub_form;
-  Widget map_canvas;
+  Widget map_canvas_widget;
+  struct canvas *map_canvas;
   Widget sell_command;
   Widget close_command, rename_command, trade_command, activate_command;
   Widget show_units_command, cityopt_command, cma_command;
@@ -107,10 +108,12 @@
   Widget improvement_viewport, improvement_list;
   Widget support_unit_label;
   Widget *support_unit_pixcomms;
+  struct canvas **support_unit_canvas;
   Widget support_unit_next_command;
   Widget support_unit_prev_command;
   Widget present_unit_label;
   Widget *present_unit_pixcomms;
+  struct canvas **present_unit_canvas;
   Widget present_unit_next_command;
   Widget present_unit_prev_command;
   Widget change_list;
@@ -344,14 +347,16 @@
   struct city_dialog *pdialog;
   
   if((pdialog=get_city_dialog(pcity))) {
-    struct canvas store = {XtWindow(pdialog->map_canvas)};
-
+    canvas_realize_with_pixmap(&pdialog->map_canvas,
+                              XtWindow(pdialog->map_canvas_widget),
+                              get_citydlg_canvas_width(),
+                              get_citydlg_canvas_height());
     city_dialog_update_improvement_list(pdialog);
     city_dialog_update_title(pdialog);
     city_dialog_update_supported_units(pdialog, 0);
     city_dialog_update_present_units(pdialog, 0);
     city_dialog_update_citizens(pdialog);
-    city_dialog_redraw_map(pdialog->pcity, &store);
+    city_dialog_redraw_map(pdialog->pcity, pdialog->map_canvas);
     city_dialog_update_production(pdialog);
     city_dialog_update_output(pdialog);
     city_dialog_update_building(pdialog);
@@ -454,9 +459,12 @@
                                   void *client_data)
 {
   struct city_dialog *pdialog = client_data;
-  struct canvas store = {XtWindow(pdialog->map_canvas)};
   
-  city_dialog_redraw_map(pdialog->pcity, &store);
+  canvas_realize_with_pixmap(&pdialog->map_canvas,
+                            XtWindow(pdialog->map_canvas_widget),
+                            get_citydlg_canvas_width(),
+                            get_citydlg_canvas_height());
+  city_dialog_redraw_map(pdialog->pcity, pdialog->map_canvas);
 }
 
 
@@ -603,7 +611,7 @@
                            NULL);
 
 
-  pdialog->map_canvas=
+  pdialog->map_canvas_widget =
     XtVaCreateManagedWidget("citymapcanvas", 
                            xfwfcanvasWidgetClass,
                            pdialog->sub_form,
@@ -613,6 +621,7 @@
                            XtNwidth, get_citydlg_canvas_width(),
                            XtNheight, get_citydlg_canvas_height(),
                            NULL);
+  pdialog->map_canvas = NULL;
 
 
   pdialog->building_label=
@@ -620,7 +629,7 @@
                            labelWidgetClass,
                            pdialog->sub_form,
                            XtNfromHoriz, 
-                           (XtArgVal)pdialog->map_canvas,
+                           (XtArgVal)pdialog->map_canvas_widget,
                            XtNlabel,
                            concise_city_production
                                ? "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
@@ -633,7 +642,7 @@
                            labelWidgetClass,
                            pdialog->sub_form,
                            XtNfromHoriz, 
-                           (XtArgVal)pdialog->map_canvas,
+                           (XtArgVal)pdialog->map_canvas_widget,
                            XtNfromVert, 
                            pdialog->building_label,
                            XtNlabel, lblbuf,
@@ -664,7 +673,7 @@
                            viewportWidgetClass,
                            pdialog->sub_form,
                            XtNfromHoriz, 
-                           (XtArgVal)pdialog->map_canvas,
+                           (XtArgVal)pdialog->map_canvas_widget,
                            XtNfromVert, 
                            pdialog->change_command,
                            NULL);
@@ -687,7 +696,7 @@
                            XtNfromVert, 
                            pdialog->improvement_viewport,
                            XtNfromHoriz, 
-                           (XtArgVal)pdialog->map_canvas,
+                           (XtArgVal)pdialog->map_canvas_widget,
                            NULL));
 
   pdialog->worklist_command=
@@ -944,6 +953,12 @@
     fc_malloc(pdialog->num_units_shown * sizeof(Widget));
   pdialog->present_unit_pixcomms=
     fc_malloc(pdialog->num_units_shown * sizeof(Widget));
+  pdialog->support_unit_canvas =
+    fc_malloc(pdialog->num_units_shown
+             * sizeof(*pdialog->support_unit_canvas));
+  pdialog->present_unit_canvas =
+    fc_malloc(pdialog->num_units_shown
+             * sizeof(*pdialog->present_unit_canvas));
 
 
   pdialog->citizen_labels[0]=first_citizen;
@@ -960,6 +975,11 @@
                            NULL);
 
 
+  for (i = 0; i < pdialog->num_units_shown; i++) {
+    pdialog->support_unit_canvas[i] = NULL;
+    pdialog->present_unit_canvas[i] = NULL;
+  }
+
   pdialog->support_unit_pixcomms[0]=first_support;
   for(i=1; i<pdialog->num_units_shown; i++) {
     pdialog->support_unit_pixcomms[i]=
@@ -1556,7 +1576,8 @@
 
   if (i >= pdialog->num_citizens_shown && i < pcity->size) {
     i = pdialog->num_citizens_shown - 1;
-    xaw_set_bitmap(pdialog->citizen_labels[i], sprites.right_arrow->pixmap);
+    xaw_set_bitmap(pdialog->citizen_labels[i],
+                  sprites.right_arrow->gui->pixmap);
     XtSetSensitive(pdialog->citizen_labels[i], FALSE);
     XtRemoveAllCallbacks(pdialog->citizen_labels[i], XtNcallback);
     return;
@@ -1668,8 +1689,6 @@
   i = 0; /* number of displayed units */
   j = 0; /* index into list */
   unit_list_iterate(plist, punit) {
-    struct canvas store;
-
     if (j++ < pdialog->support_unit_base) {
       continue;
     }
@@ -1678,15 +1697,16 @@
     }
 
     pixcomm=pdialog->support_unit_pixcomms[i];
-    store.pixmap = XawPixcommPixmap(pixcomm);
+    canvas_realize_with_pixmap(&pdialog->support_unit_canvas[i],
+                              XawPixcommPixmap(pixcomm),
+                              UNIT_TILE_WIDTH, 3 * NORMAL_TILE_HEIGHT / 2);
 
     if(!adj_base && unitid && punit->id!=unitid)
       continue;
 
     XawPixcommClear(pixcomm); /* STG */
-    put_unit(punit, &store, 0, 0);
-    put_unit_pixmap_city_overlays(punit,
-                                 XawPixcommPixmap(pixcomm));
+    put_unit(punit, pdialog->support_unit_canvas[i], 0, 0);
+    put_unit_pixmap_city_overlays(punit, pdialog->support_unit_canvas[i]);
 
     xaw_expose_now(pixcomm);
 
@@ -1728,8 +1748,6 @@
   i = 0; /* number of displayed units */
   j = 0; /* index into list */
   unit_list_iterate(plist, punit) {
-    struct canvas store;
-
     if (j++ < pdialog->present_unit_base) {
       continue;
     }
@@ -1738,13 +1756,15 @@
     }
 
     pixcomm=pdialog->present_unit_pixcomms[i];
-    store.pixmap = XawPixcommPixmap(pixcomm);
+    canvas_realize_with_pixmap(&pdialog->present_unit_canvas[i],
+                              XawPixcommPixmap(pixcomm),
+                              UNIT_TILE_WIDTH, 3 * NORMAL_TILE_HEIGHT / 2);
 
     if(!adj_base && unitid && punit->id!=unitid)
       continue;
 
     XawPixcommClear(pixcomm); /* STG */
-    put_unit(punit, &store, 0, 0);
+    put_unit(punit, pdialog->present_unit_canvas[i], 0, 0);
 
     xaw_expose_now(pixcomm);
 
@@ -1826,7 +1846,7 @@
   struct city *pcity = NULL;
 
   dialog_list_iterate(dialog_list, pdialog) {
-    if (pdialog->map_canvas == w) {
+    if (pdialog->map_canvas_widget == w) {
       pcity = pdialog->pcity;
       break;
     }
Index: client/gui-xaw/dialogs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/dialogs.c,v
retrieving revision 1.109
diff -u -r1.109 dialogs.c
--- client/gui-xaw/dialogs.c    22 Jan 2005 19:45:41 -0000      1.109
+++ client/gui-xaw/dialogs.c    29 Jan 2005 05:05:31 -0000
@@ -106,7 +106,7 @@
 static Widget unit_select_form;
 static Widget unit_select_commands[MAX_SELECT_UNITS];
 static Widget unit_select_labels[MAX_SELECT_UNITS];
-static Pixmap unit_select_pixmaps[MAX_SELECT_UNITS];
+static struct canvas *unit_select_pixmaps[MAX_SELECT_UNITS];
 static int unit_select_ids[MAX_SELECT_UNITS];
 static int unit_select_no;
 
@@ -1456,7 +1456,7 @@
     struct unit *punit = unit_list[i];
     struct unit_type *punittemp=unit_type(punit);
     struct city *pcity;
-    struct canvas store;
+    Pixmap p;
     
     if(!(i%r))  {
       nargs=0;
@@ -1476,17 +1476,20 @@
            pcity ? pcity->name : "",
            unit_activity_text(punit));
 
-    unit_select_pixmaps[i]=XCreatePixmap(display, XtWindow(map_canvas), 
+    p = XCreatePixmap(display, XtWindow(map_canvas), 
                                         UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT,
                                         display_depth);
+    unit_select_pixmaps[i]
+      = canvas_create_with_pixmap(p,
+                                 UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
 
-    XFillRectangle(display, unit_select_pixmaps[i], fill_bg_gc,
+    XFillRectangle(display, unit_select_pixmaps[i]->gui->pixmap, fill_bg_gc,
                   0, 0, UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
-    store.pixmap = unit_select_pixmaps[i];
-    put_unit(punit, &store, 0, 0);
+    put_unit(punit, unit_select_pixmaps[i], 0, 0);
 
     nargs=0;
-    XtSetArg(args[nargs], XtNbitmap, (XtArgVal)unit_select_pixmaps[i]);nargs++;
+    XtSetArg(args[nargs], XtNbitmap,
+            (XtArgVal)unit_select_pixmaps[i]->gui->pixmap);nargs++;
     XtSetArg(args[nargs], XtNsensitive, 
              can_unit_do_activity(punit, ACTIVITY_IDLE));nargs++;
     if(i%r)  {
Index: client/gui-xaw/graphics.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/graphics.c,v
retrieving revision 1.54
diff -u -r1.54 graphics.c
--- client/gui-xaw/graphics.c   1 Dec 2004 18:56:53 -0000       1.54
+++ client/gui-xaw/graphics.c   29 Jan 2005 05:05:31 -0000
@@ -24,6 +24,7 @@
 #include <X11/Xlib.h>
 #include <X11/Intrinsic.h>
 
+#include <cairo-xlib.h>
 #include <png.h>
 
 #include "fcintl.h"
@@ -119,7 +120,7 @@
 
   w = XmbTextEscapement(main_font_set, motto, strlen(motto));
   XSetForeground(display, font_gc, face.pixel);
-  XmbDrawString(display, intro_gfx_sprite->pixmap,
+  XmbDrawString(display, intro_gfx_sprite->gui->pixmap,
              main_font_set, font_gc, 
              tot/2-w/2, y, 
              motto, strlen(motto));
@@ -134,12 +135,12 @@
 
   w = XmbTextEscapement(main_font_set, word_version(), strlen(word_version()));
   XSetForeground(display, font_gc, colors_standard[COLOR_STD_BLACK]);
-  XmbDrawString(display, radar_gfx_sprite->pixmap,
+  XmbDrawString(display, radar_gfx_sprite->gui->pixmap,
              main_font_set, font_gc, 
              (tot/2-w/2)+1, y+1, 
              word_version(), strlen(word_version()));
   XSetForeground(display, font_gc, colors_standard[COLOR_STD_WHITE]);
-  XmbDrawString(display, radar_gfx_sprite->pixmap,
+  XmbDrawString(display, radar_gfx_sprite->gui->pixmap,
              main_font_set, font_gc, 
              tot/2-w/2, y, 
              word_version(), strlen(word_version()));
@@ -151,11 +152,11 @@
              PATCH_VERSION, VERSION_LABEL);
   w = XmbTextEscapement(main_font_set, s, strlen(s));
   XSetForeground(display, font_gc, colors_standard[COLOR_STD_BLACK]);
-  XmbDrawString(display, radar_gfx_sprite->pixmap,
+  XmbDrawString(display, radar_gfx_sprite->gui->pixmap,
              main_font_set, font_gc, 
              (tot/2-w/2)+1, y+1, s, strlen(s));
   XSetForeground(display, font_gc, colors_standard[COLOR_STD_WHITE]);
-  XmbDrawString(display, radar_gfx_sprite->pixmap,
+  XmbDrawString(display, radar_gfx_sprite->gui->pixmap,
              main_font_set, font_gc, 
              tot/2-w/2, y, s, strlen(s));
 
@@ -183,14 +184,14 @@
 
   mypixmap = XCreatePixmap(display, root_window,
                           width, height, display_depth);
-  XCopyArea(display, source->pixmap, mypixmap, civ_gc, 
+  XCopyArea(display, source->gui->pixmap, mypixmap, civ_gc, 
            x, y, width, height, 0, 0);
 
-  if (source->has_mask) {
+  if (source->mask) {
     mymask = XCreatePixmap(display, root_window, width, height, 1);
 
     plane_gc = XCreateGC(display, mymask, 0, NULL);
-    XCopyArea(display, source->mask, mymask, plane_gc, 
+    XCopyArea(display, source->gui->mask, mymask, plane_gc, 
              x, y, width, height, 0, 0);
     XFreeGC(display, plane_gc);
 
@@ -200,7 +201,7 @@
       values.function = GXand;
 
       plane_gc = XCreateGC(display, mymask, GCFunction, &values);
-      XCopyArea(display, mask->mask, mymask, plane_gc,
+      XCopyArea(display, mask->gui->mask, mymask, plane_gc,
                x - mask_offset_x, y - mask_offset_y, width, height, 0, 0);
       XFreeGC(display, plane_gc);
     }
@@ -210,7 +211,7 @@
     mymask = XCreatePixmap(display, root_window, width, height, 1);
 
     plane_gc = XCreateGC(display, mymask, 0, NULL);
-    XCopyArea(display, source->mask, mymask, plane_gc, 
+    XCopyArea(display, source->gui->mask, mymask, plane_gc, 
              x, y, width, height, 0, 0);
     XFreeGC(display, plane_gc);
     return ctor_sprite_mask(mypixmap, mymask, width, height);
@@ -305,12 +306,17 @@
 ***************************************************************************/
 static struct Sprite *ctor_sprite(Pixmap mypixmap, int width, int height)
 {
-  struct Sprite *mysprite=fc_malloc(sizeof(struct Sprite));
-  mysprite->pixmap=mypixmap;
-  mysprite->width=width;
-  mysprite->height=height;
-  mysprite->pcolorarray = NULL;
-  mysprite->has_mask=0;
+  struct Sprite *mysprite=fc_malloc(sizeof(*mysprite));
+  Colormap cmap = DefaultColormap(display, screen_number);
+
+  mysprite->pix = cairo_xlib_surface_create(display, mypixmap, NULL,
+                                           CAIRO_FORMAT_RGB24, cmap);
+  mysprite->mask = NULL;
+  mysprite->width = width;
+  mysprite->height = height;
+  mysprite->gui = fc_malloc(sizeof(*mysprite->gui));
+  mysprite->gui->pixmap = mypixmap;
+
   return mysprite;
 }
 
@@ -320,14 +326,12 @@
 static struct Sprite *ctor_sprite_mask(Pixmap mypixmap, Pixmap mask, 
                                       int width, int height)
 {
-  struct Sprite *mysprite=fc_malloc(sizeof(struct Sprite));
-  mysprite->pixmap=mypixmap;
-  mysprite->mask=mask;
-
-  mysprite->width=width;
-  mysprite->height=height;
-  mysprite->pcolorarray = NULL;
-  mysprite->has_mask=1;
+  struct Sprite *mysprite = ctor_sprite(mypixmap, width, height);
+  Colormap cmap = DefaultColormap(display, screen_number);
+  
+  mysprite->mask = cairo_xlib_surface_create(display, mask, NULL,
+                                            CAIRO_FORMAT_A1, cmap);
+  mysprite->gui->mask = mask;
   return mysprite;
 }
 
@@ -382,9 +386,10 @@
   png_uint_32 stride;
   unsigned long *pcolorarray;
   bool *ptransarray;
-  struct Sprite *mysprite;
   XImage *xi;
-  int has_mask;
+  bool has_mask;
+  Pixmap pixmap, mask;
+  struct Sprite *sprite;
 
   fp = fopen(filename, "rb");
   if (!fp) {
@@ -480,8 +485,6 @@
     png_destroy_read_struct(&pngp, &infop, NULL);
   }
 
-  mysprite = fc_malloc(sizeof(*mysprite));
-
 
   xi = XCreateImage(display, DefaultVisual(display, screen_number),
                    display_depth, ZPixmap, 0, NULL, width, height, 32, 0);
@@ -494,7 +497,7 @@
     }
     pb += stride;
   }
-  mysprite->pixmap = image2pixmap(xi);
+  pixmap = image2pixmap(xi);
   XDestroyImage(xi);
 
   if (has_mask) {
@@ -511,21 +514,20 @@
       }
       pb += stride;
     }
-    mysprite->mask = image2pixmap(xm);
+    mask = image2pixmap(xm);
     XDestroyImage(xm);
-  }
 
-  mysprite->has_mask = has_mask;
-  mysprite->width = width;
-  mysprite->height = height;
-  mysprite->pcolorarray = pcolorarray;
-  mysprite->ncols = npalette;
+    sprite = ctor_sprite_mask(pixmap, mask, width, height);
+  } else {
+    sprite = ctor_sprite(pixmap, width, height);
+  }
 
   if (has_mask) {
     free(ptransarray);
   }
   free(buf);
-  return mysprite;
+
+  return sprite;
 }
 
 /***************************************************************************
@@ -533,15 +535,13 @@
 ***************************************************************************/
 void free_sprite(struct Sprite *s)
 {
-  XFreePixmap(display, s->pixmap);
-  if (s->has_mask) {
-    XFreePixmap(display, s->mask);
-  }
-  if (s->pcolorarray) {
-    free_colors(s->pcolorarray, s->ncols);
-    free(s->pcolorarray);
-    s->pcolorarray = NULL;
+  XFreePixmap(display, s->gui->pixmap);
+  cairo_surface_destroy(s->pix);
+  if (s->mask) {
+    XFreePixmap(display, s->gui->mask);
+    cairo_surface_destroy(s->mask);
   }
+  free(s->gui);
   free(s);
 }
 
@@ -573,8 +573,10 @@
     struct Sprite *flag=get_nation_by_plr(game.player_ptr)->flag_sprite;
 
     XSetClipOrigin(display, civ_gc, 0,0);
-    XSetClipMask(display, civ_gc, flag->mask);
-    XCopyArea(display, flag->pixmap, pm, civ_gc, 0,0, 
+    if (flag->mask) {
+      XSetClipMask(display, civ_gc, flag->gui->mask);
+    }
+    XCopyArea(display, flag->gui->pixmap, pm, civ_gc, 0,0, 
              flag->width,flag->height, 0,0);
     XSetClipMask(display, civ_gc, None);
   }
@@ -584,8 +586,10 @@
     struct Sprite *s=get_unit_type(i)->sprite;
 
     XSetClipOrigin(display,civ_gc,0,0);
-    XSetClipMask(display,civ_gc,s->mask);
-    XCopyArea(display, s->pixmap, pm, civ_gc,
+    if (s->mask) {
+      XSetClipMask(display, civ_gc, s->gui->mask);
+    }
+    XCopyArea(display, s->gui->pixmap, pm, civ_gc,
              0,0, s->width,s->height, 0,0 );
     XSetClipMask(display,civ_gc,None);
   }
Index: client/gui-xaw/graphics.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/graphics.h,v
retrieving revision 1.10
diff -u -r1.10 graphics.h
--- client/gui-xaw/graphics.h   8 Mar 2004 07:20:50 -0000       1.10
+++ client/gui-xaw/graphics.h   29 Jan 2005 05:05:31 -0000
@@ -17,14 +17,13 @@
 
 #include "graphics_g.h"
 
-struct Sprite {
-  Pixmap pixmap, mask;
-  int width, height, ncols;
-  unsigned long *pcolorarray;
-  int has_mask;
+struct gui_sprite {
+  Pixmap pixmap;
+  Pixmap mask;
 };
 
-struct canvas {
+struct gui_canvas {
+  bool owns_pixmap;
   Pixmap pixmap;
 };
 
Index: client/gui-xaw/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/gui_main.c,v
retrieving revision 1.99
diff -u -r1.99 gui_main.c
--- client/gui-xaw/gui_main.c   1 Dec 2004 22:15:23 -0000       1.99
+++ client/gui-xaw/gui_main.c   29 Jan 2005 05:05:31 -0000
@@ -196,7 +196,9 @@
 Widget bulb_label, sun_label, flake_label, government_label, timeout_label;
 Widget unit_info_label;
 Widget unit_pix_canvas;
+struct canvas *unit_pix_canvas_canvas;
 Widget unit_below_canvas[MAX_NUM_UNITS_BELOW];
+struct canvas *unit_below_canvas_canvas[MAX_NUM_UNITS_BELOW];
 Widget main_vpane;
 Pixmap unit_below_pixmap[MAX_NUM_UNITS_BELOW];
 Widget more_arrow_label;
@@ -446,7 +448,7 @@
     struct Sprite *s = i < 5 ? sprites.tax_science : sprites.tax_gold;
 
     XtVaSetValues(econ_label[i], XtNbitmap,
-                 s->pixmap, NULL);
+                 s->gui->pixmap, NULL);
     XtAddCallback(econ_label[i], XtNcallback, taxrates_callback,
                  INT_TO_XTPOINTER(i));
   }
@@ -854,20 +856,23 @@
 void set_unit_icon(int idx, struct unit *punit)
 {
   Widget w;
+  struct canvas **canvas;
   
   assert(idx>=-1 && idx<num_units_below);
   if (idx == -1) {
     w = unit_pix_canvas;
+    canvas = &unit_pix_canvas_canvas;
   } else {
     w = unit_below_canvas[idx];
     unit_ids[idx] = punit ? punit->id : 0;
+    canvas = &unit_below_canvas_canvas[idx];
   }
-  
+
   XawPixcommClear(w);
   if (punit) {
-    struct canvas store = {XawPixcommPixmap(w)};
-
-    put_unit(punit, &store, 0, 0);
+    canvas_realize_with_pixmap(canvas, XawPixcommPixmap(w),
+                              UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
+    put_unit(punit, *canvas, 0, 0);
     xaw_expose_now(w);
   }
 }
@@ -882,7 +887,7 @@
   static bool showing = FALSE;
 
   if (onoff && !showing) {
-    xaw_set_bitmap(more_arrow_label, sprites.right_arrow->pixmap);
+    xaw_set_bitmap(more_arrow_label, sprites.right_arrow->gui->pixmap);
     showing = TRUE;
   }
   else if(!onoff && showing) {
Index: client/gui-xaw/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/mapview.c,v
retrieving revision 1.186
diff -u -r1.186 mapview.c
--- client/gui-xaw/mapview.c    1 Dec 2004 18:56:53 -0000       1.186
+++ client/gui-xaw/mapview.c    29 Jan 2005 05:05:31 -0000
@@ -23,12 +23,15 @@
 #include <X11/StringDefs.h>
 #include <X11/Xaw/Scrollbar.h>
 
+#include <cairo-xlib.h>
+
 #include "canvas.h"
 #include "pixcomm.h"
 
 #include "fcintl.h"
 #include "game.h"
 #include "government.h"                /* government_graphic() */
+#include "log.h"
 #include "map.h"
 #include "mem.h"
 #include "player.h"
@@ -53,7 +56,7 @@
 
 #include "mapview.h"
 
-#define map_canvas_store (mapview_canvas.store->pixmap)
+#define map_canvas_store (mapview_canvas.store->gui->pixmap)
 
 static void pixmap_put_overlay_tile(Pixmap pixmap, int x, int y,
                                    struct Sprite *ssprite);
@@ -82,16 +85,47 @@
   XtVaSetValues(bottom_form, XtNwidth, w, NULL);
 }
 
+struct canvas *canvas_create_with_pixmap(Pixmap pixmap, int w, int h)
+{
+  struct canvas *result = fc_malloc(sizeof(*result));
+
+  XSync(display, False);
+  freelog(LOG_NORMAL, "Create with pixmap");
+  XSync(display, False);
+
+  result->gui = fc_malloc(sizeof(*result->gui));
+  result->gui->pixmap = pixmap;
+  result->gui->owns_pixmap = TRUE; /* Default to owning. */
+
+  result->width = w;
+  result->height = h;
+
+  result->cr = cairo_create();
+  cairo_set_target_drawable(result->cr, display, pixmap);
+  result->surf = cairo_current_target_surface(result->cr);
+
+  return result;
+}
+
+void canvas_realize_with_pixmap(struct canvas **canvas, Pixmap pixmap,
+                               int width, int height)
+{
+  if (!*canvas) {
+    *canvas = canvas_create_with_pixmap(pixmap, width, height);
+    (*canvas)->gui->owns_pixmap = FALSE;
+  }
+}
+
 /**************************************************************************
 ...
 **************************************************************************/
 struct canvas *canvas_create(int width, int height)
 {
   struct canvas *result = fc_malloc(sizeof(*result));
+  Pixmap pixmap;
 
-  result->pixmap =
-      XCreatePixmap(display, root_window, width, height, display_depth);
-  return result;
+  pixmap = XCreatePixmap(display, root_window, width, height, display_depth);
+  return canvas_create_with_pixmap(pixmap, width, height);
 }
 
 /**************************************************************************
@@ -99,7 +133,13 @@
 **************************************************************************/
 void canvas_free(struct canvas *store)
 {
-  XFreePixmap(display, store->pixmap);
+  if (store->gui->owns_pixmap) {
+    XFreePixmap(display, store->gui->pixmap);
+  }
+  if (store->cr) {
+    cairo_destroy(store->cr);
+  }
+  free(store->gui);
   free(store);
 }
 
@@ -108,11 +148,20 @@
 ****************************************************************************/
 struct canvas *get_overview_window(void)
 {
-  static struct canvas store;
+  static struct canvas *canvas;
+  Pixmap pixmap = XtWindow(overview_canvas);
 
-  store.pixmap = XtWindow(overview_canvas);
+  if (!canvas) {
+    canvas = fc_malloc(sizeof(*canvas));
+    canvas->gui = fc_malloc(sizeof(*canvas->gui));
+    canvas->gui->owns_pixmap = FALSE;
+    canvas->cr = cairo_create();
+  }
+  cairo_set_target_drawable(canvas->cr, display, pixmap);
+  canvas->surf = cairo_current_target_surface(canvas->cr);
+  canvas->gui->pixmap = pixmap;
 
-  return &store;
+  return canvas;
 }
 
 /**************************************************************************
@@ -176,13 +225,13 @@
 
   d=0;
   for(;d<(game.player_ptr->economic.luxury)/10;d++)
-    xaw_set_bitmap(econ_label[d], sprites.tax_luxury->pixmap);
+    xaw_set_bitmap(econ_label[d], sprites.tax_luxury->gui->pixmap);
  
   
for(;d<(game.player_ptr->economic.science+game.player_ptr->economic.luxury)/10;d++)
-    xaw_set_bitmap(econ_label[d], sprites.tax_science->pixmap);
+    xaw_set_bitmap(econ_label[d], sprites.tax_science->gui->pixmap);
  
    for(;d<10;d++)
-     xaw_set_bitmap(econ_label[d], sprites.tax_gold->pixmap);
+     xaw_set_bitmap(econ_label[d], sprites.tax_gold->gui->pixmap);
  
   update_timeout_label();
 }
@@ -241,7 +290,7 @@
 **************************************************************************/
 Pixmap get_thumb_pixmap(int onoff)
 {
-  return sprites.treaty_thumb[BOOL_VAL(onoff)]->pixmap;
+  return sprites.treaty_thumb[BOOL_VAL(onoff)]->gui->pixmap;
 }
 
 /**************************************************************************
@@ -250,7 +299,7 @@
 Pixmap get_citizen_pixmap(struct citizen_type type, int cnum,
                          struct city *pcity)
 {
-  return get_citizen_sprite(type, cnum, pcity)->pixmap;
+  return get_citizen_sprite(type, cnum, pcity)->gui->pixmap;
 }
 
 
@@ -265,9 +314,9 @@
   sol = CLIP(0, sol, NUM_TILES_PROGRESS-1);
   flake = CLIP(0, flake, NUM_TILES_PROGRESS-1);
 
-  xaw_set_bitmap(bulb_label, sprites.bulb[bulb]->pixmap);
-  xaw_set_bitmap(sun_label, sprites.warming[sol]->pixmap);
-  xaw_set_bitmap(flake_label, sprites.cooling[flake]->pixmap);
+  xaw_set_bitmap(bulb_label, sprites.bulb[bulb]->gui->pixmap);
+  xaw_set_bitmap(sun_label, sprites.warming[sol]->gui->pixmap);
+  xaw_set_bitmap(flake_label, sprites.cooling[flake]->gui->pixmap);
 
   if (game.government_count==0) {
     /* HACK: the UNHAPPY citizen is used for the government
@@ -278,7 +327,7 @@
   } else {
     gov_sprite = get_government(gov)->sprite;
   }
-  xaw_set_bitmap(government_label, gov_sprite->pixmap);
+  xaw_set_bitmap(government_label, gov_sprite->gui->pixmap);
 }
 
 /**************************************************************************
@@ -291,7 +340,8 @@
   
   if (!can_client_change_view()) {
     if (radar_gfx_sprite) {
-      XCopyArea(display, radar_gfx_sprite->pixmap, XtWindow(overview_canvas),
+      XCopyArea(display, radar_gfx_sprite->gui->pixmap,
+               XtWindow(overview_canvas),
                  civ_gc,
                  event->xexpose.x, event->xexpose.y,
                  event->xexpose.width, event->xexpose.height,
@@ -312,7 +362,8 @@
                 int src_x, int src_y, int dest_x, int dest_y,
                 int width, int height)
 {
-  XCopyArea(display, src->pixmap, dest->pixmap, civ_gc, src_x, src_y, width,
+  XCopyArea(display, src->gui->pixmap, dest->gui->pixmap,
+           civ_gc, src_x, src_y, width,
            height, dest_x, dest_y);
 }
 
@@ -339,7 +390,7 @@
        XFreePixmap(display, scaled_intro_pixmap);
       }
 
-      scaled_intro_pixmap=x_scale_pixmap(intro_gfx_sprite->pixmap,
+      scaled_intro_pixmap=x_scale_pixmap(intro_gfx_sprite->gui->pixmap,
                                         intro_gfx_sprite->width,
                                         intro_gfx_sprite->height, 
                                         width, height, root_window);
@@ -379,18 +430,18 @@
                              int offset_x, int offset_y,
                              int width, int height)
 {
-  if (sprite->has_mask) {
+  if (sprite->mask) {
     XSetClipOrigin(display, civ_gc, canvas_x, canvas_y);
-    XSetClipMask(display, civ_gc, sprite->mask);
+    XSetClipMask(display, civ_gc, sprite->gui->mask);
   }
 
-  XCopyArea(display, sprite->pixmap, pixmap, 
+  XCopyArea(display, sprite->gui->pixmap, pixmap, 
            civ_gc,
            offset_x, offset_y,
            width, height, 
            canvas_x, canvas_y);
 
-  if (sprite->has_mask) {
+  if (sprite->mask) {
     XSetClipMask(display, civ_gc, None);
   }
 }
@@ -403,7 +454,7 @@
                       struct Sprite *sprite,
                       int offset_x, int offset_y, int width, int height)
 {
-  pixmap_put_sprite(pcanvas->pixmap, canvas_x, canvas_y,
+  pixmap_put_sprite(pcanvas->gui->pixmap, canvas_x, canvas_y,
                    sprite, offset_x, offset_y, width, height);
 }
 
@@ -442,7 +493,7 @@
                          int canvas_x, int canvas_y, int width, int height)
 {
   XSetForeground(display, fill_bg_gc, colors_standard[color]);
-  XFillRectangle(display, pcanvas->pixmap, fill_bg_gc,
+  XFillRectangle(display, pcanvas->gui->pixmap, fill_bg_gc,
                 canvas_x, canvas_y, width, height);
 }
 
@@ -453,16 +504,16 @@
                             struct Sprite *psprite, enum color_std color,
                             int canvas_x, int canvas_y)
 {
-  if (psprite->has_mask) {
+  if (psprite->mask) {
     XSetClipOrigin(display, fill_tile_gc, canvas_x, canvas_y);
-    XSetClipMask(display, fill_tile_gc, psprite->mask);
+    XSetClipMask(display, fill_tile_gc, psprite->gui->mask);
   }
   XSetForeground(display, fill_tile_gc, colors_standard[color]);
 
-  XFillRectangle(display, pcanvas->pixmap, fill_tile_gc,
+  XFillRectangle(display, pcanvas->gui->pixmap, fill_tile_gc,
                 canvas_x, canvas_y, psprite->width, psprite->height);
 
-  if (psprite->has_mask) {
+  if (psprite->mask) {
     XSetClipMask(display, fill_tile_gc, None);
   }
 }
@@ -473,18 +524,18 @@
 void canvas_fog_sprite_area(struct canvas *pcanvas, struct Sprite *psprite,
                            int canvas_x, int canvas_y)
 {
-  if (psprite->has_mask) {
+  if (psprite->mask) {
     XSetClipOrigin(display, fill_tile_gc, canvas_x, canvas_y);
-    XSetClipMask(display, fill_tile_gc, psprite->mask);
+    XSetClipMask(display, fill_tile_gc, psprite->gui->mask);
   }
   XSetStipple(display, fill_tile_gc, gray50);
   XSetTSOrigin(display, fill_tile_gc, canvas_x, canvas_y);
   XSetForeground(display, fill_tile_gc, colors_standard[COLOR_STD_BLACK]);
 
-  XFillRectangle(display, pcanvas->pixmap, fill_tile_gc,
+  XFillRectangle(display, pcanvas->gui->pixmap, fill_tile_gc,
                 canvas_x, canvas_y, psprite->width, psprite->height);
 
-  if (psprite->has_mask) {
+  if (psprite->mask) {
     XSetClipMask(display, fill_tile_gc, None);
   }
 }
@@ -513,7 +564,7 @@
   }
 
   XSetForeground(display, gc, colors_standard[color]);
-  XDrawLine(display, pcanvas->pixmap, gc,
+  XDrawLine(display, pcanvas->gui->pixmap, gc,
            start_x, start_y, start_x + dx, start_y + dy);
 }
 
@@ -677,11 +728,11 @@
   y -= XExtentsOfFontSet(fontset)->max_logical_extent.y;
 
   XSetForeground(display, font_gc, colors_standard[shadow]);
-  XmbDrawString(display, pcanvas->pixmap, fontset, font_gc,
+  XmbDrawString(display, pcanvas->gui->pixmap, fontset, font_gc,
       x + 1, y + 1, string, len);
 
   XSetForeground(display, font_gc, colors_standard[foreground]);
-  XmbDrawString(display, pcanvas->pixmap, fontset, font_gc,
+  XmbDrawString(display, pcanvas->gui->pixmap, fontset, font_gc,
       x, y, string, len);
 }
 
@@ -756,16 +807,15 @@
   the proper way to do this is probably something like what Civ II does.
   (One food/shield/mask drawn N times, possibly one top of itself. -- SKi 
 **************************************************************************/
-void put_unit_pixmap_city_overlays(struct unit *punit, Pixmap pm)
+void put_unit_pixmap_city_overlays(struct unit *punit, struct canvas *canvas)
 {
-  struct canvas store = {pm};
- 
   /* wipe the slate clean */
   XSetForeground(display, fill_bg_gc, colors_standard[COLOR_STD_WHITE]);
-  XFillRectangle(display, pm, fill_bg_gc, 0, NORMAL_TILE_WIDTH, 
+  XFillRectangle(display, canvas->gui->pixmap, fill_bg_gc, 0,
+                NORMAL_TILE_WIDTH, 
                 NORMAL_TILE_HEIGHT, NORMAL_TILE_HEIGHT+SMALL_TILE_HEIGHT);
 
-  put_unit_city_overlays(punit, &store, 0, NORMAL_TILE_HEIGHT);
+  put_unit_city_overlays(punit, canvas, 0, NORMAL_TILE_HEIGHT);
 }
 
 /**************************************************************************
@@ -812,7 +862,7 @@
 
   XSetTSOrigin(display, fill_tile_gc, canvas_x, canvas_y);
   XSetForeground(display, fill_tile_gc, colors_standard[color]);
-  XFillRectangle(display, pcanvas->pixmap, fill_tile_gc,
+  XFillRectangle(display, pcanvas->gui->pixmap, fill_tile_gc,
                 canvas_x, canvas_y,
                 NORMAL_TILE_WIDTH, NORMAL_TILE_HEIGHT);
 }
Index: client/gui-xaw/mapview.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/mapview.h,v
retrieving revision 1.24
diff -u -r1.24 mapview.h
--- client/gui-xaw/mapview.h    10 Jul 2004 18:48:19 -0000      1.24
+++ client/gui-xaw/mapview.h    29 Jan 2005 05:05:31 -0000
@@ -28,8 +28,11 @@
 Pixmap get_citizen_pixmap(struct citizen_type type, int cnum,
                          struct city *pcity);
 
-void put_unit_pixmap_city_overlays(struct unit *punit, Pixmap pm);
+void put_unit_pixmap_city_overlays(struct unit *punit, struct canvas *canvas);
 
+struct canvas *canvas_create_with_pixmap(Pixmap pixmap, int w, int h);
+void canvas_realize_with_pixmap(struct canvas **canvas, Pixmap pixmap,
+                               int width, int height);
 void overview_canvas_expose(Widget w, XEvent *event, Region exposed, 
                            void *client_data);
 void map_canvas_expose(Widget w, XEvent *event, Region exposed, 
Index: client/gui-xaw/spaceshipdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/spaceshipdlg.c,v
retrieving revision 1.24
diff -u -r1.24 spaceshipdlg.c
--- client/gui-xaw/spaceshipdlg.c       22 Jan 2005 19:45:41 -0000      1.24
+++ client/gui-xaw/spaceshipdlg.c       29 Jan 2005 05:05:31 -0000
@@ -290,8 +290,10 @@
              k==1 ? sprites.spaceship.life_support :
                     sprites.spaceship.solar_panels);
     XSetClipOrigin(display, civ_gc, x, y);
-    XSetClipMask(display, civ_gc, sprite->mask);
-    XCopyArea(display, sprite->pixmap, XtWindow(pdialog->image_canvas), 
+    if (sprite->mask) {
+      XSetClipMask(display, civ_gc, sprite->gui->mask);
+    }
+    XCopyArea(display, sprite->gui->pixmap, XtWindow(pdialog->image_canvas), 
              civ_gc, 
              0, 0,
              sprite->width, sprite->height, x, y);
@@ -311,8 +313,10 @@
     sprite = (k==0) ? sprites.spaceship.fuel : sprites.spaceship.propulsion;
 
     XSetClipOrigin(display, civ_gc, x, y);
-    XSetClipMask(display, civ_gc, sprite->mask);
-    XCopyArea(display, sprite->pixmap, XtWindow(pdialog->image_canvas), 
+    if (sprite->mask) {
+      XSetClipMask(display, civ_gc, sprite->gui->mask);
+    }
+    XCopyArea(display, sprite->gui->pixmap, XtWindow(pdialog->image_canvas), 
              civ_gc, 
              0, 0,
              sprite->width, sprite->height, x, y);
@@ -328,8 +332,10 @@
     y = structurals_info[i].y * sprite->height / 4 - sprite->height / 2;
 
     XSetClipOrigin(display, civ_gc, x, y);
-    XSetClipMask(display, civ_gc, sprite->mask);
-    XCopyArea(display, sprite->pixmap, XtWindow(pdialog->image_canvas), 
+    if (sprite->mask) {
+      XSetClipMask(display, civ_gc, sprite->gui->mask);
+    }
+    XCopyArea(display, sprite->gui->pixmap, XtWindow(pdialog->image_canvas), 
              civ_gc, 
              0, 0,
              sprite->width, sprite->height, x, y);

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#12042) cairo for mapview drawing, Jason Short <=