Re: GtkEntry needs to be fixed in order to work correctly with fonts (not fontsets) under non-latin1 single-byte locale



On 13 Mar 2001, Owen Taylor wrote:

> 
> Vlad Harchev <hvv hippo ru> writes:
> 
> >  Hi, 
> > 
> >  The GtkEntry recent version of gtk, 1.2.9, still has bugs of not working
> > correctly with fonts (not fontsets) under non-latin1 single-byte locale -
> > since GtkEntry uses *_wc family of functions independant of the use_wchar -
> > i.e. _wc functions are used for multibyte text too!
> >  This bug leads to displaying completely wrong glyphs in GtkEntry!
> 
> I guess it's good that we didn't switch over the RC files to use
> fonts, then!

 On the other hand, we would find the bug faster..
 
> >  The gross hack to fix this problem is
> > change
> > 	entry->use_wchar = FALSE;
> > to 
> > 	entry->use_wchar = TRUE;
> > in gtk_entry_init. It works just fine, the only issues it has is decreasing
> > performance (but it's negligible I think).
> 
> We can't make this change for GTK+-1.2.10. There are a substantial 
> number of systems where the wide character functions (gdk_iswspace,
> and so forth) are broken. 
> 
> Now, if we were putting out a release with a long testing period
> be able to figure out exactly what, if anything, would break.
> 
> But 1.2.10 is going out tomorrow morning, with the goal of introducing
> zero new defects beyond those in 1.2.9. 
> 
> So this is not a change I feel comfortable with. I'd be much
> more comfortable with a patch that:
> 
>  - Always used the GDK functions for converting between multi-byte
>    and wide characters.
> 
>  - But, as currently, only used iswspace and relatives when 
>    a fontset is in use.
>  
> >  Also I can prepare a patch for GtkEntry that fixes all problems in a clean
> > way (i.e. calling non-wc versions of functions if entry->use_wchar  is FALSE
> > and *_wc version of functions when entry->use_wchar is TRUE). Of course it
> > will complicate code somewhat.. Will this patch be accepted and included in 
> > 1.2.10 (if it has no technical flaws) or hackish solution will be preferred?
> 
> If you can get me a patch by tomorrow morning, my time, that:
>  
>  - Fixes all occurences of conversion between characters and bytes
>    by direct assignment by using the GDK functions.
> 
>    (Note that this occurs in GtkText as well - see, e.g., line 3773)
> 
>  - Is thoroughly tested out. 
>    
> Then I'll consider it for inclusion in 1.2.10. But I don't want to
> just make random changes in hopes of moving forward.
> 
> Thanks,
>                                         Owen

 Here are the patch against gtkentry.c (tested with and without fontsets under
russian locale, with and without use_std_env in XLC_LOCALE) - everything seems
to work fine (and the bug is fixed by it of course).

 Also a small patch to GtkText attached of the similar brand. Though I never
triggered a problem it potentially fixes, so it's not that necessary to apply
it..

 What do you think of them? Will they go into gtk-1.2.10?

 Thanks.

 Best regards,
  -Vlad
--- gtkentry.c-orig	Wed Mar 14 12:04:11 2001
+++ gtkentry.c	Wed Mar 14 12:51:07 2001
@@ -374,6 +374,34 @@
   return GTK_WIDGET (gtk_type_new (GTK_TYPE_ENTRY));
 }
 
+/*
+ * Draws teh string as gdk_draw_text{,_wc} do, but it treats text as 
+ * WChars or multibyte sequence depending on 'really_wchars'
+ */
+static void
+gtk_draw_text_aux (GdkDrawable	 *drawable,
+			  GdkFont	 *font,
+			  GdkGC		 *gc,
+			  gint		  x,
+			  gint		  y,
+			  const GdkWChar *text,
+			  gint		  text_length,
+                          gboolean        really_wchars)
+{
+  if (really_wchars)     
+    gdk_draw_text_wc (drawable, font, gc, x, y, text, text_length);
+  else
+    {
+      gchar* mbstr = g_new(gchar, text_length);
+      int i;
+      for(i=0; i<text_length; ++i)
+        mbstr[i] = text[i];
+      gdk_draw_text (drawable, font, gc, x, y, mbstr, text_length);    
+      g_free(mbstr);
+    }
+}
+
+                                                                                                                                                            
 GtkWidget*
 gtk_entry_new_with_max_length (guint16 max)
 {
@@ -1406,11 +1434,11 @@
 	}
       
       if (selection_start_pos > start_pos)
