diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2011-12-06 16:55:51 +0000 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2011-12-06 16:55:51 +0000 |
| commit | d250e21542818846c8a2cbd9b04e67b099eb05ce (patch) | |
| tree | 760a9bcbfd384852be808d1c834cde8aae18c3bc /src | |
| parent | 3edb5e5aba329198d9e58468a472237de2f98160 (diff) | |
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.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@9196 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl_Input_.cxx | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/src/Fl_Input_.cxx b/src/Fl_Input_.cxx index eea14b838..003d2db4b 100644 --- a/src/Fl_Input_.cxx +++ b/src/Fl_Input_.cxx @@ -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 @@ static void undobuffersize(int n) { 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 @@ static void undobuffersize(int n) { \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 @@ static void undobuffersize(int n) { \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 @@ int Fl_Input_::replace(int b, int e, const char* text, int ilen) { } 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); |
