PATCH: GTK I18N patch



Hello
	I tried to make the GTK widget display internationalized 
text with X11R5/R6 I18N mechanism. It can now display non-ASCII, 
two bytes or multibytes characters whenever X Locale is supported.
The patch has been tested on Linux/X11R6 in a Traditional Chinese
enviroment (zh_TW.big5).

How is it done:
	The GdkFont structure is extended to have an entry called 
 	GdkFontType, which can have value either GDK_FONT_FONT or
	GDK_FONT_FONTSET. GDK_FONT_FONT indicates that the "font" entry
	in GdkFont is a pointer point to a XFontStruct, XFontStruct is
	used to render non-i18n texts. On the other hand, 		
	GDK_FONT_FONTSET indicates that "font" points to a XFontSet.
	XFontSet is used to render I18N texts.

	A new resource entry named "fontset" is added to each text 
	displaying widget to take place the role of "font" resource 
	when I18N text is to be drwan. The "fontset" resource takes
	higher precedence than the "font" resource, i.e. when "fontset"
	and "font" are both specified, "fontset" is used. When "fontset"
	is not specified, "font"  or default font is used.

	Unforutnately, the interface of some functions had to be changed 
	to incoporate with XFontSet when drawing multibyte characters. 
	The functions that were changed are gdk_draw_string() and 
	gdk_draw_text(). Originally, fonts used to draw texts are 
	specified by the GC of the window to be drawn on, but XFontSet 
	is not in the GC so it is necessary to specify it explicitely. 
	The calling procedure beccomes:

		void gdk_draw_string (GdkDrawable  *drawable,
			  	      GdkFont      *font, 
 				      GdkGC        *gc,
 		        	      gint          x,
 			      	      gint          y,
 			      	      gchar        *string);

	instead of

		void gdk_draw_string (GdkDrawable  *drawable,
		 		      GdkGC        *gc,
 			              gint          x,
 				      gint          y,
 				      gchar        *string);

	The patch file is self-conained that the influence of the	
	mofidication on current existing applications should be minimal. 
	For example, only two lines of GIMP should be modified.

How to apply the patch.

	Use the patch command in the usual way and reconfigure the 
	package. Note that if the C lib does not support your locale,
	you should specify -DX_LOCALE in the CFLAGS which makes X locale
	utilized. After recompiling and installing the package. it is
	ready to display I18N text with GTK. An example of "hello world"
	will be presented in another mail latter.
diff -r -u gtk+970606/gdk/gdk.h gtk+970606-i18n/gdk/gdk.h
--- gtk+970606/gdk/gdk.h	Fri Jun  6 15:02:05 1997
+++ gtk+970606-i18n/gdk/gdk.h	Thu Jun 26 21:54:06 1997
@@ -323,7 +323,9 @@
 /* Fonts
  */
 GdkFont* gdk_font_load      (gchar    *font_name);
+GdkFont* gdk_fontset_load   (gchar    *fontset_name);
 void     gdk_font_free      (GdkFont  *font);
+void     gdk_fontset_free   (GdkFont  *font);
 void     gdk_font_ref       (GdkFont  *font);
 gint     gdk_font_id        (GdkFont  *font);
 gint     gdk_font_equal     (GdkFont  *fonta,
@@ -374,11 +376,13 @@
 			  GdkPoint     *points,
 			  gint          npoints);
 void gdk_draw_string     (GdkDrawable  *drawable,
+			  GdkFont      *font,
 			  GdkGC        *gc,
 			  gint          x,
 			  gint          y,
 			  gchar        *string);
 void gdk_draw_text       (GdkDrawable  *drawable,
+			  GdkFont      *font,
 			  GdkGC        *gc,
 			  gint          x,
 			  gint          y,
diff -r -u gtk+970606/gdk/gdkdraw.c gtk+970606-i18n/gdk/gdkdraw.c
--- gtk+970606/gdk/gdkdraw.c	Thu Feb 20 07:53:13 1997
+++ gtk+970606-i18n/gdk/gdkdraw.c	Sat Jun 28 00:12:13 1997
@@ -140,29 +140,68 @@
     }
 }
 
