summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorvincentdarley <vincentdarley>2003-11-07 15:36:24 (GMT)
committervincentdarley <vincentdarley>2003-11-07 15:36:24 (GMT)
commitf4b5ed83cac2135eee47665181613178a33293ee (patch)
treea1d683e81cad5acc063a7a19da19b30cb5e568b6 /generic
parent2a739cee5e02ba828e59bcf8348ff158ef53db67 (diff)
downloadtk-f4b5ed83cac2135eee47665181613178a33293ee.zip
tk-f4b5ed83cac2135eee47665181613178a33293ee.tar.gz
tk-f4b5ed83cac2135eee47665181613178a33293ee.tar.bz2
better elide tag handling
Diffstat (limited to 'generic')
-rw-r--r--generic/tkText.c30
-rw-r--r--generic/tkText.h27
-rw-r--r--generic/tkTextBTree.c75
-rw-r--r--generic/tkTextDisp.c38
-rw-r--r--generic/tkTextImage.c4
-rw-r--r--generic/tkTextIndex.c164
-rw-r--r--generic/tkTextMark.c8
-rw-r--r--generic/tkTextTag.c4
-rw-r--r--generic/tkTextWind.c4
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;
}