Index: includes/unicode.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/unicode.inc,v
retrieving revision 1.27
diff -u -r1.27 unicode.inc
--- includes/unicode.inc	21 Oct 2007 18:59:01 -0000	1.27
+++ includes/unicode.inc	17 Dec 2007 18:25:05 -0000
@@ -209,22 +209,24 @@
  *   The truncated string.
  */
 function truncate_utf8($string, $len, $wordsafe = FALSE, $dots = FALSE) {
-  $slen = strlen($string);
-  if ($slen <= $len) {
+  if (drupal_strlen($string) <= $len) {
     return $string;
   }
+  if ($dots) {
+    $len -= 4;
+  }  
   if ($wordsafe) {
-    $end = $len;
-    while (($string[--$len] != ' ') && ($len > 0)) {};
-    if ($len == 0) {
-      $len = $end;
-    }
-  }
-  if ((ord($string[$len]) < 0x80) || (ord($string[$len]) >= 0xC0)) {
-    return substr($string, 0, $len) . ($dots ? ' ...' : '');
-  }
-  while (--$len >= 0 && ord($string[$len]) >= 0x80 && ord($string[$len]) < 0xC0) {};
-  return substr($string, 0, $len) . ($dots ? ' ...' : '');
+    $string = drupal_substr($string, 0, $len + 1); // leave one more character
+    $last_space = drupal_strrpos($string, ' ');
+    if ($last_space) { // space exists AND is not on position 0
+      $len = $last_space;
+    }    
+  }
+  $string = drupal_substr($string, 0, $len);
+  if ($dots) {
+    $string .= ' ...';
+  }  
+  return $string;
 }
 
 /**
@@ -375,6 +377,26 @@
   }
 }
 
+/**     
+ * Find position of last occurance of a string in another string.
+ * Compatible with mb_strrpos(), an UTF-8 friendly replacement for strrpos()
+ */
+function drupal_strrpos($haystack, $needle) {
+  global $multibyte;
+  if ($multibyte == UNICODE_MULTIBYTE) {
+    return mb_strrpos($haystack, $needle);
+  }
+  else {
+    $pos = strrpos($haystack, $needle); 
+    if ($pos === false) {
+      return false;
+    }
+    else {
+      return drupal_strlen(substr($haystack, 0, $pos));
+    }
+  }
+} 
+
 /**
  * Uppercase a UTF-8 string.
  */
