Tk Source Code

Check-in [b4542df5]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:(1) TkBTreeGetSegmentTags() now is sorting tags according to given sort method. This is simplifying function MakeStyle() significantly, and the tags in output of commands "dump" and "inspect" will also be sorted. (2) DEF_TEXT_INACTIVE_SELECT_FG_COLOR has been set to NULL for Windows.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | revised_text | tip-466
Files: files | file ages | folders
SHA1: b4542df53cfa2ca396034ce697d607a555bfc6d4
User & Date: gcramer 2017-05-24 12:16:45
Context
2017-05-24
16:24
Correction of typo in comment. check-in: b61d5510 user: gcramer tags: revised_text, tip-466
12:16
(1) TkBTreeGetSegmentTags() now is sorting tags according to given sort method. This is simplifying function MakeStyle() significantly, and the tags in output of commands "dump" and "inspect" will also be sorted. (2) DEF_TEXT_INACTIVE_SELECT_FG_COLOR has been set to NULL for Windows. check-in: b4542df5 user: gcramer tags: revised_text, tip-466
2017-05-21
10:31
Some corrections in manual. check-in: ec4c6a81 user: gcramer tags: revised_text, tip-466
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to doc/text.n.

3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
.
Include information about tags in the result. If additionally option
\fB\-nested\fR is specified, then two tag sets will be provided: firstly all
the tags starting with this content, and secondly all the tags ending after
this content (similar to the \fItagon\fR and \fItagoff\fR ranges in the
\fBdump\fR format). Without the \fB\-nested\fR option (this is the default) only
one list will be provided, namely all the tags associated to this segment
content. The tag list will be written in decreasing order, sorted by the
priority of the tag.
.TP
\fB\-text\fR
.
Include information about text (characters) in the dump result. The content
of this segment is the text up to the next segment. The segmentation of text
depends on the tagging information, any change in tagging is starting a new
segment. Note that soft hyphens (Unicode point U+00AD) do not belong to this







|
|







3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
.
Include information about tags in the result. If additionally option
\fB\-nested\fR is specified, then two tag sets will be provided: firstly all
the tags starting with this content, and secondly all the tags ending after
this content (similar to the \fItagon\fR and \fItagoff\fR ranges in the
\fBdump\fR format). Without the \fB\-nested\fR option (this is the default) only
one list will be provided, namely all the tags associated to this segment
content. The tag list will be sorted in order from lowest priority to highest
priority.
.TP
\fB\-text\fR
.
Include information about text (characters) in the dump result. The content
of this segment is the text up to the next segment. The segmentation of text
depends on the tagging information, any change in tagging is starting a new
segment. Note that soft hyphens (Unicode point U+00AD) do not belong to this

Changes to generic/tkText.c.

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
 * Support of tk8.6/8.5.
 */
#ifndef DEF_TEXT_INACTIVE_SELECT_FG_COLOR
# if defined(MAC_OSX_TK)
#  define DEF_TEXT_INACTIVE_SELECT_FG_COLOR "systemDialogActiveText"
# elif defined(_WIN32)
#  define DEF_TEXT_INACTIVE_SELECT_FG_COLOR "SystemWindowText"
# else /* X11 */
#  define DEF_TEXT_INACTIVE_SELECT_FG_COLOR BLACK
# endif
# define DEF_TEXT_INACTIVE_SELECT_BG_COLOR DEF_TEXT_INACTIVE_SELECT_COLOR
#endif

/*







|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
 * Support of tk8.6/8.5.
 */
#ifndef DEF_TEXT_INACTIVE_SELECT_FG_COLOR
# if defined(MAC_OSX_TK)
#  define DEF_TEXT_INACTIVE_SELECT_FG_COLOR "systemDialogActiveText"
# elif defined(_WIN32)
#  define DEF_TEXT_INACTIVE_SELECT_FG_COLOR NULL
# else /* X11 */
#  define DEF_TEXT_INACTIVE_SELECT_FG_COLOR BLACK
# endif
# define DEF_TEXT_INACTIVE_SELECT_BG_COLOR DEF_TEXT_INACTIVE_SELECT_COLOR
#endif

/*
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
    {TK_OPTION_COLOR, "-hyphencolor", "hyphenColor", "HyphenColor",
	DEF_TEXT_FG, -1, Tk_Offset(TkText, hyphenColor), TK_OPTION_NULL_OK, 0, TK_TEXT_LINE_REDRAW},
    {TK_OPTION_BOOLEAN, "-hyphens", "hyphens", "Hyphens",
	"0", -1, Tk_Offset(TkText, useHyphenSupport), 0, 0, TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_BORDER, "-inactiveselectbackground", "inactiveSelectBackground", "Foreground",
	DEF_TEXT_INACTIVE_SELECT_BG_COLOR, -1, Tk_Offset(TkText, inactiveSelBorder),
	TK_OPTION_NULL_OK, DEF_TEXT_SELECT_MONO, 0},
    {TK_OPTION_COLOR, "-inactiveselectforeground", "inactiveSelectForeground",
	"Background", DEF_TEXT_INACTIVE_SELECT_FG_COLOR, -1,
	Tk_Offset(TkText, inactiveSelFgColorPtr), TK_OPTION_NULL_OK, DEF_TEXT_SELECT_FG_MONO, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_TEXT_INSERT_BG, -1, Tk_Offset(TkText, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_TEXT_INSERT_BD_COLOR, -1, Tk_Offset(TkText, insertBorderWidth), 0,
	(ClientData) DEF_TEXT_INSERT_BD_MONO, 0},
    {TK_OPTION_COLOR, "-insertforeground", "insertForeground", "InsertForeground",
	DEF_TEXT_BG_COLOR, -1, Tk_Offset(TkText, insertFgColorPtr), 0, 0, 0},







|
|
|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
    {TK_OPTION_COLOR, "-hyphencolor", "hyphenColor", "HyphenColor",
	DEF_TEXT_FG, -1, Tk_Offset(TkText, hyphenColor), TK_OPTION_NULL_OK, 0, TK_TEXT_LINE_REDRAW},
    {TK_OPTION_BOOLEAN, "-hyphens", "hyphens", "Hyphens",
	"0", -1, Tk_Offset(TkText, useHyphenSupport), 0, 0, TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_BORDER, "-inactiveselectbackground", "inactiveSelectBackground", "Foreground",
	DEF_TEXT_INACTIVE_SELECT_BG_COLOR, -1, Tk_Offset(TkText, inactiveSelBorder),
	TK_OPTION_NULL_OK, DEF_TEXT_SELECT_MONO, 0},
    {TK_OPTION_COLOR, "-inactiveselectforeground", "inactiveSelectForeground", "Background",
    	DEF_TEXT_INACTIVE_SELECT_FG_COLOR, -1, Tk_Offset(TkText, inactiveSelFgColorPtr),
	TK_OPTION_NULL_OK, DEF_TEXT_SELECT_FG_MONO, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_TEXT_INSERT_BG, -1, Tk_Offset(TkText, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_TEXT_INSERT_BD_COLOR, -1, Tk_Offset(TkText, insertBorderWidth), 0,
	(ClientData) DEF_TEXT_INSERT_BD_MONO, 0},
    {TK_OPTION_COLOR, "-insertforeground", "insertForeground", "InsertForeground",
	DEF_TEXT_BG_COLOR, -1, Tk_Offset(TkText, insertFgColorPtr), 0, 0, 0},
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
    }
    tree = textPtr->sharedTextPtr->tree;
    textPtr->sharedTextPtr->inspectEpoch += 1;
    lineno = TkBTreeLinesTo(tree, textPtr, TkTextIndexGetLine(&index1), NULL);
    prevByteIndex = index1;
    if (TkTextIndexBackBytes(textPtr, &index1, 1, &prevByteIndex) == 0) {
	unsigned epoch = textPtr->sharedTextPtr->inspectEpoch + 1;
	tagPtr = TkBTreeGetTags(&prevByteIndex);
	for (tPtr = tagPtr; tPtr; tPtr = tPtr->nextPtr) { tPtr->epoch = epoch; }
    } else {
	tagPtr = NULL;
    }
    if (TkTextIndexGetLine(&index1) == TkTextIndexGetLine(&index2)) {
	/* we are at the end, so we can ignore the return code of DumpLine */
	DumpLine(interp, textPtr, what, TkTextIndexGetLine(&index1),







|







7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
    }
    tree = textPtr->sharedTextPtr->tree;
    textPtr->sharedTextPtr->inspectEpoch += 1;
    lineno = TkBTreeLinesTo(tree, textPtr, TkTextIndexGetLine(&index1), NULL);
    prevByteIndex = index1;
    if (TkTextIndexBackBytes(textPtr, &index1, 1, &prevByteIndex) == 0) {
	unsigned epoch = textPtr->sharedTextPtr->inspectEpoch + 1;
	tagPtr = TkBTreeGetTags(&prevByteIndex, TK_TEXT_SORT_NONE, NULL);
	for (tPtr = tagPtr; tPtr; tPtr = tPtr->nextPtr) { tPtr->epoch = epoch; }
    } else {
	tagPtr = NULL;
    }
    if (TkTextIndexGetLine(&index1) == TkTextIndexGetLine(&index2)) {
	/* we are at the end, so we can ignore the return code of DumpLine */
	DumpLine(interp, textPtr, what, TkTextIndexGetLine(&index1),
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
	unsigned epoch = sharedTextPtr->inspectEpoch;

	TkTextIndexClear(&index, textPtr);
	TkTextIndexSetByteIndex2(&index, linePtr, startByte);
	TkBTreeMoveBackward(&index, 1);
	segPtr = TkTextIndexGetContentSegment(&index, NULL);
	assert(segPtr);
	tagPtr = TkBTreeGetSegmentTags(textPtr->sharedTextPtr, segPtr, textPtr, NULL);
	for (tPtr = tagPtr; tPtr; tPtr = tPtr->nextPtr) {
	    tPtr->flag = epoch; /* mark as open */
	}
    }

    /*
     * Must loop through line looking at its segments: character, hyphen, mark, image, window.







|







7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
	unsigned epoch = sharedTextPtr->inspectEpoch;

	TkTextIndexClear(&index, textPtr);
	TkTextIndexSetByteIndex2(&index, linePtr, startByte);
	TkBTreeMoveBackward(&index, 1);
	segPtr = TkTextIndexGetContentSegment(&index, NULL);
	assert(segPtr);
	tagPtr = TkBTreeGetSegmentTags(textPtr->sharedTextPtr, segPtr, textPtr, TK_TEXT_SORT_NONE, NULL);
	for (tPtr = tagPtr; tPtr; tPtr = tPtr->nextPtr) {
	    tPtr->flag = epoch; /* mark as open */
	}
    }

    /*
     * Must loop through line looking at its segments: character, hyphen, mark, image, window.
7634
7635
7636
7637
7638
7639
7640
7641

7642
7643
7644
7645
7646
7647
7648
    }

    while (segPtr && offset < endByte) {
	currentSize = segPtr->size;

	if (offset + MAX(1, currentSize) > startByte) {
	    if ((what & TK_DUMP_TAG) && segPtr->tagInfoPtr) {
		TkTextTag *tagPtr = TkBTreeGetSegmentTags(sharedTextPtr, segPtr, textPtr, NULL);

		unsigned epoch = sharedTextPtr->inspectEpoch;
		unsigned nextEpoch = epoch + 1;
		TkTextTag *tPtr;

		for (tPtr = tagPtr; tPtr; tPtr = tPtr->nextPtr) {
		    if (tPtr->flag == epoch) {
			tPtr->flag = nextEpoch; /* mark as still open */







