]>
Commit | Line | Data |
---|---|---|
ac980e67 | 1 | Return-Path: a-higuti@math.sci.hokudai.ac.jp |
2 | Delivery-Date: Thu Sep 23 14:52:43 1999 | |
3 | Return-Path: <a-higuti@math.sci.hokudai.ac.jp> | |
4 | Received: 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 | |
7 | Received: 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) | |
10 | Received: 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 | |
13 | Received: 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 | |
16 | Received: 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) | |
19 | Date: Fri, 24 Sep 1999 03:01:10 +0900 (JST) | |
20 | Message-Id: <199909231801.DAA23889@math.sci.hokudai.ac.jp> | |
21 | From: a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi) | |
22 | To: otaylor@redhat.com | |
23 | Subject: Adding more gdk_isw* macros | |
24 | Mime-Version: 1.0 | |
25 | Content-Type: text/plain; charset=US-ASCII | |
26 | Status: O | |
27 | Lines: 528 | |
28 | Xref: fresnel.labs.redhat.com prog-gtk:648 | |
29 | ||
30 | Hello Owen, | |
31 | ||
32 | I'm working on adding CJK support to gnome apps, and I need your advice. | |
33 | ||
34 | As you know, gtk+-1.2 has some support for CJK. It's sufficient for most | |
35 | gnome apps to be internationalized, but some problems remain. The most | |
36 | problem is that there is no way of doing word wrapping for CJK strings. | |
37 | ||
38 | For example, gtk-xmhtml shows Japanese text very uglily, because Japanese | |
39 | sentences are recognized as very long words. (a Japanese sentence | |
40 | contain any spaces in most cases.) The same problem is in gtk+ itself, too; | |
41 | Word wrapping in GtkLabel and GtkText doesn't work correctly for CJK text, | |
42 | because of the same reason as above. | |
43 | ||
44 | In order to fix it, we need more gdk_isw* functions than we already have | |
45 | in gdki18n.h. (I regret I didn't add them before gtk+-1.2 was released.) | |
46 | I attach herewith a patch which fixes it, but I think it's not acceptable | |
47 | to adding a new macro to a stable version of gtk+. (is it?) | |
48 | ||
49 | The question I want to ask you is: what's the best way of fixing the | |
50 | problem without adding these macros to gdki18n.h? A solution is to add | |
51 | these macros to each *.c files (in GtkLabel, GtkText, and gtkxmhtml etc.) | |
52 | rather than gtki18n.h, but it's very ugly I think. | |
53 | ||
54 | Please don't say "wait until gscript is completed" ;-( I don't want to | |
55 | wait for a long time. (Please let me know if I can help you with gscript | |
56 | BTW. I've not hacked gscript yet, because it seems to be too early to be | |
57 | hacked by other than you.) | |
58 | ||
59 | Thanks, | |
60 | Akira Higuchi | |
61 | ---------------- x8 ---------------- x8 ---------------- x8 ---------------- | |
62 | diff -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__ */ | |
98 | diff -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 | } | |
195 | diff -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; | |
365 | diff -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 | -------------------------------------- | |
554 | Akira Higuchi | |
555 | Dept. of Mathematics, Hokkaido Univ. | |
556 | Hokkaido, Japan | |
557 | Email: a-higuti@math.sci.hokudai.ac.jp |