diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2010-04-05 22:18:14 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2010-04-05 22:18:14 +0000 |
| commit | 61cf49ddfce0cbf26a769928df9be7093ed88366 (patch) | |
| tree | c7c080c3c370df66e696aaf5cbbc768f22337b97 /src | |
| parent | 07a4509a63bfc06fca31972002e2861449df49c3 (diff) | |
Another update to Fl_Text_Buffer. This is by no means perfect, but at least it currently does not crash (I am so easily satisfied :-P).
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7449 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl_Text_Buffer.cxx | 117 | ||||
| -rw-r--r-- | src/Fl_Text_Display.cxx | 88 |
2 files changed, 97 insertions, 108 deletions
diff --git a/src/Fl_Text_Buffer.cxx b/src/Fl_Text_Buffer.cxx index 2b091ec95..0e8884972 100644 --- a/src/Fl_Text_Buffer.cxx +++ b/src/Fl_Text_Buffer.cxx @@ -209,14 +209,19 @@ Fl_Text_Buffer::~Fl_Text_Buffer() } } + +// This function copies verbose whatever is in front and after the gap into a +// single buffer. +// - unicode ok char *Fl_Text_Buffer::text() const { - char *t = (char *) malloc(mLength + 1); //UTF8: we alloc from a string len, but as (non-utf8 aware) strlen() - // is used to affect mLength, it is equal to buffer size - 1 and thus correct. + char *t = (char *) malloc(mLength + 1); memcpy(t, mBuf, mGapStart); memcpy(&t[mGapStart], &mBuf[mGapEnd], mLength - mGapStart); t[mLength] = '\0'; return t; -} void Fl_Text_Buffer::text(const char *t) +} + +void Fl_Text_Buffer::text(const char *t) { call_predelete_callbacks(0, length()); @@ -249,6 +254,9 @@ char *Fl_Text_Buffer::text() const { free((void *) deletedText); } + +// Creates a new buffer and copies verbose from around the gap. +// - unicode ok char *Fl_Text_Buffer::text_range(int start, int end) const { char *s = NULL; @@ -284,6 +292,8 @@ char *Fl_Text_Buffer::text_range(int start, int end) const { return s; } + +// FIXME: a character must be UCS-4 encoded char Fl_Text_Buffer::character(int pos) const { if (pos < 0 || pos >= mLength) return '\0'; @@ -291,7 +301,10 @@ char Fl_Text_Buffer::character(int pos) const { return mBuf[pos]; else return mBuf[pos + mGapEnd - mGapStart]; -} void Fl_Text_Buffer::insert(int pos, const char *text) +} + + +void Fl_Text_Buffer::insert(int pos, const char *text) { /* if pos is not contiguous to existing text, make it */ if (pos > mLength) @@ -930,25 +943,23 @@ int Fl_Text_Buffer::word_end(int pos) const { } return pos; } + +// Expand from the byte representation into some readable text. +// Under unicode, this is not really needed because all characters should +// be prinatble one way or the other. But since we use this to (badly) simulate +// tabs, we can leave this here anyway. +// - unicode ok int Fl_Text_Buffer::expand_character(int pos, int indent, char *outStr) const { - char c = character(pos); - int ret = expand_character(c, indent, outStr, mTabDist); - if (ret > 1 && (c & 0x80)) - { - int i; - i = fl_utf8len(c); - while (i > 1) { - i--; - pos++; - outStr++; - *outStr = character(pos); - }} - - return ret; + const char *src = address(pos); + return expand_character(src, indent, outStr, mTabDist); } -int Fl_Text_Buffer::expand_character(char c, int indent, char *outStr, int tabDist) + +// static function and counterpart to "character_width" +// - unicode ok +int Fl_Text_Buffer::expand_character(const char *src, int indent, char *outStr, int tabDist) { + char c = *src; /* Convert tabs to spaces */ if (c == '\t') { int nSpaces = tabDist - (indent % tabDist); @@ -958,7 +969,6 @@ int Fl_Text_Buffer::expand_character(char c, int indent, char *outStr, int tabDi } /* Convert control codes to readable character sequences */ - /*... is this safe with international character sets? */ if (((unsigned char) c) <= 31) { sprintf(outStr, "<%s>", ControlCodeTable[(unsigned char) c]); return strlen(outStr); @@ -972,8 +982,9 @@ int Fl_Text_Buffer::expand_character(char c, int indent, char *outStr, int tabDi *outStr = c; return 1; } else if (c & 0x80) { - *outStr = c; - return fl_utf8len(c); + int i, n = fl_utf8len(c); + for (i=0; i<n; i++) *outStr++ = *src++; + return n; } /* Otherwise, just return the character */ @@ -981,9 +992,16 @@ int Fl_Text_Buffer::expand_character(char c, int indent, char *outStr, int tabDi return 1; } -int Fl_Text_Buffer::character_width(char c, int indent, int tabDist) + +// This function takes a character and optionally converts it into a little +// string which will replace the character on screen. This function returns +// the number of bytes in the replacement string, but *not* the number of +// bytes in the original character! +// - unicode ok +int Fl_Text_Buffer::character_width(const char *src, int indent, int tabDist) { /* Note, this code must parallel that in Fl_Text_Buffer::ExpandCharacter */ + char c = *src; if (c == '\t') { return tabDist - (indent % tabDist); } else if (((unsigned char) c) <= 31) { @@ -1011,18 +1029,22 @@ int Fl_Text_Buffer::count_displayed_characters(int lineStartPos, while (pos < targetPos) charCount += expand_character(pos++, charCount, expandedChar); return charCount; -} int Fl_Text_Buffer::skip_displayed_characters(int lineStartPos, - int nChars) +} + + +// All values are number of bytes. +// - unicode ok +int Fl_Text_Buffer::skip_displayed_characters(int lineStartPos, int nChars) { int pos = lineStartPos; - char c; for (int charCount = 0; charCount < nChars && pos < mLength;) { - c = character(pos); + const char *src = address(pos); + char c = *src; if (c == '\n') return pos; - charCount += character_width(c, charCount, mTabDist); - pos++; + charCount += character_width(src, charCount, mTabDist); + pos += fl_utf8len(c); } return pos; } @@ -1488,7 +1510,7 @@ static void insertColInLine(const char *line, char *insLine, int column, for (linePtr = line; *linePtr != '\0'; linePtr++) { len = - Fl_Text_Buffer::character_width(*linePtr, indent, tabDist); + Fl_Text_Buffer::character_width(linePtr, indent, tabDist); if (indent + len > column) break; indent += len; @@ -1532,7 +1554,7 @@ static void insertColInLine(const char *line, char *insLine, int column, for (const char *c = retabbedStr; *c != '\0'; c++) { *outPtr++ = *c; len = - Fl_Text_Buffer::character_width(*c, indent, tabDist); + Fl_Text_Buffer::character_width(c, indent, tabDist); indent += len; } free((void *) retabbedStr); @@ -1583,7 +1605,7 @@ static void deleteRectFromLine(const char *line, int rectStart, if (indent > rectStart) break; len = - Fl_Text_Buffer::character_width(*c, indent, tabDist); + Fl_Text_Buffer::character_width(c, indent, tabDist); if (indent + len > rectStart && (indent == rectStart || *c == '\t')) break; indent += len; @@ -1594,7 +1616,7 @@ static void deleteRectFromLine(const char *line, int rectStart, /* skip the characters between rectStart and rectEnd */ for (; *c != '\0' && indent < rectEnd; c++) indent += - Fl_Text_Buffer::character_width(*c, indent, tabDist); + Fl_Text_Buffer::character_width(c, indent, tabDist); int postRectIndent = indent; /* If the line ended before rectEnd, there's nothing more to do */ @@ -1641,7 +1663,7 @@ static void overlayRectInLine(const char *line, char *insLine, for (; *linePtr != '\0'; linePtr++) { len = - Fl_Text_Buffer::character_width(*linePtr, inIndent, tabDist); + Fl_Text_Buffer::character_width(linePtr, inIndent, tabDist); if (inIndent + len > rectStart) break; inIndent += len; @@ -1668,7 +1690,7 @@ static void overlayRectInLine(const char *line, char *insLine, int postRectIndent = rectEnd; for (; *linePtr != '\0'; linePtr++) { inIndent += - Fl_Text_Buffer::character_width(*linePtr, inIndent, tabDist); + Fl_Text_Buffer::character_width(linePtr, inIndent, tabDist); if (inIndent >= rectEnd) { linePtr++; postRectIndent = inIndent; @@ -1697,7 +1719,7 @@ static void overlayRectInLine(const char *line, char *insLine, for (const char *c = retabbedStr; *c != '\0'; c++) { *outPtr++ = *c; len = - Fl_Text_Buffer::character_width(*c, outIndent, tabDist); + Fl_Text_Buffer::character_width(c, outIndent, tabDist); outIndent += len; } free((void *) retabbedStr); @@ -1852,8 +1874,8 @@ static void addPadding(char *string, int startIndent, int toIndent, if (useTabs) { while (indent < toIndent) { - len = - Fl_Text_Buffer::character_width('\t', indent, tabDist); + static char t = '\t'; + len = Fl_Text_Buffer::character_width(&t, indent, tabDist); if (len > 1 && indent + len <= toIndent) { *outPtr++ = '\t'; indent += len; @@ -2115,14 +2137,14 @@ static int textWidth(const char *text, int tabDist) { int width = 0, maxWidth = 0; - for (const char *c = text; *c != '\0'; c++) { + for (const char *c = text; *c != '\0'; c++) { // FIXME: increment is wrong! if (*c == '\n') { if (width > maxWidth) maxWidth = width; width = 0; } else width += - Fl_Text_Buffer::character_width(*c, width, tabDist); + Fl_Text_Buffer::character_width(c, width, tabDist); } if (width > maxWidth) return width; @@ -2145,7 +2167,7 @@ void Fl_Text_Buffer::rectangular_selection_boundaries(int lineStartPos, if (c == '\n') break; width = - Fl_Text_Buffer::character_width(c, indent, mTabDist); + Fl_Text_Buffer::character_width(&c, indent, mTabDist); // FIXME: c si not unicode if (indent + width > rectStart) { if (indent != rectStart && c != '\t') { pos++; @@ -2163,7 +2185,7 @@ void Fl_Text_Buffer::rectangular_selection_boundaries(int lineStartPos, if (c == '\n') break; width = - Fl_Text_Buffer::character_width(c, indent, mTabDist); + Fl_Text_Buffer::character_width(&c, indent, mTabDist); // FIXME: c is not unicode indent += width; if (indent > rectEnd) { if (indent - width != rectEnd && c != '\t') @@ -2220,7 +2242,7 @@ static char *expandTabs(const char *text, int startIndent, int tabDist, int *new for (c = text; *c != '\0'; c++) { if (*c == '\t') { len = - Fl_Text_Buffer::character_width(*c, indent, tabDist); + Fl_Text_Buffer::character_width(c, indent, tabDist); outLen += len; indent += len; } else if (*c == '\n') { @@ -2228,7 +2250,7 @@ static char *expandTabs(const char *text, int startIndent, int tabDist, int *new outLen++; } else { indent += - Fl_Text_Buffer::character_width(*c, indent, tabDist); + Fl_Text_Buffer::character_width(c, indent, tabDist); outLen++; } } @@ -2240,7 +2262,7 @@ static char *expandTabs(const char *text, int startIndent, int tabDist, int *new for (c = text; *c != '\0'; c++) { if (*c == '\t') { len = - Fl_Text_Buffer::expand_character(*c, indent, outPtr, tabDist); + Fl_Text_Buffer::expand_character(c, indent, outPtr, tabDist); outPtr += len; indent += len; } else if (*c == '\n') { @@ -2248,7 +2270,7 @@ static char *expandTabs(const char *text, int startIndent, int tabDist, int *new *outPtr++ = *c; } else { indent += - Fl_Text_Buffer::character_width(*c, indent, tabDist); + Fl_Text_Buffer::character_width(c, indent, tabDist); *outPtr++ = *c; } } @@ -2271,8 +2293,9 @@ static char *unexpandTabs(char *text, int startIndent, int tabDist, int *newLen) for (const char *c = text; *c != '\0';) { if (*c == ' ') { + static char tab = '\t'; len = - Fl_Text_Buffer::expand_character('\t', indent, expandedChar, tabDist); + Fl_Text_Buffer::expand_character(&tab, indent, expandedChar, tabDist); if (len >= 3 && !strncmp(c, expandedChar, len)) { c += len; *outPtr++ = '\t'; diff --git a/src/Fl_Text_Display.cxx b/src/Fl_Text_Display.cxx index 31ea985b8..0b72b39d3 100644 --- a/src/Fl_Text_Display.cxx +++ b/src/Fl_Text_Display.cxx @@ -629,7 +629,7 @@ void Fl_Text_Display::overstrike(const char* text) { startIndent = mBuffer->count_displayed_characters( lineStart, startPos ); indent = startIndent; for ( c = text; *c != '\0'; c++ ) - indent += Fl_Text_Buffer::character_width( *c, indent, buf->tab_distance() ); + indent += Fl_Text_Buffer::character_width( c, indent, buf->tab_distance() ); endIndent = indent; /* find which characters to remove, and if necessary generate additional @@ -641,7 +641,7 @@ void Fl_Text_Display::overstrike(const char* text) { ch = buf->character( p ); if ( ch == '\n' ) break; - indent += Fl_Text_Buffer::character_width( ch, indent, buf->tab_distance() ); + indent += Fl_Text_Buffer::character_width( &ch, indent, buf->tab_distance() ); // FIXME: not unicode if ( indent == endIndent ) { p++; break; @@ -722,18 +722,12 @@ int Fl_Text_Display::position_to_xy( int pos, int* X, int* Y ) const { to "pos" to calculate the X coordinate */ xStep = text_area.x - mHorizOffset; outIndex = 0; - for ( charIndex = 0; charIndex < lineLen && charIndex < pos - lineStartPos; charIndex++ ) { - charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, + for (charIndex = 0; + charIndex < lineLen && charIndex < pos - lineStartPos; + charIndex += fl_utf8len(lineStr[charIndex]) ) + { + charLen = Fl_Text_Buffer::expand_character( lineStr+charIndex, outIndex, expandedChar, mBuffer->tab_distance()); - if (charLen > 1 && (lineStr[ charIndex ] & 0x80)) { - int i, ii = 0;; - i = fl_utf8len(lineStr[ charIndex ]); - while (i > 1) { - i--; - ii++; - expandedChar[ii] = lineStr[ charIndex + ii]; - } - } charStyle = position_style( lineStartPos, lineLen, charIndex, outIndex ); xStep += string_width( expandedChar, charLen, charStyle ); @@ -1475,20 +1469,10 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, that character */ X = text_area.x - mHorizOffset; outIndex = 0; - for ( charIndex = 0; ; charIndex++ ) { + for ( charIndex = 0; ; charIndex += lineStr ? fl_utf8len(lineStr[charIndex]) : 1 ) { charLen = charIndex >= lineLen ? 1 : - Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, + Fl_Text_Buffer::expand_character( lineStr+charIndex, outIndex, expandedChar, buf->tab_distance()); - if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { - int i, ii = 0;; - i = fl_utf8len(lineStr[ charIndex ]); - while (i > 1) { - i--; - ii++; - expandedChar[ii] = lineStr[ charIndex + ii]; - } - } - style = position_style( lineStartPos, lineLen, charIndex, outIndex + dispIndexOffset ); charWidth = charIndex >= lineLen ? stdCharWidth : @@ -1513,19 +1497,13 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, outPtr = outStr; outIndex = outStartIndex; X = startX; - for ( charIndex = startIndex; charIndex < rightCharIndex; charIndex++ ) { + for (charIndex = startIndex; + charIndex < rightCharIndex; + charIndex += lineStr ? fl_utf8len(lineStr[charIndex]) : 1 ) + { charLen = charIndex >= lineLen ? 1 : - Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, + Fl_Text_Buffer::expand_character( lineStr+charIndex, outIndex, expandedChar, buf->tab_distance()); - if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { - int i, ii = 0;; - i = fl_utf8len(lineStr[ charIndex ]); - while (i > 1) { - i--; - ii++; - expandedChar[ii] = lineStr[ charIndex + ii]; - } - } charStyle = position_style( lineStartPos, lineLen, charIndex, outIndex + dispIndexOffset ); for ( i = 0; i < charLen; i++ ) { @@ -1561,19 +1539,13 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, outPtr = outStr; outIndex = outStartIndex; X = startX; - for ( charIndex = startIndex; charIndex < rightCharIndex; charIndex++ ) { + for (charIndex = startIndex; + charIndex < rightCharIndex; + charIndex += lineStr ? fl_utf8len(lineStr[charIndex]) : 0) + { charLen = charIndex >= lineLen ? 1 : - Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, + Fl_Text_Buffer::expand_character( lineStr+charIndex, outIndex, expandedChar, buf->tab_distance()); - if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { - int i, ii = 0;; - i = fl_utf8len(lineStr[ charIndex ]); - while (i > 1) { - i--; - ii++; - expandedChar[ii] = lineStr[ charIndex + ii]; - } - } charStyle = position_style( lineStartPos, lineLen, charIndex, outIndex + dispIndexOffset ); for ( i = 0; i < charLen; i++ ) { @@ -1923,18 +1895,12 @@ int Fl_Text_Display::xy_to_position( int X, int Y, int posType ) const { to find the character position corresponding to the X coordinate */ xStep = text_area.x - mHorizOffset; outIndex = 0; - for ( charIndex = 0; charIndex < lineLen; charIndex++ ) { - charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, + for (charIndex = 0; + charIndex < lineLen; + charIndex += fl_utf8len(lineStr[charIndex]) ) + { + charLen = Fl_Text_Buffer::expand_character( lineStr+charIndex, outIndex, expandedChar, mBuffer->tab_distance()); - if (charLen > 1 && (lineStr[ charIndex ] & 0x80)) { - int i, ii = 0;; - i = fl_utf8len(lineStr[ charIndex ]); - while (i > 1) { - i--; - ii++; - expandedChar[ii] = lineStr[ charIndex + ii]; - } - } charStyle = position_style( lineStart, lineLen, charIndex, outIndex ); charWidth = string_width( expandedChar, charLen, charStyle ); if ( X < xStep + ( posType == CURSOR_POS ? charWidth / 2 : charWidth ) ) { @@ -2732,7 +2698,7 @@ void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, colNum = 0; width = 0; } else { - colNum += Fl_Text_Buffer::character_width(c, colNum, tabDist); + colNum += Fl_Text_Buffer::character_width((char*)&c, colNum, tabDist); // FIXME: unicode if (countPixels) width += measure_proportional_character(c, colNum, p+styleBufOffset); } @@ -2762,7 +2728,7 @@ void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, } if (!foundBreak) { /* no whitespace, just break at margin */ newLineStart = max(p, lineStart+1); - colNum = Fl_Text_Buffer::character_width(c, colNum, tabDist); + colNum = Fl_Text_Buffer::character_width((char*)&c, colNum, tabDist); // FIXME: unicode if (countPixels) width = measure_proportional_character(c, colNum, p+styleBufOffset); } @@ -2814,7 +2780,7 @@ int Fl_Text_Display::measure_proportional_character(char c, int colNum, int pos) char expChar[ FL_TEXT_MAX_EXP_CHAR_LEN ]; Fl_Text_Buffer *styleBuf = mStyleBuffer; - charLen = Fl_Text_Buffer::expand_character(c, colNum, expChar, buffer()->tab_distance()); + charLen = Fl_Text_Buffer::expand_character(&c, colNum, expChar, buffer()->tab_distance()); // FIXME: unicode if (styleBuf == 0) { style = 0; } else { |
