[Nautilus-list] Two patches for Eel library 1.0



Hello,
   I made two patches for Eel library 1.0 to deal with multibyte string
ellipsize and smooth text layout bugs.
   I have test these patch under zh_CN.GB2312 and zh_CN.GBK locales.

   And, I meet a problem when I try to input Chinese characters into notes
and embedded mozilla forms under zh_CN.GB18030 locale. If I set the locale
to zh_CN.GBK, I can input Chinese in notes, but cannot input into embedded
mozilla. My XIM input server was tested ok under several other gnome
programs such as galeon. 

   btw, XFree86 4.x does not support GB18030 locale, so I made a patch
(for 4.0.3 or 4.1.0). Under GB18030 locale, XFree86 4.x uses UTF-8 as
Compound Text encoding and UCS2BE as font encoding. ( GB18030 is just a 
variant of ISO10646 like UTF-8 ). If you are interested in this patch, I
can send it to you.

Regards,

James Su
diff -urN eel-1.0/eel/eel-gdk-font-extensions.c eel-1.0.new/eel/eel-gdk-font-extensions.c
--- eel-1.0/eel/eel-gdk-font-extensions.c	Wed Apr 18 04:05:12 2001
+++ eel-1.0.new/eel/eel-gdk-font-extensions.c	Wed Jun 13 04:00:18 2001
@@ -643,21 +643,39 @@
 static char *
 eel_string_ellipsize_start (const char *string, GdkFont *font, int width)
 {
+	GdkWChar *wc_string;
+	gchar *mb_string;
+	char *result;
+
+	int wc_len;
 	int truncate_offset;
 	int resulting_width;
 
-	resulting_width = gdk_string_width (font, string);
+	wc_len = strlen(string) + 1;
+	wc_string = g_new( GdkWChar, wc_len );
+	wc_len = gdk_mbstowcs( wc_string, string, wc_len );
+
+	if( wc_len <= 0 ) {
+		g_free(wc_string);
+		return g_strdup("");
+	}
+
+	wc_string[ wc_len ] = L'\0';
+
+	resulting_width = gdk_text_width_wc (font, wc_string, wc_len);
 	if (resulting_width <= width) {
 		/* String is already short enough. */
-		return g_strdup (string);
+		mb_string = gdk_wcstombs(wc_string);
+		g_free(wc_string);
+		return mb_string;
 	}
 	
 	/* Account for the width of the ellipsis. */
 	width -= gdk_string_width (font, ELLIPSIS);
-	
 
 	if (width < 0) {
 		/* No room even for a an ellipsis. */
+		g_free(wc_string);
 		return g_strdup ("");
 	}
 	
@@ -668,31 +686,55 @@
 	 * gdk_string_width ("foobar")
 	 */
         for (truncate_offset = 1; ; truncate_offset++) {
-        	if (string[truncate_offset] == '\0') {
+        	if (wc_string[truncate_offset] == L'\0') {
 			break;
         	}
 
-        	resulting_width -= gdk_char_width (font, string[truncate_offset - 1]);
+        	resulting_width -= gdk_char_width_wc (font, wc_string[truncate_offset - 1]);
 
         	if (resulting_width <= width) {
 			break;
         	}
         }
 
-	return g_strconcat (ELLIPSIS, string + truncate_offset, NULL);
+	mb_string = gdk_wcstombs(wc_string + truncate_offset);
+	result = g_strconcat( ELLIPSIS, mb_string, NULL );
+
+	g_free( mb_string );
+	g_free( wc_string );
+
+	return result;
 }
 
 static char *
 eel_string_ellipsize_end (const char *string, GdkFont *font, int width)
 {
-	int truncated_length;
+	GdkWChar *wc_string;
+	gchar *mb_string;
 	char *result;
+
+	int wc_len;
+
+	int truncated_length;
 	int resulting_width;
 
-	resulting_width = gdk_string_width (font, string);
+	wc_len = strlen(string) + 1;
+	wc_string = g_new( GdkWChar, wc_len );
+	wc_len = gdk_mbstowcs( wc_string, string, wc_len );
+
+	if( wc_len <= 0 ) {
+		g_free(wc_string);
+		return g_strdup("");
+	}
+
+	wc_string[ wc_len ] = L'\0';
+
+	resulting_width = gdk_text_width_wc (font, wc_string, wc_len);
 	if (resulting_width <= width) {
 		/* String is already short enough. */
-		return g_strdup (string);
+		mb_string = gdk_wcstombs(wc_string);
+		g_free(wc_string);
+		return mb_string;
 	}
 	
 	/* Account for the width of the ellipsis. */
@@ -701,19 +743,24 @@
 
 	if (width < 0) {
 		/* No room even for a an ellipsis. */
+		g_free(wc_string);
 		return g_strdup ("");
 	}
 	
-        for (truncated_length = strlen (string) - 1; truncated_length > 0; truncated_length--) {
-        	resulting_width -= gdk_char_width (font, string[truncated_length]);
+        for (truncated_length = wc_len - 1; truncated_length > 0; truncated_length--) {
+        	resulting_width -= gdk_char_width_wc (font, wc_string[truncated_length]);
         	if (resulting_width <= width) {
 			break;
         	}
         }
-	
-	result = g_malloc (truncated_length + strlen (ELLIPSIS) + 1);
-	memcpy (result, string, truncated_length);
-	strcpy (result + truncated_length, ELLIPSIS);
+
+	wc_string [ truncated_length ] = L'\0';
+
+	mb_string = gdk_wcstombs( wc_string );
+	result = g_strconcat( mb_string, ELLIPSIS, NULL );
+
+	g_free( mb_string );
+	g_free( wc_string );
 
 	return result;
 }
@@ -721,29 +768,48 @@
 static char *
 eel_string_ellipsize_middle (const char *string, GdkFont *font, int width)
 {
+	GdkWChar *wc_string;
+	gchar *mb_string;
+	char *left, *right, *result;
+
+	int wc_len;
+
 	int original_length;
 	int starting_fragment_length;
 	int ending_fragment_offset;
 	int resulting_width;
-	char *result;
 
-	resulting_width = gdk_string_width (font, string);
+	wc_len = strlen(string) + 1;
+	wc_string = g_new( GdkWChar, wc_len );
+	wc_len = gdk_mbstowcs( wc_string, string, wc_len );
+
+	if( wc_len <= 0 ) {
+		g_free(wc_string);
+		return g_strdup("");
+	}
+
+	wc_string[ wc_len ] = L'\0';
+
+	resulting_width = gdk_text_width_wc (font, wc_string, wc_len);
+
 	if (resulting_width <= width) {
 		/* String is already short enough. */
-		return g_strdup (string);
+		mb_string = gdk_wcstombs(wc_string);
+		g_free(wc_string);
+		return mb_string;
 	}
 	
 	/* Account for the width of the ellipsis. */
 	width -= gdk_string_width (font, ELLIPSIS);
-	
 
 	if (width < 0) {
 		/* No room even for a an ellipsis. */
+		g_free(wc_string);
 		return g_strdup ("");
 	}
 
 	/* Split the original string into two halves */
-	original_length = strlen (string);
+	original_length = wc_len;
 	
 	g_assert (original_length > 0);
 	
@@ -753,7 +819,7 @@
 	/* Shave off a character at a time from the first and the second half
 	 * until we can fit
 	 */
-	resulting_width -= gdk_char_width (font, string[ending_fragment_offset - 1]);
+	resulting_width -= gdk_char_width_wc (font, wc_string[ending_fragment_offset - 1]);
 	
 	/* depending on whether the original string length is odd or even, start by
 	 * shaving off the characters from the starting or ending fragment
@@ -768,7 +834,7 @@
 			if (starting_fragment_length > 0) {
 				starting_fragment_length--;
 			}
-			resulting_width -= gdk_char_width (font, string[starting_fragment_length]);
+			resulting_width -= gdk_char_width_wc (font, wc_string[starting_fragment_length]);
 	case 1:
 			if (resulting_width <= width) {
 				break;
@@ -777,16 +843,21 @@
 			if (ending_fragment_offset < original_length) {
 				ending_fragment_offset++;
 			}
-			resulting_width -= gdk_char_width (font, string[ending_fragment_offset - 1]);
+			resulting_width -= gdk_char_width_wc (font, wc_string[ending_fragment_offset - 1]);
 	        }
 	}
-	
+
 	/* patch the two fragments together with an ellipsis */
-	result = g_malloc (starting_fragment_length + (original_length - ending_fragment_offset)
-		+ strlen (ELLIPSIS) + 1);
-	memcpy (result, string, starting_fragment_length);
-	strcpy (result + starting_fragment_length, ELLIPSIS);
-	strcpy (result + starting_fragment_length + strlen (ELLIPSIS), string + ending_fragment_offset);
+
+	right = gdk_wcstombs(wc_string+ending_fragment_offset);
+	wc_string[ starting_fragment_length ] = L'\0';
+	left = gdk_wcstombs(wc_string);
+
+	result = g_strconcat( left, ELLIPSIS, right, NULL );
+
+	g_free( wc_string );
+	g_free( left );
+	g_free( right );
 
 	return result;
 }
diff -urN eel-1.0/eel/eel-smooth-text-layout.c eel-1.0.new/eel/eel-smooth-text-layout.c
--- eel-1.0/eel/eel-smooth-text-layout.c	Tue May  1 21:20:38 2001
+++ eel-1.0.new/eel/eel-smooth-text-layout.c	Wed Jun 13 16:13:54 2001
@@ -1088,25 +1088,45 @@
 {
 	EelTextLayout *text_layout;
 	EelTextLayoutRow *row;
-	const char *row_end;
-	const char *s, *word_start, *word_end, *old_word_end;
+
 	char *sub_text;
-	int i, w_len;
-	int w;
-	const char *text_iter;
-	int text_len, separators_len;
+	int i;
+
+	GdkWChar *wc_text, *wc_separators;
+	GdkWChar *wc_text_iter, *wc_row_end, *wc_word_start, *wc_word_end, *wc_old_word_end, *wc_s;
+	GdkWChar wc_char;
+
+	char *mb_word;
+
+	int wc_text_len, wc_separators_len, wc_word_len;
+	int mb_word_len, word_width;
 
 	g_return_val_if_fail (font != NULL, NULL);
 	g_return_val_if_fail (font_size > 0, NULL);
 	g_return_val_if_fail (text != NULL, NULL);
 	g_return_val_if_fail (eel_strlen (text) > 0, NULL);
 
+	wc_text_len = strlen(text) + 1;
+	wc_text = g_new0( GdkWChar, wc_text_len );
+	wc_text_len = gdk_mbstowcs( wc_text, text, wc_text_len );
+
+	if( wc_text_len <= 0 ){
+		g_free( wc_text );
+		return NULL;
+	}
+
 	if (!separators)
 		separators = " ";
 
-	text_len = strlen (text);
-
-	separators_len = strlen (separators);
+	wc_separators_len = strlen( separators ) + 1;
+	wc_separators = g_new0( GdkWChar, wc_separators_len );
+	wc_separators_len = gdk_mbstowcs( wc_separators, separators, wc_separators_len );
+
+	if( wc_separators_len <= 0 ){
+		g_free( wc_text );
+		g_free( wc_separators );
+		return NULL;
+	}
 
 	text_layout = g_new0 (EelTextLayout, 1);
 
@@ -1117,60 +1137,79 @@
 	text_layout->height = 0;
 	text_layout->baseline_skip = font_size;
 
-	word_end = NULL;
+	wc_word_end = NULL;
 
-	text_iter = text;
-	while (*text_iter) {
-		for (row_end = text_iter; *row_end != 0 && *row_end != '\n'; row_end++);
+	wc_text_iter = wc_text;
+	while (*wc_text_iter != L'\0') {
+		for (wc_row_end = wc_text_iter; *wc_row_end != L'\0' && *wc_row_end != L'\n'; wc_row_end++);
 
 		/* Accumulate words from this row until they don't fit in the max_width */
 
-		s = text_iter;
+		wc_s = wc_text_iter;
 
-		while (s < row_end) {
-			word_start = s;
-			old_word_end = word_end;
-			for (word_end = word_start; *word_end; word_end++) {
-				const char *p;
-				for (p = separators; *p; p++) {
-					if (*word_end == *p)
+		while (wc_s < wc_row_end) {
+			wc_word_start = wc_s;
+			wc_old_word_end = wc_word_end;
+			for (wc_word_end = wc_word_start; *wc_word_end != L'\0'; wc_word_end++) {
+				const GdkWChar *wc_p;
+				for (wc_p = wc_separators; *wc_p != L'\0'; wc_p++) {
+					if (*wc_word_end == *wc_p)
 						goto found;
 				}
 			}
 		found:
-			if (word_end < row_end)
-				word_end++;
+			if (wc_word_end < wc_row_end)
+				wc_word_end++;
+
+			wc_char = *wc_word_end;
+			*wc_word_end = L'\0';
+			mb_word = gdk_wcstombs (wc_text_iter);
+			mb_word_len = strlen(mb_word);
+			*wc_word_end = wc_char;
 
-			if (eel_scalable_font_text_width (font, font_size, text_iter, word_end - text_iter) > max_width) {
-				if (word_start == text_iter) {
+			word_width = eel_scalable_font_text_width (font, font_size, mb_word, mb_word_len);
+			g_free(mb_word);
+
+			if ( word_width > max_width) {
+				if (wc_word_start == wc_text_iter) {
 					if (confine) {
 						/* We must force-split the word.  Look for a proper
                                                  * place to do it.
 						 */
 
-						w_len = word_end - word_start;
+						wc_word_len = wc_word_end - wc_word_start;
 						
-						for (i = 1; i < w_len; i++) {
-							w = eel_scalable_font_text_width (font, font_size, word_start, i);
-							if (w > max_width) {
+						for (i = 1; i < wc_word_len; i++) {
+
+							wc_char = *(wc_word_start+i);
+							*(wc_word_start+i) = L'\0';
+							mb_word = gdk_wcstombs (wc_word_start);
+							mb_word_len = strlen(mb_word);
+							*(wc_word_start+i) = wc_char;
+							word_width = eel_scalable_font_text_width (font, font_size, mb_word, mb_word_len);
+							g_free(mb_word);
+
+							if (word_width > max_width) {
 								if (i == 1)
 									/* Shit, not even a single character fits */
-									max_width = w;
+									max_width = word_width;
 								else
 									break;
 							}
 						}
 
 						/* Create sub-row with the chars that fit */
-
-						sub_text = g_strndup (word_start, i - 1);
+						wc_char = *(wc_word_start+i-1);
+						*(wc_word_start+i-1) = L'\0';
+						sub_text = gdk_wcstombs (wc_word_start);
+						*(wc_word_start+i-1) = wc_char;
 						
 						row = g_new0 (EelTextLayoutRow, 1);
 						row->text = sub_text;
-						row->text_length = i - 1;
+						row->text_length = strlen(sub_text);
 						row->width = eel_scalable_font_text_width (font, font_size, 
 											   sub_text, 
-											   strlen (sub_text));
+											   row->text_length);
 
 						text_layout->rows = g_list_append (text_layout->rows, row);
 
@@ -1181,26 +1220,33 @@
 
 						/* Bump the text pointer */
 
-						text_iter += i - 1;
-						s = text_iter;
+						wc_text_iter += i - 1;
+						wc_s = wc_text_iter;
 
 						continue;
-					} else
-						max_width = eel_scalable_font_text_width (font, font_size, word_start, word_end - word_start);
-
+					} else {
+						wc_char = *wc_word_end;
+						*wc_word_end = L'\0';
+						mb_word = gdk_wcstombs (wc_text_iter);
+						mb_word_len = strlen(mb_word);
+						*wc_word_end = wc_char;
+
+						max_width = eel_scalable_font_text_width (font, font_size, mb_word, mb_word_len);
+						g_free(mb_word);
+					}
 					continue; /* Retry split */
 				} else {
-					word_end = old_word_end; /* Restore to region that does fit */
+					wc_word_end = wc_old_word_end; /* Restore to region that does fit */
 					break; /* Stop the loop because we found something that doesn't fit */
 				}
 			}
 
-			s = word_end;
+			wc_s = wc_word_end;
 		}
 
 		/* Append row */
 
-		if (text_iter == row_end) {
+		if (wc_text_iter == wc_row_end) {
 			/* We are on a newline, so append an empty row */
 
 			text_layout->rows = g_list_append (text_layout->rows, NULL);
@@ -1208,19 +1254,18 @@
 
 			/* Next! */
 
-			text_iter = row_end + 1;
+			wc_text_iter = wc_row_end + 1;
 		} else {
 			/* Create subrow and append it to the list */
-
-			int sub_len;
-			sub_len = word_end - text_iter;
-
-			sub_text = g_strndup (text_iter, sub_len);
+			wc_char = *wc_word_end;
+			*wc_word_end = L'\0';
+			sub_text = gdk_wcstombs (wc_text_iter);
+			*wc_word_end = wc_char;
 
 			row = g_new0 (EelTextLayoutRow, 1);
 			row->text = sub_text;
-			row->text_length = sub_len;
-			row->width = eel_scalable_font_text_width (font, font_size, sub_text, sub_len);
+			row->text_length = strlen(sub_text);
+			row->width = eel_scalable_font_text_width (font, font_size, sub_text, row->text_length);
 
 			text_layout->rows = g_list_append (text_layout->rows, row);
 
@@ -1231,10 +1276,10 @@
 
 			/* Next! */
 
-			text_iter = word_end;
+			wc_text_iter = wc_word_end;
 		}
 	}
-
+	g_free(wc_text);
 	return text_layout;
 }
 


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