diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2008-09-10 23:56:49 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2008-09-10 23:56:49 +0000 |
| commit | b6bde2e4569aa617c8a6af64947c688c624ed7f8 (patch) | |
| tree | 010d15843eb7d4faf7cd1b0cd44d5b9c00462a83 /src/Fl_Input_.cxx | |
| parent | dfb50e85292687561927610e689eb5ab30d0ba26 (diff) | |
Merging the UTF8 patch, consisting of O'ksi'd s original 1.1.6 patch and additions by Ian. PLEASE BE AWARE that the patch in its current incarnation is a regression in many aspects and further work is required before we can announce Unicode support.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6212 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Input_.cxx')
| -rw-r--r-- | src/Fl_Input_.cxx | 118 |
1 files changed, 77 insertions, 41 deletions
diff --git a/src/Fl_Input_.cxx b/src/Fl_Input_.cxx index 08378f7b8..ae4799e45 100644 --- a/src/Fl_Input_.cxx +++ b/src/Fl_Input_.cxx @@ -36,6 +36,7 @@ #include <FL/fl_draw.H> #include <FL/fl_ask.H> #include <math.h> +#include <FL/fl_utf8.H> #include "flstring.h" #include <stdlib.h> #include <ctype.h> @@ -57,9 +58,14 @@ const char* Fl_Input_::expand(const char* p, char* buf) const { int width_to_lastspace = 0; int word_count = 0; int word_wrap; +// const char *pe = p + strlen(p); if (input_type()==FL_SECRET_INPUT) { - while (o<e && p < value_+size_) {*o++ = '*'; p++;} + while (o<e && p < value_+size_) { + if (fl_utf8len((char)p[0]) >= 1) *o++ = '*'; + p++; + } + } else while (o<e) { if (wrap() && (p >= value_+size_ || isspace(*p & 255))) { word_wrap = w() - Fl::box_dw(box()) - 2; @@ -79,27 +85,13 @@ const char* Fl_Input_::expand(const char* p, char* buf) const { if (c < ' ' || c == 127) { if (c=='\n' && input_type()==FL_MULTILINE_INPUT) {p--; break;} if (c == '\t' && input_type()==FL_MULTILINE_INPUT) { - for (c = (o-buf)%8; c<8 && o<e; c++) *o++ = ' '; + for (c = fl_utf_nb_char((uchar*)buf, o-buf)%8; c<8 && o<e; c++) { + *o++ = ' '; + } } else { *o++ = '^'; *o++ = c ^ 0x40; } -#ifdef __APPLE__ - // In MacRoman, all characters are defined, and non-break-space is 0xca - } else if (c == 0xCA) { // nbsp - *o++ = ' '; -#else - // in ISO 8859-1, undefined characters are rendered as octal - // this is commented out since most X11 seems to use MSWindows Latin-1 - //} else if (c >= 128 && c < 0xA0) { - // these codes are not defined in ISO code, so we output the octal code instead - // *o++ = '\\'; - // *o++ = ((c>>6)&0x03) + '0'; - // *o++ = ((c>>3)&0x07) + '0'; - // *o++ = (c&0x07) + '0'; - } else if (c == 0xA0) { // nbsp - *o++ = ' '; -#endif } else { *o++ = c; } @@ -116,23 +108,24 @@ double Fl_Input_::expandpos( int* returnn // return offset into buf here ) const { int n = 0; - if (input_type()==FL_SECRET_INPUT) n = e-p; - else while (p<e) { - int c = *p++ & 255; + int chr = 0; + if (input_type()==FL_SECRET_INPUT) { + while (p<e) { + if (fl_utf8len((char)p[0]) >= 1) n++; + p++; + } + } else while (p<e) { + int c = *p & 255; if (c < ' ' || c == 127) { - if (c == '\t' && input_type()==FL_MULTILINE_INPUT) n += 8-(n%8); - else n += 2; -#ifdef __APPLE__ - // in MacRoman, all characters are defined -#else - // in Windows Latin-1 all characters are defined - //} else if (c >= 128 && c < 0xA0) { - // these codes are not defined in ISO code, so we output the octal code instead - // n += 4; -#endif + if (c == '\t' && input_type()==FL_MULTILINE_INPUT) { + n += 8-(chr%8); + chr += 8-(chr%8); + } else n += 2; } else { n++; } + chr += fl_utf8len((char)p[0]) >= 1; + p++; } if (returnn) *returnn = n; return fl_width(buf, n); @@ -344,6 +337,10 @@ void Fl_Input_::drawtext(int X, int Y, int W, int H) { } fl_pop_clip(); + if (Fl::focus() == this) { + fl_set_spot(textfont(), textsize(), + (int)xpos+curx, Y+ypos-fl_descent(), W, H); + } } static int isword(char c) { @@ -423,14 +420,20 @@ void Fl_Input_::handle_mouse(int X, int Y, int /*W*/, int /*H*/, int drag) { const char *l, *r, *t; double f0 = Fl::event_x()-X+xscroll_; for (l = p, r = e; l<r; ) { double f; - t = l+(r-l+1)/2; + int cw = fl_utf8len((char)l[0]); + if (cw < 1) cw = 1; + t = l+cw; f = X-xscroll_+expandpos(p, t, buf, 0); if (f <= Fl::event_x()) {l = t; f0 = Fl::event_x()-f;} - else r = t-1; + else r = t-cw; } if (l < e) { // see if closer to character on right: - double f1 = X-xscroll_+expandpos(p, l+1, buf, 0)-Fl::event_x(); - if (f1 < f0) l = l+1; + double f1; + int cw = fl_utf8len((char)l[0]); + if (cw > 0) { + f1 = X-xscroll_+expandpos(p, l + cw, buf, 0) - Fl::event_x(); + if (f1 < f0) l = l+cw; + } } newpos = l-value(); @@ -470,12 +473,33 @@ void Fl_Input_::handle_mouse(int X, int Y, int /*W*/, int /*H*/, int drag) { } int Fl_Input_::position(int p, int m) { + int is_same = 0; was_up_down = 0; if (p<0) p = 0; if (p>size()) p = size(); if (m<0) m = 0; if (m>size()) m = size(); + if (p == m) is_same = 1; + + while (p < position_ && p > 0 && (size() - p) > 0 && + (fl_utf8len((char)(value() + p)[0]) < 1)) { p--; } + int ul = fl_utf8len((char)(value() + p)[0]); + while (p < size() && p > position_ && ul < 0) { + p++; + ul = fl_utf8len((char)(value() + p)[0]); + } + + while (m < mark_ && m > 0 && (size() - m) > 0 && + (fl_utf8len((char)(value() + m)[0]) < 1)) { m--; } + ul = fl_utf8len((char)(value() + m)[0]); + while (m < size() && m > mark_ && ul < 0) { + m++; + ul = fl_utf8len((char)(value() + m)[0]); + } + if (is_same) m = p; if (p == position_ && m == mark_) return 0; + + //if (Fl::selection_owner() == this) Fl::selection_owner(0); if (p != m) { if (p != position_) minimal_update(position_, p); @@ -551,7 +575,7 @@ static void undobuffersize(int n) { // all changes go through here, delete characters b-e and insert text: int Fl_Input_::replace(int b, int e, const char* text, int ilen) { - + int ul, om, op; was_up_down = 0; if (b<0) b = 0; @@ -559,6 +583,13 @@ int Fl_Input_::replace(int b, int e, const char* text, int ilen) { if (b>size_) b = size_; if (e>size_) e = size_; if (e<b) {int t=b; b=e; e=t;} + while (b != e && b > 0 && (size_ - b) > 0 && + (fl_utf8len((value_ + b)[0]) < 1)) { b--; } + ul = fl_utf8len((char)(value_ + e)[0]); + while (e < size_ && e > 0 && ul < 0) { + e++; + ul = fl_utf8len((char)(value_ + e)[0]); + } 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_) { @@ -605,7 +636,9 @@ int Fl_Input_::replace(int b, int e, const char* text, int ilen) { size_ += ilen; } undowidget = this; - undoat = b+ilen; + om = mark_; + op = position_; + mark_ = position_ = undoat = b+ilen; // Insertions into the word at the end of the line will cause it to // wrap to the next line, so we must indicate that the changes may start @@ -615,7 +648,7 @@ int Fl_Input_::replace(int b, int e, const char* text, int ilen) { if (wrap()) { // if there is a space in the pasted text, the whole line may have rewrapped int i; - for (i=0; i<ilen; i++) + for (i=0; i<ilen; i++) if (text[i]==' ') break; if (i==ilen) while (b > 0 && !isspace(index(b) & 255) && index(b)!='\n') b--; @@ -624,8 +657,8 @@ int Fl_Input_::replace(int b, int e, const char* text, int ilen) { } // make sure we redraw the old selection or cursor: - if (mark_ < b) b = mark_; - if (position_ < b) b = position_; + if (om < b) b = om; + if (op < b) b = op; minimal_update(b); @@ -702,6 +735,7 @@ int Fl_Input_::handletext(int event, int X, int Y, int W, int H) { return 1; case FL_FOCUS: + fl_set_spot(textfont(), textsize(), x(), y(), w(), h()); if (mark_ == position_) { minimal_update(size()+1); } else //if (Fl::selection_owner() != this) @@ -715,7 +749,9 @@ int Fl_Input_::handletext(int event, int X, int Y, int W, int H) { } else //if (Fl::selection_owner() != this) minimal_update(mark_, position_); case FL_HIDE: - if (!readonly() && (when() & FL_WHEN_RELEASE)) + fl_reset_spot(); + if (!readonly() && + (when() & (FL_WHEN_RELEASE | FL_WHEN_NOT_CHANGED))) maybe_do_callback(); return 1; |
