summaryrefslogtreecommitdiffstats
path: root/generic/tkTextDisp.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkTextDisp.c')
-rw-r--r--generic/tkTextDisp.c653
1 files changed, 343 insertions, 310 deletions
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index 548e47e..b75a152 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"
@@ -415,8 +415,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;
@@ -446,6 +446,7 @@ typedef struct BaseCharInfo {
* LayoutDLine(). */
} BaseCharInfo;
+/* TODO: Thread safety */
static TkTextDispChunk *baseCharChunkPtr = NULL;
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
@@ -542,23 +543,23 @@ static void DisplayDLine(TkText *textPtr, DLine *dlPtr,
static void DisplayLineBackground(TkText *textPtr, DLine *dlPtr,
DLine *prevPtr, Pixmap pixmap);
static void DisplayText(ClientData clientData);
-static DLine * FindDLine(DLine *dlPtr, CONST TkTextIndex *indexPtr);
+static DLine * FindDLine(DLine *dlPtr, 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);
@@ -568,8 +569,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,
@@ -577,7 +578,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);
@@ -585,7 +586,7 @@ 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 AsyncUpdateYScrollbar(ClientData clientData);
@@ -625,7 +626,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;
@@ -661,10 +662,10 @@ TkTextCreateDInfo(
textPtr->refCount++;
dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(0,
- AsyncUpdateLineMetrics, (ClientData) textPtr);
+ AsyncUpdateLineMetrics, textPtr);
textPtr->refCount++;
dInfoPtr->scrollbarTimer = Tcl_CreateTimerHandler(200,
- AsyncUpdateYScrollbar, (ClientData) textPtr);
+ AsyncUpdateYScrollbar, textPtr);
textPtr->dInfoPtr = dInfoPtr;
}
@@ -706,7 +707,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);
@@ -718,7 +719,7 @@ TkTextFreeDInfo(
textPtr->refCount--;
dInfoPtr->scrollbarTimer = NULL;
}
- ckfree((char *) dInfoPtr);
+ ckfree(dInfoPtr);
}
/*
@@ -742,7 +743,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;
@@ -922,7 +923,7 @@ GetStyle(
}
}
if (tagPtrs != NULL) {
- ckfree((char *) tagPtrs);
+ ckfree(tagPtrs);
}
/*
@@ -932,7 +933,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;
}
@@ -941,7 +942,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;
@@ -1006,7 +1007,7 @@ FreeStyle(
Tk_FreeGC(textPtr->display, stylePtr->fgGC);
}
Tcl_DeleteHashEntry(stylePtr->hPtr);
- ckfree((char *) stylePtr);
+ ckfree(stylePtr);
}
}
@@ -1047,7 +1048,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. */
{
@@ -1105,7 +1106,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;
@@ -1265,14 +1266,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;
}
}
@@ -1336,7 +1337,7 @@ LayoutDLine(
* into a single display line.
*
if (segPtr == NULL && chunkPtr != NULL) {
- ckfree((char *) chunkPtr);
+ ckfree(chunkPtr);
chunkPtr = NULL;
}
*/
@@ -1350,7 +1351,7 @@ LayoutDLine(
continue;
}
if (chunkPtr == NULL) {
- chunkPtr = (TkTextDispChunk *) ckalloc(sizeof(TkTextDispChunk));
+ chunkPtr = ckalloc(sizeof(TkTextDispChunk));
chunkPtr->nextPtr = NULL;
chunkPtr->clientData = NULL;
}
@@ -1459,7 +1460,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);
}
@@ -1482,7 +1483,7 @@ LayoutDLine(
*/
if (chunkPtr != NULL) {
- ckfree((char *) chunkPtr);
+ ckfree(chunkPtr);
}
break;
}
@@ -1611,18 +1612,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 */
@@ -2307,13 +2308,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) {
@@ -2405,7 +2406,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,
@@ -2453,7 +2454,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);
@@ -2727,7 +2728,7 @@ DisplayLineBackground(
rightX2 + xOffset, y, sValuePtr->borderWidth,
sValuePtr->borderWidth, 1, sValuePtr->relief);
Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
- leftX + xOffset, y, rightX2 + sValuePtr->borderWidth -
+ leftX + xOffset, y, rightX2 + sValuePtr->borderWidth -
leftX, sValuePtr->borderWidth, leftXIn, 0, 1,
sValuePtr->relief);
}
@@ -2879,7 +2880,7 @@ static void
AsyncUpdateLineMetrics(
ClientData clientData) /* Information about widget. */
{
- register TkText *textPtr = (TkText *) clientData;
+ register TkText *textPtr = clientData;
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
int lineNum;
@@ -2891,7 +2892,7 @@ AsyncUpdateLineMetrics(
*/
if (--textPtr->refCount == 0) {
- ckfree((char *) textPtr);
+ ckfree(textPtr);
}
return;
}
@@ -2902,6 +2903,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 =
@@ -2938,7 +2944,7 @@ AsyncUpdateLineMetrics(
textPtr->refCount--;
if (textPtr->refCount == 0) {
- ckfree((char *) textPtr);
+ ckfree(textPtr);
}
return;
}
@@ -2950,7 +2956,7 @@ AsyncUpdateLineMetrics(
*/
dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
- AsyncUpdateLineMetrics, (ClientData) textPtr);
+ AsyncUpdateLineMetrics, textPtr);
}
/*
@@ -3051,86 +3057,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) {
+ if (pixelHeight == 0) {
/*
- * 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.
+ * These have already been stored, unless we just
+ * started the new line.
*/
- 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 {
- /*
- * We're done with this long 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 {
/*
@@ -3331,7 +3333,7 @@ TextInvalidateLineMetrics(
if (dInfoPtr->lineUpdateTimer == NULL) {
textPtr->refCount++;
dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
- AsyncUpdateLineMetrics, (ClientData) textPtr);
+ AsyncUpdateLineMetrics, textPtr);
}
}
@@ -3381,6 +3383,8 @@ TkTextFindDisplayLineEnd(
* of the original index within its display
* line. */
{
+ TkTextIndex index;
+
if (!end && indexPtr->byteIndex == 0) {
/*
* Nothing to do.
@@ -3390,95 +3394,93 @@ 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,
- indexPtr->byteIndex - dlPtr->index.byteIndex);
- }
- if (end) {
- /*
- * The index we want is one less than the number of bytes
- * in the display line.
- */
+ *xOffset = DlineXOfIndex(textPtr, dlPtr,
+ indexPtr->byteIndex - dlPtr->index.byteIndex);
+ }
+ 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;
}
}
@@ -3520,7 +3522,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. */
@@ -3591,7 +3593,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. */
{
@@ -3862,7 +3864,7 @@ TkTextUpdateOneLine(
if (textPtr->dInfoPtr->scrollbarTimer == NULL) {
textPtr->refCount++;
textPtr->dInfoPtr->scrollbarTimer = Tcl_CreateTimerHandler(200,
- AsyncUpdateYScrollbar, (ClientData) textPtr);
+ AsyncUpdateYScrollbar, textPtr);
}
return displayLines;
}
@@ -3890,10 +3892,19 @@ RedisplayText(
{
register TkText *textPtr = (TkText *) clientData;
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
- TkRegion damageRegion = TkCreateRegion();
- XRectangle rectangle = {0, 0, dInfoPtr->maxX, dInfoPtr->maxY};
+ TkRegion damageRegion;
+ XRectangle rectangle;
+
+ if (dInfoPtr == NULL) {
+ return;
+ }
+ damageRegion = TkCreateRegion();
+ rectangle.x = 0;
+ rectangle.y = 0;
+ rectangle.width = dInfoPtr->maxX;
+ rectangle.height = dInfoPtr->maxY;
TkUnionRectWithRegion(&rectangle, damageRegion, damageRegion);
-
+
TextInvalidateRegion(textPtr, damageRegion);
DisplayText(clientData);
}
@@ -3903,7 +3914,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;
@@ -3925,7 +3936,7 @@ DisplayText(
}
interp = textPtr->interp;
- Tcl_Preserve((ClientData) interp);
+ Tcl_Preserve(interp);
if (tkTextDebug) {
Tcl_SetVar2(interp, "tk_textRelayout", NULL, "", TCL_GLOBAL_ONLY);
@@ -3971,7 +3982,7 @@ DisplayText(
dInfoPtr->flags &= ~REPICK_NEEDED;
TkTextPickCurrent(textPtr, &textPtr->pickEvent);
if (--textPtr->refCount == 0) {
- ckfree((char *) textPtr);
+ ckfree(textPtr);
goto end;
}
if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
@@ -4051,7 +4062,7 @@ DisplayText(
*/
if ((y + height) > dInfoPtr->maxY) {
- height = dInfoPtr->maxY -y;
+ height = dInfoPtr->maxY - y;
}
oldY = dlPtr->oldY;
if (y < dInfoPtr->y) {
@@ -4379,7 +4390,7 @@ DisplayText(
}
end:
- Tcl_Release((ClientData) interp);
+ Tcl_Release(interp);
}
/*
@@ -4408,7 +4419,7 @@ TkTextEventuallyRepick(
dInfoPtr->flags |= REPICK_NEEDED;
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
dInfoPtr->flags |= REDRAW_PENDING;
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
}
@@ -4452,7 +4463,7 @@ TkTextRedrawRegion(
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
dInfoPtr->flags |= REDRAW_PENDING;
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ Tcl_DoWhenIdle(DisplayText, textPtr);
}
TkDestroyRegion(damageRgn);
}
@@ -4546,8 +4557,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) {
@@ -4564,8 +4575,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;
@@ -4589,7 +4600,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;
@@ -4771,7 +4782,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;
@@ -4876,7 +4887,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;
@@ -4971,7 +4982,7 @@ TkTextRelayoutWindow(
if (dInfoPtr->lineUpdateTimer == NULL) {
textPtr->refCount++;
dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
- AsyncUpdateLineMetrics, (ClientData) textPtr);
+ AsyncUpdateLineMetrics, textPtr);
}
}
}
@@ -5155,7 +5166,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;
}
@@ -5245,7 +5256,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
@@ -5349,7 +5360,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". */
{
@@ -5421,7 +5432,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,
@@ -5430,27 +5441,25 @@ 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;
+ } else 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;
}
@@ -5478,7 +5487,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". */
{
@@ -5531,7 +5540,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;
}
@@ -5616,7 +5625,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;
}
@@ -5733,7 +5742,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;
}
@@ -5761,7 +5770,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". */
{
@@ -5787,7 +5796,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",
@@ -5942,7 +5951,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". */
{
@@ -6013,7 +6022,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;
@@ -6021,8 +6030,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;
@@ -6095,16 +6107,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);
}
}
}
@@ -6226,9 +6244,8 @@ GetYPixelCount(
notFirst = 1;
}
break;
- } else {
- dlPtr = dlPtr->nextPtr;
}
+ dlPtr = dlPtr->nextPtr;
} while (dlPtr->index.linePtr == linePtr);
return count;
@@ -6378,16 +6395,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);
}
}
}
@@ -6414,7 +6437,7 @@ static void
AsyncUpdateYScrollbar(
ClientData clientData) /* Information about widget. */
{
- register TkText *textPtr = (TkText *) clientData;
+ register TkText *textPtr = clientData;
textPtr->dInfoPtr->scrollbarTimer = NULL;
@@ -6423,7 +6446,7 @@ AsyncUpdateYScrollbar(
}
if (--textPtr->refCount == 0) {
- ckfree((char *) textPtr);
+ ckfree(textPtr);
}
}
@@ -6450,7 +6473,7 @@ static DLine *
FindDLine(
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. */
{
TkTextLine *linePtr;
@@ -6579,25 +6602,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) {
@@ -6690,7 +6714,7 @@ DlineIndexOfX(
*/
if (chunkPtr->numBytes > 1) {
- indexPtr->byteIndex += (*chunkPtr->measureProc)(chunkPtr, x);
+ indexPtr->byteIndex += chunkPtr->measureProc(chunkPtr, x);
}
}
@@ -6762,10 +6786,10 @@ DlineXOfIndex(
* coordinate. */
{
register TkTextDispChunk *chunkPtr = dlPtr->chunkPtr;
- int x;
+ int x = 0;
if (byteIndex == 0 || chunkPtr == NULL) {
- return 0;
+ return x;
}
/*
@@ -6778,15 +6802,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;
@@ -6820,7 +6843,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,
@@ -6874,7 +6897,7 @@ TkTextIndexBbox(
* coordinate on the screen. Translate it to reflect horizontal scrolling.
*/
- (*chunkPtr->bboxProc)(textPtr, chunkPtr, byteIndex,
+ chunkPtr->bboxProc(textPtr, chunkPtr, byteIndex,
dlPtr->y + dlPtr->spaceAbove,
dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, xPtr, yPtr, widthPtr,
@@ -6953,7 +6976,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. */
@@ -7111,22 +7134,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;
@@ -7182,7 +7205,7 @@ TkTextCharLayoutProc(
} else {
Tcl_DStringSetLength(baseString,lineOffset);
}
- ckfree((char *) ciPtr);
+ ckfree(ciPtr);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
return 0;
}
@@ -7208,9 +7231,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 */
@@ -7248,11 +7270,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) {
@@ -7312,7 +7344,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) {
@@ -7325,7 +7357,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;
@@ -7365,7 +7397,7 @@ CharChunkMeasureChars(
return fit - bstart;
}
}
-#endif
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
}
/*
@@ -7401,7 +7433,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;
@@ -7419,7 +7451,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);
@@ -7552,7 +7584,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
@@ -7579,7 +7611,7 @@ CharUndisplayProc(
ciPtr->numBytes = 0;
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
- ckfree((char *) ciPtr);
+ ckfree(ciPtr);
chunkPtr->clientData = NULL;
}
}
@@ -7655,7 +7687,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;
@@ -7818,7 +7850,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;
@@ -7839,23 +7871,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
@@ -8093,7 +8125,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. */
@@ -8108,7 +8140,7 @@ MeasureChars(
* here. */
{
int curX, width, ch;
- CONST char *special, *end, *start;
+ const char *special, *end, *start;
ch = 0; /* lint. */
curX = startX;
@@ -8155,11 +8187,10 @@ MeasureChars(
break;
}
if (special < end) {
- if (ch == '\t') {
- start++;
- } else {
+ if (ch != '\t') {
break;
}
+ start++;
}
}
@@ -8200,19 +8231,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 {
@@ -8220,8 +8251,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;
}
@@ -8240,8 +8271,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) {
@@ -8319,7 +8350,7 @@ FinalizeBaseChunk(
if (chunkPtr->displayProc != CharDisplayProc) {
continue;
}
- ciPtr = (CharInfo *)chunkPtr->clientData;
+ ciPtr = chunkPtr->clientData;
if (ciPtr->baseChunkPtr != baseCharChunkPtr) {
break;
}
@@ -8336,7 +8367,7 @@ FinalizeBaseChunk(
}
if (addChunkPtr != NULL) {
- ciPtr = (CharInfo *)addChunkPtr->clientData;
+ ciPtr = addChunkPtr->clientData;
ciPtr->chars = baseChars + ciPtr->baseOffset;
#if TK_DRAW_IN_CONTEXT
@@ -8387,7 +8418,7 @@ FreeBaseChunk(
if (chunkPtr->undisplayProc != CharUndisplayProc) {
continue;
}
- ciPtr = (CharInfo *) chunkPtr->clientData;
+ ciPtr = chunkPtr->clientData;
if (ciPtr->baseChunkPtr != baseChunkPtr) {
break;
}
@@ -8396,7 +8427,9 @@ FreeBaseChunk(
ciPtr->chars = NULL;
}
- Tcl_DStringFree(&((BaseCharInfo *) baseChunkPtr->clientData)->baseChars);
+ if (baseChunkPtr) {
+ Tcl_DStringFree(&((BaseCharInfo *) baseChunkPtr->clientData)->baseChars);
+ }
}
/*
@@ -8505,14 +8538,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)) {