Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2005:
[Freeciv-Dev] (PR#13518) city dialog scaling
Home

[Freeciv-Dev] (PR#13518) city dialog scaling

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13518) city dialog scaling
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 22 Jul 2005 19:28:57 -0700
Reply-to: bugs@xxxxxxxxxxx

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

This patch does scaling of the city dialog citymap.  A maximum width of
300 pixels is imposed on the dialog - anything wider than this will be
scaled down to fit.

The main problem is that it uses gdkpixbuf canvases, which are poorly
supported.  Some operations aren't supported at all, and the
canvas_put_sprite operation doesn't do clipping which, inconceivably,
causes gdkpixbuf to fail and emit an error.  Perhaps most problematic
canvas_put_sprite converts all sprites into pixbufs which means most
sprites are duplicated.

See http://freeciv.org/~jdorje/scaled.png for a screenshot.

Of course this doesn't scale indefinitely.  In the screenshot the
citymap-radius is changed to 3.  Even here the quality starts to
degrade.  With a larger citymap radius it would become unusable.
However it does work pretty well at making the citydlg smaller with a
regular 96x48 tileset.

-jason

Index: client/gui-gtk-2.0/citydlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/citydlg.c,v
retrieving revision 1.133
diff -p -u -r1.133 citydlg.c
--- client/gui-gtk-2.0/citydlg.c        23 Jul 2005 00:59:33 -0000      1.133
+++ client/gui-gtk-2.0/citydlg.c        23 Jul 2005 02:20:55 -0000
@@ -59,6 +59,9 @@
 
 #include "citydlg.h"
 
+#define CITYMAP_WIDTH MIN(300, canvas_width)
+#define CITYMAP_HEIGHT (CITYMAP_WIDTH * canvas_height / canvas_width)
+
 struct city_dialog;
 
 /* get 'struct dialog_list' and related function */
@@ -104,7 +107,7 @@ struct city_dialog {
   GtkWidget *shell;
   GtkWidget *name_label;
   GtkWidget *citizen_pixmap;
-  GdkPixmap *map_canvas_store;
+  GdkPixbuf *map_canvas_store, *map_canvas_store_unscaled;
   GtkWidget *notebook;
 
   GtkTooltips *tips;
@@ -679,8 +682,8 @@ static void create_and_append_overview_p
   gtk_container_add(GTK_CONTAINER(align), pdialog->overview.map_canvas);
   gtk_widget_add_events(pdialog->overview.map_canvas, GDK_BUTTON_PRESS_MASK);
 
-  pdialog->overview.map_canvas_pixmap =
-       gtk_image_new_from_pixmap(pdialog->map_canvas_store, NULL);
+  pdialog->overview.map_canvas_pixmap
+    = gtk_image_new_from_pixbuf(pdialog->map_canvas_store);
   gtk_container_add(GTK_CONTAINER(pdialog->overview.map_canvas),
                    pdialog->overview.map_canvas_pixmap);
 
@@ -968,8 +971,8 @@ static void create_and_append_happiness_
   gtk_container_add(GTK_CONTAINER(align), pdialog->happiness.map_canvas);
   gtk_widget_add_events(pdialog->happiness.map_canvas, GDK_BUTTON_PRESS_MASK);
 
-  pdialog->happiness.map_canvas_pixmap =
-       gtk_image_new_from_pixmap(pdialog->map_canvas_store, NULL);
+  pdialog->happiness.map_canvas_pixmap
+    = gtk_image_new_from_pixbuf(pdialog->map_canvas_store);
   gtk_container_add(GTK_CONTAINER(pdialog->happiness.map_canvas),
                    pdialog->happiness.map_canvas_pixmap);
   g_signal_connect(pdialog->happiness.map_canvas,
@@ -1165,8 +1168,11 @@ static struct city_dialog *create_city_d
   pdialog->rename_shell = NULL;
   pdialog->happiness.map_canvas = NULL;         /* make sure NULL if spy */
   pdialog->happiness.map_canvas_pixmap = NULL;  /* ditto */
-  pdialog->map_canvas_store = gdk_pixmap_new(root_window, canvas_width,
-                                            canvas_height, -1);
+  pdialog->map_canvas_store = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
+                                            CITYMAP_WIDTH, CITYMAP_HEIGHT);
+  pdialog->map_canvas_store_unscaled
+    = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
+                    canvas_width, canvas_height);
 
 
   pdialog->shell = gtk_dialog_new_with_buttons(pcity->name,
@@ -1446,10 +1452,17 @@ static void city_dialog_update_map(struc
 {
   struct canvas store;
 
-  store.type = CANVAS_PIXMAP;
-  store.v.pixmap = pdialog->map_canvas_store;
+  store.type = CANVAS_PIXBUF;
+  store.v.pixbuf = pdialog->map_canvas_store_unscaled;
 
   city_dialog_redraw_map(pdialog->pcity, &store);
+  gdk_pixbuf_composite(pdialog->map_canvas_store_unscaled,
+                      pdialog->map_canvas_store,
+                      0, 0, CITYMAP_WIDTH, CITYMAP_HEIGHT,
+                      0.0, 0.0,
+                      (double)CITYMAP_WIDTH / (double)canvas_width,
+                      (double)CITYMAP_HEIGHT / (double)canvas_height,
+                      GDK_INTERP_BILINEAR, 255);
 
   /* draw to real window */
   draw_map_canvas(pdialog);
@@ -2328,14 +2341,17 @@ static gboolean button_down_citymap(GtkW
                                    gpointer data)
 {
   struct city_dialog *pdialog = data;
-  int xtile, ytile;
+  int canvas_x, canvas_y, city_x, city_y;
 
   if (!can_client_issue_orders()) {
     return FALSE;
   }
 
-  if (canvas_to_city_pos(&xtile, &ytile, ev->x, ev->y)) {
-    city_toggle_worker(pdialog->pcity, xtile, ytile);
+  canvas_x = ev->x * (double)canvas_width / (double)CITYMAP_WIDTH;
+  canvas_y = ev->y * (double)canvas_height / (double)CITYMAP_HEIGHT;
+
+  if (canvas_to_city_pos(&city_x, &city_y, canvas_x, canvas_y)) {
+    city_toggle_worker(pdialog->pcity, city_x, city_y);
   }
 
   return TRUE;

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#13518) city dialog scaling, Jason Short <=