Re: GtkEntry needs to be fixed in order to work correctly with fonts (not fontsets) under non-latin1 single-byte locale
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list gnome org
- Cc: Vlad Harchev <hvv hippo ru>
- Subject: Re: GtkEntry needs to be fixed in order to work correctly with fonts (not fontsets) under non-latin1 single-byte locale
- Date: 15 Mar 2001 15:16:27 -0500
Vlad Harchev <hvv hippo ru> writes:
> > 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..
I had absolutely no trouble causing GTK+ to die with an assertion failure
in about two seconds with LC_ALL=koi8-r, a font (not fontset), and without
this patch.
So, I think it's pretty necessary to apply it if you want this to work.
> What do you think of them? Will they go into gtk-1.2.10?
The attached patch is basically your patch, with some cleanups. I've
also added a small fix for the handling of '*' which was broken in
a similar way, though I don't think it was causing any problems.
I do plan to apply this for 1.2.10.
Thanks,
Owen
? memprof.out1
? memprof.out2
? russian.xkm
Index: gtkentry.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkentry.c,v
retrieving revision 1.75.2.8
diff -u -r1.75.2.8 gtkentry.c
--- gtkentry.c 2001/02/22 20:38:13 1.75.2.8
+++ gtkentry.c 2001/03/15 20:15:44
@@ -374,6 +374,48 @@
return GTK_WIDGET (gtk_type_new (GTK_TYPE_ENTRY));
}
+static GdkWChar
+gtk_entry_get_invisible_char (GtkEntry *entry)
+{
+ GdkWChar ch;
+
+ if (entry->use_wchar)
+ gdk_mbstowcs (&ch, "*", 1);
+ else
+ ch = '*';
+
+ return ch;
+}
+
+/*
+ * Draws the string, noting that if entry->use_wchar is false, then
+ * the text is not really wide characters, but narrow characters
+ * stored as wide characters.
+ */
+static void
+gtk_entry_draw_wchars (GtkEntry *entry,
+ GdkDrawable *drawable,
+ GdkFont *font,
+ GdkGC *gc,
+ gint x,
+ gint y,
+ const GdkWChar *text,
+ gint text_length)
+{
+ if (entry->use_wchar)
+ gdk_draw_text_wc (drawable, font, gc, x, y, text, text_length);
+ else
+ {
+ gint i;
+ gchar *mbstr = g_new (gchar, text_length);
+
+ 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)
{
@@ -1398,19 +1440,20 @@
else
{
gint i;
+ GdkWChar invisible_char = gtk_entry_get_invisible_char (entry);
stars = g_new (GdkWChar, end_pos - start_pos);
for (i = 0; i < end_pos - start_pos; i++)
- stars[i] = '*';
+ stars[i] = invisible_char;
toprint = stars;
}
if (selection_start_pos > start_pos)
- gdk_draw_text_wc (drawable, widget->style->font,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- INNER_BORDER + start_xoffset, y,
- toprint,
- selection_start_pos - start_pos);
+ gtk_entry_draw_wchars (entry, drawable, widget->style->font,
+ widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ INNER_BORDER + start_xoffset, y,
+ toprint,
+ selection_start_pos - start_pos);
if ((selection_end_pos >= start_pos) &&
(selection_start_pos < end_pos) &&
@@ -1423,19 +1466,19 @@
INNER_BORDER,
selection_end_xoffset - selection_start_xoffset,
height - 2*INNER_BORDER);
- gdk_draw_text_wc (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);
+ gtk_entry_draw_wchars (entry, 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);
}
if (selection_end_pos < end_pos)
- gdk_draw_text_wc (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);
+ gtk_entry_draw_wchars (entry, 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);
/* free the space allocated for the stars if it's neccessary. */
if (!editable->visible)
g_free (toprint);
@@ -1510,9 +1553,9 @@
*(entry->text + editable->current_pos) :
'*';
- gdk_draw_text_wc (drawable, widget->style->font,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- xoffset, yoffset, &c, 1);
+ gtk_entry_draw_wchars (entry, drawable, widget->style->font,
+ widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ xoffset, yoffset, &c, 1);
}
}
@@ -1780,21 +1823,23 @@
gint offset = 0;
for (i = last_pos; i >= end_pos; i--)
- entry->char_offset[i]
- = entry->char_offset[i - insertion_length];
+ entry->char_offset[i] = entry->char_offset[i - insertion_length];
for (i=start_pos; i<end_pos; i++)
{
+ GdkWChar ch;
+
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]);
- }
+ ch = entry->text[i];
+ else
+ ch = gtk_entry_get_invisible_char (entry);
+
+ if (entry->use_wchar)
+ offset += gdk_char_width_wc (GTK_WIDGET (entry)->style->font, ch);
else
- {
- offset += gdk_char_width (GTK_WIDGET (entry)->style->font, '*');
- }
+ offset += gdk_char_width (GTK_WIDGET (entry)->style->font, ch);
}
for (i = end_pos; i <= last_pos; i++)
entry->char_offset[i] += offset;
@@ -1813,21 +1858,25 @@
{
gint i;
gint offset = 0;
+ GtkEditable *editable = GTK_EDITABLE (entry);
for (i=0; i<entry->text_length; i++)
{
+ GdkWChar ch;
+
entry->char_offset[i] = offset;
- if (GTK_EDITABLE (entry)->visible)
- {
- offset += gdk_char_width_wc (GTK_WIDGET (entry)->style->font,
- entry->text[i]);
- }
+
+ if (editable->visible)
+ ch = entry->text[i];
else
- {
- offset += gdk_char_width (GTK_WIDGET (entry)->style->font, '*');
- }
- }
+ ch = gtk_entry_get_invisible_char (entry);
+ if (entry->use_wchar)
+ offset += gdk_char_width_wc (GTK_WIDGET (entry)->style->font, ch);
+ else
+ offset += gdk_char_width (GTK_WIDGET (entry)->style->font, ch);
+ }
+
entry->char_offset[i] = offset;
}
Index: gtktext.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktext.c,v
retrieving revision 1.79.2.10
diff -u -r1.79.2.10 gtktext.c
--- gtktext.c 2001/02/22 20:38:15 1.79.2.10
+++ gtktext.c 2001/03/15 20:15:44
@@ -5041,7 +5041,7 @@
pixel_width = gdk_text_width_wc (gc_values.font,
buffer.wc, len);
else
- pixel_width = gdk_text_width (gc_values.font,
+ pixel_width = gdk_text_width (gc_values.font,
buffer.ch, len);
}
else
@@ -5205,15 +5205,26 @@
{
if (font->type == GDK_FONT_FONT)
gdk_gc_set_font (text->gc, font);
-
+
gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (text, &text->cursor_mark));
-
- 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);
+
+ 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
+ {
+ guchar 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,
+ (gchar *)&ch,
+ 1);
+ }
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]