Author: matt
Date: 2010-04-30 14:09:44 -0700 (Fri, 30 Apr 2010)
New Revision: 7571
Log:
Fixed left and right cursor movement taking utf8 encoding and gaps into account.

Modified:
   branches/branch-1.3-STR2158-matt/src/Fl_Text_Display.cxx

Modified: branches/branch-1.3-STR2158-matt/src/Fl_Text_Display.cxx
===================================================================
--- branches/branch-1.3-STR2158-matt/src/Fl_Text_Display.cxx    2010-04-30 
20:36:31 UTC (rev 7570)
+++ branches/branch-1.3-STR2158-matt/src/Fl_Text_Display.cxx    2010-04-30 
21:09:44 UTC (rev 7571)
@@ -877,32 +877,34 @@
 /*
    Cursor movement functions
 */
-/**  Moves the current insert position right one character.*/
+
+/**  
+ Moves the current insert position right one character.
+ \return 1 if the cursor moved, 0 if the end of the text was reached
+ */
 int Fl_Text_Display::move_right() {
-  int ok = 0;
-  while (!ok) {
   if ( mCursorPos >= mBuffer->length() )
     return 0;
-  insert_position( mCursorPos + 1 );
-    int pos = insert_position();
-    // FIXME: character is ucs-4
-    char c = buffer()->at( pos );
-    if (!((c & 0x80) && !(c & 0x40))) ok = 1;
-  }
+  int p = insert_position();
+  const char *a = buffer()->address(p);
+  int o = fl_utf8len(*a);
+  if (o==-1)
+    return 0;
+  insert_position(p+o);
   return 1;
 }
-/**  Moves the current insert position left one character.*/
+
+/**  
+ Moves the current insert position left one character.
+ \return 1 if the cursor moved, 0 if the beginning of the text was reached
+ */
 int Fl_Text_Display::move_left() {
-  int ok = 0;
-  while (!ok) {
   if ( mCursorPos <= 0 )
     return 0;
-  insert_position( mCursorPos - 1 );
-    int pos = insert_position();
-    // FIXME: character is ucs-4
-    char c = buffer()->at( pos );
-    if (!((c & 0x80) && !(c & 0x40))) ok = 1;
-  }
+  int p = insert_position();
+  const char *a = buffer()->address(p-1); // avoid falling into gap
+  const char *b = a; while (((*b) & 0xc0)==0x80) b--; // FIXME: fl_utf8_back( 
+  insert_position(p+(b-a)-1);
   return 1;
 }
 
@@ -1852,6 +1854,7 @@
   }
   fl_font( font, fsize );
 
+  // FIXME: how often is this called? Will we have to optimize the code?
   return ( int ) ( fl_width( string, length ) );
 }
 
@@ -2321,7 +2324,16 @@
 */
 int Fl_Text_Display::measure_vline( int visLineNum ) const {
   
-  return 1024; // FIXME: time waster?
+  return 1024; // FIXME: time waster!
+  /* The line above helps us clean up this widget.
+   
+   The original code measures each individual character. That is not only 
+   horribly inefficient but also quite wrong, because a good text rendering 
+   engine may concatenate and overlap consecutive characters.
+   
+   The correct and fastest solution is to measure text segments that are as 
long
+   as possible. A new segment begins only when the style changes.
+   */
   
   int i, width = 0, len, style, lineLen = vline_length( visLineNum );
   int charCount = 0, lineStartPos = mLineStarts[ visLineNum ];

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to