--- htmltextslave.c	2003-06-12 17:02:18.000000000 +0800
+++ htmltextslave.c.1.1	2003-06-12 17:18:21.000000000 +0800
@@ -35,9 +35,147 @@
 #include "htmlplainpainter.h"
 #include "htmlgdkpainter.h"
 
-
 /* #define HTML_TEXT_SLAVE_DEBUG */
 
+/*
+ * Added by zhancb 2003-6-6,char of puncutation should be avoid breaking
+ */
+
+// Define a struct for UTF8 code
+struct _BreakUTF8Code
+{
+    gint xCode ;
+    gint yCode ;
+    gint zCode ;
+} ;
+typedef struct _BreakUTF8Code BreakUTF8Code ;
+
+// The below is the puntuation should be broken after(UTF-8),total 18 puncs
+// £¬¡£¡¢£¡£©£º£»¡±¡¯£¿¡µ¡»¡·¡¹¡½¡¿£Ý£ý
+static BreakUTF8Code cBreakAfter[] =
+    {
+        { 0Xffffffef, 0Xffffffbc, 0Xffffff8c  } ,
+        { 0Xffffffe3, 0Xffffff80, 0Xffffff82 } ,
+        { 0Xffffffe3, 0Xffffff80, 0Xffffff81 } ,
+        { 0Xffffffef, 0Xffffffbc, 0Xffffff81  } ,
+        { 0Xffffffef, 0Xffffffbc, 0Xffffff89  } ,
+        { 0Xffffffef, 0Xffffffbc, 0Xffffff9a  } ,
+        { 0Xffffffef, 0Xffffffbc, 0Xffffff9b  } ,
+        { 0Xffffffe2, 0Xffffff80, 0Xffffff9d } ,
+        { 0Xffffffe2, 0Xffffff80, 0Xffffff99 } ,
+        { 0Xffffffef, 0Xffffffbc, 0Xffffff9f  } ,
+        { 0Xffffffe3, 0Xffffff80, 0Xffffff89 } ,
+        { 0Xffffffe3, 0Xffffff80, 0Xffffff8f } ,
+        { 0Xffffffe3, 0Xffffff80, 0Xffffff8b } ,
+        { 0Xffffffe3, 0Xffffff80, 0Xffffff8d } ,
+        { 0Xffffffe3, 0Xffffff80, 0Xffffff97 } ,
+        { 0Xffffffe3, 0Xffffff80, 0Xffffff91 } ,
+        { 0Xffffffef, 0Xffffffbc, 0Xffffffbd  } ,
+        { 0Xffffffef, 0Xffffffbd, 0Xffffff9d  } 
+    };
+
+// The below is the puntuation should be broken before(UTF-8),totally 11 puncs
+// ¡°¡®£¨¡¶¡´¡¸¡º¡¼¡¾£Û£û
+static BreakUTF8Code cBreakBefore[] =
+    {
+       { 0Xffffffe2, 0Xffffff80, 0Xffffff9c  } ,
+       { 0Xffffffe2, 0Xffffff80, 0Xffffff98  } ,
+       { 0Xffffffef, 0Xffffffbc, 0Xffffff88   } ,
+       { 0Xffffffe3, 0Xffffff80, 0Xffffff8a  } ,
+       { 0Xffffffe3, 0Xffffff80, 0Xffffff88  } ,
+       { 0Xffffffe3, 0Xffffff80, 0Xffffff8c  } ,
+       { 0Xffffffe3, 0Xffffff80, 0Xffffff8e  } ,
+       { 0Xffffffe3, 0Xffffff80, 0Xffffff96  } ,
+       { 0Xffffffe3, 0Xffffff80, 0Xffffff90  } ,
+       { 0Xffffffef, 0Xffffffbc, 0Xffffffbb   } ,
+       { 0Xffffffef, 0Xffffffbd, 0Xffffff9b   } 
+    };
+
+// break type of the char
+typedef enum
+{
+    BREAK_NONE ,
+    BREAK_FREE ,
+    BREAK_AFTER ,
+    BREAK_BEFORE
+} BreakType ;
+
+// The function to check if a Chinese word could be broken.
+// Param: if xByte < 0,yByte and zByte is the last two code of a Chinese word;
+// if xByte >= 0,yByte is the prev char of xByte and zByte is next char
+// Return: break type of the char
+BreakType ChkBreakType( gchar xByte, gchar yByte, gchar zByte )
+{
+    
+    if ( xByte < 0 )  // In UTF-8 and under Linux,Chinese text code less than 0
+    {
+        int i = 0 ;
+        for ( ; i < 18; ++i )
+        {
+            if ( cBreakAfter[i].xCode == xByte && cBreakAfter[i].yCode == yByte
+                && cBreakAfter[i].zCode == zByte )
+			{
+    			return BREAK_AFTER ;
+			}
+        }
+
+        for ( i = 0; i < 11; ++i )
+        {
+            if ( cBreakBefore[i].xCode == xByte && cBreakBefore[i].yCode == yByte
+                && cBreakBefore[i].zCode == zByte )
+            {
+				return BREAK_BEFORE ;
+			}
+        }
+
+        // Other Chinese words could be broken free
+	    return BREAK_FREE ;    
+    }
+    else
+    {
+        if ( xByte == 0 || xByte == -1 ) return BREAK_FREE ;
+			
+		if ( ( xByte >='a' && xByte <= 'z' ) || ( xByte >='A' || xByte <='Z' ) || ( xByte >='0' && xByte <= '9' ) )
+        {
+            if ( ( yByte == ' ' || yByte == '\t' )
+                && ( zByte == ' ' || zByte == '\t' ) )
+			{
+             	return BREAK_FREE ;
+			}
+            else if ( yByte == ' ' || yByte == '\t' )
+			{
+             	return BREAK_BEFORE ;
+			}
+            else if ( zByte == ' ' || zByte == '\t' )
+			{
+				return BREAK_AFTER ;
+			}
+            else
+			{
+				return BREAK_NONE ;
+			}
+        }   
+        else if ( '!' == xByte || '%' == xByte || ',' == xByte || '.' == xByte
+                || ']' == xByte || '}' == xByte || ';' == xByte || ':' == xByte
+                || '?' == xByte || ')' == xByte)
+		{
+			return BREAK_AFTER ;
+		}
+        else if ( '[' == xByte || '{' == xByte || '(' == xByte )
+		{
+			return BREAK_BEFORE ;
+		}
+        else
+		{
+			return BREAK_FREE ;
+		}
+    }        
+}
+
+/*
+ * Added End
+ */
+
 HTMLTextSlaveClass html_text_slave_class;
 static HTMLObjectClass *parent_class = NULL;
 
