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