slackware-current/source/l/gtk+/gtk+-1.2.10-ahiguti.patch

558 lines
18 KiB
Diff
Raw Permalink Normal View History

Return-Path: a-higuti@math.sci.hokudai.ac.jp
Delivery-Date: Thu Sep 23 14:52:43 1999
Return-Path: <a-higuti@math.sci.hokudai.ac.jp>
Received: from localhost (IDENT:otaylor@localhost [127.0.0.1])
by fresnel.labs.redhat.com (8.9.3/8.9.3) with ESMTP id OAA00891
for <otaylor@localhost>; Thu, 23 Sep 1999 14:52:41 -0400
Received: from lacrosse.redhat.com
by localhost with POP3 (fetchmail-5.0.0)
for otaylor@localhost (single-drop); Thu, 23 Sep 1999 14:52:42 -0400 (EDT)
Received: from mail.redhat.com (mail.redhat.com [199.183.24.239])
by lacrosse.corp.redhat.com (8.9.3/8.9.3) with ESMTP id OAA19205
for <otaylor@lacrosse.redhat.com>; Thu, 23 Sep 1999 14:01:27 -0400
Received: from math.sci.hokudai.ac.jp (seki.math.sci.hokudai.ac.jp [133.50.152.8])
by mail.redhat.com (8.8.7/8.8.7) with ESMTP id OAA13383
for <otaylor@redhat.com>; Thu, 23 Sep 1999 14:01:49 -0400
Received: from heathcliff (a-higuti@hilbert.math.sci.hokudai.ac.jp [133.50.152.11])
by math.sci.hokudai.ac.jp (8.8.8/3.6W01/06/98) with SMTP id DAA23889
for <otaylor@redhat.com>; Fri, 24 Sep 1999 03:01:10 +0900 (JST)
Date: Fri, 24 Sep 1999 03:01:10 +0900 (JST)
Message-Id: <199909231801.DAA23889@math.sci.hokudai.ac.jp>
From: a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi)
To: otaylor@redhat.com
Subject: Adding more gdk_isw* macros
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Status: O
Lines: 528
Xref: fresnel.labs.redhat.com prog-gtk:648
Hello Owen,
I'm working on adding CJK support to gnome apps, and I need your advice.
As you know, gtk+-1.2 has some support for CJK. It's sufficient for most
gnome apps to be internationalized, but some problems remain. The most
problem is that there is no way of doing word wrapping for CJK strings.
For example, gtk-xmhtml shows Japanese text very uglily, because Japanese
sentences are recognized as very long words. (a Japanese sentence
contain any spaces in most cases.) The same problem is in gtk+ itself, too;
Word wrapping in GtkLabel and GtkText doesn't work correctly for CJK text,
because of the same reason as above.
In order to fix it, we need more gdk_isw* functions than we already have
in gdki18n.h. (I regret I didn't add them before gtk+-1.2 was released.)
I attach herewith a patch which fixes it, but I think it's not acceptable
to adding a new macro to a stable version of gtk+. (is it?)
The question I want to ask you is: what's the best way of fixing the
problem without adding these macros to gdki18n.h? A solution is to add
these macros to each *.c files (in GtkLabel, GtkText, and gtkxmhtml etc.)
rather than gtki18n.h, but it's very ugly I think.
Please don't say "wait until gscript is completed" ;-( I don't want to
wait for a long time. (Please let me know if I can help you with gscript
BTW. I've not hacked gscript yet, because it seems to be too early to be
hacked by other than you.)
Thanks,
Akira Higuchi
---------------- x8 ---------------- x8 ---------------- x8 ----------------
diff -up gtk+-1.2.10/gdk/gdki18n.h.ahiguti gtk+-1.2.10/gdk/gdki18n.h
--- gtk+-1.2.10/gdk/gdki18n.h.ahiguti 2000-01-24 03:58:21.000000000 +0100
+++ gtk+-1.2.10/gdk/gdki18n.h 2008-10-02 10:43:26.000000000 +0200
@@ -51,4 +51,32 @@
# define gdk_iswspace(c) ((wchar_t)(c) <= 0xFF && isspace(c))
#endif
+/* The following 9 macros are added in gtk+ 1.2.X. Don't use them without
+ * checking GTK_CHECK_VERSION. For example,
+ * #if GTK_CHECK_VERSION (1,2,X)
+ * ... code which uses gdk_iswalpha(), gdk_iswcntrl(), etc. ...
+ * #endif
+ */
+#if !defined(G_HAVE_BROKEN_WCTYPE) && (defined(G_HAVE_WCTYPE_H) || defined(G_HAVE_WCHAR_H)) && !defined(X_LOCALE)
+# define gdk_iswalpha(c) iswalpha(c)
+# define gdk_iswcntrl(c) iswcntrl(c)
+# define gdk_iswdigit(c) iswdigit(c)
+# define gdk_iswlower(c) iswlower(c)
+# define gdk_iswgraph(c) iswgraph(c)
+# define gdk_iswprint(c) iswprint(c)
+# define gdk_iswpunct(c) iswpunct(c)
+# define gdk_iswupper(c) iswupper(c)
+# define gdk_iswxdigit(c) iswxdigit(c)
+#else
+# define gdk_iswalpha(c) ((wchar_t)(c) <= 0xFF && isalpha(c))
+# define gdk_iswcntrl(c) ((wchar_t)(c) <= 0xFF && iscntrl(c))
+# define gdk_iswdigit(c) ((wchar_t)(c) <= 0xFF && isdigit(c))
+# define gdk_iswlower(c) ((wchar_t)(c) <= 0xFF && islower(c))
+# define gdk_iswgraph(c) ((wchar_t)(c) > 0xFF || isgraph(c))
+# define gdk_iswprint(c) ((wchar_t)(c) > 0xFF || isprint(c))
+# define gdk_iswpunct(c) ((wchar_t)(c) <= 0xFF && ispunct(c))
+# define gdk_iswupper(c) ((wchar_t)(c) <= 0xFF && isupper(c))
+# define gdk_iswxdigit(c) ((wchar_t)(c) <= 0xFF && isxdigit(c))
+#endif
+
#endif /* __GDK_I18N_H__ */
diff -up gtk+-1.2.10/gtk/gtkentry.c.ahiguti gtk+-1.2.10/gtk/gtkentry.c
--- gtk+-1.2.10/gtk/gtkentry.c.ahiguti 2001-04-02 04:14:54.000000000 +0200
+++ gtk+-1.2.10/gtk/gtkentry.c 2008-10-02 10:43:26.000000000 +0200
@@ -2036,11 +2036,21 @@ gtk_entry_move_word (GtkEditable *editab
}
}
+static gboolean
+alnum_or_ideogram (GtkEntry *entry, guint index)
+{
+ GdkWChar ch;
+ ch = entry->text[index];
+ if (entry->use_wchar)
+ return !(gdk_iswpunct (ch) || gdk_iswcntrl (ch) || gdk_iswspace (ch));
+ else
+ return !(ispunct (ch) || iscntrl (ch) || isspace (ch));
+}
+
static void
gtk_move_forward_word (GtkEntry *entry)
{
GtkEditable *editable;
- GdkWChar *text;
gint i;
editable = GTK_EDITABLE (entry);
@@ -2054,21 +2064,12 @@ gtk_move_forward_word (GtkEntry *entry)
if (entry->text && (editable->current_pos < entry->text_length))
{
- text = entry->text;
- i = editable->current_pos;
-
- if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
- for (; i < entry->text_length; i++)
- {
- if ((entry->use_wchar) ? gdk_iswalnum (text[i]) : isalnum (text[i]))
- break;
- }
-
+ for (i = editable->current_pos; i < entry->text_length; i++)
+ if (alnum_or_ideogram (entry, i))
+ break;
for (; i < entry->text_length; i++)
- {
- if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
- break;
- }
+ if (!alnum_or_ideogram (entry, i))
+ break;
editable->current_pos = i;
}
@@ -2078,7 +2079,6 @@ static void
gtk_move_backward_word (GtkEntry *entry)
{
GtkEditable *editable;
- GdkWChar *text;
gint i;
editable = GTK_EDITABLE (entry);
@@ -2092,26 +2092,19 @@ gtk_move_backward_word (GtkEntry *entry)
if (entry->text && editable->current_pos > 0)
{
- text = entry->text;
- i = editable->current_pos - 1;
- if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
- for (; i >= 0; i--)
+ for (i = editable->current_pos - 1; i >= 0; i--)
+ if (alnum_or_ideogram (entry, i))
+ break;
+ for (; i >= 0; i--)
+ if (!alnum_or_ideogram (entry, i))
{
- if ((entry->use_wchar) ? gdk_iswalnum (text[i]) : isalnum (text[i]))
- break;
+ i++;
+ break;
}
- for (; i >= 0; i--)
- {
- if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
- {
- i++;
- break;
- }
- }
-
+
if (i < 0)
i = 0;
-
+
editable->current_pos = i;
}
}
diff -up gtk+-1.2.10/gtk/gtklabel.c.ahiguti gtk+-1.2.10/gtk/gtklabel.c
--- gtk+-1.2.10/gtk/gtklabel.c.ahiguti 2001-04-02 05:12:38.000000000 +0200
+++ gtk+-1.2.10/gtk/gtklabel.c 2008-10-02 10:43:26.000000000 +0200
@@ -56,6 +56,7 @@ struct _GtkLabelWord
GtkLabelWord *next;
gint uline_y;
GtkLabelULine *uline;
+ gboolean paragraph_break;
};
struct _GtkLabelULine
@@ -396,6 +397,7 @@ gtk_label_word_alloc (void)
word->beginning = NULL;
word->next = NULL;
word->uline = NULL;
+ word->paragraph_break = FALSE;
return word;
}
@@ -441,6 +443,7 @@ gtk_label_split_text (GtkLabel *label)
if (str == label->label_wc || str[-1] == '\n')
{
/* Paragraph break */
+ word->paragraph_break = TRUE;
word->space = 0;
max_line_width = MAX (line_width, max_line_width);
@@ -488,6 +491,7 @@ gtk_label_split_text (GtkLabel *label)
{
word = gtk_label_word_alloc ();
+ word->paragraph_break = TRUE;
word->space = 0;
word->beginning = str;
word->length = 0;
@@ -500,6 +504,13 @@ gtk_label_split_text (GtkLabel *label)
return MAX (line_width, max_line_width);
}
+static gboolean
+is_ideogram (GdkWChar wc)
+{
+ return !(gdk_iswalnum (wc) || gdk_iswspace (wc) ||
+ gdk_iswpunct (wc) || gdk_iswcntrl (wc));
+}
+
/* this needs to handle white space better. */
static gint
gtk_label_split_text_wrapped (GtkLabel *label)
@@ -526,6 +537,7 @@ gtk_label_split_text_wrapped (GtkLabel *
if (str == label->label_wc || str[-1] == '\n')
{
/* Paragraph break */
+ word->paragraph_break = TRUE;
word->space = 0;
max_line_width = MAX (line_width, max_line_width);
@@ -546,24 +558,30 @@ gtk_label_split_text_wrapped (GtkLabel *
else
word->space = space_width * nspaces;
}
- else
+ else if (gdk_iswspace (str[-1]))
{
/* Regular inter-word space */
word->space = space_width;
}
+ else
+ {
+ word->space = 0;
+ }
word->beginning = str;
word->length = 0;
p = word->beginning;
while (*p && !gdk_iswspace (*p))
{
+ if (word->length > 0 && (is_ideogram (p[-1]) || is_ideogram (*p)))
+ break;
word->length++;
p++;
}
word->width = gdk_text_width_wc (GTK_WIDGET (label)->style->font, str, word->length);
str += word->length;
- if (*str)
+ if (*str && gdk_iswspace (*str))
str++;
line_width += word->space + word->width;
@@ -600,7 +618,7 @@ gtk_label_pick_width (GtkLabel *label,
width = 0;
for (word = label->words; word; word = word->next)
{
- if (word->space == 0
+ if (word->paragraph_break
|| (line_width
&& (line_width >= min_width
|| line_width + word->width + word->space > max_width)))
@@ -716,7 +734,8 @@ gtk_label_finalize_lines_wrap (GtkLabel
GtkLabelWord *word, *line, *next_line;
GtkWidget *widget;
gchar *ptrn;
- gint x, y, space, extra_width, add_space, baseline_skip;
+ gint x, y, space, num_words, extra_width, add_space, baseline_skip;
+ gboolean deliver_equivalently;
g_return_if_fail (label->wrap);
@@ -724,20 +743,24 @@ gtk_label_finalize_lines_wrap (GtkLabel
y = 0;
baseline_skip = (GTK_WIDGET (label)->style->font->ascent +
GTK_WIDGET (label)->style->font->descent + 1);
+ deliver_equivalently = FALSE;
for (line = label->words; line != 0; line = next_line)
{
- space = 0;
+ space = num_words = 0;
extra_width = max_line_width - line->width;
for (next_line = line->next; next_line; next_line = next_line->next)
{
- if (next_line->space == 0)
+ if (next_line->paragraph_break)
break; /* New paragraph */
if (next_line->space + next_line->width > extra_width)
break;
+ if (next_line->space == 0)
+ deliver_equivalently = TRUE; /* An ideogram is found. */
extra_width -= next_line->space + next_line->width;
space += next_line->space;
+ num_words++;
}
line->x = 0;
@@ -747,14 +770,18 @@ gtk_label_finalize_lines_wrap (GtkLabel
for (word = line->next; word != next_line; word = word->next)
{
- if (next_line && next_line->space)
+ if (next_line && !next_line->paragraph_break &&
+ label->jtype == GTK_JUSTIFY_FILL &&
+ (deliver_equivalently ? num_words : space) > 0)
{
- /* Not last line of paragraph --- fill line if needed */
- if (label->jtype == GTK_JUSTIFY_FILL) {
+ /* Not last line of paragraph --- fill line */
+ if (deliver_equivalently)
+ add_space = (extra_width + num_words / 2) / num_words;
+ else
add_space = (extra_width * word->space + space / 2) / space;
- extra_width -= add_space;
- space -= word->space;
- }
+ extra_width -= add_space;
+ space -= word->space;
+ num_words--;
}
word->x = x + word->space + add_space;
@@ -925,7 +952,7 @@ gtk_label_expose (GtkWidget *widget
for (word = label->words; word; word = word->next)
{
- gchar save = word->beginning[word->length];
+ GdkWChar save = word->beginning[word->length];
word->beginning[word->length] = '\0';
gtk_label_paint_word (label, x, y, word, &event->area);
word->beginning[word->length] = save;
diff -up gtk+-1.2.10/gtk/gtktext.c.ahiguti gtk+-1.2.10/gtk/gtktext.c
--- gtk+-1.2.10/gtk/gtktext.c.ahiguti 2001-03-15 21:15:12.000000000 +0100
+++ gtk+-1.2.10/gtk/gtktext.c 2008-10-02 10:43:27.000000000 +0200
@@ -101,6 +101,13 @@ enum {
ARG_WORD_WRAP
};
+typedef enum {
+ CHAR_CLASS_SPACE,
+ CHAR_CLASS_ALNUM,
+ CHAR_CLASS_IDEOGRAM,
+ CHAR_CLASS_OTHERS /* punct, cntrl */
+} CharClass;
+
typedef struct _TextProperty TextProperty;
typedef struct _TabStopMark TabStopMark;
typedef struct _PrevTabCont PrevTabCont;
@@ -300,6 +307,8 @@ static LineParams find_line_params (GtkT
const GtkPropertyMark *mark,
const PrevTabCont *tab_cont,
PrevTabCont *next_cont);
+static void find_word_wrap_position (GtkText* text, LineParams *lp);
+static CharClass char_class (GtkText* text, guint index);
static void recompute_geometry (GtkText* text);
static void insert_expose (GtkText* text, guint old_pixels, gint nchars, guint new_line_count);
static void delete_expose (GtkText* text,
@@ -4111,27 +4120,21 @@ gtk_text_move_forward_word (GtkText *tex
undraw_cursor (text, FALSE);
- if (text->use_wchar)
+ while (!LAST_INDEX (text, text->cursor_mark))
{
- while (!LAST_INDEX (text, text->cursor_mark) &&
- !gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
- advance_mark (&text->cursor_mark);
-
- while (!LAST_INDEX (text, text->cursor_mark) &&
- gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
- advance_mark (&text->cursor_mark);
+ CharClass cc = char_class (text, text->cursor_mark.index);
+ if (cc == CHAR_CLASS_ALNUM || cc == CHAR_CLASS_IDEOGRAM)
+ break;
+ advance_mark (&text->cursor_mark);
}
- else
+ while (!LAST_INDEX (text, text->cursor_mark))
{
- while (!LAST_INDEX (text, text->cursor_mark) &&
- !isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
- advance_mark (&text->cursor_mark);
-
- while (!LAST_INDEX (text, text->cursor_mark) &&
- isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
- advance_mark (&text->cursor_mark);
+ CharClass cc = char_class (text, text->cursor_mark.index);
+ if (cc != CHAR_CLASS_ALNUM && cc != CHAR_CLASS_IDEOGRAM)
+ break;
+ advance_mark (&text->cursor_mark);
}
-
+
find_cursor (text, TRUE);
draw_cursor (text, FALSE);
}
@@ -4143,25 +4146,19 @@ gtk_text_move_backward_word (GtkText *te
undraw_cursor (text, FALSE);
- if (text->use_wchar)
+ while (text->cursor_mark.index > 0)
{
- while ((text->cursor_mark.index > 0) &&
- !gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
- decrement_mark (&text->cursor_mark);
-
- while ((text->cursor_mark.index > 0) &&
- gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
- decrement_mark (&text->cursor_mark);
+ CharClass cc = char_class (text, text->cursor_mark.index - 1);
+ if (cc == CHAR_CLASS_ALNUM || cc == CHAR_CLASS_IDEOGRAM)
+ break;
+ decrement_mark (&text->cursor_mark);
}
- else
+ while (text->cursor_mark.index > 0)
{
- while ((text->cursor_mark.index > 0) &&
- !isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
- decrement_mark (&text->cursor_mark);
-
- while ((text->cursor_mark.index > 0) &&
- isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
- decrement_mark (&text->cursor_mark);
+ CharClass cc = char_class (text, text->cursor_mark.index - 1);
+ if (cc != CHAR_CLASS_ALNUM && cc != CHAR_CLASS_IDEOGRAM)
+ break;
+ decrement_mark (&text->cursor_mark);
}
find_cursor (text, TRUE);
@@ -4782,27 +4779,8 @@ find_line_params (GtkText* text,
GtkPropertyMark saved_mark = lp.end;
guint saved_characters = lp.displayable_chars;
- lp.displayable_chars += 1;
-
- if (text->use_wchar)
- {
- while (!gdk_iswspace (GTK_TEXT_INDEX (text, lp.end.index)) &&
- (lp.end.index > lp.start.index))
- {
- decrement_mark (&lp.end);
- lp.displayable_chars -= 1;
- }
- }
- else
- {
- while (!isspace(GTK_TEXT_INDEX (text, lp.end.index)) &&
- (lp.end.index > lp.start.index))
- {
- decrement_mark (&lp.end);
- lp.displayable_chars -= 1;
- }
- }
-
+ find_word_wrap_position (text, &lp);
+
/* If whole line is one word, revert to char wrapping */
if (lp.end.index == lp.start.index)
{
@@ -4850,6 +4828,54 @@ find_line_params (GtkText* text,
return lp;
}
+static CharClass
+char_class (GtkText* text, guint index)
+{
+ GdkWChar wc;
+ wc = GTK_TEXT_INDEX (text, index);
+ if (text->use_wchar)
+ {
+ if (gdk_iswspace (wc))
+ return CHAR_CLASS_SPACE;
+ else if (gdk_iswalnum (wc))
+ return CHAR_CLASS_ALNUM;
+ else if (gdk_iswpunct (wc) || gdk_iswcntrl (wc))
+ return CHAR_CLASS_OTHERS;
+ else
+ return CHAR_CLASS_IDEOGRAM;
+ }
+ else
+ {
+ if (isspace (wc))
+ return CHAR_CLASS_SPACE;
+ else if (isalnum (wc))
+ return CHAR_CLASS_ALNUM;
+ else if (ispunct (wc) || iscntrl (wc))
+ return CHAR_CLASS_OTHERS;
+ else
+ return CHAR_CLASS_IDEOGRAM;
+ }
+}
+
+static void
+find_word_wrap_position (GtkText* text, LineParams *lp)
+{
+ while (lp->end.index > lp->start.index &&
+ char_class (text, lp->end.index) != CHAR_CLASS_SPACE &&
+ char_class (text, lp->end.index) != CHAR_CLASS_IDEOGRAM &&
+ char_class (text, lp->end.index - 1) != CHAR_CLASS_IDEOGRAM)
+ {
+ decrement_mark (&lp->end);
+ lp->displayable_chars -= 1;
+ }
+
+ /* lp->end.index points the position to be cut just now. If it's not a
+ * space, move it to the next display line. */
+ if (lp->end.index > lp->start.index &&
+ char_class (text, lp->end.index) != CHAR_CLASS_SPACE)
+ decrement_mark (&lp->end);
+}
+
static void
expand_scratch_buffer (GtkText* text, guint len)
{
---------------- x8 ---------------- x8 ---------------- x8 ----------------
--------------------------------------
Akira Higuchi
Dept. of Mathematics, Hokkaido Univ.
Hokkaido, Japan
Email: a-higuti@math.sci.hokudai.ac.jp