@@ -112,7 +250,7 @@
 
 		space = str;
 		while (words && *space && len < slave->posLen) {
-			if (*space == ' ')
+			if (*space == ' ' || *space < 0/*Added by zhancb,new condition*/)
 				words --;
 
 			if (words) {
@@ -123,7 +261,7 @@
 
 		/* printf ("width %d --> ", width); */
 		width += html_painter_get_space_width (p, html_text_get_font_style (text), text->face)*(html_text_text_line_length (str, &line_offset, len, &tabs) - len);
-		/* printf ("%d\n", width); */
+       /* printf ("In get_words_width(),second width is%d\n", width); */
 	}
 
 	return width;
@@ -224,7 +362,7 @@
 	str = sep = buffer;
 
 	while (off < len && *sep) {
-		if (*sep == ' ') 
+		if (*sep == ' ' || *sep < 0/*Added by zhancb,a new condiftion*/) 
 			(*words) ++;
 
 		sep = g_utf8_next_char (sep);
@@ -330,7 +468,6 @@
 	for (i = 0; i < len; i++)
 		putchar (text [i]);
 
-	printf ("'\n");
 }
 #endif
 
@@ -371,11 +508,12 @@
 	gint width = 0;
 
 	if (HTML_TEXT (slave->owner)->text_len == 0
-	    || html_text_get_char (HTML_TEXT (slave->owner), slave->posStart + slave->posLen - 1) != ' ') {
+	    || (html_text_get_char (HTML_TEXT (slave->owner), slave->posStart + slave->posLen - 1) != ' '
+         && html_text_get_char (HTML_TEXT (slave->owner), slave->posStart + slave->posLen - 1) >= 0)/*Added by zhancb,a new and condition*/) {
 		HTMLObject *obj;
 		obj = html_object_next_not_slave (HTML_OBJECT (slave));
 		if (obj && html_object_is_text (obj)
-		    && html_text_get_char (HTML_TEXT (obj), 0) != ' ')
+		    && html_text_get_char (HTML_TEXT (obj), 0) != ' ' && html_text_get_char (HTML_TEXT (obj), 0) > 0/*Added by zhancb,a new and condition*/ )
 			width = html_text_get_nb_width (HTML_TEXT (obj), painter, TRUE);
 	}
 
