[Freeciv-Dev] Re: (PR#2708) patch: backing rectangle for city descriptio
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=2708 >
Here is an updated an much-improved patch. See
http://bugs.freeciv.org/Ticket/Attachment/92195/58696/citybar.png
it includes PR#12470. There are only two real issues:
1. It uses sprites.mask.worked to get a 50%-alpha black background.
This is a hack, of course. Instead we should add a new sprite for it.
2. In single-player games the human is always player 0 which has a dark
maroon color. This doesn't show up very well against the transparent
black background. Bright colors show up better.
-jason
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.208
diff -u -r1.208 mapview_common.c
--- client/mapview_common.c 9 Mar 2005 18:12:33 -0000 1.208
+++ client/mapview_common.c 10 Mar 2005 02:03:31 -0000
@@ -1307,6 +1307,136 @@
queue_mapview_tile_update(pcity->tile, TILE_UPDATE_CITY_DESC);
}
+/****************************************************************************
+ Draw a description for the given city. This description may include the
+ name, turns-to-grow, production, and city turns-to-build (depending on
+ client options).
+
+ (canvas_x, canvas_y) gives the location on the given canvas at which to
+ draw the description. This is the location of the city itself so the
+ text must be drawn underneath it. pcity gives the city to be drawn,
+ while (*width, *height) should be set by show_ctiy_desc to contain the
+ width and height of the text block (centered directly underneath the
+ city's tile).
+****************************************************************************/
+static void show_city_desc(struct canvas *pcanvas,
+ const int canvas_xx, const int canvas_yy,
+ struct city *pcity, int *width, int *height)
+{
+ const bool draw_city_prod = (draw_city_productions
+ && pcity->owner == game.player_idx);
+ const bool multi = (draw_city_prod && draw_city_names);
+ static char name[512], growth[32], prod[512];
+ enum color_std growth_color, owner_color;
+ struct {
+ int x, y, w, h;
+ } name_rect = {0, 0, 0, 0}, growth_rect = {0, 0, 0, 0},
+ prod_rect = {0, 0, 0, 0};
+ int width1 = 0, width2 = 0, height1 = 0, height2 = 0;
+ struct Sprite *sprite = sprites.mask.worked_tile; /* FIXME */
+ int sprite_w, sprite_h, x, y;
+ const int canvas_x = canvas_xx + NORMAL_TILE_WIDTH / 2;
+ const int canvas_y = canvas_yy + NORMAL_TILE_HEIGHT;
+ const int border = 6;
+
+ get_sprite_dimensions(sprite, &sprite_w, &sprite_h);
+ *width = *height = 0;
+
+ if (!draw_city_names && !draw_city_prod) {
+ return;
+ }
+
+ /* First: calculate rect dimensions (but not positioning). */
+ if (draw_city_names) {
+ int extra_width = 0;
+
+ get_city_mapview_name_and_growth(pcity, name, sizeof(name),
+ growth, sizeof(growth), &growth_color);
+
+ get_text_size(&name_rect.w, &name_rect.h, FONT_CITY_NAME, name);
+
+ if (growth[0] != '\0') {
+ get_text_size(&growth_rect.w, &growth_rect.h, FONT_CITY_PROD, growth);
+ extra_width = border;
+ }
+ width1 = name_rect.w + extra_width + growth_rect.w;
+ height1 = MAX(name_rect.h, growth_rect.h);
+ }
+ if (draw_city_prod) {
+ get_city_mapview_production(pcity, prod, sizeof(prod));
+ get_text_size(&prod_rect.w, &prod_rect.h, FONT_CITY_PROD, prod);
+
+ width2 = prod_rect.w;
+ height2 = prod_rect.h;
+ }
+
+ *width = MAX(width1, width2) + border;
+ *height = border + height1 + height2 + (multi ? border : 0);
+
+ /* Next fill in X and Y locations. */
+ if (draw_city_names) {
+ int growth_w = 0;
+
+ if (growth[0] != '\0') {
+ growth_rect.x
+ = canvas_x + (MAX(width1, width2) + 1) / 2 - growth_rect.w;
+ growth_rect.y = canvas_y + border / 2 + (height1 - growth_rect.h) / 2;
+ growth_w = growth_rect.w + border;
+ }
+
+ name_rect.x = canvas_x - (name_rect.w + growth_w) / 2;
+ name_rect.y = canvas_y + border / 2;
+ }
+ if (draw_city_prod) {
+ prod_rect.x = canvas_x - width2 / 2;
+ prod_rect.y = canvas_y + border / 2
+ + (draw_city_names ? border + height1 : 0);
+ }
+
+ /* Now draw. */
+ for (x = 0; x < *width; x += sprite_w) {
+ for (y = 0; y < *height; y += sprite_h) {
+ canvas_put_sprite(pcanvas, canvas_x - *width / 2 + x,
+ canvas_y + y,
+ sprite,
+ 0, 0, *width - x, *height - y);
+ }
+ }
+ owner_color = player_color(city_owner(pcity));
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ canvas_x - *width / 2, canvas_y,
+ *width, 0);
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ canvas_x - *width / 2, canvas_y,
+ 0, *height);
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ canvas_x - *width / 2, canvas_y + *height,
+ *width, 0);
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ canvas_x - *width / 2 + *width, canvas_y,
+ 0, *height);
+ if (draw_city_names) {
+ canvas_put_text(pcanvas, name_rect.x, name_rect.y,
+ FONT_CITY_NAME, COLOR_STD_WHITE, name);
+ if (growth[0] != '\0') {
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ growth_rect.x - border / 2, canvas_y,
+ 0, height1 + border);
+ canvas_put_text(pcanvas, growth_rect.x, growth_rect.y,
+ FONT_CITY_PROD, growth_color, growth);
+ }
+ }
+ if (draw_city_prod) {
+ if (draw_city_names) {
+ canvas_put_line(pcanvas, owner_color, LINE_NORMAL,
+ canvas_x - *width / 2, canvas_y + height1 + border,
+ *width, 0);
+ }
+ canvas_put_text(pcanvas, prod_rect.x, prod_rect.y,
+ FONT_CITY_PROD, COLOR_STD_WHITE, prod);
+ }
+}
+
/**************************************************************************
Show descriptions for all cities visible on the map canvas.
**************************************************************************/
@@ -1319,8 +1449,6 @@
return;
}
- prepare_show_city_descriptions();
-
/* A city description is shown below the city. It has a specified
* maximum width and height (although these are only estimates). Thus
* we need to update some tiles above the mapview and some to the left
@@ -1341,7 +1469,7 @@
*/
gui_rect_iterate(mapview.gui_x0 + canvas_x - dx / 2,
mapview.gui_y0 + canvas_y - dy,
- width + dx, height + dy - NORMAL_TILE_HEIGHT,
+ width + dx, height + dy,
ptile, pedge, pcorner, gui_x, gui_y) {
const int canvas_x = gui_x - mapview.gui_x0;
const int canvas_y = gui_y - mapview.gui_y0;
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.103
diff -u -r1.103 mapview_common.h
--- client/mapview_common.h 5 Mar 2005 02:23:29 -0000 1.103
+++ client/mapview_common.h 10 Mar 2005 02:03:34 -0000
@@ -55,6 +55,12 @@
extern struct view mapview;
extern struct overview overview;
+enum client_font {
+ FONT_CITY_NAME,
+ FONT_CITY_PROD,
+ FONT_COUNT
+};
+
/* HACK: Callers can set this to FALSE to disable sliding. It should be
* reenabled afterwards. */
extern bool can_slide;
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 10 Mar 2005 02:03:34 -0000
@@ -461,117 +461,63 @@
update_map_canvas_visible();
}
-/**************************************************************************
- If necessary, clear the city descriptions out of the buffer.
-**************************************************************************/
-void prepare_show_city_descriptions(void)
-{
- /* Nothing to do */
-}
+static PangoLayout *layout;
+static PangoFontDescription **fonts[FONT_COUNT] = {&main_font,
+ &city_productions_font};
/****************************************************************************
- Draw a description for the given city. This description may include the
- name, turns-to-grow, production, and city turns-to-build (depending on
- client options).
-
- (canvas_x, canvas_y) gives the location on the given canvas at which to
- draw the description. This is the location of the city itself so the
- text must be drawn underneath it. pcity gives the city to be drawn,
- while (*width, *height) should be set by show_ctiy_desc to contain the
- width and height of the text block (centered directly underneath the
- city's tile).
+ Return the size of the given text in the given font. This size should
+ include the ascent and descent of the text. Either of width or height
+ may be NULL in which case those values simply shouldn't be filled out.
****************************************************************************/
-void show_city_desc(struct canvas *pcanvas, int canvas_x, int canvas_y,
- struct city *pcity, int *width, int *height)
+void get_text_size(int *width, int *height,
+ enum client_font font, const char *text)
{
- if (pcanvas->type == CANVAS_PIXMAP) {
- static char buffer[512], buffer2[32];
- PangoRectangle rect, rect2;
- enum color_std color;
- int extra_width = 0;
- static PangoLayout *layout;
+ PangoRectangle rect;
if (!layout) {
layout = pango_layout_new(gdk_pango_context_get());
}
- *width = *height = 0;
-
- canvas_x += NORMAL_TILE_WIDTH / 2;
- canvas_y += NORMAL_TILE_HEIGHT;
-
- if (draw_city_names) {
- get_city_mapview_name_and_growth(pcity, buffer, sizeof(buffer),
- buffer2, sizeof(buffer2), &color);
-
- pango_layout_set_font_description(layout, main_font);
- if (buffer2[0] != '\0') {
- /* HACK: put a character's worth of space between the two strings. */
- 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;
-
- 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);
- } else {
- rect2.width = 0;
- }
-
- 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);
-
- if (draw_city_growth && pcity->owner == game.player_idx) {
- pango_layout_set_font_description(layout, city_productions_font);
- pango_layout_set_text(layout, buffer2, -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);
- }
-
- canvas_y += rect.height + 3;
+ pango_layout_set_font_description(layout, *fonts[font]);
+ pango_layout_set_text(layout, text, -1);
- *width = rect.width + rect2.width;
- *height += rect.height + 3;
+ pango_layout_get_pixel_extents(layout, &rect, NULL);
+ if (width) {
+ *width = rect.width;
}
+ if (height) {
+ *height = rect.height;
+ }
+}
- if (draw_city_productions && (pcity->owner==game.player_idx)) {
- get_city_mapview_production(pcity, buffer, sizeof(buffer));
-
- pango_layout_set_font_description(layout, city_productions_font);
- pango_layout_set_text(layout, buffer, -1);
-
- pango_layout_get_pixel_extents(layout, &rect, NULL);
- 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);
+/****************************************************************************
+ Draw the text onto the canvas in the given color and font. The canvas
+ position does not account for the ascent of the text; this function must
+ take care of this manually. The text will not be NULL but may be empty.
+****************************************************************************/
+void canvas_put_text(struct canvas *pcanvas, int canvas_x, int canvas_y,
+ enum client_font font, enum color_std color,
+ const char *text)
+{
+ PangoRectangle rect;
- *width = MAX(*width, rect.width);
- *height += rect.height;
+ if (pcanvas->type != CANVAS_PIXMAP) {
+ return;
}
+ if (!layout) {
+ layout = pango_layout_new(gdk_pango_context_get());
}
+
+ gdk_gc_set_foreground(civ_gc, colors_standard[color]);
+ pango_layout_set_font_description(layout, *fonts[font]);
+ pango_layout_set_text(layout, text, -1);
+
+ pango_layout_get_pixel_extents(layout, &rect, NULL);
+ gtk_draw_shadowed_string(pcanvas->v.pixmap,
+ toplevel->style->black_gc, civ_gc,
+ canvas_x,
+ canvas_y + PANGO_ASCENT(rect), layout);
}
/**************************************************************************
Index: client/gui-stub/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-stub/mapview.c,v
retrieving revision 1.50
diff -u -r1.50 mapview.c
--- client/gui-stub/mapview.c 2 Mar 2005 18:22:59 -0000 1.50
+++ client/gui-stub/mapview.c 10 Mar 2005 02:03:34 -0000
@@ -122,19 +122,30 @@
}
/****************************************************************************
- Draw a description for the given city. This description may include the
- name, turns-to-grow, production, and city turns-to-build (depending on
- client options).
-
- (canvas_x, canvas_y) gives the location on the given canvas at which to
- draw the description. This is the location of the city itself so the
- text must be drawn underneath it. pcity gives the city to be drawn,
- while (*width, *height) should be set by show_ctiy_desc to contain the
- width and height of the text block (centered directly underneath the
- city's tile).
+ Return the size of the given text in the given font. This size should
+ include the ascent and descent of the text. Either of width or height
+ may be NULL in which case those values simply shouldn't be filled out.
****************************************************************************/
-void show_city_desc(struct canvas *pcanvas, int canvas_x, int canvas_y,
- struct city *pcity, int *width, int *height)
+void get_text_size(int *width, int *height,
+ enum client_font font, const char *text)
+{
+ /* PORTME */
+ if (width) {
+ *width = 0;
+ }
+ if (height) {
+ *height = 0;
+ }
+}
+
+/****************************************************************************
+ Draw the text onto the canvas in the given color and font. The canvas
+ position does not account for the ascent of the text; this function must
+ take care of this manually. The text will not be NULL but may be empty.
+****************************************************************************/
+void canvas_put_text(struct canvas *pcanvas, int canvas_x, int canvas_y,
+ enum client_font font, enum color_std color,
+ const char *text)
{
/* PORTME */
}
@@ -322,14 +333,6 @@
}
/****************************************************************************
- If necessary, clear the city descriptions out of the buffer.
-****************************************************************************/
-void prepare_show_city_descriptions(void)
-{
- /* PORTME */
-}
-
-/****************************************************************************
Draw a cross-hair overlay on a tile.
****************************************************************************/
void put_cross_overlay_tile(struct tile *ptile)
Index: client/gui-xaw/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/mapview.c,v
retrieving revision 1.193
diff -u -r1.193 mapview.c
--- client/gui-xaw/mapview.c 5 Mar 2005 23:43:59 -0000 1.193
+++ client/gui-xaw/mapview.c 10 Mar 2005 02:03:35 -0000
@@ -641,14 +641,6 @@
}
/**************************************************************************
- If necessary, clear the city descriptions out of the buffer.
-**************************************************************************/
-void prepare_show_city_descriptions(void)
-{
- /* Nothing to do */
-}
-
-/**************************************************************************
Draw at x = left of string, y = top of string.
**************************************************************************/
static void draw_shadowed_string(struct canvas *pcanvas,
@@ -670,69 +662,38 @@
x, y, string, len);
}
+static XFontSet *fonts[FONT_COUNT] = {&main_font_set, &prod_font_set};
+static GC *font_gcs[FONT_COUNT] = {&font_gc, &prod_font_gc};
+
/****************************************************************************
- Draw a description for the given city. This description may include the
- name, turns-to-grow, production, and city turns-to-build (depending on
- client options).
-
- (canvas_x, canvas_y) gives the location on the given canvas at which to
- draw the description. This is the location of the city itself so the
- text must be drawn underneath it. pcity gives the city to be drawn,
- while (*width, *height) should be set by show_ctiy_desc to contain the
- width and height of the text block (centered directly underneath the
- city's tile).
+ Return the size of the given text in the given font. This size should
+ include the ascent and descent of the text. Either of width or height
+ may be NULL in which case those values simply shouldn't be filled out.
****************************************************************************/
-void show_city_desc(struct canvas *pcanvas, int canvas_x, int canvas_y,
- struct city *pcity, int *width, int *height)
+void get_text_size(int *width, int *height,
+ enum client_font font, const char *text)
{
- char buffer[512], buffer2[512];
- enum color_std color;
- int w, w2;
- XFontSetExtents *main_exts = XExtentsOfFontSet(main_font_set);
- XFontSetExtents *prod_exts = XExtentsOfFontSet(prod_font_set);
-
- canvas_x += NORMAL_TILE_WIDTH / 2;
- canvas_y += NORMAL_TILE_HEIGHT;
-
- get_city_mapview_name_and_growth(pcity, buffer, sizeof(buffer),
- buffer2, sizeof(buffer2), &color);
-
- w = XmbTextEscapement(main_font_set, buffer, strlen(buffer));
- if (buffer2[0] != '\0') {
- /* HACK: put a character's worth of space between the two strings. */
- w += XmbTextEscapement(main_font_set, "M", 1);
- }
- w2 = XmbTextEscapement(main_font_set, buffer2, strlen(buffer2));
-
- draw_shadowed_string(pcanvas, main_font_set, font_gc,
- COLOR_STD_WHITE, COLOR_STD_BLACK,
- canvas_x - (w + w2) / 2,
- canvas_y, buffer);
-
- draw_shadowed_string(pcanvas, prod_font_set, prod_font_gc, color,
- COLOR_STD_BLACK,
- canvas_x - (w + w2) / 2 + w,
- canvas_y, buffer2);
-
- *width = w + w2;
- *height = main_exts->max_logical_extent.height;
-
- if (draw_city_productions && (pcity->owner == game.player_idx)) {
- if (draw_city_names) {
- canvas_y += main_exts->max_logical_extent.height;
- }
-
- get_city_mapview_production(pcity, buffer, sizeof(buffer));
- w = XmbTextEscapement(prod_font_set, buffer, strlen(buffer));
-
- draw_shadowed_string(pcanvas, prod_font_set, prod_font_gc,
- COLOR_STD_WHITE, COLOR_STD_BLACK,
- canvas_x - w / 2,
- canvas_y, buffer);
-
- *width = MAX(*width, w);
- *height += prod_exts->max_logical_extent.height;
+ if (width) {
+ *width = XmbTextEscapement(*fonts[font], text, strlen(text));
}
+ if (height) {
+ /* ??? */
+ *height = main_exts->max_logical_extent.height;
+ }
+}
+
+/****************************************************************************
+ Draw the text onto the canvas in the given color and font. The canvas
+ position does not account for the ascent of the text; this function must
+ take care of this manually. The text will not be NULL but may be empty.
+****************************************************************************/
+void canvas_put_text(struct canvas *pcanvas, int canvas_x, int canvas_y,
+ enum client_font font, enum color_std color,
+ const char *text)
+{
+ draw_shadowed_string(pcanvas, fonts[font], font_gcs[font],
+ color, COLOR_STD_BLACK,
+ canvas_x, canvas_y, text);
}
/**************************************************************************
Index: client/include/mapview_g.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/include/mapview_g.h,v
retrieving revision 1.60
diff -u -r1.60 mapview_g.h
--- client/include/mapview_g.h 2 Mar 2005 18:23:00 -0000 1.60
+++ client/include/mapview_g.h 10 Mar 2005 02:03:35 -0000
@@ -34,10 +34,12 @@
void canvas_free(struct canvas *store);
struct canvas *get_overview_window(void);
-void show_city_desc(struct canvas *pcanvas, int canvas_x, int canvas_y,
- struct city *pcity, int *width, int *height);
-void prepare_show_city_descriptions(void);
+void get_text_size(int *width, int *height,
+ enum client_font font, const char *text);
+void canvas_put_text(struct canvas *pcanvas, int canvas_x, int canvas_y,
+ enum client_font font, enum color_std color,
+ const char *text);
void canvas_put_sprite(struct canvas *pcanvas,
int canvas_x, int canvas_y, struct Sprite *sprite,
int offset_x, int offset_y, int width, int height);
- [Freeciv-Dev] Re: (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Jason Short, 2005/03/08
- [Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Guest, 2005/03/08
- [Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Guest, 2005/03/09
- [Freeciv-Dev] Re: (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Per I. Mathisen, 2005/03/09
- [Freeciv-Dev] Re: (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Jason Short, 2005/03/09
- [Freeciv-Dev] Re: (PR#2708) patch: backing rectangle for city descriptions in gtk2 client,
Jason Short <=
- [Freeciv-Dev] Re: (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Per I. Mathisen, 2005/03/10
- [Freeciv-Dev] Re: (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Christian Knoke, 2005/03/10
- [Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Guest, 2005/03/10
- [Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Guest, 2005/03/10
- [Freeciv-Dev] Re: (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Christian Knoke, 2005/03/10
- [Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Guest, 2005/03/10
- [Freeciv-Dev] Re: (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Christian Knoke, 2005/03/10
- [Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Jason Short, 2005/03/11
- [Freeciv-Dev] Re: (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Jason Short, 2005/03/13
- [Freeciv-Dev] (PR#2708) patch: backing rectangle for city descriptions in gtk2 client, Jason Short, 2005/03/19
|
|