Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2005:
[Freeciv-Dev] (PR#14731) Demographics report and localization
Home

[Freeciv-Dev] (PR#14731) Demographics report and localization

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: himasaram@xxxxxxxx
Subject: [Freeciv-Dev] (PR#14731) Demographics report and localization
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 1 Dec 2005 19:25:25 -0800
Reply-to: bugs@xxxxxxxxxxx

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

> [dmarks - Wed Nov 30 08:23:58 2005]:
> 
> When you translate the demographic strings (e.g. Population, Land Area 
> etc) they have to retain the relative length as the English originals, 
> otherwise the demographics report's columns become shifted (see 
> screen.)
> 
> This patch for server/report.c add ?demographics: to the affected 
> strings, allowing translators add extra whitespaces where needed to 
> adjust them.

That patch won't fix it.  The problem is unfixable using conventional
means because it's a charsets problem.  The server puts the string into
a fixed-width 18-bytes buffer, which it then sends to the client.  The
problem, of course, if your string has multi-byte characters (as, in the
screenshot, you do) then these will take up some of the 18 bytes of the
buffer and the buffer will show wrongly sized because 18 bytes is not
the same as 18 characters.

So, how to fix it?  Well, this patch should do it.  Of course the real
fix is, as Vasco said, to send the raw data to the client and use the
GUI to format it.  This problem only shows up because we're trying to do
something that we shouldn't be doing in the first place.

Can you test this patch?  I cannot.

Interestingly, the demographics display doesn't seem to use a
fixed-width font so even with this change the columns do not line up
exactly.

-jason

Index: utility/fciconv.c
===================================================================
--- utility/fciconv.c   (revision 11284)
+++ utility/fciconv.c   (working copy)
@@ -355,3 +355,27 @@
   fputs(output, stream);
   fflush(stream);
 }
+
+/****************************************************************************
+  Return the length, in *characters*, of the string.  This can be used in
+  place of strlen in some places because it returns the number of characters
+  not the number of bytes (with multi-byte characters in UTF-8, the two
+  may not be the same).
+
+  Use of this function outside of GUI layout code is probably a hack.  For
+  instance the demographics code uses it, but this should instead pass the
+  data directly to the GUI library for formatting.
+****************************************************************************/
+size_t get_internal_string_length(const char *text)
+{
+  int text2[(strlen(text) + 1)]; /* UCS-4 text */
+  int i = 0;
+
+  convert_string(text, internal_encoding, "UCS-4",
+                (char *)text2, sizeof(text2));
+  for (i = 0; ; i++) {
+    if (text2[i] == 0) {
+      return i;
+    }
+  }
+}
Index: utility/fciconv.h
===================================================================
--- utility/fciconv.h   (revision 11284)
+++ utility/fciconv.h   (working copy)
@@ -43,4 +43,6 @@
                     const char *to,
                     char *buf, size_t bufsz);
 
+size_t get_internal_string_length(const char *text);
+
 #endif /* FC__FCICONV_H */
Index: server/report.c
===================================================================
--- server/report.c     (revision 11284)
+++ server/report.c     (working copy)
@@ -20,6 +20,7 @@
 #include <string.h>
 
 #include "events.h"
+#include "fciconv.h"
 #include "fcintl.h"
 #include "game.h"
 #include "government.h"
@@ -599,8 +600,11 @@
                          bv_cols selcols)
 {
   if (BV_ISSET(selcols, DEM_COL_QUANTITY)) {
-      cat_snprintf(outptr, out_size, " %-18s",
-                  prow->to_text(prow->get_value(pplayer)));
+    const char *text = prow->to_text(prow->get_value(pplayer));
+
+    cat_snprintf(outptr, out_size, " %s", text);
+    cat_snprintf(outptr, out_size, "%*s",
+                18 - get_internal_string_length(text), "");
   }
 
   if (BV_ISSET(selcols, DEM_COL_RANK)) {
@@ -739,7 +743,11 @@
   buffer[0] = '\0';
   for (i = 0; i < ARRAY_SIZE(rowtable); i++) {
     if (strchr(game.demography, rowtable[i].key)) {
-      cat_snprintf(buffer, sizeof(buffer), "%-18s", _(rowtable[i].name));
+      const char *name = _(rowtable[i].name);
+
+      cat_snprintf(buffer, sizeof(buffer), "%s", name);
+      cat_snprintf(buffer, sizeof(buffer), "%*s",
+                  18 - get_internal_string_length(name), "");
       dem_line_item(buffer, sizeof(buffer), pplayer, &rowtable[i], selcols);
       sz_strlcat(buffer, "\n");
     }

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