summaryrefslogtreecommitdiffstats
path: root/generic/tkTextDisp.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkTextDisp.c')
-rw-r--r--generic/tkTextDisp.c874
1 files changed, 548 insertions, 326 deletions
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index 1f39112..095bb5e 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -16,7 +16,7 @@
#include "tkInt.h"
#include "tkText.h"
-#ifdef __WIN32__
+#ifdef _WIN32
#include "tkWinInt.h"
#elif defined(__CYGWIN__)
#include "tkUnixInt.h"
@@ -136,11 +136,15 @@ typedef struct StyleValues {
* line of each text line. */
int lMargin2; /* Left margin, in pixels, for second and
* later display lines of each text line. */
+ Tk_3DBorder lMarginColor; /* Color of left margins (1 and 2). */
int offset; /* Offset in pixels of baseline, relative to
* baseline of line. */
int overstrike; /* Non-zero means draw overstrike through
* text. */
+ XColor *overstrikeColor; /* Foreground color for overstrike through
+ * text. */
int rMargin; /* Right margin, in pixels. */
+ Tk_3DBorder rMarginColor; /* Color of right margin. */
int spacing1; /* Spacing above first dline in text line. */
int spacing2; /* Spacing between lines of dline. */
int spacing3; /* Spacing below last dline in text line. */
@@ -149,6 +153,8 @@ typedef struct StyleValues {
int tabStyle; /* One of TABULAR or WORDPROCESSOR. */
int underline; /* Non-zero means draw underline underneath
* text. */
+ XColor *underlineColor; /* Foreground color for underline underneath
+ * text. */
int elide; /* Zero means draw text, otherwise not. */
TkWrapMode wrapMode; /* How to handle wrap-around for this tag.
* One of TEXT_WRAPMODE_CHAR,
@@ -167,6 +173,8 @@ typedef struct TextStyle {
GC bgGC; /* Graphics context for background. None means
* use widget background. */
GC fgGC; /* Graphics context for foreground. */
+ GC ulGC; /* Graphics context for underline. */
+ GC ovGC; /* Graphics context for overstrike. */
StyleValues *sValuePtr; /* Raw information from which GCs were
* derived. */
Tcl_HashEntry *hPtr; /* Pointer to entry in styleTable. Used to
@@ -234,6 +242,14 @@ typedef struct DLine {
int spaceBelow; /* How much extra space was added to the
* bottom of the line because of spacing
* options. This is included in height. */
+ Tk_3DBorder lMarginColor; /* Background color of the area corresponding
+ * to the left margin of the display line. */
+ int lMarginWidth; /* Pixel width of the area corresponding to
+ * the left margin. */
+ Tk_3DBorder rMarginColor; /* Background color of the area corresponding
+ * to the right margin of the display line. */
+ int rMarginWidth; /* Pixel width of the area corresponding to
+ * the right margin. */
int length; /* Total length of line, in pixels. */
TkTextDispChunk *chunkPtr; /* Pointer to first chunk in list of all of
* those that are displayed on this line of
@@ -416,8 +432,8 @@ typedef struct TextDInfo {
typedef struct CharInfo {
int numBytes; /* Number of bytes to display. */
- char chars[4]; /* UTF characters to display. Actual size will
- * be numBytes, not 4. THIS MUST BE THE LAST
+ char chars[1]; /* UTF characters to display. Actual size will
+ * be numBytes, not 1. THIS MUST BE THE LAST
* FIELD IN THE STRUCTURE. */
} CharInfo;
@@ -447,6 +463,7 @@ typedef struct BaseCharInfo {
* LayoutDLine(). */
} BaseCharInfo;
+/* TODO: Thread safety */
static TkTextDispChunk *baseCharChunkPtr = NULL;
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
@@ -544,23 +561,23 @@ static void DisplayLineBackground(TkText *textPtr, DLine *dlPtr,
DLine *prevPtr, Pixmap pixmap);
static void DisplayText(ClientData clientData);
static DLine * FindDLine(TkText *textPtr, DLine *dlPtr,
- CONST TkTextIndex *indexPtr);
+ const TkTextIndex *indexPtr);
static void FreeDLines(TkText *textPtr, DLine *firstPtr,
DLine *lastPtr, int action);
static void FreeStyle(TkText *textPtr, TextStyle *stylePtr);
-static TextStyle * GetStyle(TkText *textPtr, CONST TkTextIndex *indexPtr);
+static TextStyle * GetStyle(TkText *textPtr, const TkTextIndex *indexPtr);
static void GetXView(Tcl_Interp *interp, TkText *textPtr,
int report);
static void GetYView(Tcl_Interp *interp, TkText *textPtr,
int report);
static int GetYPixelCount(TkText *textPtr, DLine *dlPtr);
static DLine * LayoutDLine(TkText *textPtr,
- CONST TkTextIndex *indexPtr);
-static int MeasureChars(Tk_Font tkfont, CONST char *source,
+ const TkTextIndex *indexPtr);
+static int MeasureChars(Tk_Font tkfont, const char *source,
int maxBytes, int rangeStart, int rangeLength,
int startX, int maxX, int flags, int *nextXPtr);
static void MeasureUp(TkText *textPtr,
- CONST TkTextIndex *srcPtr, int distance,
+ const TkTextIndex *srcPtr, int distance,
TkTextIndex *dstPtr, int *overlap);
static int NextTabStop(Tk_Font tkfont, int x, int tabOrigin);
static void UpdateDisplayInfo(TkText *textPtr);
@@ -570,8 +587,8 @@ static int SizeOfTab(TkText *textPtr, int tabStyle,
TkTextTabArray *tabArrayPtr, int *indexPtr, int x,
int maxX);
static void TextChanged(TkText *textPtr,
- CONST TkTextIndex *index1Ptr,
- CONST TkTextIndex *index2Ptr);
+ const TkTextIndex *index1Ptr,
+ const TkTextIndex *index2Ptr);
static void TextInvalidateRegion(TkText *textPtr, TkRegion region);
static void TextRedrawTag(TkText *textPtr,
TkTextIndex *index1Ptr, TkTextIndex *index2Ptr,
@@ -579,7 +596,7 @@ static void TextRedrawTag(TkText *textPtr,
static void TextInvalidateLineMetrics(TkText *textPtr,
TkTextLine *linePtr, int lineCount, int action);
static int CalculateDisplayLineHeight(TkText *textPtr,
- CONST TkTextIndex *indexPtr, int *byteCountPtr,
+ const TkTextIndex *indexPtr, int *byteCountPtr,
int *mergedLinePtr);
static void DlineIndexOfX(TkText *textPtr,
DLine *dlPtr, int x, TkTextIndex *indexPtr);
@@ -587,9 +604,10 @@ static int DlineXOfIndex(TkText *textPtr,
DLine *dlPtr, int byteIndex);
static int TextGetScrollInfoObj(Tcl_Interp *interp,
TkText *textPtr, int objc,
- Tcl_Obj *CONST objv[], double *dblPtr,
+ Tcl_Obj *const objv[], double *dblPtr,
int *intPtr);
static void AsyncUpdateLineMetrics(ClientData clientData);
+static void GenerateWidgetViewSyncEvent(TkText *textPtr, Bool InSync);
static void AsyncUpdateYScrollbar(ClientData clientData);
static int IsStartOfNotMergedLine(TkText *textPtr,
CONST TkTextIndex *indexPtr);
@@ -629,7 +647,7 @@ TkTextCreateDInfo(
register TextDInfo *dInfoPtr;
XGCValues gcValues;
- dInfoPtr = (TextDInfo *) ckalloc(sizeof(TextDInfo));
+ dInfoPtr = ckalloc(sizeof(TextDInfo));
Tcl_InitHashTable(&dInfoPtr->styleTable, sizeof(StyleValues)/sizeof(int));
dInfoPtr->dLinePtr = NULL;
dInfoPtr->copyGC = None;
@@ -701,7 +719,7 @@ TkTextFreeDInfo(
}
Tk_FreeGC(textPtr->display, dInfoPtr->scrollGC);
if (dInfoPtr->flags & REDRAW_PENDING) {
- Tcl_CancelIdleCall(DisplayText, (ClientData) textPtr);
+ Tcl_CancelIdleCall(DisplayText, textPtr);
}
if (dInfoPtr->lineUpdateTimer != NULL) {
Tcl_DeleteTimerHandler(dInfoPtr->lineUpdateTimer);
@@ -713,7 +731,7 @@ TkTextFreeDInfo(
textPtr->refCount--;
dInfoPtr->scrollbarTimer = NULL;
}
- ckfree((char *) dInfoPtr);
+ ckfree(dInfoPtr);
}
/*
@@ -737,7 +755,7 @@ TkTextFreeDInfo(
static TextStyle *
GetStyle(
TkText *textPtr, /* Overall information about text widget. */
- CONST TkTextIndex *indexPtr)/* The character in the text for which display
+ const TkTextIndex *indexPtr)/* The character in the text for which display
* information is wanted. */
{
TkTextTag **tagPtrs;
@@ -746,6 +764,7 @@ GetStyle(
TextStyle *stylePtr;
Tcl_HashEntry *hPtr;
int numTags, isNew, i;
+ int isSelected;
XGCValues gcValues;
unsigned long mask;
/*
@@ -756,6 +775,7 @@ GetStyle(
int fgPrio, fontPrio, fgStipplePrio;
int underlinePrio, elidePrio, justifyPrio, offsetPrio;
int lMargin1Prio, lMargin2Prio, rMarginPrio;
+ int lMarginColorPrio, rMarginColorPrio;
int spacing1Prio, spacing2Prio, spacing3Prio;
int overstrikePrio, tabPrio, tabStylePrio, wrapPrio;
@@ -770,11 +790,14 @@ GetStyle(
fgPrio = fontPrio = fgStipplePrio = -1;
underlinePrio = elidePrio = justifyPrio = offsetPrio = -1;
lMargin1Prio = lMargin2Prio = rMarginPrio = -1;
+ lMarginColorPrio = rMarginColorPrio = -1;
spacing1Prio = spacing2Prio = spacing3Prio = -1;
overstrikePrio = tabPrio = tabStylePrio = wrapPrio = -1;
memset(&styleValues, 0, sizeof(StyleValues));
styleValues.relief = TK_RELIEF_FLAT;
styleValues.fgColor = textPtr->fgColor;
+ styleValues.underlineColor = textPtr->fgColor;
+ styleValues.overstrikeColor = textPtr->fgColor;
styleValues.tkfont = textPtr->tkfont;
styleValues.justify = TK_JUSTIFY_LEFT;
styleValues.spacing1 = textPtr->spacing1;
@@ -784,12 +807,22 @@ GetStyle(
styleValues.tabStyle = textPtr->tabStyle;
styleValues.wrapMode = textPtr->wrapMode;
styleValues.elide = 0;
+ isSelected = 0;
+
+ for (i = 0 ; i < numTags; i++) {
+ if (textPtr->selTagPtr == tagPtrs[i]) {
+ isSelected = 1;
+ break;
+ }
+ }
for (i = 0 ; i < numTags; i++) {
Tk_3DBorder border;
+ XColor *fgColor;
tagPtr = tagPtrs[i];
border = tagPtr->border;
+ fgColor = tagPtr->fgColor;
/*
* If this is the selection tag, and inactiveSelBorder is NULL (the
@@ -809,6 +842,14 @@ GetStyle(
border = textPtr->inactiveSelBorder;
}
+ if ((tagPtr->selBorder != NULL) && (isSelected)) {
+ border = tagPtr->selBorder;
+ }
+
+ if ((tagPtr->selFgColor != None) && (isSelected)) {
+ fgColor = tagPtr->selFgColor;
+ }
+
if ((border != NULL) && (tagPtr->priority > borderPrio)) {
styleValues.border = border;
borderPrio = tagPtr->priority;
@@ -832,8 +873,8 @@ GetStyle(
styleValues.bgStipple = tagPtr->bgStipple;
bgStipplePrio = tagPtr->priority;
}
- if ((tagPtr->fgColor != None) && (tagPtr->priority > fgPrio)) {
- styleValues.fgColor = tagPtr->fgColor;
+ if ((fgColor != None) && (tagPtr->priority > fgPrio)) {
+ styleValues.fgColor = fgColor;
fgPrio = tagPtr->priority;
}
if ((tagPtr->tkfont != None) && (tagPtr->priority > fontPrio)) {
@@ -860,6 +901,11 @@ GetStyle(
styleValues.lMargin2 = tagPtr->lMargin2;
lMargin2Prio = tagPtr->priority;
}
+ if ((tagPtr->lMarginColor != NULL)
+ && (tagPtr->priority > lMarginColorPrio)) {
+ styleValues.lMarginColor = tagPtr->lMarginColor;
+ lMarginColorPrio = tagPtr->priority;
+ }
if ((tagPtr->offsetString != NULL)
&& (tagPtr->priority > offsetPrio)) {
styleValues.offset = tagPtr->offset;
@@ -869,12 +915,22 @@ GetStyle(
&& (tagPtr->priority > overstrikePrio)) {
styleValues.overstrike = tagPtr->overstrike;
overstrikePrio = tagPtr->priority;
+ if (tagPtr->overstrikeColor != None) {
+ styleValues.overstrikeColor = tagPtr->overstrikeColor;
+ } else if (fgColor != None) {
+ styleValues.overstrikeColor = fgColor;
+ }
}
if ((tagPtr->rMarginString != NULL)
&& (tagPtr->priority > rMarginPrio)) {
styleValues.rMargin = tagPtr->rMargin;
rMarginPrio = tagPtr->priority;
}
+ if ((tagPtr->rMarginColor != NULL)
+ && (tagPtr->priority > rMarginColorPrio)) {
+ styleValues.rMarginColor = tagPtr->rMarginColor;
+ rMarginColorPrio = tagPtr->priority;
+ }
if ((tagPtr->spacing1String != NULL)
&& (tagPtr->priority > spacing1Prio)) {
styleValues.spacing1 = tagPtr->spacing1;
@@ -904,6 +960,11 @@ GetStyle(
&& (tagPtr->priority > underlinePrio)) {
styleValues.underline = tagPtr->underline;
underlinePrio = tagPtr->priority;
+ if (tagPtr->underlineColor != None) {
+ styleValues.underlineColor = tagPtr->underlineColor;
+ } else if (fgColor != None) {
+ styleValues.underlineColor = fgColor;
+ }
}
if ((tagPtr->elideString != NULL)
&& (tagPtr->priority > elidePrio)) {
@@ -917,7 +978,7 @@ GetStyle(
}
}
if (tagPtrs != NULL) {
- ckfree((char *) tagPtrs);
+ ckfree(tagPtrs);
}
/*
@@ -927,7 +988,7 @@ GetStyle(
hPtr = Tcl_CreateHashEntry(&textPtr->dInfoPtr->styleTable,
(char *) &styleValues, &isNew);
if (!isNew) {
- stylePtr = (TextStyle *) Tcl_GetHashValue(hPtr);
+ stylePtr = Tcl_GetHashValue(hPtr);
stylePtr->refCount++;
return stylePtr;
}
@@ -936,7 +997,7 @@ GetStyle(
* No existing style matched. Make a new one.
*/
- stylePtr = (TextStyle *) ckalloc(sizeof(TextStyle));
+ stylePtr = ckalloc(sizeof(TextStyle));
stylePtr->refCount = 1;
if (styleValues.border != NULL) {
gcValues.foreground = Tk_3DBorderColor(styleValues.border)->pixel;
@@ -960,6 +1021,11 @@ GetStyle(
mask |= GCStipple|GCFillStyle;
}
stylePtr->fgGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues);
+ mask = GCForeground;
+ gcValues.foreground = styleValues.underlineColor->pixel;
+ stylePtr->ulGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues);
+ gcValues.foreground = styleValues.overstrikeColor->pixel;
+ stylePtr->ovGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues);
stylePtr->sValuePtr = (StyleValues *)
Tcl_GetHashKey(&textPtr->dInfoPtr->styleTable, hPtr);
stylePtr->hPtr = hPtr;
@@ -1000,8 +1066,14 @@ FreeStyle(
if (stylePtr->fgGC != None) {
Tk_FreeGC(textPtr->display, stylePtr->fgGC);
}
+ if (stylePtr->ulGC != None) {
+ Tk_FreeGC(textPtr->display, stylePtr->ulGC);
+ }
+ if (stylePtr->ovGC != None) {
+ Tk_FreeGC(textPtr->display, stylePtr->ovGC);
+ }
Tcl_DeleteHashEntry(stylePtr->hPtr);
- ckfree((char *) stylePtr);
+ ckfree(stylePtr);
}
}
@@ -1042,7 +1114,7 @@ FreeStyle(
static DLine *
LayoutDLine(
TkText *textPtr, /* Overall information about text widget. */
- CONST TkTextIndex *indexPtr)/* Beginning of display line. May not
+ const TkTextIndex *indexPtr)/* Beginning of display line. May not
* necessarily point to a character
* segment. */
{
@@ -1100,7 +1172,7 @@ LayoutDLine(
* Create and initialize a new DLine structure.
*/
- dlPtr = (DLine *) ckalloc(sizeof(DLine));
+ dlPtr = ckalloc(sizeof(DLine));
dlPtr->index = *indexPtr;
dlPtr->byteCount = 0;
dlPtr->y = 0;
@@ -1111,6 +1183,10 @@ LayoutDLine(
dlPtr->nextPtr = NULL;
dlPtr->flags = NEW_LAYOUT | OLD_Y_INVALID;
dlPtr->logicalLinesMerged = 0;
+ dlPtr->lMarginColor = NULL;
+ dlPtr->lMarginWidth = 0;
+ dlPtr->rMarginColor = NULL;
+ dlPtr->rMarginWidth = 0;
/*
* This is not necessarily totally correct, where we have merged logical
@@ -1260,14 +1336,14 @@ LayoutDLine(
*/
TkTextLine *linePtr = TkBTreeNextLine(NULL, curIndex.linePtr);
- if (linePtr != NULL) {
- dlPtr->logicalLinesMerged++;
- curIndex.byteIndex = 0;
- curIndex.linePtr = linePtr;
- segPtr = curIndex.linePtr->segPtr;
- } else {
+ if (linePtr == NULL) {
break;
}
+
+ dlPtr->logicalLinesMerged++;
+ curIndex.byteIndex = 0;
+ curIndex.linePtr = linePtr;
+ segPtr = curIndex.linePtr->segPtr;
}
}
@@ -1331,7 +1407,7 @@ LayoutDLine(
* into a single display line.
*
if (segPtr == NULL && chunkPtr != NULL) {
- ckfree((char *) chunkPtr);
+ ckfree(chunkPtr);
chunkPtr = NULL;
}
*/
@@ -1345,7 +1421,7 @@ LayoutDLine(
continue;
}
if (chunkPtr == NULL) {
- chunkPtr = (TkTextDispChunk *) ckalloc(sizeof(TkTextDispChunk));
+ chunkPtr = ckalloc(sizeof(TkTextDispChunk));
chunkPtr->nextPtr = NULL;
chunkPtr->clientData = NULL;
}
@@ -1385,6 +1461,7 @@ LayoutDLine(
x = chunkPtr->stylePtr->sValuePtr->lMargin2;
}
+ dlPtr->lMarginWidth = x;
if (wrapMode == TEXT_WRAPMODE_NONE) {
maxX = -1;
} else {
@@ -1454,7 +1531,7 @@ LayoutDLine(
code = 1;
} else {
- code = (*segPtr->typePtr->layoutProc)(textPtr, &curIndex, segPtr,
+ code = segPtr->typePtr->layoutProc(textPtr, &curIndex, segPtr,
byteOffset, maxX-tabSize, maxBytes, noCharsYet, wrapMode,
chunkPtr);
}
@@ -1477,7 +1554,7 @@ LayoutDLine(
*/
if (chunkPtr != NULL) {
- ckfree((char *) chunkPtr);
+ ckfree(chunkPtr);
}
break;
}
@@ -1606,18 +1683,18 @@ LayoutDLine(
FreeStyle(textPtr, chunkPtr->stylePtr);
breakChunkPtr->nextPtr = chunkPtr->nextPtr;
if (chunkPtr->undisplayProc != NULL) {
- (*chunkPtr->undisplayProc)(textPtr, chunkPtr);
+ chunkPtr->undisplayProc(textPtr, chunkPtr);
}
- ckfree((char *) chunkPtr);
+ ckfree(chunkPtr);
}
if (breakByteOffset != breakChunkPtr->numBytes) {
if (breakChunkPtr->undisplayProc != NULL) {
- (*breakChunkPtr->undisplayProc)(textPtr, breakChunkPtr);
+ breakChunkPtr->undisplayProc(textPtr, breakChunkPtr);
}
segPtr = TkTextIndexToSeg(&breakIndex, &byteOffset);
- (*segPtr->typePtr->layoutProc)(textPtr, &breakIndex,
- segPtr, byteOffset, maxX, breakByteOffset, 0,
- wrapMode, breakChunkPtr);
+ segPtr->typePtr->layoutProc(textPtr, &breakIndex, segPtr,
+ byteOffset, maxX, breakByteOffset, 0, wrapMode,
+ breakChunkPtr);
#if TK_LAYOUT_WITH_BASE_CHUNKS
FinalizeBaseChunk(NULL);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
@@ -1696,6 +1773,11 @@ LayoutDLine(
}
dlPtr->height += dlPtr->spaceAbove + dlPtr->spaceBelow;
dlPtr->baseline += dlPtr->spaceAbove;
+ dlPtr->lMarginColor = sValuePtr->lMarginColor;
+ dlPtr->rMarginColor = sValuePtr->rMarginColor;
+ if (wrapMode != TEXT_WRAPMODE_NONE) {
+ dlPtr->rMarginWidth = rMargin;
+ }
/*
* Recompute line length: may have changed because of justification.
@@ -2302,13 +2384,13 @@ FreeDLines(
for (chunkPtr = firstPtr->chunkPtr; chunkPtr != NULL;
chunkPtr = nextChunkPtr) {
if (chunkPtr->undisplayProc != NULL) {
- (*chunkPtr->undisplayProc)(textPtr, chunkPtr);
+ chunkPtr->undisplayProc(textPtr, chunkPtr);
}
FreeStyle(textPtr, chunkPtr->stylePtr);
nextChunkPtr = chunkPtr->nextPtr;
- ckfree((char *) chunkPtr);
+ ckfree(chunkPtr);
}
- ckfree((char *) firstPtr);
+ ckfree(firstPtr);
firstPtr = nextDLinePtr;
}
if (action != DLINE_FREE_TEMP) {
@@ -2382,12 +2464,26 @@ DisplayDLine(
Tk_Width(textPtr->tkwin), dlPtr->height, 0, TK_RELIEF_FLAT);
/*
- * Next, draw background information for the whole line.
+ * Second, draw background information for the whole line.
*/
DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap);
/*
+ * Third, draw the background color of the left and right margins.
+ */
+ if (dlPtr->lMarginColor != NULL) {
+ Tk_Fill3DRectangle(textPtr->tkwin, pixmap, dlPtr->lMarginColor, 0, y,
+ dlPtr->lMarginWidth + dInfoPtr->x - dInfoPtr->curXPixelOffset,
+ dlPtr->height, 0, TK_RELIEF_FLAT);
+ }
+ if (dlPtr->rMarginColor != NULL) {
+ Tk_Fill3DRectangle(textPtr->tkwin, pixmap, dlPtr->rMarginColor,
+ dInfoPtr->maxX - dlPtr->rMarginWidth + dInfoPtr->curXPixelOffset,
+ y, dlPtr->rMarginWidth, dlPtr->height, 0, TK_RELIEF_FLAT);
+ }
+
+ /*
* Make another pass through all of the chunks to redraw the insertion
* cursor, if it is visible on this line. Must do it here rather than in
* the foreground pass below because otherwise a wide insertion cursor
@@ -2400,7 +2496,7 @@ DisplayDLine(
if (chunkPtr->displayProc == TkTextInsertDisplayProc) {
int x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curXPixelOffset;
- (*chunkPtr->displayProc)(textPtr, chunkPtr, x,
+ chunkPtr->displayProc(textPtr, chunkPtr, x,
y + dlPtr->spaceAbove,
dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, display, pixmap,
@@ -2448,7 +2544,7 @@ DisplayDLine(
x = -chunkPtr->width;
}
- (*chunkPtr->displayProc)(textPtr, chunkPtr, x,
+ chunkPtr->displayProc(textPtr, chunkPtr, x,
y + dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove -
dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove,
display, pixmap, dlPtr->y + dlPtr->spaceAbove);
@@ -2897,7 +2993,7 @@ static void
AsyncUpdateLineMetrics(
ClientData clientData) /* Information about widget. */
{
- register TkText *textPtr = (TkText *) clientData;
+ register TkText *textPtr = clientData;
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
int lineNum;
@@ -2909,8 +3005,8 @@ AsyncUpdateLineMetrics(
* The widget has been deleted, or is not mapped. Don't do anything.
*/
- if (--textPtr->refCount == 0) {
- ckfree((char *) textPtr);
+ if (textPtr->refCount-- <= 1) {
+ ckfree(textPtr);
}
return;
}
@@ -2921,6 +3017,11 @@ AsyncUpdateLineMetrics(
return;
}
+ /*
+ * Reify where we end or all hell breaks loose with the calculations when
+ * we try to update. [Bug 2677890]
+ */
+
lineNum = dInfoPtr->currentMetricUpdateLine;
if (dInfoPtr->lastMetricUpdateLine == -1) {
dInfoPtr->lastMetricUpdateLine =
@@ -2935,6 +3036,8 @@ AsyncUpdateLineMetrics(
lineNum = TkTextUpdateLineMetrics(textPtr, lineNum,
dInfoPtr->lastMetricUpdateLine, 256);
+ dInfoPtr->currentMetricUpdateLine = lineNum;
+
if (tkTextDebug) {
char buffer[2 * TCL_INTEGER_SPACE + 1];
@@ -2952,16 +3055,36 @@ AsyncUpdateLineMetrics(
/*
* We have looped over all lines, so we're done. We must release our
* refCount on the widget (the timer token was already set to NULL
- * above).
+ * above). If there is a registered aftersync command, run that first.
*/
- textPtr->refCount--;
- if (textPtr->refCount == 0) {
- ckfree((char *) textPtr);
+ if (textPtr->afterSyncCmd) {
+ int code;
+ Tcl_Preserve((ClientData) textPtr->interp);
+ code = Tcl_EvalObjEx(textPtr->interp, textPtr->afterSyncCmd,
+ TCL_EVAL_GLOBAL);
+ if (code == TCL_ERROR) {
+ Tcl_AddErrorInfo(textPtr->interp, "\n (text sync)");
+ Tcl_BackgroundError(textPtr->interp);
+ }
+ Tcl_Release((ClientData) textPtr->interp);
+ Tcl_DecrRefCount(textPtr->afterSyncCmd);
+ textPtr->afterSyncCmd = NULL;
+ }
+
+ /*
+ * Fire the <<WidgetViewSync>> event since the widget view is in sync
+ * with its internal data (actually it will be after the next trip
+ * through the event loop, because the widget redraws at idle-time).
+ */
+
+ GenerateWidgetViewSyncEvent(textPtr, 1);
+
+ if (textPtr->refCount-- <= 1) {
+ ckfree(textPtr);
}
return;
}
- dInfoPtr->currentMetricUpdateLine = lineNum;
/*
* Re-arm the timer. We already have a refCount on the text widget so no
@@ -2969,7 +3092,37 @@ AsyncUpdateLineMetrics(
*/
dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
- AsyncUpdateLineMetrics, (ClientData) textPtr);
+ AsyncUpdateLineMetrics, textPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateWidgetViewSyncEvent --
+ *
+ * Send the <<WidgetViewSync>> event related to the text widget
+ * line metrics asynchronous update.
+ * This is equivalent to:
+ * event generate $textWidget <<WidgetViewSync>> -data $s
+ * where $s is the sync status: true (when the widget view is in
+ * sync with its internal data) or false (when it is not).
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * If corresponding bindings are present, they will trigger.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GenerateWidgetViewSyncEvent(
+ TkText *textPtr, /* Information about text widget. */
+ Bool InSync) /* true if in sync, false otherwise */
+{
+ TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
+ Tcl_NewBooleanObj(InSync));
}
/*
@@ -3070,86 +3223,82 @@ TkTextUpdateLineMetrics(
*/
if (TkBTreeLinePixelEpoch(textPtr, linePtr)
- != textPtr->dInfoPtr->lineMetricUpdateEpoch) {
- if (doThisMuch == -1) {
- count += 8 * TkTextUpdateOneLine(textPtr, linePtr, 0,
- NULL, 0);
- } else {
- TkTextIndex index;
- TkTextIndex *indexPtr;
- int pixelHeight;
+ == textPtr->dInfoPtr->lineMetricUpdateEpoch) {
+ /*
+ * This line is already up to date. That means there's nothing
+ * to do here.
+ */
+ } else if (doThisMuch == -1) {
+ count += 8 * TkTextUpdateOneLine(textPtr, linePtr, 0,NULL,0);
+ } else {
+ TkTextIndex index;
+ TkTextIndex *indexPtr;
+ int pixelHeight;
+ /*
+ * If the metric epoch is the same as the widget's epoch, then
+ * we know that indexPtrs are still valid, and if the cached
+ * metricIndex (if any) is for the same line as we wish to
+ * examine, then we are looking at a long line wrapped many
+ * times, which we will examine in pieces.
+ */
+
+ if (textPtr->dInfoPtr->metricEpoch ==
+ textPtr->sharedTextPtr->stateEpoch &&
+ textPtr->dInfoPtr->metricIndex.linePtr==linePtr) {
+ indexPtr = &textPtr->dInfoPtr->metricIndex;
+ pixelHeight = textPtr->dInfoPtr->metricPixelHeight;
+ } else {
/*
- * If the metric epoch is the same as the widget's epoch,
- * then we know that indexPtrs are still valid, and if the
- * cached metricIndex (if any) is for the same line as we
- * wish to examine, then we are looking at a long line
- * wrapped many times, which we will examine in pieces.
+ * We must reset the partial line height calculation data
+ * here, so we don't use it when it is out of date.
*/
- if (textPtr->dInfoPtr->metricEpoch ==
- textPtr->sharedTextPtr->stateEpoch &&
- textPtr->dInfoPtr->metricIndex.linePtr==linePtr) {
- indexPtr = &textPtr->dInfoPtr->metricIndex;
- pixelHeight = textPtr->dInfoPtr->metricPixelHeight;
- } else {
- /*
- * We must reset the partial line height calculation
- * data here, so we don't use it when it is out of
- * date.
- */
+ textPtr->dInfoPtr->metricEpoch = -1;
+ index.tree = textPtr->sharedTextPtr->tree;
+ index.linePtr = linePtr;
+ index.byteIndex = 0;
+ index.textPtr = NULL;
+ indexPtr = &index;
+ pixelHeight = 0;
+ }
- textPtr->dInfoPtr->metricEpoch = -1;
- index.tree = textPtr->sharedTextPtr->tree;
- index.linePtr = linePtr;
- index.byteIndex = 0;
- index.textPtr = NULL;
- indexPtr = &index;
- pixelHeight = 0;
- }
+ /*
+ * Update the line and update the counter, counting 8 for each
+ * display line we actually re-layout.
+ */
+
+ count += 8 * TkTextUpdateOneLine(textPtr, linePtr,
+ pixelHeight, indexPtr, 1);
+ if (indexPtr->linePtr == linePtr) {
/*
- * Update the line and update the counter, counting 8 for
- * each display line we actually re-layout.
+ * We didn't complete the logical line, because it
+ * produced very many display lines, which must be because
+ * it must be a long line wrapped many times. So we must
+ * cache as far as we got for next time around.
*/
- count += 8 * TkTextUpdateOneLine(textPtr, linePtr,
- pixelHeight, indexPtr, 1);
-
- if (indexPtr->linePtr == linePtr) {
- /*
- * We didn't complete the logical line, because it
- * produced very many display lines - it must be a
- * long line wrapped many times. So we must cache as
- * far as we got for next time around.
- */
-
- if (pixelHeight == 0) {
- /*
- * These have already been stored, unless we just
- * started the new line.
- */
-
- textPtr->dInfoPtr->metricIndex = index;
- textPtr->dInfoPtr->metricEpoch =
- textPtr->sharedTextPtr->stateEpoch;
- }
- textPtr->dInfoPtr->metricPixelHeight =
- TkBTreeLinePixelCount(textPtr, linePtr);
- break;
- } else {
+ if (pixelHeight == 0) {
/*
- * We're done with this long line.
+ * These have already been stored, unless we just
+ * started the new line.
*/
- textPtr->dInfoPtr->metricEpoch = -1;
+ textPtr->dInfoPtr->metricIndex = index;
+ textPtr->dInfoPtr->metricEpoch =
+ textPtr->sharedTextPtr->stateEpoch;
}
+ textPtr->dInfoPtr->metricPixelHeight =
+ TkBTreeLinePixelCount(textPtr, linePtr);
+ break;
}
- } else {
+
/*
- * This line is already up to date. That means there's nothing
- * to do here.
+ * We're done with this long line.
*/
+
+ textPtr->dInfoPtr->metricEpoch = -1;
}
} else {
/*
@@ -3350,7 +3499,8 @@ TextInvalidateLineMetrics(
if (dInfoPtr->lineUpdateTimer == NULL) {
textPtr->refCount++;
dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
- AsyncUpdateLineMetrics, (ClientData) textPtr);
+ AsyncUpdateLineMetrics, textPtr);
+ GenerateWidgetViewSyncEvent(textPtr, 0);
}
}
@@ -3400,6 +3550,8 @@ TkTextFindDisplayLineEnd(
* of the original index within its display
* line. */
{
+ TkTextIndex index;
+
if (!end && IsStartOfNotMergedLine(textPtr, indexPtr)) {
/*
* Nothing to do.
@@ -3409,96 +3561,94 @@ TkTextFindDisplayLineEnd(
*xOffset = 0;
}
return;
- } else {
- TkTextIndex index = *indexPtr;
-
- index.byteIndex = 0;
- index.textPtr = NULL;
-
- while (1) {
- TkTextIndex endOfLastLine;
+ }
- if (TkTextIndexBackBytes(textPtr, &index, 1, &endOfLastLine)) {
- /*
- * Reached beginning of text.
- */
+ index = *indexPtr;
+ index.byteIndex = 0;
+ index.textPtr = NULL;
- break;
- }
+ while (1) {
+ TkTextIndex endOfLastLine;
- if (!TkTextIsElided(textPtr, &endOfLastLine, NULL)) {
- /*
- * The eol is not elided, so 'index' points to the start of a
- * display line (as well as logical line).
- */
+ if (TkTextIndexBackBytes(textPtr, &index, 1, &endOfLastLine)) {
+ /*
+ * Reached beginning of text.
+ */
- break;
- }
+ break;
+ }
+ if (!TkTextIsElided(textPtr, &endOfLastLine, NULL)) {
/*
- * indexPtr's logical line is actually merged with the previous
- * logical line whose eol is elided. Continue searching back to
- * get a real line start.
+ * The eol is not elided, so 'index' points to the start of a
+ * display line (as well as logical line).
*/
- index = endOfLastLine;
- index.byteIndex = 0;
+ break;
}
- while (1) {
- DLine *dlPtr;
- int byteCount;
- TkTextIndex nextLineStart;
+ /*
+ * indexPtr's logical line is actually merged with the previous
+ * logical line whose eol is elided. Continue searching back to get a
+ * real line start.
+ */
- dlPtr = LayoutDLine(textPtr, &index);
- byteCount = dlPtr->byteCount;
+ index = endOfLastLine;
+ index.byteIndex = 0;
+ }
+
+ while (1) {
+ DLine *dlPtr;
+ int byteCount;
+ TkTextIndex nextLineStart;
+
+ dlPtr = LayoutDLine(textPtr, &index);
+ byteCount = dlPtr->byteCount;
+
+ TkTextIndexForwBytes(textPtr, &index, byteCount, &nextLineStart);
- TkTextIndexForwBytes(textPtr, &index, byteCount, &nextLineStart);
+ /*
+ * 'byteCount' goes up to the beginning of the next display line, so
+ * equality here says we need one more line. We try to perform a quick
+ * comparison which is valid for the case where the logical line is
+ * the same, but otherwise fall back on a full TkTextIndexCmp.
+ */
+ if (((index.linePtr == indexPtr->linePtr)
+ && (index.byteIndex + byteCount > indexPtr->byteIndex))
+ || (dlPtr->logicalLinesMerged > 0
+ && TkTextIndexCmp(&nextLineStart, indexPtr) > 0)) {
/*
- * 'byteCount' goes up to the beginning of the next display line,
- * so equality here says we need one more line. We try to perform
- * a quick comparison which is valid for the case where the
- * logical line is the same, but otherwise fall back on a full
- * TkTextIndexCmp.
+ * It's on this display line.
*/
- if (((index.linePtr == indexPtr->linePtr)
- && (index.byteIndex + byteCount > indexPtr->byteIndex))
- || (dlPtr->logicalLinesMerged > 0
- && TkTextIndexCmp(&nextLineStart, indexPtr) > 0)) {
+ if (xOffset != NULL) {
/*
- * It's on this display line.
+ * This call takes a byte index relative to the start of the
+ * current _display_ line, not logical line. We are about to
+ * overwrite indexPtr->byteIndex, so we must do this now.
*/
- if (xOffset != NULL) {
- /*
- * This call takes a byte index relative to the start of
- * the current _display_ line, not logical line. We are
- * about to overwrite indexPtr->byteIndex, so we must do
- * this now.
- */
-
- *xOffset = DlineXOfIndex(textPtr, dlPtr,
- TkTextIndexCountBytes(textPtr, &dlPtr->index,
- indexPtr));
- }
- if (end) {
- /*
- * The index we want is one less than the number of bytes
- * in the display line.
- */
+ *xOffset = DlineXOfIndex(textPtr, dlPtr,
+ TkTextIndexCountBytes(textPtr, &dlPtr->index,
+ indexPtr));
+ }
+ if (end) {
+ /*
+ * The index we want is one less than the number of bytes in
+ * the display line.
+ */
- TkTextIndexBackBytes(textPtr, &nextLineStart, 1, indexPtr);
- } else {
- *indexPtr = index;
- }
- FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP);
- return;
+ TkTextIndexBackBytes(textPtr, &nextLineStart, 1, indexPtr);
+ } else {
+ *indexPtr = index;
}
FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP);
- index = nextLineStart;
+ return;
}
+
+ FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP);
+ index = nextLineStart;
}
}
@@ -3540,7 +3690,7 @@ TkTextFindDisplayLineEnd(
static int
CalculateDisplayLineHeight(
TkText *textPtr, /* Widget record for text widget. */
- CONST TkTextIndex *indexPtr,/* The index at the beginning of the display
+ const TkTextIndex *indexPtr,/* The index at the beginning of the display
* line of interest. */
int *byteCountPtr, /* NULL or used to return the number of byte
* indices on the given display line. */
@@ -3632,7 +3782,7 @@ CalculateDisplayLineHeight(
int
TkTextIndexYPixels(
TkText *textPtr, /* Widget record for text widget. */
- CONST TkTextIndex *indexPtr)/* The index of which we want the pixel
+ const TkTextIndex *indexPtr)/* The index of which we want the pixel
* distance from top of logical line to top of
* index. */
{
@@ -3925,7 +4075,7 @@ TkTextUpdateOneLine(
if (textPtr->dInfoPtr->scrollbarTimer == NULL) {
textPtr->refCount++;
textPtr->dInfoPtr->scrollbarTimer = Tcl_CreateTimerHandler(200,
- AsyncUpdateYScrollbar, (ClientData) textPtr);
+ AsyncUpdateYScrollbar, textPtr);
}
return displayLines;
}
@@ -3951,7 +4101,7 @@ static void
DisplayText(
ClientData clientData) /* Information about widget. */
{
- register TkText *textPtr = (TkText *) clientData;
+ register TkText *textPtr = clientData;
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
register DLine *dlPtr;
DLine *prevPtr;
@@ -3969,8 +4119,8 @@ DisplayText(
TkWindow *winPtr = (TkWindow *)(textPtr->tkwin);
MacDrawable *macWin = winPtr->privatePtr;
if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
- dInfoPtr->flags &= ~REDRAW_PENDING;
- return;
+ dInfoPtr->flags &= ~REDRAW_PENDING;
+ return;
}
#endif
@@ -3983,7 +4133,7 @@ DisplayText(
}
interp = textPtr->interp;
- Tcl_Preserve((ClientData) interp);
+ Tcl_Preserve(interp);
if (tkTextDebug) {
Tcl_SetVar2(interp, "tk_textRelayout", NULL, "", TCL_GLOBAL_ONLY);
@@ -4012,8 +4162,8 @@ DisplayText(
textPtr->refCount++;
dInfoPtr->flags &= ~REPICK_NEEDED;
TkTextPickCurrent(textPtr, &textPtr->pickEvent);
- if (--textPtr->refCount == 0) {
- ckfree((char *) textPtr);
+ if (textPtr->refCount-- <= 1) {
+ ckfree(textPtr);
goto end;
}
if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
@@ -4093,7 +4243,7 @@ DisplayText(
*/
if ((y + height) > dInfoPtr->maxY) {
- height = dInfoPtr->maxY -y;
+ height = dInfoPtr->maxY - y;
}
oldY = dlPtr->oldY;
if (y < dInfoPtr->y) {
@@ -4148,8 +4298,9 @@ DisplayText(
if (TkScrollWindow(textPtr->tkwin, dInfoPtr->scrollGC, dInfoPtr->x,
oldY, dInfoPtr->maxX-dInfoPtr->x, height, 0, y-oldY,
damageRgn)) {
+#ifndef MAC_OSX_TK
TextInvalidateRegion(textPtr, damageRgn);
-
+#endif
}
numCopies++;
TkDestroyRegion(damageRgn);
@@ -4406,7 +4557,7 @@ DisplayText(
}
end:
- Tcl_Release((ClientData) interp);
+ Tcl_Release(interp);
}
/*
@@ -4435,7 +4586,7 @@ TkTextEventuallyRepick(
dInfoPtr->flags |= REPICK_NEEDED;
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
dInfoPtr->flags |= REDRAW_PENDING;
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
}
@@ -4479,7 +4630,7 @@ TkTextRedrawRegion(
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
dInfoPtr->flags |= REDRAW_PENDING;
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
TkDestroyRegion(damageRgn);
}
@@ -4573,8 +4724,8 @@ void
TkTextChanged(
TkSharedText *sharedTextPtr,/* Shared widget section, or NULL. */
TkText *textPtr, /* Widget record for text widget, or NULL. */
- CONST TkTextIndex*index1Ptr,/* Index of first character to redisplay. */
- CONST TkTextIndex*index2Ptr)/* Index of character just after last one to
+ const TkTextIndex*index1Ptr,/* Index of first character to redisplay. */
+ const TkTextIndex*index2Ptr)/* Index of character just after last one to
* redisplay. */
{
if (sharedTextPtr == NULL) {
@@ -4591,8 +4742,8 @@ TkTextChanged(
static void
TextChanged(
TkText *textPtr, /* Widget record for text widget, or NULL. */
- CONST TkTextIndex*index1Ptr,/* Index of first character to redisplay. */
- CONST TkTextIndex*index2Ptr)/* Index of character just after last one to
+ const TkTextIndex*index1Ptr,/* Index of first character to redisplay. */
+ const TkTextIndex*index2Ptr)/* Index of character just after last one to
* redisplay. */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
@@ -4618,7 +4769,7 @@ TextChanged(
*/
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
@@ -4855,7 +5006,7 @@ TextRedrawTag(
*/
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
@@ -4959,7 +5110,7 @@ TkTextRelayoutWindow(
*/
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
dInfoPtr->flags |= REDRAW_PENDING|REDRAW_BORDERS|DINFO_OUT_OF_DATE
|REPICK_NEEDED;
@@ -5054,7 +5205,8 @@ TkTextRelayoutWindow(
if (dInfoPtr->lineUpdateTimer == NULL) {
textPtr->refCount++;
dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
- AsyncUpdateLineMetrics, (ClientData) textPtr);
+ AsyncUpdateLineMetrics, textPtr);
+ GenerateWidgetViewSyncEvent(textPtr, 0);
}
}
}
@@ -5253,7 +5405,7 @@ TkTextSetYView(
scheduleUpdate:
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
}
@@ -5343,7 +5495,7 @@ TkTextMeasureDown(
static void
MeasureUp(
TkText *textPtr, /* Text widget in which to measure. */
- CONST TkTextIndex *srcPtr, /* Index of character from which to start
+ const TkTextIndex *srcPtr, /* Index of character from which to start
* measuring. */
int distance, /* Vertical distance in pixels measured from
* the pixel just below the lowest one in
@@ -5462,7 +5614,7 @@ TkTextSeeCmd(
TkText *textPtr, /* Information about text widget. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already
+ Tcl_Obj *const objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
* objv[1] is "see". */
{
@@ -5542,7 +5694,7 @@ TkTextSeeCmd(
*/
if (chunkPtr != NULL) {
- (*chunkPtr->bboxProc)(textPtr, chunkPtr, byteCount,
+ chunkPtr->bboxProc(textPtr, chunkPtr, byteCount,
dlPtr->y + dlPtr->spaceAbove,
dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, &x, &y, &width,
@@ -5551,27 +5703,26 @@ TkTextSeeCmd(
oneThird = lineWidth/3;
if (delta < 0) {
if (delta < -oneThird) {
- dInfoPtr->newXPixelOffset = (x - lineWidth/2);
+ dInfoPtr->newXPixelOffset = x - lineWidth/2;
} else {
- dInfoPtr->newXPixelOffset -= ((-delta) );
+ dInfoPtr->newXPixelOffset += delta;
}
} else {
- delta -= (lineWidth - width);
- if (delta > 0) {
- if (delta > oneThird) {
- dInfoPtr->newXPixelOffset = (x - lineWidth/2);
- } else {
- dInfoPtr->newXPixelOffset += (delta );
- }
- } else {
+ delta -= lineWidth - width;
+ if (delta <= 0) {
return TCL_OK;
}
+ if (delta > oneThird) {
+ dInfoPtr->newXPixelOffset = x - lineWidth/2;
+ } else {
+ dInfoPtr->newXPixelOffset += delta;
+ }
}
}
dInfoPtr->flags |= DINFO_OUT_OF_DATE;
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
dInfoPtr->flags |= REDRAW_PENDING;
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
return TCL_OK;
}
@@ -5599,7 +5750,7 @@ TkTextXviewCmd(
TkText *textPtr, /* Information about text widget. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already
+ Tcl_Obj *const objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
* objv[1] is "xview". */
{
@@ -5652,7 +5803,7 @@ TkTextXviewCmd(
dInfoPtr->flags |= DINFO_OUT_OF_DATE;
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
dInfoPtr->flags |= REDRAW_PENDING;
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
return TCL_OK;
}
@@ -5737,7 +5888,7 @@ YScrollByPixels(
return;
}
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
}
@@ -5872,7 +6023,7 @@ YScrollByLines(
scheduleUpdate:
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
}
@@ -5900,7 +6051,7 @@ TkTextYviewCmd(
TkText *textPtr, /* Information about text widget. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already
+ Tcl_Obj *const objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
* objv[1] is "yview". */
{
@@ -5926,7 +6077,7 @@ TkTextYviewCmd(
pickPlace = 0;
if (Tcl_GetString(objv[2])[0] == '-') {
- register CONST char *switchStr =
+ register const char *switchStr =
Tcl_GetStringFromObj(objv[2], &switchLength);
if ((switchLength >= 2) && (strncmp(switchStr, "-pickplace",
@@ -6061,6 +6212,35 @@ TkTextYviewCmd(
/*
*--------------------------------------------------------------
*
+ * TkTextPendingsync --
+ *
+ * This function checks if any line heights are not up-to-date.
+ *
+ * Results:
+ * Returns a boolean true if it is the case, or false if all line
+ * heights are up-to-date.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+Bool
+TkTextPendingsync(
+ TkText *textPtr) /* Information about text widget. */
+{
+ TextDInfo *dInfoPtr = textPtr->dInfoPtr;
+
+ return (
+ ((dInfoPtr->metricEpoch == -1) &&
+ (dInfoPtr->lastMetricUpdateLine == dInfoPtr->currentMetricUpdateLine)) ?
+ 0 : 1);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
* TkTextScanCmd --
*
* This function is invoked to process the "scan" option for the widget
@@ -6081,7 +6261,7 @@ TkTextScanCmd(
register TkText *textPtr, /* Information about text widget. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already
+ Tcl_Obj *const objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
* objv[1] is "scan". */
{
@@ -6152,7 +6332,7 @@ TkTextScanCmd(
dInfoPtr->flags |= DINFO_OUT_OF_DATE;
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
dInfoPtr->flags |= REDRAW_PENDING;
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
} else if (c=='m' && strncmp(Tcl_GetString(objv[2]), "mark", length)==0) {
dInfoPtr->scanMarkXPixel = dInfoPtr->newXPixelOffset;
@@ -6160,8 +6340,11 @@ TkTextScanCmd(
dInfoPtr->scanTotalYScroll = 0;
dInfoPtr->scanMarkY = y;
} else {
- Tcl_AppendResult(interp, "bad scan option \"", Tcl_GetString(objv[2]),
- "\": must be mark or dragto", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad scan option \"%s\": must be mark or dragto",
+ Tcl_GetString(objv[2])));
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "scan option",
+ Tcl_GetString(objv[2]), NULL);
return TCL_ERROR;
}
return TCL_OK;
@@ -6234,16 +6417,22 @@ GetXView(
if (textPtr->xScrollCmd != NULL) {
char buf1[TCL_DOUBLE_SPACE+1];
char buf2[TCL_DOUBLE_SPACE+1];
+ Tcl_DString buf;
buf1[0] = ' ';
buf2[0] = ' ';
Tcl_PrintDouble(NULL, first, buf1+1);
Tcl_PrintDouble(NULL, last, buf2+1);
- code = Tcl_VarEval(interp, textPtr->xScrollCmd, buf1, buf2, NULL);
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, textPtr->xScrollCmd, -1);
+ Tcl_DStringAppend(&buf, buf1, -1);
+ Tcl_DStringAppend(&buf, buf2, -1);
+ code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
+ Tcl_DStringFree(&buf);
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (horizontal scrolling command executed by text)");
- Tcl_BackgroundError(interp);
+ Tcl_BackgroundException(interp, code);
}
}
}
@@ -6362,9 +6551,8 @@ GetYPixelCount(
notFirst = 1;
}
break;
- } else {
- dlPtr = dlPtr->nextPtr;
}
+ dlPtr = dlPtr->nextPtr;
} while (dlPtr->index.linePtr == linePtr);
return count;
@@ -6514,16 +6702,22 @@ GetYView(
if (textPtr->yScrollCmd != NULL) {
char buf1[TCL_DOUBLE_SPACE+1];
char buf2[TCL_DOUBLE_SPACE+1];
+ Tcl_DString buf;
buf1[0] = ' ';
buf2[0] = ' ';
Tcl_PrintDouble(NULL, first, buf1+1);
Tcl_PrintDouble(NULL, last, buf2+1);
- code = Tcl_VarEval(interp, textPtr->yScrollCmd, buf1, buf2, NULL);
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, textPtr->yScrollCmd, -1);
+ Tcl_DStringAppend(&buf, buf1, -1);
+ Tcl_DStringAppend(&buf, buf2, -1);
+ code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
+ Tcl_DStringFree(&buf);
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (vertical scrolling command executed by text)");
- Tcl_BackgroundError(interp);
+ Tcl_BackgroundException(interp, code);
}
}
}
@@ -6550,7 +6744,7 @@ static void
AsyncUpdateYScrollbar(
ClientData clientData) /* Information about widget. */
{
- register TkText *textPtr = (TkText *) clientData;
+ register TkText *textPtr = clientData;
textPtr->dInfoPtr->scrollbarTimer = NULL;
@@ -6558,8 +6752,8 @@ AsyncUpdateYScrollbar(
GetYView(textPtr->interp, textPtr, 1);
}
- if (--textPtr->refCount == 0) {
- ckfree((char *) textPtr);
+ if (textPtr->refCount-- <= 1) {
+ ckfree(textPtr);
}
}
@@ -6587,7 +6781,7 @@ FindDLine(
TkText *textPtr, /* Widget record for text widget. */
register DLine *dlPtr, /* Pointer to first in list of DLines to
* search. */
- CONST TkTextIndex *indexPtr)/* Index of desired character. */
+ const TkTextIndex *indexPtr)/* Index of desired character. */
{
DLine *dlPtrPrev;
TkTextIndex indexPtr2;
@@ -6797,25 +6991,26 @@ TkTextPixelIndex(
}
*indexPtr = textPtr->topIndex;
return;
- } else {
- 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. Use
- * the last character on the last line.
- */
+ }
+ 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. Use the
+ * last character on the last line.
+ */
- x = dInfoPtr->maxX - 1;
- nearby = 1;
- break;
- }
+ x = dInfoPtr->maxX - 1;
+ nearby = 1;
+ break;
}
- if (dlPtr->chunkPtr == NULL) dlPtr = validDlPtr;
+ }
+ if (dlPtr->chunkPtr == NULL) {
+ dlPtr = validDlPtr;
}
if (nearest != NULL) {
@@ -6913,7 +7108,7 @@ DlineIndexOfX(
*/
if (chunkPtr->numBytes > 1) {
- indexPtr->byteIndex += (*chunkPtr->measureProc)(chunkPtr, x);
+ indexPtr->byteIndex += chunkPtr->measureProc(chunkPtr, x);
}
}
@@ -6988,7 +7183,7 @@ DlineXOfIndex(
int x = 0;
if (byteIndex == 0 || chunkPtr == NULL) {
- return 0;
+ return x;
}
/*
@@ -7001,15 +7196,14 @@ DlineXOfIndex(
if (byteIndex < chunkPtr->numBytes) {
int y, width, height;
- (*chunkPtr->bboxProc)(textPtr, chunkPtr, byteIndex,
+ chunkPtr->bboxProc(textPtr, chunkPtr, byteIndex,
dlPtr->y + dlPtr->spaceAbove,
dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, &x, &y, &width,
&height);
break;
- } else {
- byteIndex -= chunkPtr->numBytes;
}
+ byteIndex -= chunkPtr->numBytes;
if (chunkPtr->nextPtr == NULL || byteIndex == 0) {
x = chunkPtr->x + chunkPtr->width;
break;
@@ -7043,7 +7237,7 @@ DlineXOfIndex(
int
TkTextIndexBbox(
TkText *textPtr, /* Widget record for text widget. */
- CONST TkTextIndex *indexPtr,/* Index whose bounding box is desired. */
+ const TkTextIndex *indexPtr,/* Index whose bounding box is desired. */
int *xPtr, int *yPtr, /* Filled with index's upper-left
* coordinate. */
int *widthPtr, int *heightPtr,
@@ -7072,7 +7266,7 @@ TkTextIndexBbox(
dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr);
- /*
+ /*
* Two cases shall be trapped here because the logic later really
* needs dlPtr to be the display line containing indexPtr:
* 1. if no display line contains the desired index (NULL dlPtr)
@@ -7110,7 +7304,7 @@ TkTextIndexBbox(
* coordinate on the screen. Translate it to reflect horizontal scrolling.
*/
- (*chunkPtr->bboxProc)(textPtr, chunkPtr, byteCount,
+ chunkPtr->bboxProc(textPtr, chunkPtr, byteCount,
dlPtr->y + dlPtr->spaceAbove,
dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, xPtr, yPtr, widthPtr,
@@ -7189,7 +7383,7 @@ TkTextIndexBbox(
int
TkTextDLineInfo(
TkText *textPtr, /* Widget record for text widget. */
- CONST TkTextIndex *indexPtr,/* Index of character whose bounding box is
+ const TkTextIndex *indexPtr,/* Index of character whose bounding box is
* desired. */
int *xPtr, int *yPtr, /* Filled with line's upper-left
* coordinate. */
@@ -7216,7 +7410,7 @@ TkTextDLineInfo(
dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr);
- /*
+ /*
* Two cases shall be trapped here because the logic later really
* needs dlPtr to be the display line containing indexPtr:
* 1. if no display line contains the desired index (NULL dlPtr)
@@ -7348,6 +7542,9 @@ TkTextCharLayoutProc(
* (b) at least one pixel of the character is visible, we have not
* already exceeded the character limit, and the next character is a
* white space character.
+ * In the specific case of 'word' wrapping mode however, include all space
+ * characters following the characters that fit in the space we've got,
+ * even if no pixel of them is visible.
*/
p = segPtr->body.chars + byteOffset;
@@ -7356,22 +7553,22 @@ TkTextCharLayoutProc(
#if TK_LAYOUT_WITH_BASE_CHUNKS
if (baseCharChunkPtr == NULL) {
baseCharChunkPtr = chunkPtr;
- bciPtr = (BaseCharInfo *) ckalloc(sizeof(BaseCharInfo));
+ bciPtr = ckalloc(sizeof(BaseCharInfo));
baseString = &bciPtr->baseChars;
Tcl_DStringInit(baseString);
bciPtr->width = 0;
ciPtr = &bciPtr->ci;
} else {
- bciPtr = (BaseCharInfo *) baseCharChunkPtr->clientData;
- ciPtr = (CharInfo *) ckalloc(sizeof(CharInfo));
+ bciPtr = baseCharChunkPtr->clientData;
+ ciPtr = ckalloc(sizeof(CharInfo));
baseString = &bciPtr->baseChars;
}
lineOffset = Tcl_DStringLength(baseString);
line = Tcl_DStringAppend(baseString,p,maxBytes);
- chunkPtr->clientData = (ClientData) ciPtr;
+ chunkPtr->clientData = ciPtr;
ciPtr->baseChunkPtr = baseCharChunkPtr;
ciPtr->baseOffset = lineOffset;
ciPtr->chars = NULL;
@@ -7387,8 +7584,8 @@ TkTextCharLayoutProc(
if (bytesThatFit < maxBytes) {
if ((bytesThatFit == 0) && noCharsYet) {
- Tcl_UniChar ch;
- int chLen = Tcl_UtfToUniChar(p, &ch);
+ int ch;
+ int chLen = TkUtfToUniChar(p, &ch);
#if TK_LAYOUT_WITH_BASE_CHUNKS
bytesThatFit = CharChunkMeasureChars(chunkPtr, line,
@@ -7410,6 +7607,21 @@ TkTextCharLayoutProc(
nextX = maxX;
bytesThatFit++;
}
+ if (wrapMode == TEXT_WRAPMODE_WORD) {
+ while (p[bytesThatFit] == ' ') {
+ /*
+ * Space characters that would go at the beginning of the
+ * next line are allocated to the current line. This gives
+ * the effect of trimming white spaces that would otherwise
+ * be seen at the beginning of wrapped lines.
+ * Note that testing for '\t' is useless here because the
+ * chunk always includes at most one trailing \t, see
+ * LayoutDLine.
+ */
+
+ bytesThatFit++;
+ }
+ }
if (p[bytesThatFit] == '\n') {
/*
* A newline character takes up no space, so if the previous
@@ -7427,7 +7639,7 @@ TkTextCharLayoutProc(
} else {
Tcl_DStringSetLength(baseString,lineOffset);
}
- ckfree((char *) ciPtr);
+ ckfree(ciPtr);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
return 0;
}
@@ -7453,9 +7665,8 @@ TkTextCharLayoutProc(
chunkPtr->breakIndex = -1;
#if !TK_LAYOUT_WITH_BASE_CHUNKS
- ciPtr = (CharInfo *)
- ckalloc((unsigned) bytesThatFit + Tk_Offset(CharInfo, chars) + 1);
- chunkPtr->clientData = (ClientData) ciPtr;
+ ciPtr = ckalloc((Tk_Offset(CharInfo, chars) + 1) + bytesThatFit);
+ chunkPtr->clientData = ciPtr;
memcpy(ciPtr->chars, p, (unsigned) bytesThatFit);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
@@ -7493,11 +7704,21 @@ TkTextCharLayoutProc(
} else {
for (count = bytesThatFit, p += bytesThatFit - 1; count > 0;
count--, p--) {
- if (UCHAR(*p) < 0x80 && isspace(UCHAR(*p))) {
+ /*
+ * Don't use isspace(); effects are unpredictable and can lead to
+ * odd word-wrapping problems on some platforms. Also don't use
+ * Tcl_UniCharIsSpace here either, as it identifies non-breaking
+ * spaces as places to break. What we actually want is only the
+ * ASCII space characters, so use them explicitly...
+ */
+
+ switch (*p) {
+ case '\t': case '\n': case '\v': case '\f': case '\r': case ' ':
chunkPtr->breakIndex = count;
- break;
+ goto checkForNextChunk;
}
}
+ checkForNextChunk:
if ((bytesThatFit + byteOffset) == segPtr->size) {
for (nextPtr = segPtr->nextPtr; nextPtr != NULL;
nextPtr = nextPtr->nextPtr) {
@@ -7557,7 +7778,7 @@ CharChunkMeasureChars(
* here. */
{
Tk_Font tkfont = chunkPtr->stylePtr->sValuePtr->tkfont;
- CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData;
+ CharInfo *ciPtr = chunkPtr->clientData;
#if !TK_LAYOUT_WITH_BASE_CHUNKS
if (chars == NULL) {
@@ -7570,7 +7791,7 @@ CharChunkMeasureChars(
return MeasureChars(tkfont, chars, charsLen, start, end-start,
startX, maxX, flags, nextXPtr);
-#else
+#else /* TK_LAYOUT_WITH_BASE_CHUNKS */
{
int xDisplacement;
int fit, bstart = start, bend = end;
@@ -7598,7 +7819,7 @@ CharChunkMeasureChars(
MeasureChars(tkfont, chars, charsLen, 0, bstart,
0, -1, 0, &widthUntilStart);
- xDisplacement = startX - widthUntilStart - chunkPtr->x;
+ xDisplacement = startX - widthUntilStart - ciPtr->baseChunkPtr->x;
}
fit = MeasureChars(tkfont, chars, charsLen, 0, bend,
@@ -7610,7 +7831,7 @@ CharChunkMeasureChars(
return fit - bstart;
}
}
-#endif
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
}
/*
@@ -7646,7 +7867,7 @@ CharDisplayProc(
int screenY) /* Y-coordinate in text window that
* corresponds to y. */
{
- CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData;
+ CharInfo *ciPtr = chunkPtr->clientData;
const char *string;
TextStyle *stylePtr;
StyleValues *sValuePtr;
@@ -7664,7 +7885,7 @@ CharDisplayProc(
}
#if TK_DRAW_IN_CONTEXT
- bciPtr = (BaseCharInfo *) ciPtr->baseChunkPtr->clientData;
+ bciPtr = ciPtr->baseChunkPtr->clientData;
numBytes = Tcl_DStringLength(&bciPtr->baseChars);
string = Tcl_DStringValue(&bciPtr->baseChars);
@@ -7727,7 +7948,7 @@ CharDisplayProc(
y + baseline - sValuePtr->offset);
if (sValuePtr->underline) {
- TkUnderlineCharsInContext(display, dst, stylePtr->fgGC,
+ TkUnderlineCharsInContext(display, dst, stylePtr->ulGC,
sValuePtr->tkfont, string, numBytes,
ciPtr->baseChunkPtr->x + xDisplacement,
y + baseline - sValuePtr->offset,
@@ -7737,7 +7958,7 @@ CharDisplayProc(
Tk_FontMetrics fm;
Tk_GetFontMetrics(sValuePtr->tkfont, &fm);
- TkUnderlineCharsInContext(display, dst, stylePtr->fgGC,
+ TkUnderlineCharsInContext(display, dst, stylePtr->ovGC,
sValuePtr->tkfont, string, numBytes,
ciPtr->baseChunkPtr->x + xDisplacement,
y + baseline - sValuePtr->offset
@@ -7754,7 +7975,7 @@ CharDisplayProc(
Tk_DrawChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, string,
numBytes, offsetX, y + baseline - sValuePtr->offset);
if (sValuePtr->underline) {
- Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
+ Tk_UnderlineChars(display, dst, stylePtr->ulGC, sValuePtr->tkfont,
string, offsetX,
y + baseline - sValuePtr->offset,
0, numBytes);
@@ -7764,7 +7985,7 @@ CharDisplayProc(
Tk_FontMetrics fm;
Tk_GetFontMetrics(sValuePtr->tkfont, &fm);
- Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
+ Tk_UnderlineChars(display, dst, stylePtr->ovGC, sValuePtr->tkfont,
string, offsetX,
y + baseline - sValuePtr->offset
- fm.descent - (fm.ascent * 3) / 10,
@@ -7797,7 +8018,7 @@ CharUndisplayProc(
TkText *textPtr, /* Overall information about text widget. */
TkTextDispChunk *chunkPtr) /* Chunk that is about to be freed. */
{
- CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData;
+ CharInfo *ciPtr = chunkPtr->clientData;
if (ciPtr) {
#if TK_LAYOUT_WITH_BASE_CHUNKS
@@ -7824,7 +8045,7 @@ CharUndisplayProc(
ciPtr->numBytes = 0;
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
- ckfree((char *) ciPtr);
+ ckfree(ciPtr);
chunkPtr->clientData = NULL;
}
}
@@ -7900,7 +8121,7 @@ CharBboxProc(
int *heightPtr) /* Gets filled in with height of character, in
* pixels. */
{
- CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData;
+ CharInfo *ciPtr = chunkPtr->clientData;
int maxX;
maxX = chunkPtr->width + chunkPtr->x;
@@ -8063,7 +8284,7 @@ AdjustForTab(
if (chunkPtr2->displayProc != CharDisplayProc) {
continue;
}
- ciPtr = (CharInfo *) chunkPtr2->clientData;
+ ciPtr = chunkPtr2->clientData;
for (p = ciPtr->chars, i = 0; i < ciPtr->numBytes; p++, i++) {
if (isdigit(UCHAR(*p))) {
gotDigit = 1;
@@ -8084,23 +8305,23 @@ AdjustForTab(
if (decimalChunkPtr != NULL) {
int curX;
- ciPtr = (CharInfo *) decimalChunkPtr->clientData;
+ ciPtr = decimalChunkPtr->clientData;
CharChunkMeasureChars(decimalChunkPtr, NULL, 0, 0, decimal,
decimalChunkPtr->x, -1, 0, &curX);
desired = tabX - (curX - x);
goto update;
- } else {
- /*
- * There wasn't a decimal point. Right justify the text.
- */
+ }
- width = 0;
- for (chunkPtr2 = chunkPtr->nextPtr; chunkPtr2 != NULL;
- chunkPtr2 = chunkPtr2->nextPtr) {
- width += chunkPtr2->width;
- }
- desired = tabX - width;
+ /*
+ * There wasn't a decimal point. Right justify the text.
+ */
+
+ width = 0;
+ for (chunkPtr2 = chunkPtr->nextPtr; chunkPtr2 != NULL;
+ chunkPtr2 = chunkPtr2->nextPtr) {
+ width += chunkPtr2->width;
}
+ desired = tabX - width;
/*
* Shift all of the chunks to the right so that the left edge is at the
@@ -8338,7 +8559,7 @@ NextTabStop(
static int
MeasureChars(
Tk_Font tkfont, /* Font in which to draw characters. */
- CONST char *source, /* Characters to be displayed. Need not be
+ const char *source, /* Characters to be displayed. Need not be
* NULL-terminated. */
int maxBytes, /* Maximum # of bytes to consider from
* source. */
@@ -8353,7 +8574,7 @@ MeasureChars(
* here. */
{
int curX, width, ch;
- CONST char *special, *end, *start;
+ const char *special, *end, *start;
ch = 0; /* lint. */
curX = startX;
@@ -8400,11 +8621,10 @@ MeasureChars(
break;
}
if (special < end) {
- if (ch == '\t') {
- start++;
- } else {
+ if (ch != '\t') {
break;
}
+ start++;
}
}
@@ -8445,19 +8665,19 @@ TextGetScrollInfoObj(
Tcl_Interp *interp, /* Used for error reporting. */
TkText *textPtr, /* Information about the text widget. */
int objc, /* # arguments for command. */
- Tcl_Obj *CONST objv[], /* Arguments for command. */
+ Tcl_Obj *const objv[], /* Arguments for command. */
double *dblPtr, /* Filled in with argument "moveto" option, if
* any. */
int *intPtr) /* Filled in with number of pages or lines or
* pixels to scroll, if any. */
{
- static CONST char *subcommands[] = {
+ static const char *const subcommands[] = {
"moveto", "scroll", NULL
};
enum viewSubcmds {
VIEW_MOVETO, VIEW_SCROLL
};
- static CONST char *units[] = {
+ static const char *const units[] = {
"units", "pages", "pixels", NULL
};
enum viewUnits {
@@ -8465,8 +8685,8 @@ TextGetScrollInfoObj(
};
int index;
- if (Tcl_GetIndexFromObj(interp, objv[2], subcommands, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], subcommands,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TKTEXT_SCROLL_ERROR;
}
@@ -8485,8 +8705,8 @@ TextGetScrollInfoObj(
Tcl_WrongNumArgs(interp, 3, objv, "number units|pages|pixels");
return TKTEXT_SCROLL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[4], units, "argument", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[4], units,
+ sizeof(char *), "argument", 0, &index) != TCL_OK) {
return TKTEXT_SCROLL_ERROR;
}
switch ((enum viewUnits) index) {
@@ -8564,7 +8784,7 @@ FinalizeBaseChunk(
if (chunkPtr->displayProc != CharDisplayProc) {
continue;
}
- ciPtr = (CharInfo *)chunkPtr->clientData;
+ ciPtr = chunkPtr->clientData;
if (ciPtr->baseChunkPtr != baseCharChunkPtr) {
break;
}
@@ -8581,7 +8801,7 @@ FinalizeBaseChunk(
}
if (addChunkPtr != NULL) {
- ciPtr = (CharInfo *)addChunkPtr->clientData;
+ ciPtr = addChunkPtr->clientData;
ciPtr->chars = baseChars + ciPtr->baseOffset;
#if TK_DRAW_IN_CONTEXT
@@ -8632,7 +8852,7 @@ FreeBaseChunk(
if (chunkPtr->undisplayProc != CharUndisplayProc) {
continue;
}
- ciPtr = (CharInfo *) chunkPtr->clientData;
+ ciPtr = chunkPtr->clientData;
if (ciPtr->baseChunkPtr != baseChunkPtr) {
break;
}
@@ -8641,7 +8861,9 @@ FreeBaseChunk(
ciPtr->chars = NULL;
}
- Tcl_DStringFree(&((BaseCharInfo *) baseChunkPtr->clientData)->baseChars);
+ if (baseChunkPtr) {
+ Tcl_DStringFree(&((BaseCharInfo *) baseChunkPtr->clientData)->baseChars);
+ }
}
/*
@@ -8750,14 +8972,14 @@ RemoveFromBaseChunk(
* Reinstitute this base chunk for re-layout.
*/
- ciPtr = (CharInfo *) chunkPtr->clientData;
+ ciPtr = chunkPtr->clientData;
baseCharChunkPtr = ciPtr->baseChunkPtr;
/*
* Remove the chunk data from the base chunk data.
*/
- bciPtr = (BaseCharInfo *) baseCharChunkPtr->clientData;
+ bciPtr = baseCharChunkPtr->clientData;
if ((ciPtr->baseOffset + ciPtr->numBytes)
!= Tcl_DStringLength(&bciPtr->baseChars)) {