|
>







7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
    }

    while (segPtr && offset < endByte) {
	currentSize = segPtr->size;

	if (offset + MAX(1, currentSize) > startByte) {
	    if ((what & TK_DUMP_TAG) && segPtr->tagInfoPtr) {
		TkTextTag *tagPtr = TkBTreeGetSegmentTags(sharedTextPtr, segPtr, textPtr,
			TK_TEXT_SORT_ASCENDING, NULL);
		unsigned epoch = sharedTextPtr->inspectEpoch;
		unsigned nextEpoch = epoch + 1;
		TkTextTag *tPtr;

		for (tPtr = tagPtr; tPtr; tPtr = tPtr->nextPtr) {
		    if (tPtr->flag == epoch) {
			tPtr->flag = nextEpoch; /* mark as still open */
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
	    if (segPtr == textPtr->endMarker) {
		if (prevPtr != segPtr
		    	&& (what & SEG_GROUP_CHAR)
			&& segPtr->sectionPtr->linePtr != TkBTreeGetLastLine(textPtr)) {
		    /* print newline before finishing */
		    type = "break";
		    printTags = !!(what & TK_DUMP_TAG);
		    tagPtr = TkBTreeGetSegmentTags(sharedTextPtr,
			    segPtr->sectionPtr->linePtr->lastPtr, textPtr, NULL);
		    nextPtr = segPtr; /* repeat this mark */
		} else {
		    nextPtr = NULL; /* finished */
		}
	    } else if (!(what & SEG_GROUP_MARK)) {
		continue;
	    } else if (!TkTextIsNormalMark(segPtr)







|
|







8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
	    if (segPtr == textPtr->endMarker) {
		if (prevPtr != segPtr
		    	&& (what & SEG_GROUP_CHAR)
			&& segPtr->sectionPtr->linePtr != TkBTreeGetLastLine(textPtr)) {
		    /* print newline before finishing */
		    type = "break";
		    printTags = !!(what & TK_DUMP_TAG);
		    tagPtr = TkBTreeGetSegmentTags(sharedTextPtr, segPtr->sectionPtr->linePtr->lastPtr,
			    textPtr, TK_TEXT_SORT_ASCENDING, NULL);
		    nextPtr = segPtr; /* repeat this mark */
		} else {
		    nextPtr = NULL; /* finished */
		}
	    } else if (!(what & SEG_GROUP_MARK)) {
		continue;
	    } else if (!TkTextIsNormalMark(segPtr)
8656
8657
8658
8659
8660
8661
8662
8663

8664
8665
8666
8667
8668
8669
8670
8671
8672
8673

8674
8675
8676
8677
8678
8679
8680
		if (prevPtr == segPtr || *segPtr->body.chars == '\n') {
		    type = "break";
		    nextPtr = segPtr->sectionPtr->linePtr->nextPtr->segPtr;
		    if (prevPtr == segPtr) {
			tagPtr = prevTagPtr;
			segPtr->body.chars[segPtr->size - 1] = '\n';
		    } else if (type && printTags) {
			tagPtr = TkBTreeGetSegmentTags(sharedTextPtr, segPtr, textPtr, NULL);

		    }
		} else {
		    type = "text";
		    if (segPtr->size > 1 && segPtr->body.chars[segPtr->size - 1] == '\n') {
			nextPtr = segPtr; /* repeat this char segment */
			segPtr->body.chars[segPtr->size - 1] = '\0';
		    }
		    value = segPtr->body.chars;
		    if (printTags) {
			tagPtr = TkBTreeGetSegmentTags(sharedTextPtr, segPtr, textPtr, NULL);

		    }
		}
	    } else if (!nextPtr) {
		nextPtr = segPtr->sectionPtr->linePtr->nextPtr->segPtr;
	    }
	    break;
	default:







|
>









|
>







8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
		if (prevPtr == segPtr || *segPtr->body.chars == '\n') {
		    type = "break";
		    nextPtr = segPtr->sectionPtr->linePtr->nextPtr->segPtr;
		    if (prevPtr == segPtr) {
			tagPtr = prevTagPtr;
			segPtr->body.chars[segPtr->size - 1] = '\n';
		    } else if (type && printTags) {
			tagPtr = TkBTreeGetSegmentTags(sharedTextPtr, segPtr, textPtr,
				TK_TEXT_SORT_ASCENDING, NULL);
		    }
		} else {
		    type = "text";
		    if (segPtr->size > 1 && segPtr->body.chars[segPtr->size - 1] == '\n') {
			nextPtr = segPtr; /* repeat this char segment */
			segPtr->body.chars[segPtr->size - 1] = '\0';
		    }
		    value = segPtr->body.chars;
		    if (printTags) {
			tagPtr = TkBTreeGetSegmentTags(sharedTextPtr, segPtr, textPtr,
				TK_TEXT_SORT_ASCENDING, NULL);
		    }
		}
	    } else if (!nextPtr) {
		nextPtr = segPtr->sectionPtr->linePtr->nextPtr->segPtr;
	    }
	    break;
	default:
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
			}
			tagArray[numTags++] = prevTagPtr;
			prevTagPtr->flag = 0; /* mark as closed */
		    }
		}

		Tcl_DStringStartSublist(str);
		TkTextSortTags(numTags, tagArray);
		for (i = 0; i < numTags; ++i) {
		    Tcl_DStringAppendElement(str, tagArray[i]->name);
		}
		Tcl_DStringEndSublist(str);
	    }

	    prevTagPtr = NULL;







<







8704
8705
8706
8707
8708
8709
8710

8711
8712
8713
8714
8715
8716
8717
			}
			tagArray[numTags++] = prevTagPtr;
			prevTagPtr->flag = 0; /* mark as closed */
		    }
		}

		Tcl_DStringStartSublist(str);

		for (i = 0; i < numTags; ++i) {
		    Tcl_DStringAppendElement(str, tagArray[i]->name);
		}
		Tcl_DStringEndSublist(str);
	    }

	    prevTagPtr = NULL;
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
			    tagArray = realloc(tagArray, tagArrSize * sizeof(tagArray[0]));
			}
			tagArray[numTags++] = tPtr;
		    }
		}

		Tcl_DStringStartSublist(str);
		TkTextSortTags(numTags, tagArray);
		for (i = 0; i < numTags; ++i) {
		    Tcl_DStringAppendElement(str, tagArray[i]->name);
		}
		Tcl_DStringEndSublist(str);
	    }
	}








