openbsd-ports/x11/tk/8.0/patches/patch-af
2000-03-27 02:25:16 +00:00

428 lines
14 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--- ../generic/tkTextDisp.c.orig Mon Sep 14 14:23:18 1998
+++ ../generic/tkTextDisp.c Wed Jan 5 23:20:56 2000
@@ -55,6 +55,7 @@
* be NULL). */
int underline; /* Non-zero means draw underline underneath
* text. */
+ int elide; /* Non-zero means draw text */
Tk_Uid wrapMode; /* How to handle wrap-around for this tag.
* One of tkTextCharUid, tkTextNoneUid,
* or tkTextWordUid. */
@@ -311,6 +312,21 @@
int x));
static void CharUndisplayProc _ANSI_ARGS_((TkText *textPtr,
TkTextDispChunk *chunkPtr));
+
+/*
+ Definitions of elided procs.
+ Compiler can't inline these since we use pointers to these functions.
+ ElideDisplayProc, ElideUndisplayProc special-cased for speed,
+ as potentially many elided DLine chunks if large, tag toggle-filled
+ elided region.
+*/
+static void ElideBboxProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,
+ int index, int y, int lineHeight, int baseline,
+ int *xPtr, int *yPtr, int *widthPtr,
+ int *heightPtr));
+static int ElideMeasureProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,
+ int x));
+
static void DisplayDLine _ANSI_ARGS_((TkText *textPtr,
DLine *dlPtr, DLine *prevPtr, Pixmap pixmap));
static void DisplayLineBackground _ANSI_ARGS_((TkText *textPtr,
@@ -479,7 +495,7 @@
int borderPrio, borderWidthPrio, reliefPrio, bgStipplePrio;
int fgPrio, fontPrio, fgStipplePrio;
- int underlinePrio, justifyPrio, offsetPrio;
+ int underlinePrio, elidePrio, justifyPrio, offsetPrio;
int lMargin1Prio, lMargin2Prio, rMarginPrio;
int spacing1Prio, spacing2Prio, spacing3Prio;
int overstrikePrio, tabPrio, wrapPrio;
@@ -494,7 +510,7 @@
tagPtrs = TkBTreeGetTags(indexPtr, &numTags);
borderPrio = borderWidthPrio = reliefPrio = bgStipplePrio = -1;
fgPrio = fontPrio = fgStipplePrio = -1;
- underlinePrio = justifyPrio = offsetPrio = -1;
+ underlinePrio = elidePrio = justifyPrio = offsetPrio = -1;
lMargin1Prio = lMargin2Prio = rMarginPrio = -1;
spacing1Prio = spacing2Prio = spacing3Prio = -1;
overstrikePrio = tabPrio = wrapPrio = -1;
@@ -612,6 +628,11 @@
styleValues.underline = tagPtr->underline;
underlinePrio = tagPtr->priority;
}
+ if ((tagPtr->elideString != NULL)
+ && (tagPtr->priority > elidePrio)) {
+ styleValues.elide = tagPtr->elide;
+ elidePrio = tagPtr->priority;
+ }
if ((tagPtr->wrapMode != NULL)
&& (tagPtr->priority > wrapPrio)) {
styleValues.wrapMode = tagPtr->wrapMode;
@@ -768,7 +789,7 @@
* lines with numChars > 0. Used to
* drop 0-sized chunks from the end
* of the line. */
- int offset, ascent, descent, code;
+ int offset, ascent, descent, code, elide, elidesize;
StyleValues *sValuePtr;
/*
@@ -786,6 +807,34 @@
dlPtr->nextPtr = NULL;
dlPtr->flags = NEW_LAYOUT;
+
+ /*
+ * special case entirely elide line as there may be 1000s or more
+ */
+ elide = TkTextIsElided(textPtr, indexPtr); /* save a malloc */
+ if (elide && indexPtr->charIndex==0) {
+ maxChars = 0;
+ for (segPtr = indexPtr->linePtr->segPtr; elide && segPtr!=NULL; segPtr = segPtr->nextPtr) {
+ if ((elidesize = segPtr->size) > 0) {
+ maxChars += elidesize;
+
+ /* if have tag toggle, chance that invisibility state changed, so bail out */
+ } else if (segPtr->typePtr == &tkTextToggleOffType || segPtr->typePtr == &tkTextToggleOnType) {
+ if (segPtr->body.toggle.tagPtr->elideString!=NULL) {
+ elide = (segPtr->typePtr == &tkTextToggleOffType) ^ (segPtr->body.toggle.tagPtr->elide==1);
+ }
+ }
+ }
+
+ if (elide) {
+ dlPtr->count = maxChars;
+ dlPtr->spaceAbove = dlPtr->spaceBelow = dlPtr->length = 0;
+ return dlPtr;
+ }
+ }
+
+
+
/*
* Each iteration of the loop below creates one TkTextDispChunk for
* the new display line. The line will always have at least one
@@ -797,6 +846,7 @@
lastChunkPtr = NULL;
chunkPtr = NULL;
noCharsYet = 1;
+ elide = 0;
breakChunkPtr = NULL;
breakCharOffset = 0;
justify = TK_JUSTIFY_LEFT;
@@ -821,6 +871,31 @@
}
while (segPtr != NULL) {
+
+ /* every line still gets at least one chunk due to expectations in rest of code,
+ but able to skip elided portions of line quickly */
+ /* if current chunk elided and last chunk was too, coalese */
+ if (elide && lastChunkPtr!=NULL && lastChunkPtr->displayProc == NULL/*ElideDisplayProc*/) {
+ if ((elidesize = segPtr->size - offset) > 0) {
+ curIndex.charIndex += elidesize;
+ lastChunkPtr->numChars += elidesize;
+ breakCharOffset = lastChunkPtr->breakIndex = lastChunkPtr->numChars;
+
+ /* if have tag toggle, chance that invisibility state changed */
+ } else if (segPtr->typePtr == &tkTextToggleOffType || segPtr->typePtr == &tkTextToggleOnType) {
+ if (segPtr->body.toggle.tagPtr->elideString!=NULL) {
+ elide = (segPtr->typePtr == &tkTextToggleOffType) ^ (segPtr->body.toggle.tagPtr->elide==1);
+ }
+ }
+
+ offset = 0;
+ segPtr = segPtr->nextPtr;
+ if (segPtr == NULL && chunkPtr != NULL) ckfree((char *) chunkPtr);
+
+ continue;
+ }
+
+
if (segPtr->typePtr->layoutProc == NULL) {
segPtr = segPtr->nextPtr;
offset = 0;
@@ -831,6 +906,7 @@
chunkPtr->nextPtr = NULL;
}
chunkPtr->stylePtr = GetStyle(textPtr, &curIndex);
+ elide = chunkPtr->stylePtr->sValuePtr->elide;
/*
* Save style information such as justification and indentation,
@@ -864,7 +940,7 @@
gotTab = 0;
maxChars = segPtr->size - offset;
- if (justify == TK_JUSTIFY_LEFT) {
+ if (!elide && justify == TK_JUSTIFY_LEFT) {
if (segPtr->typePtr == &tkTextCharType) {
char *p;
@@ -877,8 +953,21 @@
}
}
}
-
chunkPtr->x = x;
+ if (elide && maxChars) {
+ /* don't free style here, as other code expects to be able to do that */
+ /*breakCharOffset =*/ chunkPtr->breakIndex = chunkPtr->numChars = maxChars;
+ chunkPtr->width = 0;
+ chunkPtr->minAscent = chunkPtr->minDescent = chunkPtr->minHeight = 0;
+
+ /* would just like to point to canonical empty chunk */
+ chunkPtr->displayProc = (Tk_ChunkDisplayProc *) NULL;
+ chunkPtr->undisplayProc = (Tk_ChunkUndisplayProc *) NULL;
+ chunkPtr->measureProc = ElideMeasureProc;
+ chunkPtr->bboxProc = ElideBboxProc;
+
+ code = 1;
+ } else
code = (*segPtr->typePtr->layoutProc)(textPtr, &curIndex, segPtr,
offset, maxX-tabSize, maxChars, noCharsYet, wrapMode,
chunkPtr);
@@ -950,6 +1039,7 @@
offset = 0;
segPtr = segPtr->nextPtr;
}
+
chunkPtr = NULL;
}
if (noCharsYet) {
@@ -998,6 +1088,7 @@
wholeLine = 0;
}
+
/*
* Make tab adjustments for the last tab stop, if there is one.
*/
@@ -1321,6 +1412,7 @@
index.linePtr = TkBTreeFindLine(textPtr->tree, lineNum);
index.charIndex = 0;
lowestPtr = NULL;
+
do {
dlPtr = LayoutDLine(textPtr, &index);
dlPtr->nextPtr = lowestPtr;
@@ -1554,6 +1646,8 @@
Display *display;
int height, x;
+ if (dlPtr->chunkPtr == NULL) return;
+
/*
* First, clear the area of the line to the background color for the
* text widget.
@@ -1620,12 +1714,16 @@
* something is off to the right).
*/
+ if (chunkPtr->displayProc != NULL)
(*chunkPtr->displayProc)(chunkPtr, -chunkPtr->width,
dlPtr->spaceAbove,
dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, display, pixmap,
dlPtr->y + dlPtr->spaceAbove);
} else {
+ /* don't call if elide. This tax ok since not very many visible DLine's in
+ an area, but potentially many elide ones */
+ if (chunkPtr->displayProc != NULL)
(*chunkPtr->displayProc)(chunkPtr, x, dlPtr->spaceAbove,
dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, display, pixmap,
@@ -1714,6 +1812,7 @@
StyleValues *sValuePtr;
Display *display;
+
/*
* Pass 1: scan through dlPtr from left to right. For each range of
* chunks with the same style, draw the main background for the style
@@ -1787,7 +1886,7 @@
rightX = maxX;
}
chunkPtr2 = NULL;
- if (prevPtr != NULL) {
+ if (prevPtr != NULL && prevPtr->chunkPtr != NULL) {
/*
* Find the chunk in the previous line that covers leftX.
*/
@@ -1908,7 +2007,8 @@
rightX = maxX;
}
chunkPtr2 = NULL;
- if (dlPtr->nextPtr != NULL) {
+/* for (dlPtr2 = dlPtr; dlPtr2->nextPtr != NULL && dlPtr2->nextPtr->chunkPtr == NULL; dlPtr2 = dlPtr2->nextPtr) {}*/
+ if (dlPtr->nextPtr != NULL && dlPtr->nextPtr->chunkPtr != NULL) {
/*
* Find the chunk in the previous line that covers leftX.
*/
@@ -2299,6 +2399,7 @@
for (prevPtr = NULL, dlPtr = textPtr->dInfoPtr->dLinePtr;
(dlPtr != NULL) && (dlPtr->y < dInfoPtr->maxY);
prevPtr = dlPtr, dlPtr = dlPtr->nextPtr) {
+ if (dlPtr->chunkPtr == NULL) continue;
if (dlPtr->oldY != dlPtr->y) {
if (tkTextDebug) {
char string[TK_POS_CHARS];
@@ -2315,6 +2416,7 @@
dlPtr->oldY = dlPtr->y;
dlPtr->flags &= ~NEW_LAYOUT;
}
+ /*prevPtr = dlPtr;*/
}
Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap);
}
@@ -3369,6 +3471,7 @@
dlPtr = LayoutDLine(textPtr, &index);
dlPtr->nextPtr = lowestPtr;
lowestPtr = dlPtr;
+ if (dlPtr->length == 0 && dlPtr->height == 0) { offset--; break; } /* elide */
TkTextIndexForwChars(&index, dlPtr->count, &index);
charsToCount -= dlPtr->count;
} while ((charsToCount > 0)
@@ -3381,7 +3484,7 @@
break;
}
}
-
+
/*
* Discard the display lines, then either return or prepare
* for the next display line to lay out.
@@ -3410,12 +3513,14 @@
TkBTreeNumLines(textPtr->tree));
for (i = 0; i < offset; i++) {
dlPtr = LayoutDLine(textPtr, &textPtr->topIndex);
+ if (dlPtr->length == 0 && dlPtr->height == 0) offset++;
dlPtr->nextPtr = NULL;
TkTextIndexForwChars(&textPtr->topIndex, dlPtr->count, &new);
FreeDLines(textPtr, dlPtr, (DLine *) NULL, 0);
if (new.linePtr == lastLinePtr) {
break;
}
+
textPtr->topIndex = new;
}
}
@@ -3949,7 +4054,7 @@
* index of the character nearest to (x,y). */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
- register DLine *dlPtr;
+ register DLine *dlPtr, *validdlPtr;
register TkTextDispChunk *chunkPtr;
/*
@@ -3982,8 +4087,9 @@
* Find the display line containing the desired y-coordinate.
*/
- for (dlPtr = dInfoPtr->dLinePtr; y >= (dlPtr->y + dlPtr->height);
+ for (dlPtr = validdlPtr = dInfoPtr->dLinePtr; y >= (dlPtr->y + dlPtr->height);
dlPtr = dlPtr->nextPtr) {
+ if (dlPtr->chunkPtr !=NULL) validdlPtr = dlPtr;
if (dlPtr->nextPtr == NULL) {
/*
* Y-coordinate is off the bottom of the displayed text.
@@ -3994,6 +4100,8 @@
break;
}
}
+ if (dlPtr->chunkPtr == NULL) dlPtr = validdlPtr;
+
/*
* Scan through the line's chunks to find the one that contains
@@ -4005,12 +4113,12 @@
*indexPtr = dlPtr->index;
x = x - dInfoPtr->x + dInfoPtr->curPixelOffset;
for (chunkPtr = dlPtr->chunkPtr; x >= (chunkPtr->x + chunkPtr->width);
- indexPtr->charIndex += chunkPtr->numChars,
- chunkPtr = chunkPtr->nextPtr) {
+ indexPtr->charIndex += chunkPtr->numChars,
+ chunkPtr = chunkPtr->nextPtr) {
if (chunkPtr->nextPtr == NULL) {
indexPtr->charIndex += chunkPtr->numChars - 1;
return;
- }
+ }
}
/*
@@ -4166,6 +4274,7 @@
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
DLine *dlPtr;
+ int dlx;
/*
* Make sure that all of the screen layout information is up to date.
@@ -4184,8 +4293,9 @@
return -1;
}
- *xPtr = dInfoPtr->x - dInfoPtr->curPixelOffset + dlPtr->chunkPtr->x;
- *widthPtr = dlPtr->length - dlPtr->chunkPtr->x;
+ dlx = (dlPtr->chunkPtr != NULL? dlPtr->chunkPtr->x: 0);
+ *xPtr = dInfoPtr->x - dInfoPtr->curPixelOffset + dlx;
+ *widthPtr = dlPtr->length - dlx;
*yPtr = dlPtr->y;
if ((dlPtr->y + dlPtr->height) > dInfoPtr->maxY) {
*heightPtr = dInfoPtr->maxY - dlPtr->y;
@@ -4196,6 +4306,41 @@
return 0;
}
+static void
+ElideBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr,
+ widthPtr, heightPtr)
+ TkTextDispChunk *chunkPtr; /* Chunk containing desired char. */
+ int index; /* Index of desired character within
+ * the chunk. */
+ int y; /* Topmost pixel in area allocated
+ * for this line. */
+ int lineHeight; /* Height of line, in pixels. */
+ int baseline; /* Location of line's baseline, in
+ * pixels measured down from y. */
+ int *xPtr, *yPtr; /* Gets filled in with coords of
+ * character's upper-left pixel.
+ * X-coord is in same coordinate
+ * system as chunkPtr->x. */
+ int *widthPtr; /* Gets filled in with width of
+ * character, in pixels. */
+ int *heightPtr; /* Gets filled in with height of
+ * character, in pixels. */
+{
+ *xPtr = chunkPtr->x;
+ *yPtr = y;
+ *widthPtr = *heightPtr = 0;
+}
+
+
+static int
+ElideMeasureProc(chunkPtr, x)
+ TkTextDispChunk *chunkPtr; /* Chunk containing desired coord. */
+ int x; /* X-coordinate, in same coordinate
+ * system as chunkPtr->x. */
+{
+ return 0 /*chunkPtr->numChars - 1*/;
+}
+
/*
*--------------------------------------------------------------
*
@@ -4421,7 +4566,7 @@
* Draw the text, underline, and overstrike for this chunk.
*/
- if (ciPtr->numChars > offsetChars) {
+ if (!sValuePtr->elide && ciPtr->numChars > offsetChars) {
int numChars = ciPtr->numChars - offsetChars;
char *string = ciPtr->chars + offsetChars;