summaryrefslogtreecommitdiffstats
path: root/generic/tkTextDisp.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkTextDisp.c')
-rw-r--r--generic/tkTextDisp.c165
1 files changed, 85 insertions, 80 deletions
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index 8acf115..2454665 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -16,13 +16,17 @@
#include "tkInt.h"
#include "tkText.h"
-#ifdef MAC_OSX_TK
+#ifdef _WIN32
+#include "tkWinInt.h"
+#elif defined(__CYGWIN__)
+#include "tkUnixInt.h"
+#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
-#define OK_TO_LOG (!TkpAppIsDrawing())
-#define FORCE_DISPLAY(winPtr) TkpDisplayWindow(winPtr)
-#else
+#define OK_TO_LOG (!TkpWillDrawWidget(textPtr->tkwin))
+#endif
+
+#if !defined(MAC_OSX_TK)
#define OK_TO_LOG 1
-#define FORCE_DISPLAY(winPtr)
#endif
/*
@@ -436,12 +440,12 @@ typedef struct TextDInfo {
* points to one of the following structures:
*/
-#if !TK_LAYOUT_WITH_BASE_CHUNKS
+#if !defined(TK_LAYOUT_WITH_BASE_CHUNKS)
typedef struct CharInfo {
int numBytes; /* Number of bytes to display. */
- char chars[1]; /* UTF characters to display. Actual size will
- * be numBytes, not 1. THIS MUST BE THE LAST
+ char chars[TKFLEXARRAY]; /* UTF characters to display.
+ * Allocated as large as necessary. THIS MUST BE THE LAST
* FIELD IN THE STRUCTURE. */
} CharInfo;
@@ -548,7 +552,7 @@ static void CharDisplayProc(TkText *textPtr,
static int CharMeasureProc(TkTextDispChunk *chunkPtr, int x);
static void CharUndisplayProc(TkText *textPtr,
TkTextDispChunk *chunkPtr);
-#if TK_LAYOUT_WITH_BASE_CHUNKS
+#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
static void FinalizeBaseChunk(TkTextDispChunk *additionalChunkPtr);
static void FreeBaseChunk(TkTextDispChunk *baseChunkPtr);
static int IsSameFGStyle(TextStyle *style1, TextStyle *style2);
@@ -1363,7 +1367,7 @@ LayoutDLine(
* expectations in the rest of the code, but we are able to skip
* elided portions of the line quickly.
*
- * If current chunk is elided and last chunk was too, coalese.
+ * If current chunk is elided and last chunk was too, coalesce.
*
* This also means that each logical line which is entirely elided
* still gets laid out into a DLine, but with zero height. This isn't
@@ -1504,7 +1508,7 @@ LayoutDLine(
}
}
-#if TK_LAYOUT_WITH_BASE_CHUNKS
+#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
if (baseCharChunkPtr != NULL) {
int expectedX =
((BaseCharInfo *) baseCharChunkPtr->clientData)->width
@@ -1646,7 +1650,7 @@ LayoutDLine(
chunkPtr = NULL;
}
-#if TK_LAYOUT_WITH_BASE_CHUNKS
+#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
FinalizeBaseChunk(NULL);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
if (noCharsYet) {
@@ -1705,7 +1709,7 @@ LayoutDLine(
segPtr->typePtr->layoutProc(textPtr, &breakIndex, segPtr,
byteOffset, maxX, breakByteOffset, 0, wrapMode,
breakChunkPtr);
-#if TK_LAYOUT_WITH_BASE_CHUNKS
+#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
FinalizeBaseChunk(NULL);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
}
@@ -3151,7 +3155,7 @@ GenerateWidgetViewSyncEvent(
*/
if (!tkTextDebug) {
- FORCE_DISPLAY(textPtr->tkwin);
+ TkpRedrawWidget(textPtr->tkwin);
}
if (NewSyncState != OldSyncState) {
@@ -3160,8 +3164,8 @@ GenerateWidgetViewSyncEvent(
} else {
textPtr->dInfoPtr->flags |= OUT_OF_SYNC;
}
- TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
- Tcl_NewBooleanObj(NewSyncState));
+ Tk_SendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
+ Tcl_NewBooleanObj(NewSyncState));
}
}
@@ -4171,11 +4175,23 @@ DisplayText(
* warnings. */
Tcl_Interp *interp;
+
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
+ /*
+ * The widget has been deleted. Don't do anything.
+ */
+
+ return;
+ }
+
#ifdef MAC_OSX_TK
/*
- * If drawing is disabled, all we need to do is
- * clear the REDRAW_PENDING flag.
+ * If the toplevel is being resized it would be dangerous to try redrawing
+ * the widget. But we can just clear the REDRAW_PENDING flag and return.
+ * This display proc will be called again after the widget has been
+ * reconfigured.
*/
+
TkWindow *winPtr = (TkWindow *)(textPtr->tkwin);
MacDrawable *macWin = winPtr->privatePtr;
if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
@@ -4184,14 +4200,6 @@ DisplayText(
}
#endif
- if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
- /*
- * The widget has been deleted. Don't do anything.
- */
-
- return;
- }
-
interp = textPtr->interp;
Tcl_Preserve(interp);
@@ -5268,7 +5276,7 @@ TkTextRelayoutWindow(
/*
* Invalidate cached scrollbar positions, so that scrollbars sliders will
- * be udpated.
+ * be updated.
*/
dInfoPtr->xScrollFirst = dInfoPtr->xScrollLast = -1;
@@ -6520,7 +6528,7 @@ GetXView(
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);
+ code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
Tcl_DStringFree(&buf);
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
@@ -6805,7 +6813,7 @@ GetYView(
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);
+ code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
Tcl_DStringFree(&buf);
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
@@ -7534,14 +7542,14 @@ TkTextDLineInfo(
static void
ElideBboxProc(
- TkText *textPtr,
+ TCL_UNUSED(TkText *),
TkTextDispChunk *chunkPtr, /* Chunk containing desired char. */
- int index, /* Index of desired character within the
+ TCL_UNUSED(int), /* Index of desired character within the
* chunk. */
int y, /* Topmost pixel in area allocated for this
* line. */
- int lineHeight, /* Height of line, in pixels. */
- int baseline, /* Location of line's baseline, in pixels
+ TCL_UNUSED(int), /* Height of line, in pixels. */
+ TCL_UNUSED(int), /* Location of line's baseline, in pixels
* measured down from y. */
int *xPtr, int *yPtr, /* Gets filled in with coords of character's
* upper-left pixel. X-coord is in same
@@ -7551,10 +7559,6 @@ ElideBboxProc(
int *heightPtr) /* Gets filled in with height of character, in
* pixels. */
{
- (void)textPtr;
- (void)index;
- (void)lineHeight;
- (void)baseline;
*xPtr = chunkPtr->x;
*yPtr = y;
@@ -7567,13 +7571,10 @@ ElideBboxProc(
static int
ElideMeasureProc(
- TkTextDispChunk *chunkPtr, /* Chunk containing desired coord. */
- int x) /* X-coordinate, in same coordinate system as
+ TCL_UNUSED(TkTextDispChunk *), /* Chunk containing desired coord. */
+ TCL_UNUSED(int)) /* X-coordinate, in same coordinate system as
* chunkPtr->x. */
{
- (void)chunkPtr;
- (void)x;
-
return 0 /*chunkPtr->numBytes - 1*/;
}
@@ -7600,8 +7601,8 @@ ElideMeasureProc(
int
TkTextCharLayoutProc(
- TkText *textPtr, /* Text widget being layed out. */
- TkTextIndex *indexPtr, /* Index of first character to lay out
+ TCL_UNUSED(TkText *), /* Text widget being layed out. */
+ TCL_UNUSED(TkTextIndex *), /* Index of first character to lay out
* (corresponds to segPtr and offset). */
TkTextSegment *segPtr, /* Segment being layed out. */
TkSizeT byteOffset, /* Byte offset within segment of first
@@ -7627,14 +7628,12 @@ TkTextCharLayoutProc(
char *p;
TkTextSegment *nextPtr;
Tk_FontMetrics fm;
-#if TK_LAYOUT_WITH_BASE_CHUNKS
+#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
const char *line;
int lineOffset;
BaseCharInfo *bciPtr;
Tcl_DString *baseString;
#endif
- (void)textPtr;
- (void)indexPtr;
/*
* Figure out how many characters will fit in the space we've got. Include
@@ -7654,7 +7653,7 @@ TkTextCharLayoutProc(
p = segPtr->body.chars + byteOffset;
tkfont = chunkPtr->stylePtr->sValuePtr->tkfont;
-#if TK_LAYOUT_WITH_BASE_CHUNKS
+#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
if (baseCharChunkPtr == NULL) {
baseCharChunkPtr = chunkPtr;
bciPtr = ckalloc(sizeof(BaseCharInfo));
@@ -7691,7 +7690,7 @@ TkTextCharLayoutProc(
int ch;
int chLen = TkUtfToUniChar(p, &ch);
-#if TK_LAYOUT_WITH_BASE_CHUNKS
+#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
bytesThatFit = CharChunkMeasureChars(chunkPtr, line,
lineOffset+chLen, lineOffset, -1, chunkPtr->x, -1, 0,
&nextX);
@@ -7735,7 +7734,7 @@ TkTextCharLayoutProc(
bytesThatFit++;
}
if (bytesThatFit == 0) {
-#if TK_LAYOUT_WITH_BASE_CHUNKS
+#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
chunkPtr->clientData = NULL;
if (chunkPtr == baseCharChunkPtr) {
baseCharChunkPtr = NULL;
@@ -7768,7 +7767,7 @@ TkTextCharLayoutProc(
chunkPtr->width = nextX - chunkPtr->x;
chunkPtr->breakIndex = -1;
-#if !TK_LAYOUT_WITH_BASE_CHUNKS
+#if !defined(TK_LAYOUT_WITH_BASE_CHUNKS)
ciPtr = (CharInfo *)ckalloc(offsetof(CharInfo, chars) + 1 + bytesThatFit);
chunkPtr->clientData = ciPtr;
memcpy(ciPtr->chars, p, bytesThatFit);
@@ -7779,7 +7778,7 @@ TkTextCharLayoutProc(
ciPtr->numBytes--;
}
-#if TK_LAYOUT_WITH_BASE_CHUNKS
+#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
/*
* Final update for the current base chunk data.
*/
@@ -7884,7 +7883,7 @@ CharChunkMeasureChars(
Tk_Font tkfont = chunkPtr->stylePtr->sValuePtr->tkfont;
CharInfo *ciPtr = (CharInfo *)chunkPtr->clientData;
-#if !TK_LAYOUT_WITH_BASE_CHUNKS
+#if !defined(TK_LAYOUT_WITH_BASE_CHUNKS)
if (chars == NULL) {
chars = ciPtr->chars;
charsLen = ciPtr->numBytes;
@@ -7957,18 +7956,18 @@ CharChunkMeasureChars(
static void
CharDisplayProc(
- TkText *textPtr,
+ TCL_UNUSED(TkText *),
TkTextDispChunk *chunkPtr, /* Chunk that is to be drawn. */
int x, /* X-position in dst at which to draw this
* chunk (may differ from the x-position in
* the chunk because of scrolling). */
int y, /* Y-position at which to draw this chunk in
* dst. */
- int height, /* Total height of line. */
+ TCL_UNUSED(int), /* Total height of line. */
int baseline, /* Offset of baseline from y. */
Display *display, /* Display to use for drawing. */
Drawable dst, /* Pixmap or window in which to draw chunk. */
- int screenY) /* Y-coordinate in text window that
+ TCL_UNUSED(int)) /* Y-coordinate in text window that
* corresponds to y. */
{
CharInfo *ciPtr = (CharInfo *)chunkPtr->clientData;
@@ -7976,12 +7975,9 @@ CharDisplayProc(
TextStyle *stylePtr;
StyleValues *sValuePtr;
int numBytes, offsetBytes, offsetX;
-#if TK_DRAW_IN_CONTEXT
+#ifdef TK_DRAW_IN_CONTEXT
BaseCharInfo *bciPtr;
#endif /* TK_DRAW_IN_CONTEXT */
- (void)textPtr;
- (void)height;
- (void)screenY;
if ((x + chunkPtr->width) <= 0) {
/*
@@ -7991,12 +7987,12 @@ CharDisplayProc(
return;
}
-#if TK_DRAW_IN_CONTEXT
+#ifdef TK_DRAW_IN_CONTEXT
bciPtr = ciPtr->baseChunkPtr->clientData;
numBytes = Tcl_DStringLength(&bciPtr->baseChars);
string = Tcl_DStringValue(&bciPtr->baseChars);
-#elif TK_LAYOUT_WITH_BASE_CHUNKS
+#elif defined(TK_LAYOUT_WITH_BASE_CHUNKS)
if (ciPtr->baseChunkPtr != chunkPtr) {
/*
* Without context drawing only base chunks display their foreground.
@@ -8037,7 +8033,7 @@ CharDisplayProc(
if (!sValuePtr->elide && (numBytes > offsetBytes)
&& (stylePtr->fgGC != NULL)) {
-#if TK_DRAW_IN_CONTEXT
+#ifdef TK_DRAW_IN_CONTEXT
int start = ciPtr->baseOffset + offsetBytes;
int len = ciPtr->numBytes - offsetBytes;
int xDisplacement = x - chunkPtr->x;
@@ -8122,14 +8118,13 @@ CharDisplayProc(
static void
CharUndisplayProc(
- TkText *textPtr, /* Overall information about text widget. */
+ TCL_UNUSED(TkText *), /* Overall information about text widget. */
TkTextDispChunk *chunkPtr) /* Chunk that is about to be freed. */
{
CharInfo *ciPtr = (CharInfo *)chunkPtr->clientData;
- (void)textPtr;
if (ciPtr) {
-#if TK_LAYOUT_WITH_BASE_CHUNKS
+#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
if (chunkPtr == ciPtr->baseChunkPtr) {
/*
* Basechunks are undisplayed first, when DLines are freed or
@@ -8212,13 +8207,13 @@ CharMeasureProc(
static void
CharBboxProc(
- TkText *textPtr,
+ TCL_UNUSED(TkText *),
TkTextDispChunk *chunkPtr, /* Chunk containing desired char. */
int byteIndex, /* Byte offset of desired character within the
* chunk. */
int y, /* Topmost pixel in area allocated for this
* line. */
- int lineHeight, /* Height of line, in pixels. */
+ TCL_UNUSED(int), /* Height of line, in pixels. */
int baseline, /* Location of line's baseline, in pixels
* measured down from y. */
int *xPtr, int *yPtr, /* Gets filled in with coords of character's
@@ -8231,8 +8226,6 @@ CharBboxProc(
{
CharInfo *ciPtr = (CharInfo *)chunkPtr->clientData;
int maxX;
- (void)textPtr;
- (void)lineHeight;
maxX = chunkPtr->width + chunkPtr->x;
CharChunkMeasureChars(chunkPtr, NULL, 0, 0, byteIndex,
@@ -8713,7 +8706,7 @@ MeasureChars(
if ((maxX >= 0) && (curX >= maxX)) {
break;
}
-#if TK_DRAW_IN_CONTEXT
+#ifdef TK_DRAW_IN_CONTEXT
start += TkpMeasureCharsInContext(tkfont, source, maxBytes,
start - source, special - start,
maxX >= 0 ? maxX - curX : -1, flags, &width);
@@ -8794,6 +8787,7 @@ TextGetScrollInfoObj(
VIEW_SCROLL_PAGES, VIEW_SCROLL_PIXELS, VIEW_SCROLL_UNITS
};
int index;
+ double d;
if (Tcl_GetIndexFromObjStruct(interp, objv[2], subcommands,
sizeof(char *), "option", 0, &index) != TCL_OK) {
@@ -8821,20 +8815,31 @@ TextGetScrollInfoObj(
}
switch ((enum viewUnits) index) {
case VIEW_SCROLL_PAGES:
- if (Tcl_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) {
+ if (Tcl_GetDoubleFromObj(interp, objv[3], &d) != TCL_OK) {
return TKTEXT_SCROLL_ERROR;
}
+ *intPtr = (d > 0) ? ceil(d) : floor(d);
+ if (dblPtr) {
+ *dblPtr = d;
+ }
return TKTEXT_SCROLL_PAGES;
case VIEW_SCROLL_PIXELS:
if (Tk_GetPixelsFromObj(interp, textPtr->tkwin, objv[3],
intPtr) != TCL_OK) {
return TKTEXT_SCROLL_ERROR;
}
+ if (dblPtr) {
+ *dblPtr = (double)*intPtr;
+ }
return TKTEXT_SCROLL_PIXELS;
case VIEW_SCROLL_UNITS:
- if (Tcl_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) {
+ if (Tcl_GetDoubleFromObj(interp, objv[3], &d) != TCL_OK) {
return TKTEXT_SCROLL_ERROR;
}
+ *intPtr = (d > 0) ? ceil(d) : floor(d);
+ if (dblPtr) {
+ *dblPtr = d;
+ }
return TKTEXT_SCROLL_UNITS;
}
}
@@ -8842,7 +8847,7 @@ TextGetScrollInfoObj(
return TKTEXT_SCROLL_ERROR;
}
-#if TK_LAYOUT_WITH_BASE_CHUNKS
+#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
/*
*----------------------------------------------------------------------
*
@@ -8873,7 +8878,7 @@ FinalizeBaseChunk(
const char *baseChars;
TkTextDispChunk *chunkPtr;
CharInfo *ciPtr;
-#if TK_DRAW_IN_CONTEXT
+#ifdef TK_DRAW_IN_CONTEXT
int widthAdjust = 0;
int newwidth;
#endif /* TK_DRAW_IN_CONTEXT */
@@ -8887,7 +8892,7 @@ FinalizeBaseChunk(
for (chunkPtr = baseCharChunkPtr; chunkPtr != NULL;
chunkPtr = chunkPtr->nextPtr) {
-#if TK_DRAW_IN_CONTEXT
+#ifdef TK_DRAW_IN_CONTEXT
chunkPtr->x += widthAdjust;
#endif /* TK_DRAW_IN_CONTEXT */
@@ -8900,7 +8905,7 @@ FinalizeBaseChunk(
}
ciPtr->chars = baseChars + ciPtr->baseOffset;
-#if TK_DRAW_IN_CONTEXT
+#ifdef TK_DRAW_IN_CONTEXT
newwidth = 0;
CharChunkMeasureChars(chunkPtr, NULL, 0, 0, -1, 0, -1, 0, &newwidth);
if (newwidth < chunkPtr->width) {
@@ -8914,7 +8919,7 @@ FinalizeBaseChunk(
ciPtr = addChunkPtr->clientData;
ciPtr->chars = baseChars + ciPtr->baseOffset;
-#if TK_DRAW_IN_CONTEXT
+#ifdef TK_DRAW_IN_CONTEXT
addChunkPtr->x += widthAdjust;
CharChunkMeasureChars(addChunkPtr, NULL, 0, 0, -1, 0, -1, 0,
&addChunkPtr->width);
@@ -9012,7 +9017,7 @@ IsSameFGStyle(
return 1;
}
-#if !TK_DRAW_IN_CONTEXT
+#if !defined(TK_DRAW_IN_CONTEXT)
if (
#ifdef MAC_OSX_TK
!TkMacOSXCompareColors(style1->fgGC->foreground,
@@ -9028,7 +9033,7 @@ IsSameFGStyle(
sv1 = style1->sValuePtr;
sv2 = style2->sValuePtr;
-#if TK_DRAW_IN_CONTEXT
+#ifdef TK_DRAW_IN_CONTEXT
return sv1->tkfont == sv2->tkfont && sv1->offset == sv2->offset;
#else
return sv1->tkfont == sv2->tkfont