Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2005:
[Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions i
Home

[Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions i

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions in gtk2 client
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 8 Mar 2005 13:57:48 -0800
Reply-to: bugs@xxxxxxxxxxx

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

Here is an updated (though still incomplete, and possibly buggy) patch
for this.  See the screenshot at

  http://bugs.freeciv.org/Ticket/Attachment/92137/58644/citydesc.jpeg

-jason

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.163
diff -u -r1.163 mapview.c
--- client/gui-gtk-2.0/mapview.c        5 Mar 2005 23:43:59 -0000       1.163
+++ client/gui-gtk-2.0/mapview.c        8 Mar 2005 21:57:27 -0000
@@ -461,6 +461,7 @@
   update_map_canvas_visible();
 }
 
+#include <string.h>
 /**************************************************************************
   If necessary, clear the city descriptions out of the buffer.
 **************************************************************************/
@@ -485,10 +486,13 @@
                    struct city *pcity, int *width, int *height)
 {
   if (pcanvas->type == CANVAS_PIXMAP) {
-  static char buffer[512], buffer2[32];
-  PangoRectangle rect, rect2;
+  static char name_buf[512], growth_buf[32], prod_buf[512];
+  PangoRectangle name_rect, growth_rect, prod_rect;
+  int name_x = 0, name_y = 0, growth_x = 0, growth_y = 0;
+  int prod_x = 0, prod_y = 0, bg_w = 0, bg_h = 0;
   enum color_std color;
   int extra_width = 0;
+  bool draw = FALSE;
   static PangoLayout *layout;
 
   if (!layout) {
@@ -497,79 +501,176 @@
 
   *width = *height = 0;
 
+  /* Draw below the city, centered. */
   canvas_x += NORMAL_TILE_WIDTH / 2;
   canvas_y += NORMAL_TILE_HEIGHT;
 
+  /* First position the text. */
   if (draw_city_names) {
-    get_city_mapview_name_and_growth(pcity, buffer, sizeof(buffer),
-                                    buffer2, sizeof(buffer2), &color);
+    int name_h, growth_h;
+
+    draw = TRUE;
+    get_city_mapview_name_and_growth(pcity, name_buf, sizeof(name_buf),
+                                    growth_buf, sizeof(growth_buf), &color);
 
     pango_layout_set_font_description(layout, main_font);
-    if (buffer2[0] != '\0') {
+    if (growth_buf[0] != '\0') {
       /* HACK: put a character's worth of space between the two strings. */
+      PangoRectangle rect;
       pango_layout_set_text(layout, "M", -1);
       pango_layout_get_pixel_extents(layout, &rect, NULL);
       extra_width = rect.width;
     }
-    pango_layout_set_text(layout, buffer, -1);
-    pango_layout_get_pixel_extents(layout, &rect, NULL);
-    rect.width += extra_width;
+    pango_layout_set_text(layout, name_buf, -1);
+    pango_layout_get_pixel_extents(layout, &name_rect, NULL);
+    name_rect.width += extra_width;
+    name_h = name_rect.height;
 
     if (draw_city_growth && pcity->owner == game.player_idx) {
       /* We need to know the size of the growth text before
         drawing anything. */
       pango_layout_set_font_description(layout, city_productions_font);
-      pango_layout_set_text(layout, buffer2, -1);
-      pango_layout_get_pixel_extents(layout, &rect2, NULL);
-
-      /* Now return the layout to its previous state. */
-      pango_layout_set_font_description(layout, main_font);
-      pango_layout_set_text(layout, buffer, -1);
+      pango_layout_set_text(layout, growth_buf, -1);
+      pango_layout_get_pixel_extents(layout, &growth_rect, NULL);
+      growth_h = growth_rect.height - PANGO_ASCENT(growth_rect)
+       + PANGO_ASCENT(name_rect);
     } else {
-      rect2.width = 0;
+      growth_rect.width = 0;
+      growth_rect.height = 0;
+      growth_h = 0;
+    }
+
+    name_x = canvas_x - (name_rect.width + growth_rect.width) / 2;
+    name_y = canvas_y + PANGO_ASCENT(name_rect);
+
+    growth_x = canvas_x - (name_rect.width + growth_rect.width) / 2
+      + name_rect.width;
+    growth_y = canvas_y + PANGO_ASCENT(name_rect);
+
+    /* With some names the growth text may be taller than the name text. */
+    bg_h = MAX(name_h, growth_h);
+    bg_w = name_rect.width + growth_rect.width;
+  }
+
+  if (draw_city_productions && (pcity->owner==game.player_idx)) {
+    if (draw_city_names) {
+      /* Add a 3-pixel separation. */
+      bg_h += 3;
+    }
+
+    draw = TRUE;
+    get_city_mapview_production(pcity, prod_buf, sizeof(prod_buf));
+
+    pango_layout_set_font_description(layout, city_productions_font);
+    pango_layout_set_text(layout, prod_buf, -1);
+
+    pango_layout_get_pixel_extents(layout, &prod_rect, NULL);
+
+    prod_x = canvas_x - prod_rect.width / 2;
+    prod_y = canvas_y + bg_h + PANGO_ASCENT(prod_rect);
+    
+    bg_h += prod_rect.height;
+    bg_w = MAX(bg_w, prod_rect.width);
+  }
+
+  if (draw) {
+    GdkPixbuf *buf;
+    int bg_x, bg_y;
+    int mapview_width, mapview_height;
+
+    /* Set X and Y positioning, after adding on a 3-pixel border. */
+    bg_w += 6;
+    bg_x = canvas_x - bg_w / 2;
+    bg_h += 6;
+    bg_y = canvas_y - 3;
+
+    *width = bg_w;
+    *height = bg_h;
+
+    /* Make sure the rect is within the screen;
+     * otherwise gdkpixbuf will fail. */
+    gdk_window_get_size(pcanvas->v.pixmap,
+                       &mapview_width, &mapview_height);
+    if (bg_x < 0) {
+      bg_w += bg_x;
+      bg_x = 0;
+    }
+    if (bg_y < 0) {
+      bg_h += bg_y;
+      bg_y = 0;
+    }
+    if (bg_x + bg_w > mapview_width) {
+      bg_w = mapview_width - bg_x;
+    }
+    if (bg_y + bg_h > mapview_height) {
+      bg_h = mapview_height - bg_y;
     }
 
+    /* Check to see if we even need to draw anything. */
+    if (bg_w <= 0 || bg_h <= 0) {
+      return;
+    }
+
+    buf = gdk_pixbuf_get_from_drawable(NULL,
+                                      map_canvas_store,
+                                      NULL,
+                                      bg_x, bg_y,
+                                      0, 0,
+                                      bg_w, bg_h);
+    if (buf) {
+      GdkPixbuf *buf2;
+      /* This value is ARGB form; one byte per element. */
+      const guint32 color = 0xFF000000;
+      /* The alpha level.  0 = opaque, 255=transparent */
+      const int alpha = 128;
+
+      buf2 = gdk_pixbuf_composite_color_simple(buf,
+                                              bg_w, bg_h,
+                                              GDK_INTERP_NEAREST,
+                                              alpha, 1024,
+                                              color, color);
+      if (buf2) {
+       gdk_draw_pixbuf(pcanvas->v.pixmap, civ_gc, buf2,
+                       0, 0,
+                       bg_x, bg_y,
+                       bg_w, bg_h,
+                       GDK_RGB_DITHER_NONE, 0, 0);
+       gdk_pixbuf_unref(buf2);
+      }
+      gdk_pixbuf_unref(buf);
+    }
+  }
+
+  /* Now draw the text. */
+  if (draw_city_names) {
+    /* Draw city name. */
+    pango_layout_set_font_description(layout, main_font);
+    pango_layout_set_text(layout, name_buf, -1);
+    gdk_gc_set_foreground(civ_gc, colors_standard[color]);
     gtk_draw_shadowed_string(pcanvas->v.pixmap,
                             toplevel->style->black_gc,
-                            toplevel->style->white_gc,
-                            canvas_x - (rect.width + rect2.width) / 2,
-                            canvas_y + PANGO_ASCENT(rect), layout);
+                            civ_gc,
+                            name_x, name_y, layout);
 
     if (draw_city_growth && pcity->owner == game.player_idx) {
+      /* Draw city growth. */
       pango_layout_set_font_description(layout, city_productions_font);
-      pango_layout_set_text(layout, buffer2, -1);
+      pango_layout_set_text(layout, growth_buf, -1);
       gdk_gc_set_foreground(civ_gc, colors_standard[color]);
       gtk_draw_shadowed_string(pcanvas->v.pixmap,
                               toplevel->style->black_gc,
                               civ_gc,
-                              canvas_x - (rect.width + rect2.width) / 2
-                              + rect.width,
-                              canvas_y + PANGO_ASCENT(rect)
-                              + rect.height / 2 - rect2.height / 2,
-                              layout);
+                              growth_x, growth_y, layout);
     }
-
-    canvas_y += rect.height + 3;
-
-    *width = rect.width + rect2.width;
-    *height += rect.height + 3;
   }
 
-  if (draw_city_productions && (pcity->owner==game.player_idx)) {
-    get_city_mapview_production(pcity, buffer, sizeof(buffer));
-
+  if (draw_city_productions && pcity->owner == game.player_idx) {
     pango_layout_set_font_description(layout, city_productions_font);
-    pango_layout_set_text(layout, buffer, -1);
-
-    pango_layout_get_pixel_extents(layout, &rect, NULL);
+    pango_layout_set_text(layout, prod_buf, -1);
     gtk_draw_shadowed_string(pcanvas->v.pixmap,
                             toplevel->style->black_gc,
                             toplevel->style->white_gc,
-                            canvas_x - rect.width / 2,
-                            canvas_y + PANGO_ASCENT(rect), layout);
-
-    *width = MAX(*width, rect.width);
-    *height += rect.height;
+                            prod_x, prod_y, layout);
   }
   }
 }

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