From accf34f276b200f87d30bc0800895420798ed2ff Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sun, 7 Nov 2010 20:13:50 +0000 Subject: Implemented search backwards for utf-8. Tested on MSWindows - OK. Tested on Linux (Ubuntu) - K. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7808 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_Text_Buffer.cxx | 79 ++++++++++++++++++++++++++++++------------------- src/Fl_Text_Display.cxx | 15 ++++------ src/fl_utf8.cxx | 8 ++--- 3 files changed, 57 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/Fl_Text_Buffer.cxx b/src/Fl_Text_Buffer.cxx index 531ec5029..52666333e 100644 --- a/src/Fl_Text_Buffer.cxx +++ b/src/Fl_Text_Buffer.cxx @@ -856,13 +856,11 @@ int Fl_Text_Buffer::word_end(int pos) const { /* - Matt: I am not sure why we need this function. Does it still make sense in - the world of proportional characters? + Count the number of characters between two positions. */ int Fl_Text_Buffer::count_displayed_characters(int lineStartPos, int targetPos) const { - // FIXME: this is misleading and may be used to count bytes instead of characters! IS_UTF8_ALIGNED(address(lineStartPos)) IS_UTF8_ALIGNED(address(targetPos)) @@ -878,16 +876,13 @@ int Fl_Text_Buffer::count_displayed_characters(int lineStartPos, /* - Matt: I am not sure why we need this function. Does it still make sense in - the world of proportional characters? + Skip ahead a number of characters from a given index. + This function breaks early if it encounters a newline character. */ -// All values are number of bytes. -// - unicode ok? int Fl_Text_Buffer::skip_displayed_characters(int lineStartPos, int nChars) { - // FIXME: this is misleading and may be used to count bytes instead of characters! IS_UTF8_ALIGNED(address(lineStartPos)) - // FIXME: is this function still needed? + int pos = lineStartPos; for (int charCount = 0; charCount < nChars && pos < mLength; charCount++) { @@ -1060,37 +1055,60 @@ int Fl_Text_Buffer::search_forward(int startPos, const char *searchString, return 0; } - -/* - Find a matching string in the buffer. - NOT TESTED FOR UNICODE. - */ int Fl_Text_Buffer::search_backward(int startPos, const char *searchString, - int *foundPos, int matchCase) const { - // FIXME: Unicode? + int *foundPos, int matchCase) const +{ + IS_UTF8_ALIGNED(address(startPos)) + IS_UTF8_ALIGNED(searchString) + if (!searchString) return 0; int bp; const char *sp; - while (startPos > 0) - { - bp = startPos - 1; - sp = searchString + strlen(searchString) - 1; - do { - if (sp < searchString) { - *foundPos = bp + 1; - return 1; + if (matchCase) { + while (startPos >= 0) { + bp = startPos; + sp = searchString; + for (;;) { + char c = *sp; + // we reached the end of the "needle", so we found the string! + if (!c) { + *foundPos = startPos; + return 1; + } + int l = fl_utf8len(c); + if (memcmp(sp, address(bp), l)) + break; + sp += l; bp += l; } - // FIXME: character is ucs-4 - } while ((matchCase ? char_at(bp--) == (unsigned int)*sp-- : - toupper(char_at(bp--)) == toupper(*sp--)) - && bp >= 0); - startPos--; - } + startPos = prev_char(startPos); + } + } else { + while (startPos >= 0) { + bp = startPos; + sp = searchString; + for (;;) { + // we reached the end of the "needle", so we found the string! + if (!*sp) { + *foundPos = startPos; + return 1; + } + int l; + unsigned int b = char_at(bp); + unsigned int s = fl_utf8decode(sp, 0, &l); + if (fl_tolower(b)!=fl_tolower(s)) + break; + sp += l; + bp = next_char(bp); + } + startPos = prev_char(startPos); + } + } return 0; } + /* Insert a string into the buffer. Pos must be at a character boundary. Text must be a correct utf8 string. @@ -1422,7 +1440,6 @@ void Fl_Text_Buffer::update_selections(int pos, int nDeleted, // unicode safe, assuming the arguments are on character boundaries void Fl_Text_Selection::update(int pos, int nDeleted, int nInserted) { - // FIXME: check if this is safe when seletion crosses selction boundaries if (!mSelected || pos > mEnd) return; if (pos + nDeleted <= mStart) { diff --git a/src/Fl_Text_Display.cxx b/src/Fl_Text_Display.cxx index a9e7c8b6b..48f726f69 100644 --- a/src/Fl_Text_Display.cxx +++ b/src/Fl_Text_Display.cxx @@ -33,6 +33,7 @@ // TODO: verify all "byte counts" vs. "character counts" // TODO: rendering of the Tab character // TODO: rendering of the "optional hyphen" +// TODO: make line numbering work again #include #include @@ -948,8 +949,6 @@ void Fl_Text_Display::display_insert() { hOffset = mHorizOffset; topLine = mTopLineNum; - // FIXME: I don't understand this well enough to know if it is correct - // it is different than nedit 5.3 if (insert_position() < mFirstChar) { topLine -= count_lines(insert_position(), mFirstChar, false); } else if (mLineStarts[mNVisibleLines-2] != -1) { @@ -1296,8 +1295,8 @@ int Fl_Text_Display::rewind_lines(int startPos, int nLines) { -// FIXME: this does not take UCS-4 encoding into account static inline int fl_isseparator(unsigned int c) { + // FIXME: this does not take UCS-4 encoding into account return c != '$' && c != '_' && (isspace(c) || ispunct(c)); } @@ -1333,7 +1332,7 @@ void Fl_Text_Display::previous_word() { while (pos && fl_isseparator(buffer()->char_at(pos))) { pos = buffer()->prev_char(pos); } - // FIXME: character is ucs-4 + while (pos && !fl_isseparator(buffer()->char_at(pos))) { pos = buffer()->prev_char(pos); } @@ -1663,7 +1662,7 @@ int Fl_Text_Display::position_to_line( int pos, int *lineNum ) const { \retval FIND_INDEX x pixel position inside given block \todo we need to handle hidden hyphens and tabs here! \todo we handle all styles and selections - \todo we must provide code to get pixle positions of the middle of a character as well + \todo we must provide code to get pixel positions of the middle of a character as well */ int Fl_Text_Display::handle_vline( int mode, @@ -2572,8 +2571,6 @@ void Fl_Text_Display::h_scrollbar_cb(Fl_Scrollbar* b, Fl_Text_Display* textD) { */ void Fl_Text_Display::draw_line_numbers(bool /*clearAll*/) { #if 0 - // FIXME: don't want this yet, so will leave for another time - int y, line, visLine, nCols, lineStart; char lineNumString[12]; int lineHeight = mMaxsize ? mMaxsize : textsize_; @@ -2940,9 +2937,7 @@ void Fl_Text_Display::measure_deleted_lines(int pos, int nDeleted) { } else lineStart = retPos; nLines++; - if (lineStart > pos + nDeleted && - // FIXME: character is ucs-4 - buf->char_at(lineStart-1) == '\n') { + if (lineStart > pos + nDeleted && buf->char_at(lineStart-1) == '\n') { break; } diff --git a/src/fl_utf8.cxx b/src/fl_utf8.cxx index 1cd809eed..6d69a588e 100644 --- a/src/fl_utf8.cxx +++ b/src/fl_utf8.cxx @@ -378,11 +378,11 @@ int fl_latin12utf(const unsigned char *str, int len, char *buf) */ unsigned int fl_nonspacing(unsigned int ucs) { -#ifdef __APPLE__ - return (ucs==0x20); // FIXME: what does this really do? -#else +//#ifdef __APPLE__ +// return (ucs==0x20); // FIXME: what does this really do? +//#else return (unsigned int) XUtf8IsNonSpacing(ucs); -#endif +//#endif } #if defined(WIN32) && !defined(__CYGWIN__) -- cgit v1.2.3