+/* gdk_draw_string
+ *
+ * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
+ *
+ * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
+ */
 void
 gdk_draw_string (GdkDrawable *drawable,
+		 GdkFont     *font,
 		 GdkGC       *gc,
 		 gint         x,
 		 gint         y,
 		 gchar       *string)
 {
   GdkWindowPrivate *drawable_private;
+  GdkFontPrivate *font_private;
   GdkGCPrivate *gc_private;
 
   g_return_if_fail (drawable != NULL);
+  g_return_if_fail (font != NULL);
   g_return_if_fail (gc != NULL);
   g_return_if_fail (string != NULL);
 
   drawable_private = (GdkWindowPrivate*) drawable;
   gc_private = (GdkGCPrivate*) gc;
+  font_private = (GdkFontPrivate*) font;
 
-  XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
-	       gc_private->xgc, x, y, string, strlen (string));
+  if (font->type == GDK_FONT_FONT)
+    {
+      XFontStruct *xfont = (XFontStruct *) font_private->xfont;
+      XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid);
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+	{
+	  XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+		       gc_private->xgc, x, y, string, strlen (string));
+	}
+      else
+	{
+	  XDrawString16 (drawable_private->xdisplay, drawable_private->xwindow,
+			 gc_private->xgc, x, y, (XChar2b *) string, 
+			 strlen (string) / 2);
+	}
+    }
+  else if (font->type == GDK_FONT_FONTSET)
+    {
+      XFontSet fontset = (XFontSet) font_private->xfont;
+      XmbDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+		     fontset, gc_private->xgc, x, y, string, strlen (string));
+    }  
+  else
+    g_error("undefined font type\n");
 }
 
+/* gdk_draw_text
+ *
+ * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
+ *
+ * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
+ */
 void
 gdk_draw_text (GdkDrawable *drawable,
+	       GdkFont     *font,
 	       GdkGC       *gc,
 	       gint         x,
 	       gint         y,
@@ -170,17 +209,41 @@
 	       gint         text_length)
 {
   GdkWindowPrivate *drawable_private;
+  GdkFontPrivate *font_private;
   GdkGCPrivate *gc_private;
-
+  
   g_return_if_fail (drawable != NULL);
+  g_return_if_fail (font != NULL);
   g_return_if_fail (gc != NULL);
   g_return_if_fail (text != NULL);
-
+  
   drawable_private = (GdkWindowPrivate*) drawable;
   gc_private = (GdkGCPrivate*) gc;
+  font_private = (GdkFontPrivate*) font;
 
-  XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
-	       gc_private->xgc, x, y, text, text_length);
+  if (font->type == GDK_FONT_FONT)
+    {
+      XFontStruct *xfont = (XFontStruct *) font_private->xfont;
+      XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid);
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+	{
+	  XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+		       gc_private->xgc, x, y, text, text_length);
+	}
+      else
+	{
+	  XDrawString16 (drawable_private->xdisplay, drawable_private->xwindow,
+			 gc_private->xgc, x, y, (XChar2b *) text, text_length / 2);
+	}
+    }
+  else if (font->type == GDK_FONT_FONTSET)
+    {
+      XFontSet fontset = (XFontSet) font_private->xfont;
+      XmbDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+		     fontset, gc_private->xgc, x, y, text, text_length);
+    }
+  else
+    g_error("undefined font type\n");
 }
 
 void
diff -r -u gtk+970606/gdk/gdkfont.c gtk+970606-i18n/gdk/gdkfont.c
--- gtk+970606/gdk/gdkfont.c	Wed Feb 26 20:00:43 1997
+++ gtk+970606-i18n/gdk/gdkfont.c	Sat Jun 28 09:32:52 1997
@@ -20,7 +20,6 @@
 #include "gdk.h"
 #include "gdkprivate.h"
 
-
 GdkFont*
 gdk_font_load (gchar *font_name)
 {
@@ -31,7 +30,8 @@
   font = (GdkFont*) private;
 
   private->xdisplay = gdk_display;
-  private->xfont = XLoadQueryFont (private->xdisplay, font_name);
+  (XFontStruct *) private->xfont = XLoadQueryFont (private->xdisplay, 
+						   font_name);
   private->ref_count = 1;
 
   if (!private->xfont)
@@ -41,15 +41,59 @@
     }
   else
     {
-      font->ascent = private->xfont->ascent;
-      font->descent = private->xfont->descent;
+      font->type = GDK_FONT_FONT;
+      font->ascent =  ((XFontStruct *) private->xfont)->ascent;
+      font->descent = ((XFontStruct *) private->xfont)->descent;
     }
 
-  gdk_xid_table_insert (&private->xfont->fid, font);
+  gdk_xid_table_insert (&((XFontStruct *) private->xfont)->fid, font);
 
   return font;
 }
 