@@ -457,7 +595,6 @@
 
 	begin = html_text_slave_remove_leading_space (slave, painter, lineBegin);
 
-	/* printf ("fit_line %d left: %d lspacetext: \"%s\"\n", firstRun, widthLeft, begin); */
 
 	prev = html_object_prev_not_slave (HTML_OBJECT (text));
 	forceFit = orig_start_word == slave->start_word
@@ -473,15 +610,27 @@
 		}
 		
 		words ++;
-		while (*sep && *sep != ' ') {
+
+       /*
+        *Modifed by zhancb 2003-6-1,For line break of Chinese Text,now I limited the line width to 60,but didn't work.
+	    *The original code is: while (*sep && *sep != ' ')
+       */
+		while (*sep && *sep != ' ' && *sep >= 0)
+       /*
+	    *Modified End
+       */
+       {
 			sep = g_utf8_next_char (sep);
 			pos++;
 		}
 
 		if (words + slave->start_word >= text->words)
+		{
 			break;
 	}
 
+	}
+
 	if (words + slave->start_word == text->words)
 		rv = HTML_FIT_COMPLETE;
 	else if (words == 0 || get_words_width (slave, painter, words) == 0) {
@@ -506,7 +655,8 @@
 
 			words ++;
 
-			while (*sep && *sep != ' ') {
+			while (*sep && *sep != ' ')
+			{
 				sep = g_utf8_next_char (sep);
 				pos ++;
 			}
@@ -514,9 +664,58 @@
 	}
 
 	if (rv == HTML_FIT_PARTIAL)
+    {
+	    // Added by zhancb 2003-6-8
+        // Check if current char could be broken after and next char could be broken before
+        if ( *sep < 0 )
+        {
+            gchar xByte, yByte, zByte ;
+			gchar xPrevByte, yPrevByte, zPrevByte ;
+			
+			zPrevByte = -1 ;
+			
+			while (1)
+            {
+     				
+				xByte = *sep ;
+				xPrevByte = *g_utf8_prev_char( sep ) ;
+				if ( *sep < 0 )
+				{
+					yByte = *(sep + 1 ) ;
+					zByte = *(sep + 2 ) ;
+				}
+				else
+				{
+					yByte = *g_utf8_prev_char( sep ) ;
+					zByte = *g_utf8_next_char( sep ) ;
+				}
+				if ( xPrevByte < 0 )
+				{
+					yPrevByte = *(g_utf8_prev_char( sep ) + 1) ;
+					zPrevByte = *(g_utf8_prev_char( sep ) + 2 ) ;					
+				}
+				else
+				{
+					yPrevByte = *g_utf8_prev_char(g_utf8_prev_char( sep ) ) ;
+					zPrevByte = *sep ;
+				}
+				
+	            if  ( ( (ChkBreakType( xByte, yByte, zByte ) == BREAK_BEFORE || ChkBreakType( xByte, yByte, zByte ) == BREAK_FREE ) && 
+					(ChkBreakType( xPrevByte, yPrevByte, zPrevByte ) == BREAK_AFTER || ChkBreakType( xPrevByte, yPrevByte, zPrevByte ) == BREAK_FREE) )
+                    || 0 == pos )
+                    break ;
+
+                sep = g_utf8_prev_char( sep ) ;
+                pos -- ;
+            }
+        }
+		// Added End
+		
 		if (pos < slave->posLen) {
 			split (slave, pos, slave->start_word + words, *sep ? sep : NULL);
 		o->width = get_words_width (slave, painter, words);
+	
+		}
 	}
 
 #ifdef HTML_TEXT_SLAVE_DEBUG
