diff options
author | fvogelnew1@free.fr <fvogel> | 2015-01-24 14:58:03 (GMT) |
---|---|---|
committer | fvogelnew1@free.fr <fvogel> | 2015-01-24 14:58:03 (GMT) |
commit | 43202bdf5b7678279ad57e69854c36c6a6e8c72d (patch) | |
tree | 756feba5ca87ddf98ea57401e90da2be2dbdd405 /generic | |
parent | 6e70d0c9924222b58ed4e45ca85bdc52104ed4e4 (diff) | |
download | tk-43202bdf5b7678279ad57e69854c36c6a6e8c72d.zip tk-43202bdf5b7678279ad57e69854c36c6a6e8c72d.tar.gz tk-43202bdf5b7678279ad57e69854c36c6a6e8c72d.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')
-rw-r--r-- | generic/tkText.h | 3 | ||||
-rw-r--r-- | generic/tkTextDisp.c | 10 | ||||
-rw-r--r-- | generic/tkTextIndex.c | 87 |
3 files changed, 94 insertions, 6 deletions
diff --git a/generic/tkText.h b/generic/tkText.h index 4ffdc8a..6f5f153 100644 --- a/generic/tkText.h +++ b/generic/tkText.h @@ -1071,6 +1071,9 @@ MODULE_SCOPE void TkTextIndexBackChars(const TkText *textPtr, TkTextIndex *dstPtr, TkTextCountType type); MODULE_SCOPE int TkTextIndexCmp(const TkTextIndex *index1Ptr, const TkTextIndex *index2Ptr); +MODULE_SCOPE int TkTextIndexCountBytes(const TkText *textPtr, + const TkTextIndex *index1Ptr, + const TkTextIndex *index2Ptr); MODULE_SCOPE int TkTextIndexCount(const TkText *textPtr, const TkTextIndex *index1Ptr, const TkTextIndex *index2Ptr, diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index a6ab13c..34202bd 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -3465,8 +3465,8 @@ TkTextFindDisplayLineEnd( */ *xOffset = DlineXOfIndex(textPtr, dlPtr, - TkTextIndexCount(textPtr, &dlPtr->index, indexPtr, - COUNT_INDICES)); + TkTextIndexCountBytes(textPtr, &dlPtr->index, + indexPtr)); } if (end) { /* @@ -5549,8 +5549,7 @@ TkTextSeeCmd( * they are elided. */ - byteCount = TkTextIndexCount(textPtr, &dlPtr->index, &index, - COUNT_INDICES); + byteCount = TkTextIndexCountBytes(textPtr, &dlPtr->index, &index); for (chunkPtr = dlPtr->chunkPtr; chunkPtr != NULL ; chunkPtr = chunkPtr->nextPtr) { if (byteCount < chunkPtr->numBytes) { @@ -7078,8 +7077,7 @@ TkTextIndexBbox( * they are elided. */ - byteCount = TkTextIndexCount(textPtr, &dlPtr->index, indexPtr, - COUNT_INDICES); + byteCount = TkTextIndexCountBytes(textPtr, &dlPtr->index, indexPtr); for (chunkPtr = dlPtr->chunkPtr; ; chunkPtr = chunkPtr->nextPtr) { if (chunkPtr == NULL) { return -1; 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 |