+GdkFont*
+gdk_fontset_load(gchar *fontset_name)
+{
+  GdkFont *font;
+  GdkFontPrivate *private;
+  XFontSet fontset;
+  gint  missing_charset_count;
+  gchar **missing_charset_list;
+  gchar *def_string;
+
+  private = g_new (GdkFontPrivate, 1);
+  font = (GdkFont*) private;
+
+  private->xdisplay = gdk_display;
+  fontset = XCreateFontSet (gdk_display, fontset_name,
+			    &missing_charset_list, &missing_charset_count, 
+			    &def_string);
+
+  if (missing_charset_count)
+    {
+      g_print("Missing charsets in FontSet creation");
+      XFreeStringList (missing_charset_list);
+    }
+  
+  private->ref_count = 1;
+
+  if (!fontset)
+    {
+      g_free (font);
+      return NULL;
+    }
+  else
+    {
+      XFontSetExtents *extent = XExtentsOfFontSet(fontset);
+
+      (XFontSet) private->xfont = fontset;
+      font->type = GDK_FONT_FONTSET;
+      /* how to define ascent and descent for fontset ??? */
+      font->ascent =  extent->max_logical_extent.height;
+      font->descent = font->ascent / 4 ;
+    }
+  return font;
+}
 void
 gdk_font_free (GdkFont *font)
 {
@@ -62,13 +106,30 @@
   private->ref_count -= 1;
   if (private->ref_count == 0)
     {
-      gdk_xid_table_remove (private->xfont->fid);
-      XFreeFont (private->xdisplay, private->xfont);
+      gdk_xid_table_remove (((XFontStruct *) private->xfont)->fid);
+      XFreeFont (private->xdisplay, (XFontStruct *) private->xfont);
       g_free (font);
     }
 }
 
 void
+gdk_fontset_free(GdkFont *font)
+{
+  GdkFontPrivate *private;
+
+  g_return_if_fail (font != NULL);
+
+  private = (GdkFontPrivate*) font;
+
+  private->ref_count -= 1;
+  if (private->ref_count == 0)
+    {
+      XFreeFontSet (private->xdisplay, (XFontSet) private->xfont);
+      g_free (font);
+    }  
+}
+
+void
 gdk_font_ref (GdkFont *font)
 {
   GdkFontPrivate *private;
@@ -82,9 +143,20 @@
 gint
 gdk_font_id (GdkFont *font)
 {
+  GdkFontPrivate *font_private;
+
   g_return_val_if_fail (font != NULL, 0);
 
-  return ((GdkFontPrivate*) font)->xfont->fid;
+  font_private = (GdkFontPrivate*) font;
+  
+  if (font->type == GDK_FONT_FONT)
+    {
+      return ((XFontStruct *) font_private->xfont)->fid;
+    }
+  else
+    {
+      return 0;
+    }
 }
 
 gint
@@ -100,21 +172,55 @@
   privatea = (GdkFontPrivate*) fonta;
   privateb = (GdkFontPrivate*) fontb;
 
-  return (privatea->xfont->fid == privateb->xfont->fid);
+  if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
+    {
+      return (((XFontStruct *) privatea->xfont)->fid == 
+	      ((XFontStruct *) privateb->xfont)->fid);
+    }
+  else if (fonta->type == GDK_FONT_FONTSET && fontb->type == GDK_FONT_FONTSET)
+    {
+      /* how to compare two fontsets ?? by basename or XFontSet ?? */
+      return (((XFontSet) privatea->xfont) == ((XFontSet) privateb->xfont));
+    }
+  else
+    /* fontset != font */
+    return 0;
 }
 
 gint
 gdk_string_width (GdkFont *font,
 		  gchar   *string)
 {
-  GdkFontPrivate *private;
+  GdkFontPrivate *font_private;
   gint width;
+  XFontStruct *xfont;
+  XFontSet fontset;
 
   g_return_val_if_fail (font != NULL, -1);
   g_return_val_if_fail (string != NULL, -1);
 
-  private = (GdkFontPrivate*) font;
-  width = XTextWidth (private->xfont, string, strlen (string));
+  font_private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      xfont = (XFontStruct *) font_private->xfont;
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+	{
+	  width = XTextWidth (xfont, string, strlen (string));
+	}
+      else
+	{
+	  width = XTextWidth16 (xfont, (XChar2b *) string, strlen (string) / 2);
+	}
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) font_private->xfont;
+      width = XmbTextEscapement (fontset, string, strlen(string));
+      break;
+    default:
+      width = 0;
+    }
 
   return width;
 }
@@ -126,16 +232,38 @@
 {
   GdkFontPrivate *private;
   gint width;
+  XFontStruct *xfont;
+  XFontSet fontset;
 
   g_return_val_if_fail (font != NULL, -1);
   g_return_val_if_fail (text != NULL, -1);
 
   private = (GdkFontPrivate*) font;
-  width = XTextWidth (private->xfont, text, text_length);
 
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+	{
+	  width = XTextWidth (xfont, text, text_length);
+	}
+      else
+	{
+	  width = XTextWidth16 (xfont, (XChar2b *) text, text_length / 2);
+	}
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) private->xfont;
+      width = XmbTextEscapement (fontset, text, text_length);
+      break;
+    default:
+      width = 0;
+    }
   return width;
 }
 
+/* Problem: What if a character is a 16 bits character ?? */
 gint
 gdk_char_width (GdkFont *font,
 		gchar    character)
@@ -143,27 +271,41 @@
   GdkFontPrivate *private;
   XCharStruct *chars;
   gint width;