<







8754
8755
8756
8757
8758
8759
8760

8761
8762
8763
8764
8765
8766
8767
			    tagArray = realloc(tagArray, tagArrSize * sizeof(tagArray[0]));
			}
			tagArray[numTags++] = tPtr;
		    }
		}

		Tcl_DStringStartSublist(str);

		for (i = 0; i < numTags; ++i) {
		    Tcl_DStringAppendElement(str, tagArray[i]->name);
		}
		Tcl_DStringEndSublist(str);
	    }
	}

9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676

9677
9678
9679
9680
9681
9682
9683
9684
9685
9686
9687
		    TkTextPrintIndex(tPtr, &index[1], idx[1]);

		    Tcl_DStringInit(&buf);
		    Tcl_DStringAppendElement(&buf, string);

		    tagPtr = NULL;
		    if (TkTextIndexBackChars(tPtr, &index[0], 1, &myIndex, COUNT_CHARS)) {
			tagPtr = TkBTreeGetTags(&myIndex);
		    }
		    AppendTags(&buf, tagPtr);
		    AppendTags(&buf, TkBTreeGetTags(&index[1]));
		    AppendTags(&buf, cmp == 0 ? NULL : TkBTreeGetTags(&index[0]));

		    if (*operation == 'd') {
			tagPtr = NULL;
			if (cmp && TkTextIndexBackChars(tPtr, &index[1], 1, &myIndex, COUNT_CHARS)) {
			    tagPtr = TkBTreeGetTags(&myIndex);
			}
			AppendTags(&buf, tagPtr);
		    }
		    Tcl_DStringAppendElement(&buf, final ? "yes" : "no");
		    arg = Tcl_DStringValue(&buf);

		    if (!TkTextTriggerWatchCmd(tPtr, operation, idx[0], idx[1],







|


|
|
>



|







9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676
9677
9678
9679
9680
9681
9682
9683
9684
9685
9686
9687
9688
9689
		    TkTextPrintIndex(tPtr, &index[1], idx[1]);

		    Tcl_DStringInit(&buf);
		    Tcl_DStringAppendElement(&buf, string);

		    tagPtr = NULL;
		    if (TkTextIndexBackChars(tPtr, &index[0], 1, &myIndex, COUNT_CHARS)) {
			tagPtr = TkBTreeGetTags(&myIndex, TK_TEXT_SORT_ASCENDING, NULL);
		    }
		    AppendTags(&buf, tagPtr);
		    AppendTags(&buf, TkBTreeGetTags(&index[1], TK_TEXT_SORT_ASCENDING, NULL));
		    AppendTags(&buf, cmp == 0 ? NULL :
			    TkBTreeGetTags(&index[0], TK_TEXT_SORT_ASCENDING, NULL));
		    if (*operation == 'd') {
			tagPtr = NULL;
			if (cmp && TkTextIndexBackChars(tPtr, &index[1], 1, &myIndex, COUNT_CHARS)) {
			    tagPtr = TkBTreeGetTags(&myIndex, TK_TEXT_SORT_ASCENDING, NULL);
			}
			AppendTags(&buf, tagPtr);
		    }
		    Tcl_DStringAppendElement(&buf, final ? "yes" : "no");
		    arg = Tcl_DStringValue(&buf);

		    if (!TkTextTriggerWatchCmd(tPtr, operation, idx[0], idx[1],
11922
11923
11924
11925
11926
11927
11928
11929

11930
11931
11932
11933
11934
11935
11936
extern int		TkBTreeGetNumberOfDisplayLines(const TkTextPixelInfo *pixelInfo);
extern TkTextPixelInfo *TkBTreeLinePixelInfo(const TkText *textPtr, TkTextLine *linePtr);
extern unsigned		TkBTreeEpoch(TkTextBTree tree);
extern unsigned		TkBTreeIncrEpoch(TkTextBTree tree);
extern struct Node	*TkBTreeGetRoot(TkTextBTree tree);
extern TkTextLine *	TkBTreePrevLogicalLine(const TkSharedText *sharedTextPtr,
			    const TkText *textPtr, TkTextLine *linePtr);
extern TkTextTag *	TkBTreeGetTags(const TkTextIndex *indexPtr);

extern TkTextLine *	TkBTreeGetStartLine(const TkText *textPtr);
extern TkTextLine *	TkBTreeGetLastLine(const TkText *textPtr);
extern TkTextLine *	TkBTreeNextLine(const TkText *textPtr, TkTextLine *linePtr);
extern TkTextLine *	TkBTreePrevLine(const TkText *textPtr, TkTextLine *linePtr);
extern unsigned		TkBTreeCountLines(const TkTextBTree tree, const TkTextLine *linePtr1,
			    const TkTextLine *linePtr2);
extern bool		TkTextGetIndexFromObj(Tcl_Interp *interp, TkText *textPtr, Tcl_Obj *objPtr,







|
>







11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
11938
11939
extern int		TkBTreeGetNumberOfDisplayLines(const TkTextPixelInfo *pixelInfo);
extern TkTextPixelInfo *TkBTreeLinePixelInfo(const TkText *textPtr, TkTextLine *linePtr);
extern unsigned		TkBTreeEpoch(TkTextBTree tree);
extern unsigned		TkBTreeIncrEpoch(TkTextBTree tree);
extern struct Node	*TkBTreeGetRoot(TkTextBTree tree);
extern TkTextLine *	TkBTreePrevLogicalLine(const TkSharedText *sharedTextPtr,
			    const TkText *textPtr, TkTextLine *linePtr);
extern TkTextTag *	TkBTreeGetTags(const TkTextIndex *indexPtr, TkTextSortMethod sortMeth,
			    int *flags);
extern TkTextLine *	TkBTreeGetStartLine(const TkText *textPtr);
extern TkTextLine *	TkBTreeGetLastLine(const TkText *textPtr);
extern TkTextLine *	TkBTreeNextLine(const TkText *textPtr, TkTextLine *linePtr);
extern TkTextLine *	TkBTreePrevLine(const TkText *textPtr, TkTextLine *linePtr);
extern unsigned		TkBTreeCountLines(const TkTextBTree tree, const TkTextLine *linePtr1,
			    const TkTextLine *linePtr2);
extern bool		TkTextGetIndexFromObj(Tcl_Interp *interp, TkText *textPtr, Tcl_Obj *objPtr,

Changes to generic/tkText.h.

1612
1613
1614
1615
1616
1617
1618
















1619
1620
1621
1622
1623
1624
1625
#define TREE_GONE		(1 << 0)
#define DELETE_BRANCHES		(1 << 1)
#define DELETE_MARKS		(1 << 2)
#define DELETE_INCLUSIVE	(1 << 3)
#define DELETE_CLEANUP		(1 << 4)
#define DELETE_LASTLINE		(1 << 5)

















/*
 * The following definition specifies the maximum number of characters needed
 * in a string to hold a position specifier.
 */

#define TK_POS_CHARS		30








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
#define TREE_GONE		(1 << 0)
#define DELETE_BRANCHES		(1 << 1)
#define DELETE_MARKS		(1 << 2)
#define DELETE_INCLUSIVE	(1 << 3)
#define DELETE_CLEANUP		(1 << 4)
#define DELETE_LASTLINE		(1 << 5)

/*
 * Flags for sorting.
 */

typedef enum {
    TK_TEXT_SORT_NONE,
    TK_TEXT_SORT_ASCENDING
} TkTextSortMethod;

/*
 * Flags nneded for function TkBTreeGetSegmentTags().
 */

#define TK_TEXT_IS_ELIDED	(1 << 0)
#define TK_TEXT_IS_SELECTED	(1 << 1)

/*
 * The following definition specifies the maximum number of characters needed
 * in a string to hold a position specifier.
 */

#define TK_POS_CHARS		30

1786
1787
1788
1789
1790
1791
1792
1793

1794
1795

1796
1797
1798
1799
1800
1801
1802
			    unsigned *displayLineNo, unsigned offset);
MODULE_SCOPE TkTextLine * TkBTreePrevDisplayLine(TkText *textPtr, TkTextLine *linePtr,
			    unsigned *displayLineNo, unsigned offset);
MODULE_SCOPE TkTextSegment * TkBTreeFindStartOfElidedRange(const TkSharedText *sharedTextPtr,
			    const TkText *textPtr, const TkTextSegment *segPtr);
MODULE_SCOPE TkTextSegment * TkBTreeFindEndOfElidedRange(const TkSharedText *sharedTextPtr,
			    const TkText *textPtr, const TkTextSegment *segPtr);
inline TkTextTag *	TkBTreeGetTags(const TkTextIndex *indexPtr);

MODULE_SCOPE TkTextTag * TkBTreeGetSegmentTags(const TkSharedText *sharedTextPtr,
			    const TkTextSegment *segPtr, const TkText *textPtr, bool *containsSelection);

MODULE_SCOPE const char * TkBTreeGetLang(const TkText *textPtr, const TkTextSegment *segPtr);
MODULE_SCOPE void	TkBTreeInsertChars(TkTextBTree tree, TkTextIndex *indexPtr, const char *string,
			    union TkTextTagSet *tagInfoPtr, TkTextTag *hyphenTagPtr,
			    TkTextUndoInfo *undoInfo);
MODULE_SCOPE TkTextSegment *TkBTreeMakeCharSegment(const char *string, unsigned length,
			    union TkTextTagSet *tagInfoPtr);
MODULE_SCOPE void	TkBTreeMakeUndoIndex(const TkSharedText *sharedTextPtr,







|
>

|
>







1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
			    unsigned *displayLineNo, unsigned offset);
MODULE_SCOPE TkTextLine * TkBTreePrevDisplayLine(TkText *textPtr, TkTextLine *linePtr,
			    unsigned *displayLineNo, unsigned offset);
MODULE_SCOPE TkTextSegment * TkBTreeFindStartOfElidedRange(const TkSharedText *sharedTextPtr,
			    const TkText *textPtr, const TkTextSegment *segPtr);
MODULE_SCOPE TkTextSegment * TkBTreeFindEndOfElidedRange(const TkSharedText *sharedTextPtr,
			    const TkText *textPtr, const TkTextSegment *segPtr);
inline TkTextTag *	TkBTreeGetTags(const TkTextIndex *indexPtr, TkTextSortMethod sortMeth,
			    int *flags);
MODULE_SCOPE TkTextTag * TkBTreeGetSegmentTags(const TkSharedText *sharedTextPtr,
			    const TkTextSegment *segPtr, const TkText *textPtr,
			    TkTextSortMethod sortMeth, int *flags);
MODULE_SCOPE const char * TkBTreeGetLang(const TkText *textPtr, const TkTextSegment *segPtr);
MODULE_SCOPE void	TkBTreeInsertChars(TkTextBTree tree, TkTextIndex *indexPtr, const char *string,
			    union TkTextTagSet *tagInfoPtr, TkTextTag *hyphenTagPtr,
			    TkTextUndoInfo *undoInfo);
MODULE_SCOPE TkTextSegment *TkBTreeMakeCharSegment(const char *string, unsigned length,
			    union TkTextTagSet *tagInfoPtr);
MODULE_SCOPE void	TkBTreeMakeUndoIndex(const TkSharedText *sharedTextPtr,

Changes to generic/tkTextBTree.c.

3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268


3269





3270
3271
3272
3273
3274
3275
3276
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static bool
TestIfElided(
    const TkTextTag *tagPtr)
{
    int highestPriority = -1;
    bool elide = false;

    for ( ; tagPtr; tagPtr = tagPtr->nextPtr) {
	if (tagPtr->elideString && (int) tagPtr->priority > highestPriority) {
	    elide = tagPtr->elide;
	    highestPriority = tagPtr->priority;
	}
    }

    return elide;
}

bool
TkTextIsElided(
    const TkTextIndex *indexPtr)/* The character in the text for which display information is wanted. */
{


    return TkBTreeGetRoot(indexPtr->tree)->numBranches > 0 && TestIfElided(TkBTreeGetTags(indexPtr));





}

/*
 *----------------------------------------------------------------------
 *
 * SegmentIsElided --
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




>
>
|
>
>
>
>
>







3241
3242
3243
3244
3245
3246
3247

















3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


















bool
TkTextIsElided(
    const TkTextIndex *indexPtr)/* The character in the text for which display information is wanted. */
{
    int flags;

    if (TkBTreeGetRoot(indexPtr->tree)->numBranches == 0) {
	return false;
    }

    TkBTreeGetTags(indexPtr, TK_TEXT_SORT_NONE, &flags);
    return !!(flags & TK_TEXT_IS_ELIDED);
}

/*
 *----------------------------------------------------------------------
 *
 * SegmentIsElided --
 *
3287
3288
3289
3290
3291
3292
3293


3294
3295
3296



3297

3298
3299
3300
3301
3302
3303
3304

static bool
SegmentIsElided(
    const TkSharedText *sharedTextPtr,
    const TkTextSegment *segPtr,
    const TkText *textPtr)		/* can be NULL */
{


    assert(segPtr->tagInfoPtr);

    return TkTextTagSetIntersectsBits(segPtr->tagInfoPtr, sharedTextPtr->elisionTags)



	    && TestIfElided(TkBTreeGetSegmentTags(sharedTextPtr, segPtr, textPtr, NULL));

}

/*
 *----------------------------------------------------------------------
 *
 * TkTextSegmentIsElided --
 *







>
>


|
>
>
>
|
>







3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300

static bool
SegmentIsElided(
    const TkSharedText *sharedTextPtr,
    const TkTextSegment *segPtr,
    const TkText *textPtr)		/* can be NULL */
{
    int flags;

    assert(segPtr->tagInfoPtr);

    if (!TkTextTagSetIntersectsBits(segPtr->tagInfoPtr, sharedTextPtr->elisionTags)) {
	return false;
    }

    TkBTreeGetSegmentTags(sharedTextPtr, segPtr, textPtr, TK_TEXT_SORT_NONE, &flags);
    return !!(flags & TK_TEXT_IS_ELIDED);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextSegmentIsElided --
 *
12520
12521
12522
12523
12524
12525
12526

12527
12528

12529
12530


12531



12532
12533
12534
12535
12536
12537
12538
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553

12554



12555




12556






12557
12558


12559



12560






12561
12562






12563
12564



12565







12566
12567
12568
12569
12570
12571
12572
12573

TkTextTag *
TkBTreeGetSegmentTags(
    const TkSharedText *sharedTextPtr,	/* Handle to shared text resource. */
    const TkTextSegment *segPtr,	/* Get tags from this segment. */
    const TkText *textPtr,		/* If non-NULL, then only return tags for this text widget
    					 * (when there are peer widgets). */

    bool *containsSelection)		/* If non-NULL, return whether this chain contains the
    					 * "sel" tag. */

{
    const TkTextTagSet *tagInfoPtr;


    TkTextTag *chainPtr = NULL;




    assert(segPtr->tagInfoPtr);

    tagInfoPtr = segPtr->tagInfoPtr;

    if (containsSelection) {
	*containsSelection = false;
    }

    if (tagInfoPtr != sharedTextPtr->emptyTagInfoPtr) {
	unsigned i = TkTextTagSetFindFirst(tagInfoPtr);

	for ( ; i != TK_TEXT_TAG_SET_NPOS; i = TkTextTagSetFindNext(tagInfoPtr, i)) {
	    TkTextTag *tagPtr = sharedTextPtr->tagLookup[i];

	    assert(tagPtr);
	    assert(!tagPtr->isDisabled);

	    if (!textPtr || !tagPtr->textPtr) {
		tagPtr->nextPtr = chainPtr;
		tagPtr->epoch = 0;
		chainPtr = tagPtr;

	    } else if (tagPtr->textPtr == textPtr) {



		tagPtr->nextPtr = chainPtr;




		tagPtr->epoch = 0;






		chainPtr = tagPtr;



		if (tagPtr == textPtr->selTagPtr && containsSelection) {



		    *containsSelection = true;






		}
	    }






	}
    }











    return chainPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeGetLang --
 *







>
|
|
>


>
>
|
>
>
>





|
|











|
<

|
>
|
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
|
|
>
>
|
>
>
>
|
>
>
>
>
>
>
|
|
>
>
>
>
>
>
|
|
>
>
>
|
>
>
>
>
>
>
>
|







12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535
12536
12537
12538
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553

12554
12555
12556
12557
12558
12559
12560
12561
12562
12563
12564
12565
12566
12567
12568
12569
12570
12571
12572
12573
12574
12575
12576
12577
12578
12579
12580
12581
12582
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
12615
12616

TkTextTag *
TkBTreeGetSegmentTags(
    const TkSharedText *sharedTextPtr,	/* Handle to shared text resource. */
    const TkTextSegment *segPtr,	/* Get tags from this segment. */
    const TkText *textPtr,		/* If non-NULL, then only return tags for this text widget
    					 * (when there are peer widgets). */
    TkTextSortMethod sortMeth,		/* Sort tags according to this method. */
    int *flags)				/* If non-NULL, return whether this chain contains the
    					 * "sel" tag (TK_TEXT_IS_SELECTED), or if this chain is elided
					 * (TK_TEXT_IS_ELIDED). */
{
    const TkTextTagSet *tagInfoPtr;
    TkTextTag *tagBuf[256];
    TkTextTag **tagArray = tagBuf;
    TkTextTag *tagPtr;
    int highestPriority = -1;
    unsigned count = 0;
    unsigned i;

    assert(segPtr->tagInfoPtr);

    tagInfoPtr = segPtr->tagInfoPtr;

    if (flags) {
	*flags = 0;
    }

    if (tagInfoPtr != sharedTextPtr->emptyTagInfoPtr) {
	unsigned i = TkTextTagSetFindFirst(tagInfoPtr);

	for ( ; i != TK_TEXT_TAG_SET_NPOS; i = TkTextTagSetFindNext(tagInfoPtr, i)) {
	    TkTextTag *tagPtr = sharedTextPtr->tagLookup[i];

	    assert(tagPtr);
	    assert(!tagPtr->isDisabled);

	    if (!textPtr || !tagPtr->textPtr || tagPtr->textPtr == textPtr) {

		tagPtr->epoch = 0;

		if (flags) {
		    if (textPtr && tagPtr == textPtr->selTagPtr && textPtr == tagPtr->textPtr) {
			*flags |= TK_TEXT_IS_SELECTED;
		    }
		    if (tagPtr->elideString && (int) tagPtr->priority > highestPriority) {
			if (tagPtr->elide) {
			    *flags |= TK_TEXT_IS_ELIDED;
			} else {
			    *flags &= ~TK_TEXT_IS_ELIDED;
			}
			highestPriority = tagPtr->priority;
		    }
		}
		if (count == sizeof(tagBuf)/sizeof(tagBuf[0])) {
		    tagArray = malloc(TkTextTagSetCount(tagInfoPtr) * sizeof(tagArray[0]));
		    memcpy(tagArray, tagBuf, sizeof(tagBuf));
		}
		tagArray[count++] = tagPtr;
	    }
	}
    }

    /*
     * Catch the most frequent cases.
     */

    switch (count) {
    case 0:
	return NULL;
    case 1:
	tagArray[0]->nextPtr = NULL;
	return tagArray[0];
    }

    switch (sortMeth) {
    case TK_TEXT_SORT_NONE:
	break;
    case TK_TEXT_SORT_ASCENDING:
	TkTextSortTags(count, tagArray);
	break;
    }

    tagPtr = tagArray[0];
    for (i = 1; i < count; ++i) {
	tagPtr = tagPtr->nextPtr = tagArray[i];
    }
    tagPtr->nextPtr = NULL;
    tagPtr = tagArray[0];

    if (tagArray != tagBuf) {
	free(tagArray);
    }

    return tagPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeGetLang --
 *

Changes to generic/tkTextDisp.c.

1800
1801
1802
1803
1804
1805
1806
1807

1808
1809
1810
1811
1812
1813
1814

/*
 *----------------------------------------------------------------------
 *
 * GetStyle --
 *
 *	This function creates all the information needed to display text at a
 *	particular location.

 *
 * Results:
 *	The return value is a pointer to a TextStyle structure that
 *	corresponds to *sValuePtr.
 *
 * Side effects:
 *	A new entry may be created in the style table for the widget.







|
>







1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815

/*
 *----------------------------------------------------------------------
 *
 * GetStyle --
 *
 *	This function creates all the information needed to display text at a
 *	particular location. We know that the given chain of tags is sorted
 *	in ascending order.
 *
 * Results:
 *	The return value is a pointer to a TextStyle structure that
 *	corresponds to *sValuePtr.
 *
 * Side effects:
 *	A new entry may be created in the style table for the widget.
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
    StyleValues styleValues;
    TextStyle *stylePtr;
    Tcl_HashEntry *hPtr;
    XGCValues gcValues;
    unsigned long mask;
    bool isNew;

    /*
     * The array below keeps track of the highest-priority specification
     * that has occurred for each of the various fields of the StyleValues.
     */

    enum {
	PRIO_BG_STIPPLE, PRIO_BORDER, PRIO_BORDER_WIDTH, PRIO_ELIDE, PRIO_EOL_COLOR, PRIO_FG,
	PRIO_FG_STIPPLE, PRIO_FONT, PRIO_HYPHEN_COLOR, PRIO_HYPHEN_RULES, PRIO_INDENT_BG,
	PRIO_JUSTIFY, PRIO_LANG, PRIO_LMARGIN_1, PRIO_LMARGIN_2, PRIO_LMARGIN_COLOR,
	PRIO_OFFSET, PRIO_OVERSTRIKE, PRIO_RELIEF, PRIO_RMARGIN, PRIO_RMARGIN_COLOR,
	PRIO_SPACING_1, PRIO_SPACING_2, PRIO_SPACING_3, PRIO_TAB, PRIO_TAB_STYLE,
	PRIO_UNDERLINE, PRIO_WRAP,
	PRIO_LAST /* must be last element */
    };

    int prio[PRIO_LAST] = {
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1 };

    assert(prio[PRIO_LAST - 1] == -1);

    /*
     * Find out what tags are present for the character, then compute a
     * StyleValues structure corresponding to those tags (scan through all of
     * the tags, saving information for the highest-priority tag).
     */

    memset(&styleValues, 0, sizeof(StyleValues));







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1826
1827
1828
1829
1830
1831
1832






















1833
1834
1835
1836
1837
1838
1839
    StyleValues styleValues;
    TextStyle *stylePtr;
    Tcl_HashEntry *hPtr;
    XGCValues gcValues;
    unsigned long mask;
    bool isNew;























    /*
     * Find out what tags are present for the character, then compute a
     * StyleValues structure corresponding to those tags (scan through all of
     * the tags, saving information for the highest-priority tag).
     */

    memset(&styleValues, 0, sizeof(StyleValues));
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
    styleValues.tabArrayPtr = textPtr->tabArrayPtr;
    styleValues.tabStyle = textPtr->tabStyle;
    styleValues.wrapMode = textPtr->wrapMode;
    styleValues.lang = textPtr->lang;
    styleValues.hyphenRules = textPtr->hyphenRulesPtr ? textPtr->hyphenRules : TK_TEXT_HYPHEN_MASK;

    for ( ; tagPtr; tagPtr = tagPtr->nextPtr) {
	Tk_3DBorder border;
        XColor *fgColor;
	int priority;

	border = tagPtr->border;
        fgColor = tagPtr->fgColor;
	priority = tagPtr->priority;

	/*
	 * If this is the selection tag, and inactiveSelBorder is NULL (the
	 * default on Windows), then we need to skip it if we don't have the
	 * focus.
	 */








|
|
<
<
<
<
<







1852
1853
1854
1855
1856
1857
1858
1859
1860





1861
1862
1863
1864
1865
1866
1867
    styleValues.tabArrayPtr = textPtr->tabArrayPtr;
    styleValues.tabStyle = textPtr->tabStyle;
    styleValues.wrapMode = textPtr->wrapMode;
    styleValues.lang = textPtr->lang;
    styleValues.hyphenRules = textPtr->hyphenRulesPtr ? textPtr->hyphenRules : TK_TEXT_HYPHEN_MASK;

    for ( ; tagPtr; tagPtr = tagPtr->nextPtr) {
	Tk_3DBorder border = tagPtr->border;
        XColor *fgColor = tagPtr->fgColor;






	/*
	 * If this is the selection tag, and inactiveSelBorder is NULL (the
	 * default on Windows), then we need to skip it if we don't have the
	 * focus.
	 */

1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
	    }
	    if (tagPtr->selFgColor != None) {
		fgColor = tagPtr->selFgColor;
	    } else if (fgColor == None) {
		fgColor = textPtr->selFgColorPtr;
	    }
	}
	if (border && priority > prio[PRIO_BORDER]) {
	    styleValues.border = border;
	    prio[PRIO_BORDER] = priority;
	}
	if (tagPtr->borderWidthPtr
		&& Tcl_GetString(tagPtr->borderWidthPtr)[0] != '\0'
		&& priority > prio[PRIO_BORDER_WIDTH]) {
	    styleValues.borderWidth = tagPtr->borderWidth;
	    prio[PRIO_BORDER_WIDTH] = priority;
	}
	if (tagPtr->reliefPtr && priority > prio[PRIO_RELIEF]) {
	    if (!styleValues.border) {
		styleValues.border = textPtr->border;
	    }
	    assert(tagPtr->relief < 8);
	    styleValues.relief = tagPtr->relief;
	    prio[PRIO_RELIEF] = priority;
	}
	if (tagPtr->bgStipple != None && priority > prio[PRIO_BG_STIPPLE]) {
	    styleValues.bgStipple = tagPtr->bgStipple;
	    prio[PRIO_BG_STIPPLE] = priority;
	}
	if (tagPtr->indentBgString != None && priority > prio[PRIO_INDENT_BG]) {
	    styleValues.indentBg = tagPtr->indentBg;
	    prio[PRIO_INDENT_BG] = priority;
	}
	if (fgColor != None && priority > prio[PRIO_FG]) {
	    styleValues.fgColor = fgColor;
	    prio[PRIO_FG] = priority;
	}
	if (tagPtr->tkfont != None && priority > prio[PRIO_FONT]) {
	    styleValues.tkfont = tagPtr->tkfont;
	    prio[PRIO_FONT] = priority;
	}
	if (tagPtr->fgStipple != None && priority > prio[PRIO_FG_STIPPLE]) {
	    styleValues.fgStipple = tagPtr->fgStipple;
	    prio[PRIO_FG_STIPPLE] = priority;
	}
	if (tagPtr->justifyString && priority > prio[PRIO_JUSTIFY]) {
	    /* assert(tagPtr->justify < 8); always true due to range */
	    styleValues.justify = tagPtr->justify;
	    prio[PRIO_JUSTIFY] = priority;
	}
	if (tagPtr->lMargin1String && priority > prio[PRIO_LMARGIN_1]) {
	    styleValues.lMargin1 = tagPtr->lMargin1;
	    prio[PRIO_LMARGIN_1] = priority;
	}
	if (tagPtr->lMargin2String && priority > prio[PRIO_LMARGIN_2]) {
	    styleValues.lMargin2 = tagPtr->lMargin2;
	    prio[PRIO_LMARGIN_2] = priority;
	}
	if (tagPtr->lMarginColor && priority > prio[PRIO_LMARGIN_COLOR]) {
	    styleValues.lMarginColor = tagPtr->lMarginColor;
	    prio[PRIO_LMARGIN_COLOR] = priority;
	}
	if (tagPtr->offsetString && priority > prio[PRIO_OFFSET]) {
	    styleValues.offset = tagPtr->offset;
	    prio[PRIO_OFFSET] = priority;
	}
	if (tagPtr->overstrikeString && priority > prio[PRIO_OVERSTRIKE]) {
	    styleValues.overstrike = tagPtr->overstrike;
	    prio[PRIO_OVERSTRIKE] = priority;
            if (tagPtr->overstrikeColor != None) {
                 styleValues.overstrikeColor = tagPtr->overstrikeColor;
            } else if (fgColor != None) {
                 styleValues.overstrikeColor = fgColor;
            }
	}
	if (tagPtr->rMarginString && priority > prio[PRIO_RMARGIN]) {
	    styleValues.rMargin = tagPtr->rMargin;
	    prio[PRIO_RMARGIN] = priority;
	}
	if (tagPtr->rMarginColor && priority > prio[PRIO_RMARGIN_COLOR]) {
	    styleValues.rMarginColor = tagPtr->rMarginColor;
	    prio[PRIO_RMARGIN_COLOR] = priority;
	}
	if (tagPtr->spacing1String && priority > prio[PRIO_SPACING_1]) {
	    styleValues.spacing1 = tagPtr->spacing1;
	    prio[PRIO_SPACING_1] = priority;
	}
	if (tagPtr->spacing2String && priority > prio[PRIO_SPACING_2]) {
	    styleValues.spacing2 = tagPtr->spacing2;
	    prio[PRIO_SPACING_2] = priority;
	}
	if (tagPtr->spacing3String && priority > prio[PRIO_SPACING_3]) {
	    styleValues.spacing3 = tagPtr->spacing3;
	    prio[PRIO_SPACING_3] = priority;
	}
	if (tagPtr->tabStringPtr && priority > prio[PRIO_TAB]) {
	    styleValues.tabArrayPtr = tagPtr->tabArrayPtr;
	    prio[PRIO_TAB] = priority;
	}
	if (tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE && priority > prio[PRIO_TAB_STYLE]) {
	    assert(tagPtr->tabStyle < 8);
	    styleValues.tabStyle = tagPtr->tabStyle;
	    prio[PRIO_TAB_STYLE] = priority;
	}
	if (tagPtr->eolColor && priority > prio[PRIO_EOL_COLOR]) {
	    styleValues.eolColor = tagPtr->eolColor;
	    prio[PRIO_EOL_COLOR] = priority;
	}
	if (tagPtr->hyphenColor && priority > prio[PRIO_HYPHEN_COLOR]) {
	    styleValues.hyphenColor = tagPtr->hyphenColor;
	    prio[PRIO_HYPHEN_COLOR] = priority;
	}
	if (tagPtr->underlineString && priority > prio[PRIO_UNDERLINE]) {
	    styleValues.underline = tagPtr->underline;
	    prio[PRIO_UNDERLINE] = priority;
            if (tagPtr->underlineColor != None) {
		styleValues.underlineColor = tagPtr->underlineColor;
            } else if (fgColor != None) {
		styleValues.underlineColor = fgColor;
            }
	}
	if (tagPtr->elideString && priority > prio[PRIO_ELIDE]) {
	    styleValues.elide = tagPtr->elide;
	    prio[PRIO_ELIDE] = priority;
	}
	if (tagPtr->langPtr && priority > prio[PRIO_LANG]) {
	    styleValues.lang = tagPtr->lang;
	    prio[PRIO_LANG] = priority;
	}
	if (tagPtr->hyphenRulesPtr && priority > prio[PRIO_HYPHEN_RULES]) {
	    styleValues.hyphenRules = tagPtr->hyphenRules;
	    prio[PRIO_HYPHEN_RULES] = priority;
	}
	if (tagPtr->wrapMode != TEXT_WRAPMODE_NULL && priority > prio[PRIO_WRAP]) {
	    /* assert(tagPtr->wrapMode < 8); always true due to range */
	    styleValues.wrapMode = tagPtr->wrapMode;
	    prio[PRIO_WRAP] = priority;
	}
    }

    /*
     * Use an existing style if there's one around that matches.
     */








|

<

<
|
<

<

|





<

|

<

|

<

|

<

|

<

|

<

|


<

|

<

|

<

|

<

|

<

|

<






|

<

|

<

|

<

|

<

|

<

|

<

|


<

|

<

|

<

|

<






|

<

|

<

|

<

|


<







1884
1885
1886
1887
1888
1889
1890
1891
1892

1893

1894

1895

1896
1897
1898
1899
1900
1901
1902

1903
1904
1905

1906
1907
1908

1909
1910
1911

1912
1913
1914

1915
1916
1917

1918
1919
1920
1921

1922
1923
1924

1925
1926
1927

1928
1929
1930

1931
1932
1933

1934
1935
1936

1937
1938
1939
1940
1941
1942
1943
1944

1945
1946
1947

1948
1949
1950

1951
1952
1953

1954
1955
1956

1957
1958
1959

1960
1961
1962
1963

1964
1965
1966

1967
1968
1969

1970
1971
1972

1973
1974
1975
1976
1977
1978
1979
1980

1981
1982
1983

1984
1985
1986

1987
1988
1989
1990

1991
1992
1993
1994
1995
1996
1997
	    }
	    if (tagPtr->selFgColor != None) {
		fgColor = tagPtr->selFgColor;
	    } else if (fgColor == None) {
		fgColor = textPtr->selFgColorPtr;
	    }
	}
	if (border) {
	    styleValues.border = border;

	}

	if (tagPtr->borderWidthPtr && Tcl_GetString(tagPtr->borderWidthPtr)[0] != '\0') {

	    styleValues.borderWidth = tagPtr->borderWidth;

	}
	if (tagPtr->reliefPtr) {
	    if (!styleValues.border) {
		styleValues.border = textPtr->border;
	    }
	    assert(tagPtr->relief < 8);
	    styleValues.relief = tagPtr->relief;

	}
	if (tagPtr->bgStipple != None) {
	    styleValues.bgStipple = tagPtr->bgStipple;

	}
	if (tagPtr->indentBgString != None) {
	    styleValues.indentBg = tagPtr->indentBg;

	}
	if (fgColor != None) {
	    styleValues.fgColor = fgColor;

	}
	if (tagPtr->tkfont != None) {
	    styleValues.tkfont = tagPtr->tkfont;

	}
	if (tagPtr->fgStipple != None) {
	    styleValues.fgStipple = tagPtr->fgStipple;

	}
	if (tagPtr->justifyString) {
	    /* assert(tagPtr->justify < 8); always true due to range */
	    styleValues.justify = tagPtr->justify;

	}
	if (tagPtr->lMargin1String) {
	    styleValues.lMargin1 = tagPtr->lMargin1;

	}
	if (tagPtr->lMargin2String) {
	    styleValues.lMargin2 = tagPtr->lMargin2;

	}
	if (tagPtr->lMarginColor) {
	    styleValues.lMarginColor = tagPtr->lMarginColor;

	}
	if (tagPtr->offsetString) {
	    styleValues.offset = tagPtr->offset;

	}
	if (tagPtr->overstrikeString) {
	    styleValues.overstrike = tagPtr->overstrike;

            if (tagPtr->overstrikeColor != None) {
                 styleValues.overstrikeColor = tagPtr->overstrikeColor;
            } else if (fgColor != None) {
                 styleValues.overstrikeColor = fgColor;
            }
	}
	if (tagPtr->rMarginString) {
	    styleValues.rMargin = tagPtr->rMargin;

	}
	if (tagPtr->rMarginColor) {
	    styleValues.rMarginColor = tagPtr->rMarginColor;

	}
	if (tagPtr->spacing1String) {
	    styleValues.spacing1 = tagPtr->spacing1;

	}
	if (tagPtr->spacing2String) {
	    styleValues.spacing2 = tagPtr->spacing2;

	}
	if (tagPtr->spacing3String) {
	    styleValues.spacing3 = tagPtr->spacing3;

	}
	if (tagPtr->tabStringPtr) {
	    styleValues.tabArrayPtr = tagPtr->tabArrayPtr;

	}
	if (tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE) {
	    assert(tagPtr->tabStyle < 8);
	    styleValues.tabStyle = tagPtr->tabStyle;

	}
	if (tagPtr->eolColor) {
	    styleValues.eolColor = tagPtr->eolColor;

	}
	if (tagPtr->hyphenColor) {
	    styleValues.hyphenColor = tagPtr->hyphenColor;

	}
	if (tagPtr->underlineString) {
	    styleValues.underline = tagPtr->underline;

            if (tagPtr->underlineColor != None) {
		styleValues.underlineColor = tagPtr->underlineColor;
            } else if (fgColor != None) {
		styleValues.underlineColor = fgColor;
            }
	}
	if (tagPtr->elideString) {
	    styleValues.elide = tagPtr->elide;

	}
	if (tagPtr->langPtr) {
	    styleValues.lang = tagPtr->lang;

	}
	if (tagPtr->hyphenRulesPtr) {
	    styleValues.hyphenRules = tagPtr->hyphenRules;

	}
	if (tagPtr->wrapMode != TEXT_WRAPMODE_NULL) {
	    /* assert(tagPtr->wrapMode < 8); always true due to range */
	    styleValues.wrapMode = tagPtr->wrapMode;

	}
    }

    /*
     * Use an existing style if there's one around that matches.
     */

2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
static TextStyle *
GetStyle(
    TkText *textPtr,		/* Overall information about text widget. */
    TkTextSegment *segPtr)	/* The text for which display information is wanted. */
{
    TextStyle *stylePtr;
    TkTextTag *tagPtr;
    bool containsSelection;

    if (segPtr && (tagPtr = TkBTreeGetSegmentTags(
		    textPtr->sharedTextPtr, segPtr, textPtr, &containsSelection))) {
	stylePtr = MakeStyle(textPtr, tagPtr, containsSelection);
    } else {
	/*
	 * Take into account that this function can be called before UpdateDefaultStyle
	 * has been called for the first time.
	 */
	if (!textPtr->dInfoPtr->defaultStyle) {
	    UpdateDefaultStyle(textPtr);







|


|
|







2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
static TextStyle *
GetStyle(
    TkText *textPtr,		/* Overall information about text widget. */
    TkTextSegment *segPtr)	/* The text for which display information is wanted. */
{
    TextStyle *stylePtr;
    TkTextTag *tagPtr;
    int flags;

    if (segPtr && (tagPtr = TkBTreeGetSegmentTags(
		    textPtr->sharedTextPtr, segPtr, textPtr, TK_TEXT_SORT_ASCENDING, &flags))) {
	stylePtr = MakeStyle(textPtr, tagPtr, !!(flags & TK_TEXT_IS_SELECTED));
    } else {
	/*
	 * Take into account that this function can be called before UpdateDefaultStyle
	 * has been called for the first time.
	 */
	if (!textPtr->dInfoPtr->defaultStyle) {
	    UpdateDefaultStyle(textPtr);

Changes to generic/tkTextMark.c.

1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
    } else {
	TkTextIndexBackChars(textPtr, newCursorIndexPtr, 1, &index, COUNT_INDICES);
    }

    numTags = 0;
    tagArrayPtr = tagArrayBuffer;
    tagArraySize = sizeof(tagArrayBuffer)/sizeof(tagArrayBuffer[0]);
    tagPtr = TkBTreeGetTags(&index);
    for ( ; tagPtr; tagPtr = tagPtr->nextPtr) {
	if (numTags == tagArraySize) {
	    tagArraySize *= 2;
	    tagArrayPtr = realloc(tagArrayPtr == tagArrayBuffer ? NULL : tagArrayPtr, tagArraySize);
	}
	tagArrayPtr[numTags++] = tagPtr;
    }
    TkTextSortTags(numTags, tagArrayPtr);
    for (i = 0; i < numTags; ++i) {
	Tcl_DStringAppendElement(&buf, tagArrayPtr[i]->name);
    }
    if (tagArrayPtr != tagArrayBuffer) {
	free(tagArrayPtr);
    }








|







<







1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507

1508
1509
1510
1511
1512
1513
1514
    } else {
	TkTextIndexBackChars(textPtr, newCursorIndexPtr, 1, &index, COUNT_INDICES);
    }

    numTags = 0;
    tagArrayPtr = tagArrayBuffer;
    tagArraySize = sizeof(tagArrayBuffer)/sizeof(tagArrayBuffer[0]);
    tagPtr = TkBTreeGetTags(&index, TK_TEXT_SORT_ASCENDING, NULL);
    for ( ; tagPtr; tagPtr = tagPtr->nextPtr) {
	if (numTags == tagArraySize) {
	    tagArraySize *= 2;
	    tagArrayPtr = realloc(tagArrayPtr == tagArrayBuffer ? NULL : tagArrayPtr, tagArraySize);
	}
	tagArrayPtr[numTags++] = tagPtr;
    }

    for (i = 0; i < numTags; ++i) {
	Tcl_DStringAppendElement(&buf, tagArrayPtr[i]->name);
    }
    if (tagArrayPtr != tagArrayBuffer) {
	free(tagArrayPtr);
    }

Changes to generic/tkTextPriv.h.

659
660
661
662
663
664
665
666


667
668
669

670
671
672
673
674
675
676
 *
 *----------------------------------------------------------------------
 */

inline
TkTextTag *
TkBTreeGetTags(
    const TkTextIndex *indexPtr)/* Indicates a particular position in the B-tree. */


{
    const TkTextSegment *segPtr = TkTextIndexGetContentSegment(indexPtr, NULL);
    return TkBTreeGetSegmentTags(TkTextIndexGetShared(indexPtr), segPtr, indexPtr->textPtr, NULL);

}

/*
 *----------------------------------------------------------------------
 *
 * TkTextGetFirstChunkOfNextDispLine --
 *







|
>
>

<
|
>







659
660
661
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
677
678
 *
 *----------------------------------------------------------------------
 */

inline
TkTextTag *
TkBTreeGetTags(
    const TkTextIndex *indexPtr,	/* Indicates a particular position in the B-tree. */
    TkTextSortMethod sortMeth,		/* Sort tags according to this method. */
    int *flags)				/* Store flags from TkBTreeGetSegmentTags(), can be NULL. */
{

    return TkBTreeGetSegmentTags(TkTextIndexGetShared(indexPtr),
	    TkTextIndexGetContentSegment(indexPtr, NULL), indexPtr->textPtr, sortMeth, flags);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextGetFirstChunkOfNextDispLine --
 *

Changes to generic/tkTextTag.c.

1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595


1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
TkTextFindTags(
    Tcl_Interp *interp,		/* Current interpreter. */
    TkText *textPtr,		/* Info about overall widget. */
    const TkTextSegment *segPtr,/* Tags from this segment. */
    bool discardSelection)	/* "sel" tag will be discarded? */
{
    TkTextTag *tagPtr;
    TkTextTag **tagArray;
    unsigned count;

    assert(segPtr);

    tagArray = malloc(textPtr->sharedTextPtr->numEnabledTags * sizeof(TkTextTag *));
    tagPtr = TkBTreeGetSegmentTags(textPtr->sharedTextPtr, segPtr, textPtr, NULL);



    for (count = 0; tagPtr; tagPtr = tagPtr->nextPtr) {
	if (!discardSelection || tagPtr != textPtr->selTagPtr) {
	    tagArray[count++] = tagPtr;
	}
    }

    AppendTags(interp, count, tagArray);
    free(tagArray);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextTagChangedUndoRedo --
 *







|
<



<
|
>
>

|

|



|
<







1582
1583
1584
1585
1586
1587
1588
1589

1590
1591
1592

1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603

1604
1605
1606
1607
1608
1609
1610
TkTextFindTags(
    Tcl_Interp *interp,		/* Current interpreter. */
    TkText *textPtr,		/* Info about overall widget. */
    const TkTextSegment *segPtr,/* Tags from this segment. */
    bool discardSelection)	/* "sel" tag will be discarded? */
{
    TkTextTag *tagPtr;
    Tcl_Obj *listObj;


    assert(segPtr);


    tagPtr = TkBTreeGetSegmentTags(textPtr->sharedTextPtr, segPtr, textPtr,
	    TK_TEXT_SORT_ASCENDING, NULL);
    listObj = Tcl_NewObj();

    for ( ; tagPtr; tagPtr = tagPtr->nextPtr) {
	if (!discardSelection || tagPtr != textPtr->selTagPtr) {
	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewStringObj(tagPtr->name, -1));
	}
    }

    Tcl_SetObjResult(interp, listObj);

}

/*
 *----------------------------------------------------------------------
 *
 * TkTextTagChangedUndoRedo --
 *

Changes to win/tkWinDefault.h.

486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
#define DEF_TEXT_INSERT_UNFOCUSSED	"none"
#define DEF_TEXT_INSERT_WIDTH		"2"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"sunken"
#define DEF_TEXT_INACTIVE_SELECT_BG_COLOR NULL
#define DEF_TEXT_INACTIVE_SELECT_FG_COLOR TEXT_FG
#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"0"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	SELECT_FG
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"flat"







|







486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
#define DEF_TEXT_INSERT_UNFOCUSSED	"none"
#define DEF_TEXT_INSERT_WIDTH		"2"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"sunken"
#define DEF_TEXT_INACTIVE_SELECT_BG_COLOR NULL
#define DEF_TEXT_INACTIVE_SELECT_FG_COLOR NULL
#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"0"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	SELECT_FG
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"flat"