-	gdk_draw_text_wc (drawable, widget->style->font,
+	gtk_draw_text_aux (drawable, widget->style->font,
 			  widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
 			  INNER_BORDER + start_xoffset, y,
 			  toprint,
-			  selection_start_pos - start_pos);
+			  selection_start_pos - start_pos, entry->use_wchar);
       
       if ((selection_end_pos >= start_pos) && 
 	  (selection_start_pos < end_pos) &&
@@ -1423,19 +1451,20 @@
 				INNER_BORDER,
 				selection_end_xoffset - selection_start_xoffset,
 				height - 2*INNER_BORDER);
-	    gdk_draw_text_wc (drawable, widget->style->font,
+	    gtk_draw_text_aux (drawable, widget->style->font,
 			      widget->style->fg_gc[selected_state],
 			      INNER_BORDER + selection_start_xoffset, y,
 			      toprint + selection_start_pos - start_pos,
-			      selection_end_pos - selection_start_pos);
+			      selection_end_pos - selection_start_pos, 
+                              entry->use_wchar);
 	 }	    
        
        if (selection_end_pos < end_pos)
-	 gdk_draw_text_wc (drawable, widget->style->font,
+	 gtk_draw_text_aux (drawable, widget->style->font,
 			   widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
 			   INNER_BORDER + selection_end_xoffset, y,
 			   toprint + selection_end_pos - start_pos,
-			   end_pos - selection_end_pos);
+			   end_pos - selection_end_pos, entry->use_wchar);
        /* free the space allocated for the stars if it's neccessary. */
       if (!editable->visible)
 	g_free (toprint);
@@ -1510,9 +1539,9 @@
 		                 *(entry->text + editable->current_pos) :
 		                 '*';
 	      
-	      gdk_draw_text_wc (drawable, widget->style->font,
+	      gtk_draw_text_aux (drawable, widget->style->font,
 				widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-				xoffset, yoffset, &c, 1);
+				xoffset, yoffset, &c, 1, entry->use_wchar);
 	    }
 	}
 
@@ -1788,8 +1817,10 @@
 	  entry->char_offset[i] = entry->char_offset[start_pos] + offset;
 	  if (editable->visible)
 	    {
-	      offset += gdk_char_width_wc (GTK_WIDGET (entry)->style->font,
-					   entry->text[i]);
+	      offset += entry->use_wchar ? gdk_char_width_wc (GTK_WIDGET (entry)->style->font,
+					           entry->text[i]) : 
+                                           gdk_char_width (GTK_WIDGET (entry)->style->font,
+					           entry->text[i]);
 	    }
 	  else
 	    {
@@ -1819,8 +1850,10 @@
       entry->char_offset[i] = offset;
       if (GTK_EDITABLE (entry)->visible)
 	{
-	  offset += gdk_char_width_wc (GTK_WIDGET (entry)->style->font,
-				       entry->text[i]);
+	  offset += entry->use_wchar ? gdk_char_width_wc (GTK_WIDGET (entry)->style->font,
+				               entry->text[i]) : 
+                                       gdk_char_width (GTK_WIDGET (entry)->style->font,
+				               entry->text[i]);
 	}
       else
 	{
--- gtktext.c~	Tue Mar 13 13:46:51 2001
+++ gtktext.c	Wed Mar 14 13:06:03 2001
@@ -5208,12 +5208,23 @@
 
 	  gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (text, &text->cursor_mark));
 
-	  gdk_draw_text_wc (text->text_area, font,
+          if (text->use_wchar)
+	    gdk_draw_text_wc (text->text_area, font,
 			 text->gc,
 			 text->cursor_pos_x,
 			 text->cursor_pos_y - text->cursor_char_offset,
 			 &text->cursor_char,
 			 1);
+           else
+             {
+               gchar ch = text->cursor_char;
+	       gdk_draw_text (text->text_area, font,
+			 text->gc,
+			 text->cursor_pos_x,
+			 text->cursor_pos_y - text->cursor_char_offset,
+			 &ch,
+			 1);               
+             }
 	}
     }
 }


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