+  XFontStruct *xfont;
+  XFontSet fontset;
 
   g_return_val_if_fail (font != NULL, -1);
 
   private = (GdkFontPrivate*) font;
 
-  if ((private->xfont->min_byte1 == 0) &&
-      (private->xfont->max_byte1 == 0) &&
-      (character >= private->xfont->min_char_or_byte2) &&
-      (character <= private->xfont->max_char_or_byte2))
-    {
-      chars = private->xfont->per_char;
-      if (chars)
-	width = chars[character - private->xfont->min_char_or_byte2].width;
-      else
-	width = private->xfont->min_bounds.width;
-    }
-  else
+  switch (font->type)
     {
-      width = XTextWidth (private->xfont, &character, 1);
+    case GDK_FONT_FONT:
+      /* only 8 bits characters are considered here */
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) &&
+	  (xfont->max_byte1 == 0) &&
+	  (character >= xfont->min_char_or_byte2) &&
+	  (character <= xfont->max_char_or_byte2))
+	{
+	  chars = xfont->per_char;
+	  if (chars)
+	    width = chars[character - xfont->min_char_or_byte2].width;
+	  else
+	    width = xfont->min_bounds.width;
+	}
+      else
+	{
+	  width = XTextWidth (xfont, &character, 1);
+	}
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) private->xfont;
+      width = XmbTextEscapement (fontset, &character, 1) ;
+      break;
+    default:
+      width = 0;
     }
-
   return width;
 }
 
@@ -184,6 +326,9 @@
 {
   GdkFontPrivate *private;
   XCharStruct overall;
+  XFontStruct *xfont;
+  XFontSet    fontset;
+  XRectangle  ink, log;
   int direction;
   int font_ascent;
   int font_descent;
@@ -193,13 +338,33 @@
   g_return_val_if_fail (text != NULL, -1);
 
   private = (GdkFontPrivate*) font;
-
-  XTextExtents (private->xfont, text, text_length,
-                &direction, &font_ascent, &font_descent,
-                &overall);
-
-  width = overall.rbearing;
-
+  
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+	{
+	  XTextExtents (xfont, text, text_length,
+			&direction, &font_ascent, &font_descent,
+			&overall);
+	}
+      else
+	{
+	  XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
+			  &direction, &font_ascent, &font_descent,
+			  &overall);
+	}
+      width = overall.rbearing;
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) private->xfont;
+      XmbTextExtents (fontset, text, text_length, &ink, &log);
+      width = log.width;
+      break;
+    default:
+      width = 0;
+    }
   return width;
 }
 
diff -r -u gtk+970606/gdk/gdkgc.c gtk+970606-i18n/gdk/gdkgc.c
--- gtk+970606/gdk/gdkgc.c	Sat Jun  7 02:40:47 1997
+++ gtk+970606-i18n/gdk/gdkgc.c	Fri Jun 27 23:25:59 1997
@@ -61,9 +61,9 @@
       xvalues.background = values->background.pixel;
       xvalues_mask |= GCBackground;
     }
-  if (values_mask & GDK_GC_FONT)
+  if ((values_mask & GDK_GC_FONT) && (values->font->type == GDK_FONT_FONT)) 
     {
-      xvalues.font = ((GdkFontPrivate*) values->font)->xfont->fid;
+      xvalues.font = ((XFontStruct *) ((GdkFontPrivate*) values->font)->xfont)->fid;
       xvalues_mask |= GCFont;
     }
   if (values_mask & GDK_GC_FUNCTION)
@@ -374,7 +374,8 @@
   gc_private = (GdkGCPrivate*) gc;
   font_private = (GdkFontPrivate*) font;
 
-  XSetFont (gc_private->xdisplay, gc_private->xgc, font_private->xfont->fid);
+  XSetFont (gc_private->xdisplay, gc_private->xgc, 
+	    ((XFontStruct *) font_private->xfont)->fid);
 }
 
 void
diff -r -u gtk+970606/gdk/gdkprivate.h gtk+970606-i18n/gdk/gdkprivate.h
--- gtk+970606/gdk/gdkprivate.h	Sat Jun  7 09:20:51 1997
+++ gtk+970606-i18n/gdk/gdkprivate.h	Mon Jun 23 18:37:46 1997
@@ -104,7 +104,9 @@
 struct _GdkFontPrivate
 {
   GdkFont font;
-  XFontStruct *xfont;
+  /* XFontStruct *xfont; */
+  /* generic pointer point to XFontStruct or XFontSet */ 
+  gpointer xfont;
   Display *xdisplay;
   gint ref_count;
 };
