diff options
author | vincentdarley <vincentdarley> | 2003-11-07 15:36:24 (GMT) |
---|---|---|
committer | vincentdarley <vincentdarley> | 2003-11-07 15:36:24 (GMT) |
commit | f4b5ed83cac2135eee47665181613178a33293ee (patch) | |
tree | a1d683e81cad5acc063a7a19da19b30cb5e568b6 /generic/tkTextIndex.c | |
parent | 2a739cee5e02ba828e59bcf8348ff158ef53db67 (diff) | |
download | tk-f4b5ed83cac2135eee47665181613178a33293ee.zip tk-f4b5ed83cac2135eee47665181613178a33293ee.tar.gz tk-f4b5ed83cac2135eee47665181613178a33293ee.tar.bz2 |
better elide tag handling
Diffstat (limited to 'generic/tkTextIndex.c')
-rw-r--r-- | generic/tkTextIndex.c | 164 |
1 files changed, 110 insertions, 54 deletions
diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index 66caa5a..123fb01 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextIndex.c,v 1.9 2003/10/31 09:02:11 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextIndex.c,v 1.10 2003/11/07 15:36:26 vincentdarley Exp $ */ #include "default.h" @@ -1118,9 +1118,9 @@ ForwBack(textPtr, string, indexPtr) type = COUNT_DISPLAY_CHARS; } if (*string == '+') { - TkTextIndexForwChars(indexPtr, count, indexPtr, type); + TkTextIndexForwChars(textPtr, indexPtr, count, indexPtr, type); } else { - TkTextIndexBackChars(indexPtr, count, indexPtr, type); + TkTextIndexBackChars(textPtr, indexPtr, count, indexPtr, type); } } else if ((*units == 'i') && (strncmp(units, "indices", length) == 0)) { TkTextCountType type; @@ -1130,9 +1130,9 @@ ForwBack(textPtr, string, indexPtr) type = COUNT_INDICES; } if (*string == '+') { - TkTextIndexForwChars(indexPtr, count, indexPtr, type); + TkTextIndexForwChars(textPtr, indexPtr, count, indexPtr, type); } else { - TkTextIndexBackChars(indexPtr, count, indexPtr, type); + TkTextIndexBackChars(textPtr, indexPtr, count, indexPtr, type); } } else if ((*units == 'l') && (strncmp(units, "lines", length) == 0)) { if (modifier == TKINDEX_DISPLAY) { @@ -1147,10 +1147,10 @@ ForwBack(textPtr, string, indexPtr) * original pixel offset. */ int xOffset, forward; - if (TkTextIsElided(textPtr, indexPtr)) { + if (TkTextIsElided(textPtr, indexPtr, NULL)) { /* Go forward to the first non-elided index */ - TkTextIndexForwChars(indexPtr, 0, indexPtr, - COUNT_DISPLAY_INDICES | COUNT_IS_ELIDED); + TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr, + COUNT_DISPLAY_INDICES); } /* * Unlike the Forw/BackChars code, the display line code @@ -1177,9 +1177,8 @@ ForwBack(textPtr, string, indexPtr) * line. */ TkTextFindDisplayLineEnd(textPtr, indexPtr, 1, NULL); - TkTextIndexForwChars(indexPtr, 1, indexPtr, - COUNT_DISPLAY_INDICES - | (COUNT_IS_ELIDED * TkTextIsElided(textPtr, indexPtr))); + TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr, + COUNT_DISPLAY_INDICES); } } else { TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, &xOffset); @@ -1189,9 +1188,8 @@ ForwBack(textPtr, string, indexPtr) * char/byte to get to the end of the previous line */ TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL); - TkTextIndexBackChars(indexPtr, 1, indexPtr, - COUNT_DISPLAY_INDICES - | (COUNT_IS_ELIDED * TkTextIsElided(textPtr, indexPtr))); + TkTextIndexBackChars(textPtr, indexPtr, 1, indexPtr, + COUNT_DISPLAY_INDICES); } TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL); } @@ -1335,7 +1333,8 @@ TkTextIndexForwBytes(srcPtr, byteCount, dstPtr) */ void -TkTextIndexForwChars(srcPtr, charCount, dstPtr, type) +TkTextIndexForwChars(textPtr, srcPtr, charCount, dstPtr, type) + CONST TkText *textPtr; /* Overall information about text widget. */ CONST TkTextIndex *srcPtr; /* Source index. */ int charCount; /* How many characters forward to move. * May be negative. */ @@ -1344,18 +1343,20 @@ TkTextIndexForwChars(srcPtr, charCount, dstPtr, type) { TkTextLine *linePtr; TkTextSegment *segPtr; + TkTextElideInfo *infoPtr = NULL; int byteOffset; char *start, *end, *p; Tcl_UniChar ch; int elide = 0; int checkElided = (type & COUNT_DISPLAY); - + if (charCount < 0) { - TkTextIndexBackChars(srcPtr, -charCount, dstPtr, type); + TkTextIndexBackChars(textPtr, srcPtr, -charCount, dstPtr, type); return; } if (checkElided) { - elide = ((type & COUNT_IS_ELIDED) ? 1 : 0); + infoPtr = (TkTextElideInfo*)ckalloc((unsigned)sizeof(TkTextElideInfo)); + elide = TkTextIsElided(textPtr, srcPtr, infoPtr); } *dstPtr = *srcPtr; @@ -1366,6 +1367,7 @@ TkTextIndexForwChars(srcPtr, charCount, dstPtr, type) */ segPtr = TkTextIndexToSeg(dstPtr, &byteOffset); + while (1) { /* * Go through each segment in line looking for specified character @@ -1381,14 +1383,27 @@ TkTextIndexForwChars(srcPtr, charCount, dstPtr, type) */ if (checkElided) { if ((segPtr->typePtr == &tkTextToggleOffType) - || (segPtr->typePtr == &tkTextToggleOnType)) { - if (segPtr->body.toggle.tagPtr->elideString != NULL) { + || (segPtr->typePtr == &tkTextToggleOnType)) { + TkTextTag *tagPtr = segPtr->body.toggle.tagPtr; + if (tagPtr->elideString != NULL + && (tagPtr->priority >= infoPtr->elidePriority)) { if (elide) { - elide = (segPtr->typePtr == &tkTextToggleOffType) - & !segPtr->body.toggle.tagPtr->elide; + elide = ((segPtr->typePtr == &tkTextToggleOffType) + & !tagPtr->elide); } else { - elide = (segPtr->typePtr == &tkTextToggleOnType) - & segPtr->body.toggle.tagPtr->elide; + elide = ((segPtr->typePtr == &tkTextToggleOnType) + & tagPtr->elide); + } + if (!elide && tagPtr->priority + == infoPtr->elidePriority) { + /* Find previous elide tag, if any */ + while (--infoPtr->elidePriority > 0) { + if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) { + break; + } + } + } else { + infoPtr->elidePriority = tagPtr->priority; } } } @@ -1401,7 +1416,7 @@ TkTextIndexForwChars(srcPtr, charCount, dstPtr, type) for (p = start; p < end; p += Tcl_UtfToUniChar(p, &ch)) { if (charCount == 0) { dstPtr->byteIndex += (p - start); - return; + goto forwardCharDone; } charCount--; } @@ -1409,7 +1424,7 @@ TkTextIndexForwChars(srcPtr, charCount, dstPtr, type) if (type & COUNT_INDICES) { if (charCount < segPtr->size - byteOffset) { dstPtr->byteIndex += charCount; - return; + goto forwardCharDone; } charCount -= segPtr->size - byteOffset; } @@ -1429,12 +1444,16 @@ TkTextIndexForwChars(srcPtr, charCount, dstPtr, type) linePtr = TkBTreeNextLine(dstPtr->linePtr); if (linePtr == NULL) { dstPtr->byteIndex -= sizeof(char); - return; + goto forwardCharDone; } dstPtr->linePtr = linePtr; dstPtr->byteIndex = 0; segPtr = dstPtr->linePtr->segPtr; } + forwardCharDone: + if (infoPtr != NULL) { + ckfree((char*) infoPtr); + } } /* @@ -1474,6 +1493,7 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type) { TkTextLine *linePtr1; TkTextSegment *segPtr, *seg2Ptr = NULL; + TkTextElideInfo *infoPtr = NULL; int byteOffset, maxBytes; int count = 0; int elide = 0; @@ -1490,7 +1510,8 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type) seg2Ptr = TkTextIndexToSeg(indexPtr2, &maxBytes); if (checkElided) { - elide = TkTextIsElided(textPtr, indexPtr1); + infoPtr = (TkTextElideInfo*)ckalloc((unsigned)sizeof(TkTextElideInfo)); + elide = TkTextIsElided(textPtr, indexPtr1, infoPtr); } while (1) { @@ -1509,13 +1530,26 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type) if (checkElided) { if ((segPtr->typePtr == &tkTextToggleOffType) || (segPtr->typePtr == &tkTextToggleOnType)) { - if (segPtr->body.toggle.tagPtr->elideString != NULL) { + TkTextTag *tagPtr = segPtr->body.toggle.tagPtr; + if (tagPtr->elideString != NULL + && (tagPtr->priority >= infoPtr->elidePriority)) { if (elide) { - elide = (segPtr->typePtr == &tkTextToggleOffType) - & !segPtr->body.toggle.tagPtr->elide; + elide = ((segPtr->typePtr == &tkTextToggleOffType) + & !tagPtr->elide); } else { - elide = (segPtr->typePtr == &tkTextToggleOnType) - & segPtr->body.toggle.tagPtr->elide; + elide = ((segPtr->typePtr == &tkTextToggleOnType) + & tagPtr->elide); + } + if (!elide && tagPtr->priority + == infoPtr->elidePriority) { + /* Find previous elide tag, if any */ + while (--infoPtr->elidePriority > 0) { + if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) { + break; + } + } + } else { + infoPtr->elidePriority = tagPtr->priority; } } } @@ -1676,7 +1710,8 @@ TkTextIndexBackBytes(srcPtr, byteCount, dstPtr) */ void -TkTextIndexBackChars(srcPtr, charCount, dstPtr, type) +TkTextIndexBackChars(textPtr, srcPtr, charCount, dstPtr, type) + CONST TkText *textPtr; /* Overall information about text widget. */ CONST TkTextIndex *srcPtr; /* Source index. */ int charCount; /* How many characters backward to move. * May be negative. */ @@ -1684,17 +1719,19 @@ TkTextIndexBackChars(srcPtr, charCount, dstPtr, type) TkTextCountType type; /* The type of item to count */ { TkTextSegment *segPtr, *oldPtr; + TkTextElideInfo *infoPtr = NULL; int lineIndex, segSize; CONST char *p, *start, *end; int elide = 0; int checkElided = (type & COUNT_DISPLAY); if (charCount < 0) { - TkTextIndexForwChars(srcPtr, -charCount, dstPtr, type); + TkTextIndexForwChars(textPtr, srcPtr, -charCount, dstPtr, type); return; } if (checkElided) { - elide = ((type & COUNT_IS_ELIDED) ? 1 : 0); + infoPtr = (TkTextElideInfo*)ckalloc((unsigned)sizeof(TkTextElideInfo)); + elide = TkTextIsElided(textPtr, srcPtr, infoPtr); } *dstPtr = *srcPtr; @@ -1723,13 +1760,26 @@ TkTextIndexBackChars(srcPtr, charCount, dstPtr, type) if (checkElided) { if ((segPtr->typePtr == &tkTextToggleOffType) || (segPtr->typePtr == &tkTextToggleOnType)) { - if (segPtr->body.toggle.tagPtr->elideString != NULL) { + TkTextTag *tagPtr = segPtr->body.toggle.tagPtr; + if (tagPtr->elideString != NULL + && (tagPtr->priority >= infoPtr->elidePriority)) { if (elide) { - elide = (segPtr->typePtr == &tkTextToggleOnType) - & !segPtr->body.toggle.tagPtr->elide; + elide = ((segPtr->typePtr == &tkTextToggleOnType) + & !tagPtr->elide); } else { - elide = (segPtr->typePtr == &tkTextToggleOffType) - & segPtr->body.toggle.tagPtr->elide; + elide = ((segPtr->typePtr == &tkTextToggleOffType) + & tagPtr->elide); + } + if (!elide && tagPtr->priority + == infoPtr->elidePriority) { + /* Find previous elide tag, if any */ + while (--infoPtr->elidePriority > 0) { + if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) { + break; + } + } + } else { + infoPtr->elidePriority = tagPtr->priority; } } } @@ -1742,7 +1792,7 @@ TkTextIndexBackChars(srcPtr, charCount, dstPtr, type) for (p = end; ; p = Tcl_UtfPrev(p, start)) { if (charCount == 0) { dstPtr->byteIndex -= (end - p); - return; + goto backwadCharDone; } if (p == start) { break; @@ -1753,7 +1803,7 @@ TkTextIndexBackChars(srcPtr, charCount, dstPtr, type) if (type & COUNT_INDICES) { if (charCount <= segSize) { dstPtr->byteIndex -= charCount; - return; + goto backwadCharDone; } charCount -= segSize; } @@ -1784,7 +1834,7 @@ TkTextIndexBackChars(srcPtr, charCount, dstPtr, type) } if (lineIndex == 0) { dstPtr->byteIndex = 0; - return; + goto backwadCharDone; } lineIndex--; dstPtr->linePtr = TkBTreeFindLine(dstPtr->tree, lineIndex); @@ -1801,6 +1851,10 @@ TkTextIndexBackChars(srcPtr, charCount, dstPtr, type) segPtr = oldPtr; segSize = segPtr->size; } + backwadCharDone: + if (infoPtr != NULL) { + ckfree((char*) infoPtr); + } } /* @@ -1908,8 +1962,8 @@ StartEnd(textPtr, string, indexPtr) */ if (modifier == TKINDEX_DISPLAY) { - TkTextIndexForwChars(indexPtr, 0, indexPtr, COUNT_DISPLAY_INDICES - | (COUNT_IS_ELIDED * TkTextIsElided(textPtr, indexPtr))); + TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr, + COUNT_DISPLAY_INDICES); } segPtr = TkTextIndexToSeg(indexPtr, &offset); while (1) { @@ -1928,10 +1982,11 @@ StartEnd(textPtr, string, indexPtr) } if (firstChar) { if (modifier == TKINDEX_DISPLAY) { - TkTextIndexForwChars(indexPtr, 1, indexPtr, COUNT_DISPLAY_INDICES - | (COUNT_IS_ELIDED * TkTextIsElided(textPtr, indexPtr))); + TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr, + COUNT_DISPLAY_INDICES); } else { - TkTextIndexForwChars(indexPtr, 1, indexPtr, COUNT_INDICES); + TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr, + COUNT_INDICES); } } } else if ((*string == 'w') && (strncmp(string, "wordstart", length) == 0) @@ -1939,8 +1994,8 @@ StartEnd(textPtr, string, indexPtr) int firstChar = 1; if (modifier == TKINDEX_DISPLAY) { - TkTextIndexForwChars(indexPtr, 0, indexPtr, COUNT_DISPLAY_INDICES - | (COUNT_IS_ELIDED * TkTextIsElided(textPtr, indexPtr))); + TkTextIndexForwChars(NULL, indexPtr, 0, indexPtr, + COUNT_DISPLAY_INDICES); } /* * Starting with the current character, look for one that's not @@ -1970,10 +2025,11 @@ StartEnd(textPtr, string, indexPtr) } if (!firstChar) { if (modifier == TKINDEX_DISPLAY) { - TkTextIndexForwChars(indexPtr, 1, indexPtr, COUNT_DISPLAY_INDICES - | (COUNT_IS_ELIDED * TkTextIsElided(textPtr, indexPtr))); + TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr, + COUNT_DISPLAY_INDICES); } else { - TkTextIndexForwChars(indexPtr, 1, indexPtr, COUNT_INDICES); + TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr, + COUNT_INDICES); } } } else { |