Author: AlbrechtS
Date: 2011-12-06 08:55:51 -0800 (Tue, 06 Dec 2011)
New Revision: 9196
Log:
Fixed Fl_Input_::maximum_size() documentation and Fl_Input::replace()
to honor maximum_size() as number of allowed characters (STR #2747).
This was a hangover from FLTK 1.1, where the number of bytes was equal
to the number of characters.


Modified:
   branches/branch-1.3/CHANGES
   branches/branch-1.3/FL/Fl_Input_.H
   branches/branch-1.3/src/Fl_Input_.cxx

Modified: branches/branch-1.3/CHANGES
===================================================================
--- branches/branch-1.3/CHANGES 2011-12-06 11:01:01 UTC (rev 9195)
+++ branches/branch-1.3/CHANGES 2011-12-06 16:55:51 UTC (rev 9196)
@@ -1,6 +1,8 @@
 
 CHANGES IN FLTK 1.3.1
 
+       - Fixed Fl_Input_::maximum_size() documentation and replace() method
+         to honor maximum_size() as number of allowed characters (STR #2747).
        - Fixed a potential crash if Fl_Double_Window::flush() was called
          before show()
        - Fixed regression (in FLTK 1.3.0) that could clear a radio

Modified: branches/branch-1.3/FL/Fl_Input_.H
===================================================================
--- branches/branch-1.3/FL/Fl_Input_.H  2011-12-06 11:01:01 UTC (rev 9195)
+++ branches/branch-1.3/FL/Fl_Input_.H  2011-12-06 16:55:51 UTC (rev 9196)
@@ -3,7 +3,7 @@
 //
 // Input base class header file for the Fast Light Tool Kit (FLTK).
 //
-// Copyright 1998-2010 by Bill Spitzak and others.
+// Copyright 1998-2011 by Bill Spitzak and others.
 //
 // This library is free software. Distribution and use rights are outlined in
 // the file "COPYING" which should have been included with this file.  If this
@@ -69,9 +69,10 @@
   \endcode
 
   All variables that represent an index into a text buffer are byte-oriented,
-  not character oriented. Since UTF-8 characters can be up to six bytes long,
-  simply incrementing such an index will not reliably advance to the next 
character
-  in the text buffer.
+  not character oriented, counting from 0 (at or before the first character)
+  to size() (at the end of the buffer, after the last byte). Since UTF-8
+  characters can be up to six bytes long, simply incrementing such an index
+  will not reliably advance to the next character in the text buffer.
 
   Indices and pointers into the text buffer should always point at a 7 bit 
ASCII
   character or the beginning of a UTF-8 character sequence. Behavior for false
@@ -123,7 +124,7 @@
       of the buffer. */
   int mu_p;
 
-  /** \internal Maximum size of buffer. \todo Is this really needed? */
+  /** \internal Maximum number of characters. */
   int maximum_size_;
 
   /** \internal Shortcut key that will fetch focus for this widget. */
@@ -260,16 +261,21 @@
     \see Fl_Widget::size(int, int) */
   void size(int W, int H) { Fl_Widget::size(W, H); }
 
-  /** Gets the maximum length of the input field.  
-    \todo It is not clear if this function is actually required */
+  /** Gets the maximum length of the input field in characters.
+    \see maximum_size(int). */
   int maximum_size() const {return maximum_size_;}
 
-  /** Sets the maximum length of the input field. 
-    \todo It is not clear if this function is actually required */
+  /** Sets the maximum length of the input field in characters.
+    This limits the number of <b>characters</b> that can be inserted
+    in the widget.
+    \since FLTK 1.3 this is different than the buffer size, since one
+    character can be more than one byte in UTF-8 encoding. In FLTK 1.1
+    this was the same (one byte = one character).
+  */
   void maximum_size(int m) {maximum_size_ = m;}
 
   /** Gets the position of the text cursor.
-    \return the cursor position as an index
+    \return the cursor position as an index in the range 0..size()
     \see position(int, int)
   */
   int position() const {return position_;}
@@ -281,7 +287,7 @@
   /* Sets the index for the cursor and mark. */
   int position(int p, int m);
 
-  /** Set the cursor position and mark.
+  /** Sets the cursor position and mark.
     position(n) is the same as <tt>position(n, n)</tt>.
     \param p new index for cursor and mark
     \return 0 if no positions changed
@@ -296,8 +302,8 @@
     \see position(), position(int, int) */
   int mark(int m) {return position(position(), m);}
 
-  /* Deletes text from b to e and inserts the new string text. */
-  int replace(int, int, const char*, int=0);
+  /* Deletes text from \p b to \p e and inserts the new string \p text. */
+  int replace(int b, int e, const char *text, int ilen=0);
 
   /**
     Deletes the current selection.

Modified: branches/branch-1.3/src/Fl_Input_.cxx
===================================================================
--- branches/branch-1.3/src/Fl_Input_.cxx       2011-12-06 11:01:01 UTC (rev 
9195)
+++ branches/branch-1.3/src/Fl_Input_.cxx       2011-12-06 16:55:51 UTC (rev 
9196)
@@ -3,7 +3,7 @@
 //
 // Common input widget routines for the Fast Light Tool Kit (FLTK).
 //
-// Copyright 1998-2010 by Bill Spitzak and others.
+// Copyright 1998-2011 by Bill Spitzak and others.
 //
 // This library is free software. Distribution and use rights are outlined in
 // the file "COPYING" which should have been included with this file.  If this
@@ -719,9 +719,9 @@
   Deletes text from \p b to \p e and inserts the new string \p text.
 
   All changes to the text buffer go through this function.
-  It deletes the region between \p a and \p b (either one may be less or
+  It deletes the region between \p b and \p e (either one may be less or
   equal to the other), and then inserts the string \p text
-  at that point and moves the mark() and
+  at that point and moves the mark() and 
   position() to the end of the insertion. Does the callback if
   <tt>when() & FL_WHEN_CHANGED</tt> and there is a change.
 
@@ -731,11 +731,23 @@
   \p ilen can be zero or <tt>strlen(text)</tt>, which
   saves a tiny bit of time if you happen to already know the
   length of the insertion, or can be used to insert a portion of a
-  string.
-  
-  \p b and \p e are clamped to the
-  <tt>0..size()</tt> range, so it is safe to pass any values.
-  
+  string. If \p ilen is zero, <tt>strlen(text)</tt> is used instead.
+
+  \p b and \p e are clamped to the <tt>0..size()</tt> range, so it is
+  safe to pass any values. \p b, \p e, and \p ilen are used as numbers
+  of bytes (not characters), where \p b and \p e count from 0 to
+  size() (end of buffer).
+
+  If \p b and/or \p e don't point to a valid UTF-8 character boundary,
+  they are adjusted to the previous (\p b) or the next (\p e) valid
+  UTF-8 character boundary, resp..
+
+  If the current number of characters in the buffer minus deleted
+  characters plus inserted characters in \p text would overflow the
+  number of allowed characters (maximum_size()), then only the first
+  characters of the string are inserted, so that maximum_size()
+  is not exceeded.
+
   cut() and insert() are just inline functions that call replace().
 
   \param [in] b beginning index of text to be deleted
@@ -743,6 +755,10 @@
   \param [in] text string that will be inserted
   \param [in] ilen length of \p text or 0 for \c nul terminated strings
   \return 0 if nothing changed
+  
+  \note If \p text does not point to a valid UTF-8 character or includes
+  invalid UTF-8 sequences, the text is inserted nevertheless (counting
+  invalid UTF-8 bytes as one character each).
 */
 int Fl_Input_::replace(int b, int e, const char* text, int ilen) {
   int ul, om, op;
@@ -762,10 +778,32 @@
   }
   if (text && !ilen) ilen = strlen(text);
   if (e<=b && !ilen) return 0; // don't clobber undo for a null operation
-  if (size_+ilen-(e-b) > maximum_size_) {
-    ilen = maximum_size_-size_+(e-b);
-    if (ilen < 0) ilen = 0;
+
+  // we must count UTF-8 *characters* to determine whether we can insert
+  // the full text or only a part of it (and how much this would be)
+
+  int nchars = 0;      // characters in value() - deleted + inserted
+  const char *p = value_;
+  while (p < (char *)(value_+size_)) {
+    if (p == (char *)(value_+b)) { // skip removed part
+      p = (char *)(value_+e);
+      if (p >= (char *)(value_+size_)) break;
+    }
+    int ulen = fl_utf8len(*p);
+    if (ulen < 1) ulen = 1; // invalid UTF-8 character: count as 1
+    nchars++;
+    p += ulen;
   }
+  int nlen = 0;                // length (in bytes) to be inserted
+  p = text;
+  while (p < (char *)(text+ilen) && nchars < maximum_size()) {
+    int ulen = fl_utf8len(*p);
+    if (ulen < 1) ulen = 1; // invalid UTF-8 character: count as 1
+    nchars++;
+    p += ulen;
+    nlen += ulen;
+  }
+  ilen = nlen;
 
   put_in_buffer(size_+ilen);
 

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

Reply via email to