diff -r -u gtk+970606/gdk/gdktypes.h gtk+970606-i18n/gdk/gdktypes.h
--- gtk+970606/gdk/gdktypes.h	Fri Jun  6 16:52:31 1997
+++ gtk+970606-i18n/gdk/gdktypes.h	Mon Jun 23 19:09:32 1997
@@ -151,6 +151,16 @@
   GDK_VISUAL_DIRECT_COLOR
 } GdkVisualType;
 
+/* Types of font.
+ *   GDK_FONT_FONT: the font is an XFontStruct.
+ *   GDK_FONT_FONTSET: the font is an XFontSet used for I18N.
+ */
+typedef enum
+{
+  GDK_FONT_FONT,
+  GDK_FONT_FONTSET
+} GdkFontType;
+
 /* Window attribute mask values.
  *   GDK_WA_TITLE: The "title" field is valid.
  *   GDK_WA_X: The "x" field is valid.
@@ -569,6 +579,7 @@
 
 struct _GdkFont
 {
+  GdkFontType type;
   gint ascent;
   gint descent;
 };
Only in gtk+970606/glib: glibconfig.h
diff -r -u gtk+970606/gtk/gtkentry.c gtk+970606-i18n/gtk/gtkentry.c
--- gtk+970606/gtk/gtkentry.c	Fri Jun  6 15:02:00 1997
+++ gtk+970606-i18n/gtk/gtkentry.c	Thu Jun 26 01:26:46 1997
@@ -1013,7 +1013,7 @@
 						      selection_end_pos);
 
               if (selection_start_pos > 0)
-                gdk_draw_text (entry->text_area,
+                gdk_draw_text (entry->text_area, widget->style->font,
                                widget->style->fg_gc[GTK_STATE_NORMAL],
                                -entry->scroll_offset, y,
                                entry->text, selection_start_pos);
@@ -1026,14 +1026,14 @@
                                   selection_end_xoffset - selection_start_xoffset,
                                   -1);
 
-              gdk_draw_text (entry->text_area,
+              gdk_draw_text (entry->text_area, widget->style->font,
                              widget->style->fg_gc[selected_state],
                              -entry->scroll_offset + selection_start_xoffset, y,
                              entry->text + selection_start_pos,
                              selection_end_pos - selection_start_pos);
 
               if (selection_end_pos < entry->text_length)
-                gdk_draw_string (entry->text_area,
+                gdk_draw_string (entry->text_area, widget->style->font,
                                  widget->style->fg_gc[GTK_STATE_NORMAL],
                                  -entry->scroll_offset + selection_end_xoffset, y,
                                  entry->text + selection_end_pos);
@@ -1043,7 +1043,7 @@
 	      GdkGCValues values;
 
 	      gdk_gc_get_values (widget->style->fg_gc[GTK_STATE_NORMAL], &values);
-              gdk_draw_string (entry->text_area,
+              gdk_draw_string (entry->text_area, widget->style->font,
                                widget->style->fg_gc[GTK_STATE_NORMAL],
                                -entry->scroll_offset, y,
                                entry->text);
diff -r -u gtk+970606/gtk/gtkhruler.c gtk+970606-i18n/gtk/gtkhruler.c
--- gtk+970606/gtk/gtkhruler.c	Wed Jun  4 10:03:03 1997
+++ gtk+970606-i18n/gtk/gtkhruler.c	Thu Jun 26 01:12:42 1997
@@ -206,7 +206,7 @@
 	      if (i == 0)
 		{
 		  sprintf (unit_str, "%d", (int) cur);
-		  gdk_draw_string (ruler->backing_store, gc,
+		  gdk_draw_string (ruler->backing_store, widget->style->font, gc,
 				   pos + 2,
 				   ythickness + digit_height - 1,
 				   unit_str);
diff -r -u gtk+970606/gtk/gtklabel.c gtk+970606-i18n/gtk/gtklabel.c
--- gtk+970606/gtk/gtklabel.c	Wed Jun  4 08:35:05 1997
+++ gtk+970606-i18n/gtk/gtklabel.c	Thu Jun 26 01:02:00 1997
@@ -212,7 +212,7 @@
 	       misc->yalign + widget->style->font->ascent) + 1.5;
 
 	  if (state == GTK_STATE_INSENSITIVE)
-	    gdk_draw_string (widget->window, widget->style->white_gc,
+	    gdk_draw_string (widget->window, widget->style->font, widget->style->white_gc,
 			     x + 1, y + 1, label->label);
 
 	  /*
@@ -222,7 +222,7 @@
 			      widget->allocation.width - 1, widget->allocation.height - 1);
 			      */
 
-	  gdk_draw_string (widget->window, widget->style->fg_gc[state],
+	  gdk_draw_string (widget->window, widget->style->font, widget->style->fg_gc[state],
 			   x, y, label->label);
 	}
       else
