summaryrefslogtreecommitdiffstats
path: root/generic/tkTextIndex.c
diff options
context:
space:
mode:
authorfvogel <fvogelnew1@free.fr>2015-01-24 14:58:03 (GMT)
committerfvogel <fvogelnew1@free.fr>2015-01-24 14:58:03 (GMT)
commit662480c9ebe208020fd0484bbd7908dbb0fa7562 (patch)
treef38ea602db1991d6f158b487369145dfa7ac873f /generic/tkTextIndex.c
parent2a1df1da7fd04bf2163249f588314d1ae33d12f5 (diff)
downloadtk-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.c87
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