Author: matt
Date: 2010-05-04 15:20:19 -0700 (Tue, 04 May 2010)
New Revision: 7589
Log:
position_to_XY and XY_to_position now works well using a singke function, so 
that changes to text drawing will need to be changed only once. Cursor drawing 
and selection works well for utf-8 now.

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

Modified: branches/branch-1.3-STR2158-matt/FL/Fl_Text_Display.H
===================================================================
--- branches/branch-1.3-STR2158-matt/FL/Fl_Text_Display.H       2010-05-04 
15:35:41 UTC (rev 7588)
+++ branches/branch-1.3-STR2158-matt/FL/Fl_Text_Display.H       2010-05-04 
22:20:19 UTC (rev 7589)
@@ -260,6 +260,7 @@
   void draw_vline(int visLineNum, int leftClip, int rightClip,
                   int leftCharIndex, int rightCharIndex);
 
+  int find_x(char *s, int len, int style, int x);
   enum { DRAW_LINE, FIND_INDEX, GET_WIDTH };
   int handle_vline(
                    int mode, 

Modified: branches/branch-1.3-STR2158-matt/src/Fl_Text_Display.cxx
===================================================================
--- branches/branch-1.3-STR2158-matt/src/Fl_Text_Display.cxx    2010-05-04 
15:35:41 UTC (rev 7588)
+++ branches/branch-1.3-STR2158-matt/src/Fl_Text_Display.cxx    2010-05-04 
22:20:19 UTC (rev 7589)
@@ -678,9 +678,8 @@
 */
 
 int Fl_Text_Display::position_to_xy( int pos, int* X, int* Y ) const {
-  int charIndex, lineStartPos, fontHeight, lineLen;
-  int visLineNum, charLen, outIndex, xStep, charStyle;
-  const char *lineStr;
+  int lineStartPos, fontHeight, lineLen;
+  int visLineNum;
 
 //  printf("position_to_xy(pos=%d, X=%p, Y=%p)\n", pos, X, Y);
 
@@ -718,6 +717,11 @@
     return 1;
   }
   lineLen = vline_length( visLineNum );
+#if 1
+  Fl_Text_Display *d = (Fl_Text_Display*)this;
+  *X = d->handle_vline(GET_WIDTH, lineStartPos, pos-lineStartPos, 0, 0, 0, 0, 
0, 0);
+  return 1;
+#else
   lineStr = mBuffer->text_range( lineStartPos, lineStartPos + lineLen );
 
   /* Step through character positions from the beginning of the line
@@ -735,6 +739,7 @@
   }
   *X = xStep;
   free((char *)lineStr);
+#endif
   return 1;
 }
 
@@ -1406,6 +1411,10 @@
 // index of last character that fits into the box
 //
 //   enum { DRAW_LINE, FIND_INDEX, GET_WIDTH };
+//
+// FIXME: we need to allow two modes for FIND_INDEX: one on the edge of the 
+// character for selection, and one on the character center for cursors.
+//
 int Fl_Text_Display::handle_vline(
   int mode, 
   int lineStartPos, int lineLen, int leftChar, int rightChar,
@@ -1426,10 +1435,11 @@
   startIndex = 0;
   if (!lineStr) {
     // just clear the background
-    style = position_style(lineStartPos, lineLen, -1);
-    draw_string( style|BG_ONLY_MASK, text_area.x, Y, text_area.x+text_area.w, 
lineStr, lineLen );
-    free(lineStr);
-    return 0;
+    if (mode==DRAW_LINE) {
+      style = position_style(lineStartPos, lineLen, -1);
+      draw_string( style|BG_ONLY_MASK, text_area.x, Y, 
text_area.x+text_area.w, lineStr, lineLen );
+    }
+    return lineStartPos;
   }
   
   // draw the line
@@ -1442,7 +1452,14 @@
     if (charStyle!=style) {
       // draw a segment whenever the style changes
       int w = string_width( lineStr+startIndex, i-startIndex, style );
-      draw_string( style, startX, Y, startX+w, lineStr+startIndex, 
i-startIndex );
+      if (mode==DRAW_LINE)
+        draw_string( style, startX, Y, startX+w, lineStr+startIndex, 
i-startIndex );
+      if (mode==FIND_INDEX && startX+w>rightClip) {
+        // find x pos inside block
+        int di = find_x(lineStr+startIndex, i-startIndex, style, 
rightClip-startX);
+        free(lineStr);
+        return lineStartPos + startIndex + di;
+      }
       style = charStyle;
       startX += w;
       startIndex = i;
@@ -1450,17 +1467,39 @@
     i += len;
   }
   int w = string_width( lineStr+startIndex, i-startIndex, style );
-  draw_string( style, startX, Y, startX+w, lineStr+startIndex, i-startIndex );
-  
+  if (mode==DRAW_LINE)
+    draw_string( style, startX, Y, startX+w, lineStr+startIndex, i-startIndex 
);
+  if (mode==FIND_INDEX) {
+    // find x pos inside block
+    int di = find_x(lineStr+startIndex, i-startIndex, style, rightClip-startX);
+    free(lineStr);
+    return lineStartPos + startIndex + di;
+  }
+  if (mode==GET_WIDTH) {
+    return startX+w;
+  }
+    
   // clear the rest of the line
   startX += w;
   style = position_style(lineStartPos, lineLen, i);
-  draw_string( style|BG_ONLY_MASK, startX, Y, text_area.x+text_area.w, 
lineStr, lineLen );
+  if (mode==DRAW_LINE)
+    draw_string( style|BG_ONLY_MASK, startX, Y, text_area.x+text_area.w, 
lineStr, lineLen );
 
   free(lineStr);
-  return 0;
+  return lineStartPos + lineLen;
 }
 
+int Fl_Text_Display::find_x(char *s, int len, int style, int x) {
+  int i = 0;
+  while (i<len) {
+    int cl = fl_utf8len(s[i]);
+    int w = string_width(s, i+cl, style);
+    if (w>x) 
+      return i;
+    i += cl;
+  }  
+  return len;
+}
 
 
 /**
@@ -1782,9 +1821,8 @@
    closest to (X, Y).
 */
 int Fl_Text_Display::xy_to_position( int X, int Y, int posType ) const {
-  int charIndex, lineStart, lineLen, fontHeight;
-  int charWidth, charLen, charStyle, visLineNum, xStep, outIndex;
-  const char *lineStr;
+  int lineStart, lineLen, fontHeight;
+  int visLineNum;
 
   /* Find the visible line number corresponding to the Y coordinate */
   fontHeight = mMaxsize;
@@ -1803,31 +1841,12 @@
 
   /* Get the line text and its length */
   lineLen = vline_length( visLineNum );
-  lineStr = mBuffer->text_range( lineStart, lineStart + lineLen );
-
-  /* Step through character positions from the beginning of the line
-     to find the character position corresponding to the X coordinate */
-  xStep = text_area.x - mHorizOffset;
-  outIndex = 0;
-  for (charIndex = 0; charIndex < lineLen; ) 
-  {
-    // FIXME: use a unified function for this
-    charLen = fl_utf8len(lineStr[charIndex]);    
-    charStyle = position_style( lineStart, lineLen, charIndex );
-    charWidth = string_width( lineStr+charIndex, charLen, charStyle );
-    if ( X < xStep + ( posType == CURSOR_POS ? charWidth / 2 : charWidth ) ) {
-      free((char *)lineStr);
-      return lineStart + charIndex;
-    }
-    xStep += charWidth;
-    outIndex += charLen;
-    charIndex += charLen;
-  }
-
-  /* If the X position was beyond the end of the line, return the position
-     of the newline at the end of the line */
-  free((char *)lineStr);
-  return lineStart + lineLen;
+  
+  Fl_Text_Display *d = (Fl_Text_Display*)this;
+  return d->handle_vline(FIND_INDEX, 
+                         lineStart, lineLen, 0, 0, 
+                         0, 0,
+                         text_area.x, X);
 }
 
 /**

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

Reply via email to