diff -r -u gtk+970606/gtk/gtkmain.c gtk+970606-i18n/gtk/gtkmain.c
--- gtk+970606/gtk/gtkmain.c	Sun Apr 27 12:00:37 1997
+++ gtk+970606-i18n/gtk/gtkmain.c	Tue Jun 24 19:26:35 1997
@@ -17,6 +17,7 @@
  */
 #include <stdio.h>
 #include <stdlib.h>
+#include <X11/Xlocale.h>
 #include "gtkbutton.h"
 #include "gtkhscrollbar.h"
 #include "gtkhseparator.h"
@@ -150,6 +151,25 @@
   initialized = TRUE;
 }
 
+gchar *
+gtk_setlocale(void)
+{
+  if (!setlocale(LC_ALL,""))
+      g_print("locale not supported by C library\n");
+
+  if (!XSupportsLocale())
+    {
+      g_print("locale not supported by Xlib, locale set to C\n");
+      setlocale(LC_ALL, "C");
+    }
+  
+  if (!XSetLocaleModifiers(""))
+    {
+      g_print("can not set locale modifiers\n");
+    }
+
+  return setlocale(LC_ALL,NULL);
+} 
 void
 gtk_exit (int errorcode)
 {
diff -r -u gtk+970606/gtk/gtkmain.h gtk+970606-i18n/gtk/gtkmain.h
--- gtk+970606/gtk/gtkmain.h	Wed Jun  4 08:35:03 1997
+++ gtk+970606-i18n/gtk/gtkmain.h	Fri Jun 27 22:43:37 1997
@@ -32,6 +32,7 @@
  */
 void       gtk_init              (int          *argc,
 				  char       ***argv);
+gchar *    gtk_setlocale         (void);
 void       gtk_exit              (gint          error_code);
 void       gtk_main              (void);
 void       gtk_main_quit         (void);
diff -r -u gtk+970606/gtk/gtkmenuitem.c gtk+970606-i18n/gtk/gtkmenuitem.c
--- gtk+970606/gtk/gtkmenuitem.c	Wed Jun  4 08:35:01 1997
+++ gtk+970606-i18n/gtk/gtkmenuitem.c	Thu Jun 26 01:14:33 1997
@@ -451,11 +451,11 @@
 	  y = y + ((height - (font->ascent + font->descent)) / 2) + font->ascent;
 
 	  if (state_type == GTK_STATE_INSENSITIVE)
-	    gdk_draw_string (widget->window,
+	    gdk_draw_string (widget->window, widget->style->font,
 			     widget->style->white_gc,
 			     x + 1, y + 1, buf);
 
-	  gdk_draw_string (widget->window,
+	  gdk_draw_string (widget->window, widget->style->font,
 			   widget->style->fg_gc[state_type],
 			   x, y, buf);
 	}
diff -r -u gtk+970606/gtk/gtkrc.c gtk+970606-i18n/gtk/gtkrc.c
--- gtk+970606/gtk/gtkrc.c	Fri Jun  6 15:01:51 1997
+++ gtk+970606-i18n/gtk/gtkrc.c	Fri Jun 27 11:53:55 1997
@@ -40,6 +40,7 @@
   TOKEN_BG_PIXMAP,
   TOKEN_FG,
   TOKEN_FONT,
+  TOKEN_FONTSET,
   TOKEN_INSENSITIVE,
   TOKEN_NORMAL,
   TOKEN_PIXMAP_PATH,
@@ -74,6 +75,7 @@
   int initialize;
   char *name;
   char *font_name;
+  char *fontset_name;
   char *bg_pixmap_name[5];
   GtkStyle *style;
 };
@@ -107,6 +109,7 @@
 static gint        gtk_rc_parse_fg                 (GtkStyle     *style);
 static gint        gtk_rc_parse_bg_pixmap          (GtkRcStyle   *rc_style);
 static gint        gtk_rc_parse_font               (GtkRcStyle   *rc_style);
+static gint	   gtk_rc_parse_fontset 	   (GtkRcStyle   *rc_style);
 static gint        gtk_rc_parse_state              (GtkStateType *state);
 static gint        gtk_rc_parse_color              (GdkColor     *color);
 static gint        gtk_rc_parse_pixmap_path        (void);
@@ -128,6 +131,7 @@
     { "bg_pixmap", TOKEN_BG_PIXMAP },
     { "fg", TOKEN_FG },
     { "font", TOKEN_FONT },
+    { "fontset", TOKEN_FONTSET },
     { "INSENSITIVE", TOKEN_INSENSITIVE },
     { "NORMAL", TOKEN_NORMAL },
     { "pixmap_path", TOKEN_PIXMAP_PATH },
@@ -278,6 +282,7 @@
   rc_style->initialize = FALSE;
   rc_style->name = NULL;
   rc_style->font_name = NULL;
+  rc_style->fontset_name = NULL;
 
   for (i = 0; i < 5; i++)
     rc_style->bg_pixmap_name[i] = NULL;
@@ -305,6 +310,7 @@
   rc_style->initialize = FALSE;
   rc_style->name = NULL;
   rc_style->font_name = NULL;
+  rc_style->fontset_name = NULL;
 
   for (i = 0; i < 5; i++)
     rc_style->bg_pixmap_name[i] = NULL;
@@ -427,7 +433,16 @@
     {
       rc_style->initialize = FALSE;
 
-      if (rc_style->font_name)
+      if (rc_style->fontset_name)
+	{
+	  old_font = rc_style->style->font;
+	  rc_style->style->font = gdk_fontset_load (rc_style->fontset_name);
+	  if (rc_style->style->font)
+	    gdk_fontset_free (old_font);
+	  else
+	    rc_style->style->font = old_font;
+	}
+      else if (rc_style->font_name)
 	{
 	  old_font = rc_style->style->font;
 	  rc_style->style->font = gdk_font_load (rc_style->font_name);
@@ -699,8 +714,9 @@
       rc_style = g_new (GtkRcStyle, 1);
       rc_style->initialize = TRUE;
       rc_style->name = g_strdup (token_str);
-
       rc_style->font_name = NULL;
+      rc_style->fontset_name = NULL;
+
       for (i = 0; i < 5; i++)
 	rc_style->bg_pixmap_name[i] = NULL;
 
@@ -741,9 +757,16 @@
 	  rc_style->style->black = parent_style->style->black;
 	  rc_style->style->white = parent_style->style->white;
 
-	  if (rc_style->font_name)
-	    g_free (rc_style->font_name);
-	  rc_style->font_name = g_strdup (parent_style->font_name);
+	  if (rc_style->fontset_name)
+	    {
+	      g_free (rc_style->fontset_name);
+	      rc_style->fontset_name = g_strdup (parent_style->fontset_name);
+	    }
+	  else if (rc_style->font_name)
+	    {
+	      g_free (rc_style->font_name);
+	      rc_style->font_name = g_strdup (parent_style->font_name);
+	    }
 
 	  for (i = 0; i < 5; i++)
 	    {
@@ -786,8 +809,11 @@
     {
       if (insert)
 	{
-	  if (rc_style->font_name)
+	  if (rc_style->fontset_name)
+	    g_free (rc_style->fontset_name);
+	  else if (rc_style->font_name)
 	    g_free (rc_style->font_name);
+
 	  for (i = 0; i < 5; i++)
 	    if (rc_style->bg_pixmap_name[i])
 	      g_free (rc_style->bg_pixmap_name[i]);
@@ -831,6 +857,10 @@
     return error;
 
   error = gtk_rc_parse_font (rc_style);
+  if (error != PARSE_SYNTAX)
+    return error;
+  
+  error = gtk_rc_parse_fontset (rc_style);
 
   return error;
 }
@@ -972,6 +1002,33 @@
   if (rc_style->font_name)
     g_free (rc_style->font_name);
   rc_style->font_name = g_strdup (token_str);
+
+  return PARSE_OK;
+}
+
+static gint
+gtk_rc_parse_fontset (GtkRcStyle *rc_style)
+{
+  gint token;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_FONTSET)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_EQUAL_SIGN))
+    return PARSE_ERROR;
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_STRING))
+    return PARSE_ERROR;
+
+  if (rc_style->fontset_name)
+    g_free (rc_style->fontset_name);
+  rc_style->fontset_name = g_strdup (token_str);
 
   return PARSE_OK;
 }
