]> git.pld-linux.org Git - packages/gtk+.git/blame - gtk+-ahiguti.patch
- fix GtkClist bug (patch from rawhide).
[packages/gtk+.git] / gtk+-ahiguti.patch
CommitLineData
ac980e67 1Return-Path: a-higuti@math.sci.hokudai.ac.jp
2Delivery-Date: Thu Sep 23 14:52:43 1999
3Return-Path: <a-higuti@math.sci.hokudai.ac.jp>
4Received: from localhost (IDENT:otaylor@localhost [127.0.0.1])
5 by fresnel.labs.redhat.com (8.9.3/8.9.3) with ESMTP id OAA00891
6 for <otaylor@localhost>; Thu, 23 Sep 1999 14:52:41 -0400
7Received: from lacrosse.redhat.com
8 by localhost with POP3 (fetchmail-5.0.0)
9 for otaylor@localhost (single-drop); Thu, 23 Sep 1999 14:52:42 -0400 (EDT)
10Received: from mail.redhat.com (mail.redhat.com [199.183.24.239])
11 by lacrosse.corp.redhat.com (8.9.3/8.9.3) with ESMTP id OAA19205
12 for <otaylor@lacrosse.redhat.com>; Thu, 23 Sep 1999 14:01:27 -0400
13Received: from math.sci.hokudai.ac.jp (seki.math.sci.hokudai.ac.jp [133.50.152.8])
14 by mail.redhat.com (8.8.7/8.8.7) with ESMTP id OAA13383
15 for <otaylor@redhat.com>; Thu, 23 Sep 1999 14:01:49 -0400
16Received: from heathcliff (a-higuti@hilbert.math.sci.hokudai.ac.jp [133.50.152.11])
17 by math.sci.hokudai.ac.jp (8.8.8/3.6W01/06/98) with SMTP id DAA23889
18 for <otaylor@redhat.com>; Fri, 24 Sep 1999 03:01:10 +0900 (JST)
19Date: Fri, 24 Sep 1999 03:01:10 +0900 (JST)
20Message-Id: <199909231801.DAA23889@math.sci.hokudai.ac.jp>
21From: a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi)
22To: otaylor@redhat.com
23Subject: Adding more gdk_isw* macros
24Mime-Version: 1.0
25Content-Type: text/plain; charset=US-ASCII
26Status: O
27Lines: 528
28Xref: fresnel.labs.redhat.com prog-gtk:648
29
30Hello Owen,
31
32I'm working on adding CJK support to gnome apps, and I need your advice.
33
34As you know, gtk+-1.2 has some support for CJK. It's sufficient for most
35gnome apps to be internationalized, but some problems remain. The most
36problem is that there is no way of doing word wrapping for CJK strings.
37
38For example, gtk-xmhtml shows Japanese text very uglily, because Japanese
39sentences are recognized as very long words. (a Japanese sentence
40contain any spaces in most cases.) The same problem is in gtk+ itself, too;
41Word wrapping in GtkLabel and GtkText doesn't work correctly for CJK text,
42because of the same reason as above.
43
44In order to fix it, we need more gdk_isw* functions than we already have
45in gdki18n.h. (I regret I didn't add them before gtk+-1.2 was released.)
46I attach herewith a patch which fixes it, but I think it's not acceptable
47to adding a new macro to a stable version of gtk+. (is it?)
48
49The question I want to ask you is: what's the best way of fixing the
50problem without adding these macros to gdki18n.h? A solution is to add
51these macros to each *.c files (in GtkLabel, GtkText, and gtkxmhtml etc.)
52rather than gtki18n.h, but it's very ugly I think.
53
54Please don't say "wait until gscript is completed" ;-( I don't want to
55wait for a long time. (Please let me know if I can help you with gscript
56BTW. I've not hacked gscript yet, because it seems to be too early to be
57hacked by other than you.)
58
59Thanks,
60Akira Higuchi
61---------------- x8 ---------------- x8 ---------------- x8 ----------------
62diff -ur gtk+-1.2.5-pre2/gdk/gdki18n.h gtk+-1.2.5-pre2.new/gdk/gdki18n.h
63--- gtk+-1.2.5-pre2/gdk/gdki18n.h Wed Jun 9 21:07:51 1999
64+++ gtk+-1.2.5-pre2.new/gdk/gdki18n.h Thu Sep 23 14:59:38 1999
65@@ -50,4 +50,32 @@
66 # define gdk_iswspace(c) ((wchar_t)(c) <= 0xFF && isspace(c))
67 #endif
68
69+/* The following 9 macros are added in gtk+ 1.2.X. Don't use them without
70+ * checking GTK_CHECK_VERSION. For example,
71+ * #if GTK_CHECK_VERSION (1,2,X)
72+ * ... code which uses gdk_iswalpha(), gdk_iswcntrl(), etc. ...
73+ * #endif
74+ */
75+#if !defined(G_HAVE_BROKEN_WCTYPE) && (defined(G_HAVE_WCTYPE_H) || defined(G_HAVE_WCHAR_H)) && !defined(X_LOCALE)
76+# define gdk_iswalpha(c) iswalpha(c)
77+# define gdk_iswcntrl(c) iswcntrl(c)
78+# define gdk_iswdigit(c) iswdigit(c)
79+# define gdk_iswlower(c) iswlower(c)
80+# define gdk_iswgraph(c) iswgraph(c)
81+# define gdk_iswprint(c) iswprint(c)
82+# define gdk_iswpunct(c) iswpunct(c)
83+# define gdk_iswupper(c) iswupper(c)
84+# define gdk_iswxdigit(c) iswxdigit(c)
85+#else
86+# define gdk_iswalpha(c) ((wchar_t)(c) <= 0xFF && isalpha(c))
87+# define gdk_iswcntrl(c) ((wchar_t)(c) <= 0xFF && iscntrl(c))
88+# define gdk_iswdigit(c) ((wchar_t)(c) <= 0xFF && isdigit(c))
89+# define gdk_iswlower(c) ((wchar_t)(c) <= 0xFF && islower(c))
90+# define gdk_iswgraph(c) ((wchar_t)(c) > 0xFF || isgraph(c))
91+# define gdk_iswprint(c) ((wchar_t)(c) > 0xFF || isprint(c))
92+# define gdk_iswpunct(c) ((wchar_t)(c) <= 0xFF && ispunct(c))
93+# define gdk_iswupper(c) ((wchar_t)(c) <= 0xFF && isupper(c))
94+# define gdk_iswxdigit(c) ((wchar_t)(c) <= 0xFF && isxdigit(c))
95+#endif
96+
97 #endif /* __GDK_I18N_H__ */
98diff -ur gtk+-1.2.5-pre2/gtk/gtkentry.c gtk+-1.2.5-pre2.new/gtk/gtkentry.c
99--- gtk+-1.2.5-pre2/gtk/gtkentry.c Wed Aug 18 14:23:53 1999
100+++ gtk+-1.2.5-pre2.new/gtk/gtkentry.c Thu Sep 23 00:22:21 1999
101@@ -1943,11 +1943,21 @@
102 gtk_move_backward_word (GTK_ENTRY (editable));
103 }
104
105+static gboolean
106+alnum_or_ideogram (GtkEntry *entry, guint index)
107+{
108+ GdkWChar ch;
109+ ch = entry->text[index];
110+ if (entry->use_wchar)
111+ return !(gdk_iswpunct (ch) || gdk_iswcntrl (ch) || gdk_iswspace (ch));
112+ else
113+ return !(ispunct (ch) || iscntrl (ch) || isspace (ch));
114+}
115+
116 static void
117 gtk_move_forward_word (GtkEntry *entry)
118 {
119 GtkEditable *editable;
120- GdkWChar *text;
121 gint i;
122
123 editable = GTK_EDITABLE (entry);
124@@ -1961,21 +1971,12 @@
125
126 if (entry->text && (editable->current_pos < entry->text_length))
127 {
128- text = entry->text;
129- i = editable->current_pos;
130-
131- if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
132- for (; i < entry->text_length; i++)
133- {
134- if ((entry->use_wchar) ? gdk_iswalnum (text[i]) : isalnum (text[i]))
135- break;
136- }
137-
138+ for (i = editable->current_pos; i < entry->text_length; i++)
139+ if (alnum_or_ideogram (entry, i))
140+ break;
141 for (; i < entry->text_length; i++)
142- {
143- if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
144- break;
145- }
146+ if (!alnum_or_ideogram (entry, i))
147+ break;
148
149 editable->current_pos = i;
150 }
151@@ -1985,7 +1986,6 @@
152 gtk_move_backward_word (GtkEntry *entry)
153 {
154 GtkEditable *editable;
155- GdkWChar *text;
156 gint i;
157
158 editable = GTK_EDITABLE (entry);
159@@ -1999,26 +1999,19 @@
160
161 if (entry->text && editable->current_pos > 0)
162 {
163- text = entry->text;
164- i = editable->current_pos - 1;
165- if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
166- for (; i >= 0; i--)
167+ for (i = editable->current_pos - 1; i >= 0; i--)
168+ if (alnum_or_ideogram (entry, i))
169+ break;
170+ for (; i >= 0; i--)
171+ if (!alnum_or_ideogram (entry, i))
172 {
173- if ((entry->use_wchar) ? gdk_iswalnum (text[i]) : isalnum (text[i]))
174- break;
175+ i++;
176+ break;
177 }
178- for (; i >= 0; i--)
179- {
180- if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
181- {
182- i++;
183- break;
184- }
185- }
186-
187+
188 if (i < 0)
189 i = 0;
190-
191+
192 editable->current_pos = i;
193 }
194 }
195diff -ur gtk+-1.2.5-pre2/gtk/gtklabel.c gtk+-1.2.5-pre2.new/gtk/gtklabel.c
196--- gtk+-1.2.5-pre2/gtk/gtklabel.c Wed Jun 9 20:40:13 1999
197+++ gtk+-1.2.5-pre2.new/gtk/gtklabel.c Thu Sep 23 11:29:25 1999
198@@ -56,6 +56,7 @@
199 GtkLabelWord *next;
200 gint uline_y;
201 GtkLabelULine *uline;
202+ gboolean paragraph_break;
203 };
204
205 struct _GtkLabelULine
206@@ -396,6 +397,7 @@
207 word->beginning = NULL;
208 word->next = NULL;
209 word->uline = NULL;
210+ word->paragraph_break = FALSE;
211
212 return word;
213 }
214@@ -441,6 +443,7 @@
215 if (str == label->label_wc || str[-1] == '\n')
216 {
217 /* Paragraph break */
218+ word->paragraph_break = TRUE;
219 word->space = 0;
220
221 max_line_width = MAX (line_width, max_line_width);
222@@ -488,6 +491,7 @@
223 {
224 word = gtk_label_word_alloc ();
225
226+ word->paragraph_break = TRUE;
227 word->space = 0;
228 word->beginning = str;
229 word->length = 0;
230@@ -500,6 +504,13 @@
231 return MAX (line_width, max_line_width);
232 }
233
234+static gboolean
235+is_ideogram (GdkWChar wc)
236+{
237+ return !(gdk_iswalnum (wc) || gdk_iswspace (wc) ||
238+ gdk_iswpunct (wc) || gdk_iswcntrl (wc));
239+}
240+
241 /* this needs to handle white space better. */
242 static gint
243 gtk_label_split_text_wrapped (GtkLabel *label)
244@@ -526,6 +537,7 @@
245 if (str == label->label_wc || str[-1] == '\n')
246 {
247 /* Paragraph break */
248+ word->paragraph_break = TRUE;
249 word->space = 0;
250
251 max_line_width = MAX (line_width, max_line_width);
252@@ -546,24 +558,30 @@
253 else
254 word->space = space_width * nspaces;
255 }
256- else
257+ else if (gdk_iswspace (str[-1]))
258 {
259 /* Regular inter-word space */
260 word->space = space_width;
261 }
262+ else
263+ {
264+ word->space = 0;
265+ }
266
267 word->beginning = str;
268 word->length = 0;
269 p = word->beginning;
270 while (*p && !gdk_iswspace (*p))
271 {
272+ if (word->length > 0 && (is_ideogram (p[-1]) || is_ideogram (*p)))
273+ break;
274 word->length++;
275 p++;
276 }
277 word->width = gdk_text_width_wc (GTK_WIDGET (label)->style->font, str, word->length);
278
279 str += word->length;
280- if (*str)
281+ if (*str && gdk_iswspace (*str))
282 str++;
283
284 line_width += word->space + word->width;
285@@ -600,7 +618,7 @@
286 width = 0;
287 for (word = label->words; word; word = word->next)
288 {
289- if (word->space == 0
290+ if (word->paragraph_break
291 || (line_width
292 && (line_width >= min_width
293 || line_width + word->width + word->space > max_width)))
294@@ -716,7 +734,8 @@
295 GtkLabelWord *word, *line, *next_line;
296 GtkWidget *widget;
297 gchar *ptrn;
298- gint x, y, space, extra_width, add_space, baseline_skip;
299+ gint x, y, space, num_words, extra_width, add_space, baseline_skip;
300+ gboolean deliver_equivalently;
301
302 g_return_if_fail (label->wrap);
303
304@@ -724,20 +743,24 @@
305 y = 0;
306 baseline_skip = (GTK_WIDGET (label)->style->font->ascent +
307 GTK_WIDGET (label)->style->font->descent + 1);
308+ deliver_equivalently = FALSE;
309
310 for (line = label->words; line != 0; line = next_line)
311 {
312- space = 0;
313+ space = num_words = 0;
314 extra_width = max_line_width - line->width;
315
316 for (next_line = line->next; next_line; next_line = next_line->next)
317 {
318- if (next_line->space == 0)
319+ if (next_line->paragraph_break)
320 break; /* New paragraph */
321 if (next_line->space + next_line->width > extra_width)
322 break;
323+ if (next_line->space == 0)
324+ deliver_equivalently = TRUE; /* An ideogram is found. */
325 extra_width -= next_line->space + next_line->width;
326 space += next_line->space;
327+ num_words++;
328 }
329
330 line->x = 0;
331@@ -747,14 +770,18 @@
332
333 for (word = line->next; word != next_line; word = word->next)
334 {
335- if (next_line && next_line->space)
336+ if (next_line && !next_line->paragraph_break &&
337+ label->jtype == GTK_JUSTIFY_FILL &&
338+ (deliver_equivalently ? num_words : space) > 0)
339 {
340- /* Not last line of paragraph --- fill line if needed */
341- if (label->jtype == GTK_JUSTIFY_FILL) {
342+ /* Not last line of paragraph --- fill line */
343+ if (deliver_equivalently)
344+ add_space = (extra_width + num_words / 2) / num_words;
345+ else
346 add_space = (extra_width * word->space + space / 2) / space;
347- extra_width -= add_space;
348- space -= word->space;
349- }
350+ extra_width -= add_space;
351+ space -= word->space;
352+ num_words--;
353 }
354
355 word->x = x + word->space + add_space;
356@@ -925,7 +952,7 @@
357
358 for (word = label->words; word; word = word->next)
359 {
360- gchar save = word->beginning[word->length];
361+ GdkWChar save = word->beginning[word->length];
362 word->beginning[word->length] = '\0';
363 gtk_label_paint_word (label, x, y, word, &event->area);
364 word->beginning[word->length] = save;
365diff -ur gtk+-1.2.5-pre2/gtk/gtktext.c gtk+-1.2.5-pre2.new/gtk/gtktext.c
366--- gtk+-1.2.5-pre2/gtk/gtktext.c Sat Sep 4 08:50:38 1999
367+++ gtk+-1.2.5-pre2.new/gtk/gtktext.c Thu Sep 23 00:21:40 1999
368@@ -101,6 +101,13 @@
369 ARG_WORD_WRAP
370 };
371
372+typedef enum {
373+ CHAR_CLASS_SPACE,
374+ CHAR_CLASS_ALNUM,
375+ CHAR_CLASS_IDEOGRAM,
376+ CHAR_CLASS_OTHERS /* punct, cntrl */
377+} CharClass;
378+
379 typedef struct _TextProperty TextProperty;
380 typedef struct _TabStopMark TabStopMark;
381 typedef struct _PrevTabCont PrevTabCont;
382@@ -298,6 +305,8 @@
383 const GtkPropertyMark *mark,
384 const PrevTabCont *tab_cont,
385 PrevTabCont *next_cont);
386+static void find_word_wrap_position (GtkText* text, LineParams *lp);
387+static CharClass char_class (GtkText* text, guint index);
388 static void recompute_geometry (GtkText* text);
389 static void insert_expose (GtkText* text, guint old_pixels, gint nchars, guint new_line_count);
390 static void delete_expose (GtkText* text,
391@@ -4084,27 +4093,21 @@
392
393 undraw_cursor (text, FALSE);
394
395- if (text->use_wchar)
396+ while (!LAST_INDEX (text, text->cursor_mark))
397 {
398- while (!LAST_INDEX (text, text->cursor_mark) &&
399- !gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
400- advance_mark (&text->cursor_mark);
401-
402- while (!LAST_INDEX (text, text->cursor_mark) &&
403- gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
404- advance_mark (&text->cursor_mark);
405+ CharClass cc = char_class (text, text->cursor_mark.index);
406+ if (cc == CHAR_CLASS_ALNUM || cc == CHAR_CLASS_IDEOGRAM)
407+ break;
408+ advance_mark (&text->cursor_mark);
409 }
410- else
411+ while (!LAST_INDEX (text, text->cursor_mark))
412 {
413- while (!LAST_INDEX (text, text->cursor_mark) &&
414- !isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
415- advance_mark (&text->cursor_mark);
416-
417- while (!LAST_INDEX (text, text->cursor_mark) &&
418- isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
419- advance_mark (&text->cursor_mark);
420+ CharClass cc = char_class (text, text->cursor_mark.index);
421+ if (cc != CHAR_CLASS_ALNUM && cc != CHAR_CLASS_IDEOGRAM)
422+ break;
423+ advance_mark (&text->cursor_mark);
424 }
425-
426+
427 find_cursor (text, TRUE);
428 draw_cursor (text, FALSE);
429 }
430@@ -4116,25 +4119,19 @@
431
432 undraw_cursor (text, FALSE);
433
434- if (text->use_wchar)
435+ while (text->cursor_mark.index > 0)
436 {
437- while ((text->cursor_mark.index > 0) &&
438- !gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
439- decrement_mark (&text->cursor_mark);
440-
441- while ((text->cursor_mark.index > 0) &&
442- gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
443- decrement_mark (&text->cursor_mark);
444+ CharClass cc = char_class (text, text->cursor_mark.index - 1);
445+ if (cc == CHAR_CLASS_ALNUM || cc == CHAR_CLASS_IDEOGRAM)
446+ break;
447+ decrement_mark (&text->cursor_mark);
448 }
449- else
450+ while (text->cursor_mark.index > 0)
451 {
452- while ((text->cursor_mark.index > 0) &&
453- !isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
454- decrement_mark (&text->cursor_mark);
455-
456- while ((text->cursor_mark.index > 0) &&
457- isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
458- decrement_mark (&text->cursor_mark);
459+ CharClass cc = char_class (text, text->cursor_mark.index - 1);
460+ if (cc != CHAR_CLASS_ALNUM && cc != CHAR_CLASS_IDEOGRAM)
461+ break;
462+ decrement_mark (&text->cursor_mark);
463 }
464
465 find_cursor (text, TRUE);
466@@ -4755,27 +4752,8 @@
467 GtkPropertyMark saved_mark = lp.end;
468 guint saved_characters = lp.displayable_chars;
469
470- lp.displayable_chars += 1;
471-
472- if (text->use_wchar)
473- {
474- while (!gdk_iswspace (GTK_TEXT_INDEX (text, lp.end.index)) &&
475- (lp.end.index > lp.start.index))
476- {
477- decrement_mark (&lp.end);
478- lp.displayable_chars -= 1;
479- }
480- }
481- else
482- {
483- while (!isspace(GTK_TEXT_INDEX (text, lp.end.index)) &&
484- (lp.end.index > lp.start.index))
485- {
486- decrement_mark (&lp.end);
487- lp.displayable_chars -= 1;
488- }
489- }
490-
491+ find_word_wrap_position (text, &lp);
492+
493 /* If whole line is one word, revert to char wrapping */
494 if (lp.end.index == lp.start.index)
495 {
496@@ -4821,6 +4799,54 @@
497 lp.tab_cont_next = *next_cont;
498
499 return lp;
500+}
501+
502+static CharClass
503+char_class (GtkText* text, guint index)
504+{
505+ GdkWChar wc;
506+ wc = GTK_TEXT_INDEX (text, index);
507+ if (text->use_wchar)
508+ {
509+ if (gdk_iswspace (wc))
510+ return CHAR_CLASS_SPACE;
511+ else if (gdk_iswalnum (wc))
512+ return CHAR_CLASS_ALNUM;
513+ else if (gdk_iswpunct (wc) || gdk_iswcntrl (wc))
514+ return CHAR_CLASS_OTHERS;
515+ else
516+ return CHAR_CLASS_IDEOGRAM;
517+ }
518+ else
519+ {
520+ if (isspace (wc))
521+ return CHAR_CLASS_SPACE;
522+ else if (isalnum (wc))
523+ return CHAR_CLASS_ALNUM;
524+ else if (ispunct (wc) || iscntrl (wc))
525+ return CHAR_CLASS_OTHERS;
526+ else
527+ return CHAR_CLASS_IDEOGRAM;
528+ }
529+}
530+
531+static void
532+find_word_wrap_position (GtkText* text, LineParams *lp)
533+{
534+ while (lp->end.index > lp->start.index &&
535+ char_class (text, lp->end.index) != CHAR_CLASS_SPACE &&
536+ char_class (text, lp->end.index) != CHAR_CLASS_IDEOGRAM &&
537+ char_class (text, lp->end.index - 1) != CHAR_CLASS_IDEOGRAM)
538+ {
539+ decrement_mark (&lp->end);
540+ lp->displayable_chars -= 1;
541+ }
542+
543+ /* lp->end.index points the position to be cut just now. If it's not a
544+ * space, move it to the next display line. */
545+ if (lp->end.index > lp->start.index &&
546+ char_class (text, lp->end.index) != CHAR_CLASS_SPACE)
547+ decrement_mark (&lp->end);
548 }
549
550 static void
551---------------- x8 ---------------- x8 ---------------- x8 ----------------
552
553--------------------------------------
554Akira Higuchi
555Dept. of Mathematics, Hokkaido Univ.
556Hokkaido, Japan
557Email: a-higuti@math.sci.hokudai.ac.jp
This page took 0.166456 seconds and 4 git commands to generate.