summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorvincentdarley <vincentdarley>2003-11-08 17:22:45 (GMT)
committervincentdarley <vincentdarley>2003-11-08 17:22:45 (GMT)
commit2551f96c4652be256bc2480e4fcc05c7065f6665 (patch)
treed3be8a33f1d8bfc5c803dad0b85a7b30184743b9 /generic
parentf4b5ed83cac2135eee47665181613178a33293ee (diff)
downloadtk-2551f96c4652be256bc2480e4fcc05c7065f6665.zip
tk-2551f96c4652be256bc2480e4fcc05c7065f6665.tar.gz
tk-2551f96c4652be256bc2480e4fcc05c7065f6665.tar.bz2
elide tag handling, once more
Diffstat (limited to 'generic')
-rw-r--r--generic/tkText.h17
-rw-r--r--generic/tkTextBTree.c25
-rw-r--r--generic/tkTextDisp.c57
-rw-r--r--generic/tkTextIndex.c171
4 files changed, 190 insertions, 80 deletions
diff --git a/generic/tkText.h b/generic/tkText.h
index 89e4f7b..16e617a 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.18 2003/11/07 15:36:26 vincentdarley Exp $
+ * RCS: @(#) $Id: tkText.h,v 1.19 2003/11/08 17:22:46 vincentdarley Exp $
*/
#ifndef _TKTEXT
@@ -827,13 +827,16 @@ typedef int TkTextCountType;
#define LOTSA_TAGS 1000
typedef struct TkTextElideInfo {
- int numTags;
- int elide;
- int elidePriority;
- int deftagCnts[LOTSA_TAGS];
+ int numTags; /* Total tags in widget */
+ int elide; /* Is the state currently elided */
+ int elidePriority; /* Tag priority controlling elide state */
+ TkTextSegment *segPtr; /* Segment to look at next */
+ int deftagCnts[LOTSA_TAGS];
TkTextTag *deftagPtrs[LOTSA_TAGS];
- int *tagCnts;
- TkTextTag **tagPtrs;
+ int *tagCnts; /* 0 or 1 depending if the tag with
+ * that priority is on or off */
+ TkTextTag **tagPtrs; /* Only filled with a tagPtr if the
+ * corresponding tagCnt is 1 */
} TkTextElideInfo;
/*
diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c
index 7be9e7d..22d91c7 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.9 2003/11/07 15:36:26 vincentdarley Exp $
+ * RCS: @(#) $Id: tkTextBTree.c,v 1.10 2003/11/08 17:22:46 vincentdarley Exp $
*/
#include "tkInt.h"
@@ -2682,13 +2682,22 @@ TkBTreeGetTags(indexPtr, numTagsPtr)
* TkTextIsElided --
*
* Special case to just return information about elided attribute.
- * Specialized from TkBTreeGetTags(indexPtr, numTagsPtr)
- * and GetStyle(textPtr, indexPtr).
- * Just need to keep track of invisibility settings for each priority,
- * pick highest one active at end
+ * Specialized from TkBTreeGetTags(indexPtr, numTagsPtr) and
+ * GetStyle(textPtr, indexPtr). Just need to keep track of
+ * invisibility settings for each priority, pick highest one active
+ * at end.
+ *
+ * Note that this returns all elide information up to and including
+ * the given index (quite obviously). However, this does mean that
+ * indexPtr is a line-start and one then iterates from the beginning
+ * of that line forwards, one will actually revisit the segPtrs of
+ * size zero (for tag toggling, for example) which have already been
+ * seen here.
*
* Results:
* Returns whether this text should be elided or not.
+ *
+ * Optionally returns more detailed information in elideInfo.
*
* Side effects:
* None.
@@ -2754,6 +2763,11 @@ TkTextIsElided(textPtr, indexPtr, elideInfo)
}
}
}
+ /*
+ * Store the first segPtr we haven't examined completely
+ * so that our caller knows where to start.
+ */
+ infoPtr->segPtr = segPtr;
/*
* Record toggles for tags in lines that are predecessors of
@@ -2817,6 +2831,7 @@ TkTextIsElided(textPtr, indexPtr, elideInfo)
}
#endif
infoPtr->elide = infoPtr->tagPtrs[i]->elide;
+ /* Note: i == infoPtr->tagPtrs[i]->priority */
infoPtr->elidePriority = i;
break;
}
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index 324b3ab..85a160d 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.24 2003/11/07 15:36:26 vincentdarley Exp $
+ * RCS: @(#) $Id: tkTextDisp.c,v 1.25 2003/11/08 17:22:46 vincentdarley Exp $
*/
#include "tkPort.h"
@@ -957,9 +957,7 @@ LayoutDLine(textPtr, indexPtr)
elide = TkTextIsElided(textPtr, indexPtr, &info);
if (elide && indexPtr->byteIndex==0) {
maxBytes = 0;
- for (segPtr = indexPtr->linePtr->segPtr;
- segPtr != NULL;
- segPtr = segPtr->nextPtr) {
+ for (segPtr = info.segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) {
if (segPtr->size > 0) {
if (elide == 0) {
/*
@@ -977,19 +975,45 @@ LayoutDLine(textPtr, indexPtr)
} else if ((segPtr->typePtr == &tkTextToggleOffType)
|| (segPtr->typePtr == &tkTextToggleOnType)) {
TkTextTag *tagPtr = segPtr->body.toggle.tagPtr;
- 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;
+ /*
+ * The elide state only changes if this tag is
+ * either the current highest priority tag
+ * (and is therefore being toggled off), or it's
+ * a new tag with higher priority.
+ */
+ if (tagPtr->elideString != NULL) {
+ info.tagCnts[tagPtr->priority]++;
+ if (info.tagCnts[tagPtr->priority] & 1) {
+ info.tagPtrs[tagPtr->priority] = tagPtr;
+ }
+ if (tagPtr->priority >= info.elidePriority) {
+ if (segPtr->typePtr == &tkTextToggleOffType) {
+ /*
+ * If it is being toggled off, and it has
+ * an elide string, it must actually be the
+ * current highest priority tag, so this
+ * check is redundant:
+ */
+ if (tagPtr->priority != info.elidePriority) {
+ panic("Bad tag priority being toggled off");
+ }
+
+ /*
+ * Find previous elide tag, if any (if not
+ * then elide will be zero, of course).
+ */
+ elide = 0;
+ while (--info.elidePriority > 0) {
+ if (info.tagCnts[info.elidePriority] & 1) {
+ elide = info.tagPtrs[info.elidePriority]
+ ->elide;
+ break;
+ }
}
+ } else {
+ elide = tagPtr->elide;
+ info.elidePriority = tagPtr->priority;
}
- } else {
- info.elidePriority = tagPtr->priority;
}
}
}
@@ -5223,7 +5247,8 @@ GetXView(interp, textPtr, report)
dInfoPtr->xScrollLast = last;
if (textPtr->xScrollCmd != NULL) {
listObj = Tcl_NewStringObj(textPtr->xScrollCmd, -1);
- code = Tcl_ListObjAppendElement(interp, listObj, Tcl_NewDoubleObj(first));
+ code = Tcl_ListObjAppendElement(interp, listObj,
+ Tcl_NewDoubleObj(first));
if (code == TCL_OK) {
Tcl_ListObjAppendElement(interp, listObj, Tcl_NewDoubleObj(last));
code = Tcl_EvalObjEx(interp, listObj,
diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c
index 123fb01..c5ef481 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.10 2003/11/07 15:36:26 vincentdarley Exp $
+ * RCS: @(#) $Id: tkTextIndex.c,v 1.11 2003/11/08 17:22:46 vincentdarley Exp $
*/
#include "default.h"
@@ -1385,25 +1385,46 @@ TkTextIndexForwChars(textPtr, srcPtr, charCount, dstPtr, type)
if ((segPtr->typePtr == &tkTextToggleOffType)
|| (segPtr->typePtr == &tkTextToggleOnType)) {
TkTextTag *tagPtr = segPtr->body.toggle.tagPtr;
- if (tagPtr->elideString != NULL
- && (tagPtr->priority >= infoPtr->elidePriority)) {
- if (elide) {
- elide = ((segPtr->typePtr == &tkTextToggleOffType)
- & !tagPtr->elide);
- } else {
- elide = ((segPtr->typePtr == &tkTextToggleOnType)
- & tagPtr->elide);
+ /*
+ * The elide state only changes if this tag is
+ * either the current highest priority tag
+ * (and is therefore being toggled off), or it's
+ * a new tag with higher priority.
+ */
+ if (tagPtr->elideString != NULL) {
+ infoPtr->tagCnts[tagPtr->priority]++;
+ if (infoPtr->tagCnts[tagPtr->priority] & 1) {
+ infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
}
- if (!elide && tagPtr->priority
- == infoPtr->elidePriority) {
- /* Find previous elide tag, if any */
- while (--infoPtr->elidePriority > 0) {
- if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) {
- break;
+ if (tagPtr->priority >= infoPtr->elidePriority) {
+ if (segPtr->typePtr == &tkTextToggleOffType) {
+ /*
+ * If it is being toggled off, and it has
+ * an elide string, it must actually be the
+ * current highest priority tag, so this
+ * check is redundant:
+ */
+ if (tagPtr->priority != infoPtr->elidePriority) {
+ panic("Bad tag priority being toggled off");
+ }
+
+ /*
+ * Find previous elide tag, if any (if not
+ * then elide will be zero, of course).
+ */
+ elide = 0;
+ while (--infoPtr->elidePriority > 0) {
+ if (infoPtr->tagCnts[infoPtr->elidePriority]
+ & 1) {
+ elide = infoPtr->tagPtrs
+ [infoPtr->elidePriority]->elide;
+ break;
+ }
}
+ } else {
+ elide = tagPtr->elide;
+ infoPtr->elidePriority = tagPtr->priority;
}
- } else {
- infoPtr->elidePriority = tagPtr->priority;
}
}
}
@@ -1529,33 +1550,54 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type)
*/
if (checkElided) {
if ((segPtr->typePtr == &tkTextToggleOffType)
- || (segPtr->typePtr == &tkTextToggleOnType)) {
+ || (segPtr->typePtr == &tkTextToggleOnType)) {
TkTextTag *tagPtr = segPtr->body.toggle.tagPtr;
- if (tagPtr->elideString != NULL
- && (tagPtr->priority >= infoPtr->elidePriority)) {
- if (elide) {
- elide = ((segPtr->typePtr == &tkTextToggleOffType)
- & !tagPtr->elide);
- } else {
- elide = ((segPtr->typePtr == &tkTextToggleOnType)
- & tagPtr->elide);
+ /*
+ * The elide state only changes if this tag is
+ * either the current highest priority tag
+ * (and is therefore being toggled off), or it's
+ * a new tag with higher priority.
+ */
+ if (tagPtr->elideString != NULL) {
+ infoPtr->tagCnts[tagPtr->priority]++;
+ if (infoPtr->tagCnts[tagPtr->priority] & 1) {
+ infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
}
- if (!elide && tagPtr->priority
- == infoPtr->elidePriority) {
- /* Find previous elide tag, if any */
- while (--infoPtr->elidePriority > 0) {
- if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) {
- break;
+ if (tagPtr->priority >= infoPtr->elidePriority) {
+ if (segPtr->typePtr == &tkTextToggleOffType) {
+ /*
+ * If it is being toggled off, and it has
+ * an elide string, it must actually be the
+ * current highest priority tag, so this
+ * check is redundant:
+ */
+ if (tagPtr->priority != infoPtr->elidePriority) {
+ panic("Bad tag priority being toggled off");
+ }
+
+ /*
+ * Find previous elide tag, if any (if not
+ * then elide will be zero, of course).
+ */
+ elide = 0;
+ while (--infoPtr->elidePriority > 0) {
+ if (infoPtr->tagCnts[infoPtr->elidePriority]
+ & 1) {
+ elide = infoPtr->tagPtrs
+ [infoPtr->elidePriority]->elide;
+ break;
+ }
}
+ } else {
+ elide = tagPtr->elide;
+ infoPtr->elidePriority = tagPtr->priority;
}
- } else {
- infoPtr->elidePriority = tagPtr->priority;
}
}
}
if (elide) {
if (segPtr == seg2Ptr) {
- return count;
+ goto countDone;
}
byteOffset = 0;
continue;
@@ -1601,7 +1643,7 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type)
}
}
if (segPtr == seg2Ptr) {
- return count;
+ goto countDone;
}
byteOffset = 0;
}
@@ -1618,6 +1660,11 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type)
}
segPtr = linePtr1->segPtr;
}
+ countDone:
+ if (infoPtr != NULL) {
+ ckfree((char*) infoPtr);
+ }
+ return count;
}
/*
@@ -1761,25 +1808,45 @@ TkTextIndexBackChars(textPtr, srcPtr, charCount, dstPtr, type)
if ((segPtr->typePtr == &tkTextToggleOffType)
|| (segPtr->typePtr == &tkTextToggleOnType)) {
TkTextTag *tagPtr = segPtr->body.toggle.tagPtr;
- if (tagPtr->elideString != NULL
- && (tagPtr->priority >= infoPtr->elidePriority)) {
- if (elide) {
- elide = ((segPtr->typePtr == &tkTextToggleOnType)
- & !tagPtr->elide);
- } else {
- elide = ((segPtr->typePtr == &tkTextToggleOffType)
- & tagPtr->elide);
+ /*
+ * The elide state only changes if this tag is
+ * either the current highest priority tag
+ * (and is therefore being toggled off), or it's
+ * a new tag with higher priority.
+ */
+ if (tagPtr->elideString != NULL) {
+ infoPtr->tagCnts[tagPtr->priority]++;
+ if (infoPtr->tagCnts[tagPtr->priority] & 1) {
+ infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
}
- if (!elide && tagPtr->priority
- == infoPtr->elidePriority) {
- /* Find previous elide tag, if any */
- while (--infoPtr->elidePriority > 0) {
- if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) {
- break;
+ if (tagPtr->priority >= infoPtr->elidePriority) {
+ if (segPtr->typePtr == &tkTextToggleOnType) {
+ /*
+ * If it is being toggled on, and it has
+ * an elide string, it must actually be the
+ * current highest priority tag, so this
+ * check is redundant:
+ */
+ if (tagPtr->priority != infoPtr->elidePriority) {
+ panic("Bad tag priority being toggled on");
}
+
+ /*
+ * Find previous elide tag, if any (if not
+ * then elide will be zero, of course).
+ */
+ elide = 0;
+ while (--infoPtr->elidePriority > 0) {
+ if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) {
+ elide = infoPtr->tagPtrs
+ [infoPtr->elidePriority]->elide;
+ break;
+ }
+ }
+ } else {
+ elide = tagPtr->elide;
+ infoPtr->elidePriority = tagPtr->priority;
}
- } else {
- infoPtr->elidePriority = tagPtr->priority;
}
}
}