diff -r -u gtk+970606/gtk/gtkstyle.c gtk+970606-i18n/gtk/gtkstyle.c
--- gtk+970606/gtk/gtkstyle.c	Wed Jun  4 09:54:36 1997
+++ gtk+970606-i18n/gtk/gtkstyle.c	Sat Jun 28 00:40:35 1997
@@ -514,7 +514,14 @@
       gdk_color_white (colormap, &style->white);
 
       gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_FONT;
-      gc_values.font = style->font;
+      if (style->font->type == GDK_FONT_FONT)
+	{
+	  gc_values.font = style->font;
+	}
+      else if (style->font->type == GDK_FONT_FONTSET)
+	{
+	  gc_values.font = default_font;
+	}
 
       gc_values.foreground = style->black;
       style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
@@ -808,7 +815,12 @@
 
   unattached_styles = g_slist_remove (unattached_styles, style);
 
-  gdk_font_free (style->font);
+  if (style->font->type == GDK_FONT_FONT)
+    gdk_font_free (style->font);
+  else if (style->font->type == GDK_FONT_FONTSET)
+    gdk_fontset_free (style->font);
+  else
+    g_error("undefined font type\n");
 
   g_free (style);
 }
@@ -1592,8 +1604,8 @@
   g_return_if_fail (window != NULL);
 
   if (state_type == GTK_STATE_INSENSITIVE)
