diff options
author | fvogel <fvogelnew1@free.fr> | 2015-01-24 14:58:03 (GMT) |
---|---|---|
committer | fvogel <fvogelnew1@free.fr> | 2015-01-24 14:58:03 (GMT) |
commit | 662480c9ebe208020fd0484bbd7908dbb0fa7562 (patch) | |
tree | f38ea602db1991d6f158b487369145dfa7ac873f /generic/tkTextIndex.c | |
parent | 2a1df1da7fd04bf2163249f588314d1ae33d12f5 (diff) | |
download | tk-662480c9ebe208020fd0484bbd7908dbb0fa7562.zip tk-662480c9ebe208020fd0484bbd7908dbb0fa7562.tar.gz tk-662480c9ebe208020fd0484bbd7908dbb0fa7562.tar.bz2 |
TkTextIndexCount is counting chars. Fix these calls where bytes counting is needed. Among other issues, this fixes horizontal scrolling when typing text at the end of a line containing multi-byte characters.
Diffstat (limited to 'generic/tkTextIndex.c')
-rw-r--r-- | generic/tkTextIndex.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index 70c94db..25b4666 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -40,6 +40,9 @@ static CONST char * StartEnd(TkText *textPtr, CONST char *string, static int GetIndex(Tcl_Interp *interp, TkSharedText *sharedPtr, TkText *textPtr, CONST char *string, TkTextIndex *indexPtr, int *canCachePtr); +static int IndexCountBytesOrdered(CONST TkText *textPtr, + CONST TkTextIndex *indexPtr1, + CONST TkTextIndex *indexPtr2); /* * The "textindex" Tcl_Obj definition: @@ -1628,6 +1631,90 @@ TkTextIndexForwChars( /* *--------------------------------------------------------------------------- * + * TkTextIndexCountBytes -- + * + * Given a pair of indices in a text widget, this function counts how + * many bytes are between the two indices. The two indices do not need + * to be ordered. + * + * Results: + * The number of bytes in the given range. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +int +TkTextIndexCountBytes( + CONST TkText *textPtr, + CONST TkTextIndex *indexPtr1, /* Index describing one location. */ + CONST TkTextIndex *indexPtr2) /* Index describing second location. */ +{ + int compare = TkTextIndexCmp(indexPtr1, indexPtr2); + + if (compare == 0) { + return 0; + } else if (compare > 0) { + return IndexCountBytesOrdered(textPtr, indexPtr2, indexPtr1); + } else { + return IndexCountBytesOrdered(textPtr, indexPtr1, indexPtr2); + } +} + +static int +IndexCountBytesOrdered( + CONST TkText *textPtr, + CONST TkTextIndex *indexPtr1, + /* Index describing location of character from + * which to count. */ + CONST TkTextIndex *indexPtr2) + /* Index describing location of last character + * at which to stop the count. */ +{ + int byteCount, offset; + TkTextSegment *segPtr, *segPtr1; + TkTextLine *linePtr; + + if (indexPtr1->linePtr == indexPtr2->linePtr) { + return indexPtr2->byteIndex - indexPtr1->byteIndex; + } + + /* + * indexPtr2 is on a line strictly after the line containing indexPtr1. + * Add up: + * bytes between indexPtr1 and end of its line + * bytes in lines strictly between indexPtr1 and indexPtr2 + * bytes between start of the indexPtr2 line and indexPtr2 + */ + + segPtr1 = TkTextIndexToSeg(indexPtr1, &offset); + byteCount = -offset; + for (segPtr = segPtr1; segPtr != NULL; segPtr = segPtr->nextPtr) { + byteCount += segPtr->size; + } + + linePtr = indexPtr1->linePtr->nextPtr; + while (linePtr != indexPtr2->linePtr) { + for (segPtr = linePtr->segPtr; segPtr != NULL; + segPtr = segPtr->nextPtr) { + byteCount += segPtr->size; + } + linePtr = TkBTreeNextLine(textPtr, linePtr); + if (linePtr == NULL) { + Tcl_Panic("TextIndexCountBytesOrdered ran out of lines"); + } + } + + byteCount += indexPtr2->byteIndex; + + return byteCount; +} + +/* + *--------------------------------------------------------------------------- + * * TkTextIndexCount -- * * Given an ordered pair of indices in a text widget, this function |