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 | |
parent | 2a739cee5e02ba828e59bcf8348ff158ef53db67 (diff) | |
download | tk-f4b5ed83cac2135eee47665181613178a33293ee.zip tk-f4b5ed83cac2135eee47665181613178a33293ee.tar.gz tk-f4b5ed83cac2135eee47665181613178a33293ee.tar.bz2 |
better elide tag handling
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkText.c | 30 | ||||
-rw-r--r-- | generic/tkText.h | 27 | ||||
-rw-r--r-- | generic/tkTextBTree.c | 75 | ||||
-rw-r--r-- | generic/tkTextDisp.c | 38 | ||||
-rw-r--r-- | generic/tkTextImage.c | 4 | ||||
-rw-r--r-- | generic/tkTextIndex.c | 164 | ||||
-rw-r--r-- | generic/tkTextMark.c | 8 | ||||
-rw-r--r-- | generic/tkTextTag.c | 4 | ||||
-rw-r--r-- | generic/tkTextWind.c | 4 |
9 files changed, 225 insertions, 129 deletions
diff --git a/generic/tkText.c b/generic/tkText.c index b0b6a21..5b9c515 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -14,7 +14,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkText.c,v 1.39 2003/10/31 09:02:08 vincentdarley Exp $ + * RCS: @(#) $Id: tkText.c,v 1.40 2003/11/07 15:36:26 vincentdarley Exp $ */ #include "default.h" @@ -922,7 +922,7 @@ TextWidgetObjCmd(clientData, interp, objc, objv) */ if (objc & 1) { indices[i] = indices[i-1]; - TkTextIndexForwChars(&indices[i], 1, &indices[i], + TkTextIndexForwChars(NULL, &indices[i], 1, &indices[i], COUNT_INDICES); objc++; } @@ -1075,7 +1075,7 @@ TextWidgetObjCmd(clientData, interp, objc, objv) goto done; } if (i+1 == objc) { - TkTextIndexForwChars(index1Ptr, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL, index1Ptr, 1, &index2, COUNT_INDICES); index2Ptr = &index2; } else { index2Ptr = TkTextGetIndexFromObj(interp, textPtr, @@ -1247,7 +1247,7 @@ TextWidgetObjCmd(clientData, interp, objc, objv) * Move the insertion position to the correct * place */ - TkTextIndexForwChars(indexFromPtr, deleteInsertOffset, + TkTextIndexForwChars(NULL, indexFromPtr, deleteInsertOffset, &index, COUNT_INDICES); TkBTreeUnlinkSegment(textPtr->tree, textPtr->insertMarkPtr, @@ -1833,7 +1833,7 @@ TextEventProc(clientData, eventPtr) TkTextRedrawTag(textPtr, NULL, NULL, textPtr->selTagPtr, 1); #endif TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index); - TkTextIndexForwChars(&index, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES); /* * While we wish to redisplay, no heights have changed, so * no need to call TkTextInvalidateLineMetrics @@ -2186,7 +2186,7 @@ DeleteChars(textPtr, indexPtr1, indexPtr2, noViewUpdate) index2 = *indexPtr2; } else { index2 = index1; - TkTextIndexForwChars(&index2, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL, &index2, 1, &index2, COUNT_INDICES); } /* @@ -2217,10 +2217,10 @@ DeleteChars(textPtr, indexPtr1, indexPtr2, noViewUpdate) TkTextIndex oldIndex2; oldIndex2 = index2; - TkTextIndexBackChars(&oldIndex2, 1, &index2, COUNT_INDICES); + TkTextIndexBackChars(NULL, &oldIndex2, 1, &index2, COUNT_INDICES); line2--; if ((index1.byteIndex == 0) && (line1 != 0)) { - TkTextIndexBackChars(&index1, 1, &index1, COUNT_INDICES); + TkTextIndexBackChars(NULL, &index1, 1, &index1, COUNT_INDICES); line1--; } arrayPtr = TkBTreeGetTags(&index2, &arraySize); @@ -2479,7 +2479,7 @@ TextFetchSelection(clientData, offset, buffer, maxBytes) } } if ((segPtr->typePtr == &tkTextCharType) - && !TkTextIsElided(textPtr, &textPtr->selIndex)) { + && !TkTextIsElided(textPtr, &textPtr->selIndex, NULL)) { memcpy((VOID *) buffer, (VOID *) (segPtr->body.chars + offsetInSeg), (size_t) chunkSize); buffer += chunkSize; @@ -3000,7 +3000,7 @@ TextSearchIndexInLine(searchSpecPtr, linePtr, byteIndex) curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) { if ((segPtr->typePtr == &tkTextCharType) && (searchSpecPtr->searchElide || - !TkTextIsElided(textPtr, &curIndex))) { + !TkTextIsElided(textPtr, &curIndex, NULL))) { if (leftToScan < segPtr->size) { if (searchSpecPtr->exact) { index += leftToScan; @@ -3068,7 +3068,7 @@ TextSearchAddNextLine(lineNum, searchSpecPtr, theLine, lenPtr) curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) { if ((segPtr->typePtr != &tkTextCharType) || (!searchSpecPtr->searchElide - && TkTextIsElided(textPtr, &curIndex))) { + && TkTextIsElided(textPtr, &curIndex, NULL))) { continue; } Tcl_AppendToObj(theLine, segPtr->body.chars, segPtr->size); @@ -3191,7 +3191,7 @@ TextSearchFoundMatch(lineNum, searchSpecPtr, clientData, theLine, if (segPtr->typePtr != &tkTextCharType) { matchOffset += segPtr->size; } else if (!searchSpecPtr->searchElide - && TkTextIsElided(textPtr, &curIndex)) { + && TkTextIsElided(textPtr, &curIndex, NULL)) { if (searchSpecPtr->exact) { matchOffset += segPtr->size; } else { @@ -3243,7 +3243,7 @@ TextSearchFoundMatch(lineNum, searchSpecPtr, clientData, theLine, numChars += segPtr->size; continue; } else if (!searchSpecPtr->searchElide - && TkTextIsElided(textPtr, &curIndex)) { + && TkTextIsElided(textPtr, &curIndex, NULL)) { numChars += Tcl_NumUtfChars(segPtr->body.chars, -1); continue; } @@ -3483,7 +3483,7 @@ TextDumpCmd(textPtr, interp, objc, objv) arg++; atEnd = 0; if (objc == arg) { - TkTextIndexForwChars(&index1, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL,&index1, 1, &index2, COUNT_INDICES); } else { int length; char *str; @@ -3956,7 +3956,7 @@ TextGetText(textPtr, indexPtr1,indexPtr2, visibleOnly) } } if (segPtr->typePtr == &tkTextCharType) { - if (!visibleOnly || !TkTextIsElided(textPtr, &tmpIndex)) { + if (!visibleOnly || !TkTextIsElided(textPtr, &tmpIndex, NULL)) { Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset, last - offset); } diff --git a/generic/tkText.h b/generic/tkText.h index f59f003..89e4f7b 100644 --- a/generic/tkText.h +++ b/generic/tkText.h @@ -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: tkText.h,v 1.17 2003/10/31 09:02:09 vincentdarley Exp $ + * RCS: @(#) $Id: tkText.h,v 1.18 2003/11/07 15:36:26 vincentdarley Exp $ */ #ifndef _TKTEXT @@ -814,11 +814,29 @@ typedef int TkTextCountType; #define COUNT_CHARS 0 #define COUNT_INDICES 1 #define COUNT_DISPLAY 2 -#define COUNT_IS_ELIDED 4 #define COUNT_DISPLAY_CHARS (COUNT_CHARS | COUNT_DISPLAY) #define COUNT_DISPLAY_INDICES (COUNT_INDICES | COUNT_DISPLAY) /* + * The following structure is used to keep track of elided text + * taking account of different tag priorities, it is need for + * quick calculations of whether a single index is elided, and + * to start at a given index and maintain a correct elide state + * as we move or count forwards or backwards. + */ + +#define LOTSA_TAGS 1000 +typedef struct TkTextElideInfo { + int numTags; + int elide; + int elidePriority; + int deftagCnts[LOTSA_TAGS]; + TkTextTag *deftagPtrs[LOTSA_TAGS]; + int *tagCnts; + TkTextTag **tagPtrs; +} TkTextElideInfo; + +/* * The constant below is used to specify a line when what is really * wanted is the entire text. For now, just use a very big number. */ @@ -951,6 +969,7 @@ EXTERN void TkTextIndexBackBytes _ANSI_ARGS_(( CONST TkTextIndex *srcPtr, int count, TkTextIndex *dstPtr)); EXTERN void TkTextIndexBackChars _ANSI_ARGS_(( + CONST TkText *textPtr, CONST TkTextIndex *srcPtr, int count, TkTextIndex *dstPtr, TkTextCountType type)); EXTERN int TkTextIndexCmp _ANSI_ARGS_(( @@ -964,6 +983,7 @@ EXTERN int TkTextIndexForwBytes _ANSI_ARGS_(( CONST TkTextIndex *srcPtr, int count, TkTextIndex *dstPtr)); EXTERN void TkTextIndexForwChars _ANSI_ARGS_(( + CONST TkText *textPtr, CONST TkTextIndex *srcPtr, int count, TkTextIndex *dstPtr, TkTextCountType type)); EXTERN void TkTextIndexOfX _ANSI_ARGS_((TkText *textPtr, @@ -984,7 +1004,8 @@ EXTERN TkTextIndex * TkTextMakeCharIndex _ANSI_ARGS_((TkTextBTree tree, EXTERN int TkTextMeasureDown _ANSI_ARGS_((TkText *textPtr, TkTextIndex *srcPtr, int distance)); EXTERN int TkTextIsElided _ANSI_ARGS_((CONST TkText *textPtr, - CONST TkTextIndex *indexPtr)); + CONST TkTextIndex *indexPtr, + TkTextElideInfo *infoPtr)); EXTERN TkTextIndex * TkTextMakeByteIndex _ANSI_ARGS_((TkTextBTree tree, int lineIndex, int byteIndex, TkTextIndex *indexPtr)); diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c index 63d10c0..7be9e7d 100644 --- a/generic/tkTextBTree.c +++ b/generic/tkTextBTree.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextBTree.c,v 1.8 2003/10/31 09:02:10 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextBTree.c,v 1.9 2003/11/07 15:36:26 vincentdarley Exp $ */ #include "tkInt.h" @@ -2036,7 +2036,7 @@ TkBTreeStartSearchBack(index1Ptr, index2Ptr, tagPtr, searchPtr) searchPtr->curIndex = index0; index1Ptr = &index0; } else { - TkTextIndexBackChars(index1Ptr, 1, &searchPtr->curIndex, + TkTextIndexBackChars(NULL,index1Ptr, 1, &searchPtr->curIndex, COUNT_INDICES); } searchPtr->segPtr = NULL; @@ -2053,7 +2053,7 @@ TkBTreeStartSearchBack(index1Ptr, index2Ptr, tagPtr, searchPtr) backOne = *index2Ptr; searchPtr->lastPtr = NULL; /* Signals special case for 1.0 */ } else { - TkTextIndexBackChars(index2Ptr, 1, &backOne, COUNT_INDICES); + TkTextIndexBackChars(NULL, index2Ptr, 1, &backOne, COUNT_INDICES); searchPtr->lastPtr = TkTextIndexToSeg(&backOne, (int *) NULL); } searchPtr->tagPtr = tagPtr; @@ -2698,33 +2698,43 @@ TkBTreeGetTags(indexPtr, numTagsPtr) /* ARGSUSED */ int -TkTextIsElided(textPtr, indexPtr) +TkTextIsElided(textPtr, indexPtr, elideInfo) CONST TkText *textPtr; /* Overall information about text widget. */ CONST TkTextIndex *indexPtr;/* The character in the text for which * display information is wanted. */ + TkTextElideInfo *elideInfo; /* NULL or a pointer to a structure in + * which indexPtr's elide state will + * be stored and returned. */ { -#define LOTSA_TAGS 1000 - int elide = 0; /* if nobody says otherwise, it's visible */ - - int deftagCnts[LOTSA_TAGS]; - int *tagCnts = deftagCnts; - TkTextTag *deftagPtrs[LOTSA_TAGS]; - TkTextTag **tagPtrs = deftagPtrs; - int numTags = textPtr->numTags; register Node *nodePtr; register TkTextLine *siblingLinePtr; register TkTextSegment *segPtr; register TkTextTag *tagPtr = NULL; register int i, index; + register TkTextElideInfo *infoPtr; + int elide; + + if (elideInfo == NULL) { + infoPtr = (TkTextElideInfo*)ckalloc((unsigned)sizeof(TkTextElideInfo)); + } else { + infoPtr = elideInfo; + } + + infoPtr->elide = 0; /* if nobody says otherwise, it's visible */ + infoPtr->tagCnts = infoPtr->deftagCnts; + infoPtr->tagPtrs = infoPtr->deftagPtrs; + infoPtr->numTags = textPtr->numTags; /* Almost always avoid malloc, so stay out of system calls */ - if (LOTSA_TAGS < numTags) { - tagCnts = (int *)ckalloc((unsigned)sizeof(int) * numTags); - tagPtrs = (TkTextTag **)ckalloc((unsigned)sizeof(TkTextTag *) * numTags); + if (LOTSA_TAGS < infoPtr->numTags) { + infoPtr->tagCnts = (int *)ckalloc((unsigned)sizeof(int) + * infoPtr->numTags); + infoPtr->tagPtrs = (TkTextTag **)ckalloc((unsigned)sizeof(TkTextTag*) + * infoPtr->numTags); } - for (i=0; i<numTags; i++) { - tagCnts[i] = 0; + for (i=0; i<infoPtr->numTags; i++) { + infoPtr->tagCnts[i] = 0; } /* @@ -2739,8 +2749,8 @@ TkTextIsElided(textPtr, indexPtr) || (segPtr->typePtr == &tkTextToggleOffType)) { tagPtr = segPtr->body.toggle.tagPtr; if (tagPtr->elideString != NULL) { - tagPtrs[tagPtr->priority] = tagPtr; - tagCnts[tagPtr->priority]++; + infoPtr->tagPtrs[tagPtr->priority] = tagPtr; + infoPtr->tagCnts[tagPtr->priority]++; } } } @@ -2759,8 +2769,8 @@ TkTextIsElided(textPtr, indexPtr) || (segPtr->typePtr == &tkTextToggleOffType)) { tagPtr = segPtr->body.toggle.tagPtr; if (tagPtr->elideString != NULL) { - tagPtrs[tagPtr->priority] = tagPtr; - tagCnts[tagPtr->priority]++; + infoPtr->tagPtrs[tagPtr->priority] = tagPtr; + infoPtr->tagCnts[tagPtr->priority]++; } } } @@ -2783,8 +2793,8 @@ TkTextIsElided(textPtr, indexPtr) if (summaryPtr->toggleCount & 1) { tagPtr = summaryPtr->tagPtr; if (tagPtr->elideString != NULL) { - tagPtrs[tagPtr->priority] = tagPtr; - tagCnts[tagPtr->priority] += summaryPtr->toggleCount; + infoPtr->tagPtrs[tagPtr->priority] = tagPtr; + infoPtr->tagCnts[tagPtr->priority] += summaryPtr->toggleCount; } } } @@ -2796,8 +2806,9 @@ TkTextIsElided(textPtr, indexPtr) * take elided value from first odd count (= on) */ - for (i = numTags-1; i >=0; i--) { - if (tagCnts[i] & 1) { + infoPtr->elidePriority = -1; + for (i = infoPtr->numTags-1; i >=0; i--) { + if (infoPtr->tagCnts[i] & 1) { #ifndef ALWAYS_SHOW_SELECTION /* who would make the selection elided? */ if ((tagPtr == textPtr->selTagPtr) @@ -2805,14 +2816,20 @@ TkTextIsElided(textPtr, indexPtr) continue; } #endif - elide = tagPtrs[i]->elide; + infoPtr->elide = infoPtr->tagPtrs[i]->elide; + infoPtr->elidePriority = i; break; } } - if (LOTSA_TAGS < numTags) { - ckfree((char *) tagCnts); - ckfree((char *) tagPtrs); + if (LOTSA_TAGS < infoPtr->numTags) { + ckfree((char *) infoPtr->tagCnts); + ckfree((char *) infoPtr->tagPtrs); + } + elide = infoPtr->elide; + + if (elideInfo == NULL) { + ckfree((char*) infoPtr); } return elide; diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index ebe9b4c..324b3ab 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextDisp.c,v 1.23 2003/11/07 12:06:47 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextDisp.c,v 1.24 2003/11/07 15:36:26 vincentdarley Exp $ */ #include "tkPort.h" @@ -934,7 +934,8 @@ LayoutDLine(textPtr, indexPtr) * of the line. */ int byteOffset, ascent, descent, code, elide, elidesize; StyleValues *sValuePtr; - + TkTextElideInfo info; /* Keep track of elide state */ + /* * Create and initialize a new DLine structure. */ @@ -953,9 +954,8 @@ LayoutDLine(textPtr, indexPtr) /* * Special case entirely elide line as there may be 1000s or more */ - elide = TkTextIsElided(textPtr, indexPtr); /* save a malloc */ + elide = TkTextIsElided(textPtr, indexPtr, &info); if (elide && indexPtr->byteIndex==0) { - int tagElidePriority = -1; maxBytes = 0; for (segPtr = indexPtr->linePtr->segPtr; segPtr != NULL; @@ -974,20 +974,22 @@ LayoutDLine(textPtr, indexPtr) * Reset tag elide priority, since we're on a new * character. */ - tagElidePriority = -1; } else if ((segPtr->typePtr == &tkTextToggleOffType) || (segPtr->typePtr == &tkTextToggleOnType)) { TkTextTag *tagPtr = segPtr->body.toggle.tagPtr; - if (tagPtr->elideString != NULL) { - /* - * Only update the elide status if this tag has - * higher priority than any other we've so far - * seen at this index. - */ - if (tagPtr->priority > tagElidePriority) { - elide = ((segPtr->typePtr == &tkTextToggleOffType) - ^ tagPtr->elide); - tagElidePriority = tagPtr->priority; + if (tagPtr->elideString != NULL + && (tagPtr->priority >= info.elidePriority)) { + elide = ((segPtr->typePtr == &tkTextToggleOffType) + ^ tagPtr->elide); + if (!elide && tagPtr->priority == info.elidePriority) { + /* Find previous elide tag, if any */ + while (--info.elidePriority > 0) { + if (info.tagCnts[info.elidePriority] & 1) { + break; + } + } + } else { + info.elidePriority = tagPtr->priority; } } } @@ -4188,7 +4190,7 @@ TkTextSetYView(textPtr, indexPtr, pickPlace) lineIndex = TkBTreeLineIndex(indexPtr->linePtr); if (lineIndex == TkBTreeNumLines(indexPtr->tree)) { - TkTextIndexBackChars(indexPtr, 1, &rounded, COUNT_INDICES); + TkTextIndexBackChars(NULL,indexPtr, 1, &rounded, COUNT_INDICES); indexPtr = &rounded; } @@ -4541,7 +4543,7 @@ TkTextSeeCmd(textPtr, interp, objc, objv) */ if (TkBTreeLineIndex(index.linePtr) == TkBTreeNumLines(index.tree)) { - TkTextIndexBackChars(&index, 1, &index, COUNT_INDICES); + TkTextIndexBackChars(NULL,&index, 1, &index, COUNT_INDICES); } /* @@ -5669,7 +5671,7 @@ DlineIndexOfX(textPtr, dlPtr, x, indexPtr) chunkPtr = chunkPtr->nextPtr) { if (chunkPtr->nextPtr == NULL) { indexPtr->byteIndex += chunkPtr->numBytes; - TkTextIndexBackChars(indexPtr, 1, indexPtr, COUNT_INDICES); + TkTextIndexBackChars(NULL, indexPtr, 1, indexPtr, COUNT_INDICES); return; } } diff --git a/generic/tkTextImage.c b/generic/tkTextImage.c index 35e4138..f086fbd 100644 --- a/generic/tkTextImage.c +++ b/generic/tkTextImage.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: tkTextImage.c,v 1.9 2003/10/31 09:02:11 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextImage.c,v 1.10 2003/11/07 15:36:26 vincentdarley Exp $ */ #include "tk.h" @@ -265,7 +265,7 @@ TkTextImageCmd(textPtr, interp, objc, objv) if (EmbImageConfigure(textPtr, eiPtr, objc-4, objv+4) != TCL_OK) { TkTextIndex index2; - TkTextIndexForwChars(&index, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES); TkBTreeDeleteChars(&index, &index2); return TCL_ERROR; } 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 { diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c index 7fcb275..3ee1738 100644 --- a/generic/tkTextMark.c +++ b/generic/tkTextMark.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: tkTextMark.c,v 1.9 2003/10/31 09:02:11 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextMark.c,v 1.10 2003/11/07 15:36:26 vincentdarley Exp $ */ #include "tkInt.h" @@ -274,7 +274,7 @@ TkTextSetMark(textPtr, name, indexPtr) if (markPtr == textPtr->insertMarkPtr) { TkTextIndex index, index2; TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index); - TkTextIndexForwChars(&index, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL,&index, 1, &index2, COUNT_INDICES); /* * While we wish to redisplay, no heights have changed, so * no need to call TkTextInvalidateLineMetrics. @@ -282,7 +282,7 @@ TkTextSetMark(textPtr, name, indexPtr) TkTextChanged(textPtr, &index, &index2); if (TkBTreeLineIndex(indexPtr->linePtr) == TkBTreeNumLines(textPtr->tree)) { - TkTextIndexBackChars(indexPtr, 1, &insertIndex, COUNT_INDICES); + TkTextIndexBackChars(NULL,indexPtr, 1, &insertIndex, COUNT_INDICES); indexPtr = &insertIndex; } } @@ -307,7 +307,7 @@ TkTextSetMark(textPtr, name, indexPtr) if (markPtr == textPtr->insertMarkPtr) { TkTextIndex index2; - TkTextIndexForwChars(indexPtr, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL,indexPtr, 1, &index2, COUNT_INDICES); /* * While we wish to redisplay, no heights have changed, so * no need to call TkTextInvalidateLineMetrics diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index 00a9193..aae070a 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextTag.c,v 1.11 2003/10/31 09:02:12 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextTag.c,v 1.12 2003/11/07 15:36:26 vincentdarley Exp $ */ #include "default.h" @@ -176,7 +176,7 @@ TkTextTagCmd(textPtr, interp, objc, objv) } } else { index2 = index1; - TkTextIndexForwChars(&index2, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL,&index2, 1, &index2, COUNT_INDICES); } if (tagPtr->affectsDisplay) { diff --git a/generic/tkTextWind.c b/generic/tkTextWind.c index 25991ac..dd829a8 100644 --- a/generic/tkTextWind.c +++ b/generic/tkTextWind.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextWind.c,v 1.8 2003/10/31 09:02:12 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextWind.c,v 1.9 2003/11/07 15:36:27 vincentdarley Exp $ */ #include "tk.h" @@ -292,7 +292,7 @@ TkTextWindowCmd(textPtr, interp, objc, objv) if (EmbWinConfigure(textPtr, ewPtr, objc-4, objv+4) != TCL_OK) { TkTextIndex index2; - TkTextIndexForwChars(&index, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL,&index, 1, &index2, COUNT_INDICES); TkBTreeDeleteChars(&index, &index2); return TCL_ERROR; } |