-    gdk_draw_string (window, style->white_gc, x + 1, y + 1, string);
-  gdk_draw_string (window, style->fg_gc[state_type], x, y, string);
+    gdk_draw_string (window, style->font, style->white_gc, x + 1, y + 1, string);
+  gdk_draw_string (window, style->font, style->fg_gc[state_type], x, y, string);
 }
 
 
diff -r -u gtk+970606/gtk/gtktext.c gtk+970606-i18n/gtk/gtktext.c
--- gtk+970606/gtk/gtktext.c	Fri Jun  6 15:01:49 1997
+++ gtk+970606-i18n/gtk/gtktext.c	Sat Jun 28 15:39:59 1997
@@ -2937,16 +2937,23 @@
 	{
 	  guchar* next_tab = memchr (buffer, '\t', chars);
 	  gint pixel_width;
+	  GdkFont *font;
 
 	  len = MIN (MARK_CURRENT_PROPERTY (&mark)->length - mark.offset, chars);
 
 	  if (next_tab)
 	    len = MIN (len, next_tab - buffer);
-
-	  gdk_gc_set_font (text->gc, MARK_CURRENT_PROPERTY (&mark)->font->gdk_font);
-
-	  gdk_gc_get_values (text->gc, &gc_values);
-	  pixel_width = gdk_text_width (gc_values.font, (gchar*) buffer, len);
+	  
+	  font = MARK_CURRENT_PROPERTY (&mark)->font->gdk_font;
+	  if (font->type == GDK_FONT_FONT)
+	    {
+	      gdk_gc_set_font (text->gc, font);
+	      gdk_gc_get_values (text->gc, &gc_values);
+	      pixel_width = gdk_text_width (gc_values.font, 
+					    (gchar*) buffer, len);
+	    }
+	  else
+	    pixel_width = gdk_text_width (font, (gchar*) buffer, len);
 
 	  if (MARK_CURRENT_BACK (&mark))
 	    {
@@ -2963,7 +2970,7 @@
 
 	  gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (&mark));
 
-	  gdk_draw_text (text->text_area,
+	  gdk_draw_text (text->text_area, MARK_CURRENT_FONT (&mark),
 			 text->gc,
 			 running_offset,
 			 pixel_height,
@@ -3102,11 +3109,12 @@
 
       if (text->cursor_char)
 	{
-	  gdk_gc_set_font (text->gc, font);
-
+	  if (font->type == GDK_FONT_FONT)
+	    gdk_gc_set_font (text->gc, font);
+	
 	  gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (&text->cursor_mark));
 
-	  gdk_draw_text (text->text_area,
+	  gdk_draw_text (text->text_area, font,
 			 text->gc,
 			 text->cursor_pos_x,
 			 text->cursor_pos_y - text->cursor_char_offset,
diff -r -u gtk+970606/gtk/gtktooltips.c gtk+970606-i18n/gtk/gtktooltips.c
--- gtk+970606/gtk/gtktooltips.c	Wed Jun  4 08:38:07 1997
+++ gtk+970606-i18n/gtk/gtktooltips.c	Thu Jun 26 01:17:55 1997
@@ -398,8 +398,8 @@
     {
       if (el->data)
        {
-         gdk_draw_string (tooltips->tip_window->window, tooltips->gc, 4, y,
-                          el->data);
+         gdk_draw_string (tooltips->tip_window->window, style->font, 
+			  tooltips->gc, 4, y, el->data);
          y += baseline_skip;
        }
       else
diff -r -u gtk+970606/gtk/gtkvruler.c gtk+970606-i18n/gtk/gtkvruler.c
--- gtk+970606/gtk/gtkvruler.c	Wed Jun  4 10:03:09 1997
+++ gtk+970606-i18n/gtk/gtkvruler.c	Thu Jun 26 01:16:31 1997
@@ -211,7 +211,7 @@
 		  for (j = 0; j < strlen (unit_str); j++)
 		    {
 		      digit_str[0] = unit_str[j];
-		      gdk_draw_string (ruler->backing_store, gc,
+		      gdk_draw_string (ruler->backing_store, widget->style->font, gc,
 				       xthickness + 1,
 				       pos + digit_height * (j + 1) + 1,
 				       digit_str);
diff -r -u gtk+970606/gtk/testgtk.c gtk+970606-i18n/gtk/testgtk.c
--- gtk+970606/gtk/testgtk.c	Fri Jun  6 15:01:44 1997
+++ gtk+970606-i18n/gtk/testgtk.c	Tue Jun 24 19:18:41 1997
@@ -2183,6 +2183,8 @@
 int
 main (int argc, char *argv[])
 {
+  gtk_setlocale();
+  
   gtk_init (&argc, &argv);
   gtk_rc_parse ("testgtkrc");
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]