summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/tkText.c82
-rw-r--r--generic/tkText.h20
-rw-r--r--generic/tkTextBTree.c14
-rw-r--r--generic/tkTextDisp.c186
-rw-r--r--generic/tkTextImage.c12
-rw-r--r--generic/tkTextIndex.c10
-rw-r--r--generic/tkTextMark.c4
-rw-r--r--generic/tkTextTag.c26
-rw-r--r--generic/tkTextWind.c4
9 files changed, 226 insertions, 132 deletions
diff --git a/generic/tkText.c b/generic/tkText.c
index 7034579..5313ed3 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkText.c,v 1.59 2005/08/11 01:55:04 dgp Exp $
+ * RCS: @(#) $Id: tkText.c,v 1.60 2005/10/10 10:36:35 vincentdarley Exp $
*/
#include "default.h"
@@ -66,6 +66,16 @@ static char *wrapStrings[] = {
};
/*
+ * The 'TkTextTabStyle' enum in tkText.h is used to define a type for
+ * the -tabstyle option of the Text widget. These values are used as
+ * indices into the string table below.
+ */
+
+static char *tabStyleStrings[] = {
+ "tabular", "wordprocessor", (char *) NULL
+};
+
+/*
* The following functions and custom option type are used to define the
* "line" option type, and thereby handle the text widget '-startline',
* '-endline' configuration options which are of that type.
@@ -214,6 +224,9 @@ static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_STRING, "-tabs", "tabs", "Tabs",
DEF_TEXT_TABS, Tk_Offset(TkText, tabOptionPtr), -1,
TK_OPTION_NULL_OK, 0, TK_TEXT_LINE_GEOMETRY},
+ {TK_OPTION_STRING_TABLE, "-tabstyle", "tabStyle", "TabStyle",
+ DEF_TEXT_TABSTYLE, -1, Tk_Offset(TkText, tabStyle),
+ 0, (ClientData) tabStyleStrings, TK_TEXT_LINE_GEOMETRY},
{TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
DEF_TEXT_TAKE_FOCUS, -1, Tk_Offset(TkText, takeFocus),
TK_OPTION_NULL_OK, 0, 0},
@@ -323,7 +336,7 @@ int tkTextDebug = 0;
static int ConfigureText(Tcl_Interp *interp,
TkText *textPtr, int objc, Tcl_Obj *CONST objv[]);
-static int DeleteChars(TkSharedText *sharedPtr, TkText *textPtr,
+static int DeleteIndexRange(TkSharedText *sharedPtr, TkText *textPtr,
CONST TkTextIndex *indexPtr1,
CONST TkTextIndex *indexPtr2, int viewUpdate);
static int CountIndices(CONST TkText *textPtr,
@@ -714,7 +727,7 @@ TextWidgetObjCmd(clientData, interp, objc, objv)
result = TCL_ERROR;
goto done;
}
- if (TkTextCharBbox(textPtr, indexPtr, &x, &y, &width, &height,
+ if (TkTextIndexBbox(textPtr, indexPtr, &x, &y, &width, &height,
NULL) == 0) {
Tcl_Obj *listObj = Tcl_NewListObj(0, NULL);
@@ -1063,7 +1076,7 @@ TextWidgetObjCmd(clientData, interp, objc, objv)
} else {
indexPtr2 = NULL;
}
- DeleteChars(NULL, textPtr, indexPtr1, indexPtr2, 1);
+ DeleteIndexRange(NULL, textPtr, indexPtr1, indexPtr2, 1);
} else {
/*
* Multi-index pair case requires that we prevalidate the
@@ -1168,7 +1181,7 @@ TextWidgetObjCmd(clientData, interp, objc, objv)
* indices are preparsed above.
*/
- DeleteChars(NULL, textPtr, &indices[i], &indices[i+1],
+ DeleteIndexRange(NULL, textPtr, &indices[i], &indices[i+1],
1);
}
}
@@ -1563,9 +1576,9 @@ SharedTextObjCmd(clientData, interp, objc, objv)
if (result != TCL_OK) {
return result;
}
- DeleteChars(sharedPtr, NULL, &index1, &index2, 1);
+ DeleteIndexRange(sharedPtr, NULL, &index1, &index2, 1);
} else {
- DeleteChars(sharedPtr, NULL, &index1, NULL, 1);
+ DeleteIndexRange(sharedPtr, NULL, &index1, NULL, 1);
}
return TCL_OK;
} else {
@@ -1702,7 +1715,7 @@ TextReplaceCmd(textPtr, interp, indexFromPtr, indexToPtr, objc, objv,
/*
* Perform the deletion and insertion, but ensure no undo-separator is
* placed between the two operations. Since we are using the helper
- * functions 'DeleteChars' and 'TextInsertCmd' we have to pretend that the
+ * functions 'DeleteIndexRange' and 'TextInsertCmd' we have to pretend that the
* autoSeparators setting is off, so that we don't get an undo-separator
* between the delete and insert.
*/
@@ -1718,7 +1731,7 @@ TextReplaceCmd(textPtr, interp, indexFromPtr, indexToPtr, objc, objv,
}
}
- DeleteChars(NULL, textPtr, indexFromPtr, indexToPtr, viewUpdate);
+ DeleteIndexRange(NULL, textPtr, indexFromPtr, indexToPtr, viewUpdate);
result = TextInsertCmd(NULL, textPtr, interp, objc-4, objv+4,
indexFromPtr, viewUpdate);
@@ -2857,7 +2870,7 @@ CountIndices(textPtr, indexPtr1, indexPtr2, type)
/*
*----------------------------------------------------------------------
*
- * DeleteChars --
+ * DeleteIndexRange --
*
* This function implements most of the functionality of the "delete"
* widget command.
@@ -2866,7 +2879,8 @@ CountIndices(textPtr, indexPtr1, indexPtr2, type)
* Returns a standard Tcl result, currently always TCL_OK.
*
* Side effects:
- * Characters get deleted from the text.
+ * Characters and other entities (windows, images) get deleted
+ * from the text.
*
* If 'viewUpdate' is true, we may adjust the window contents'
* y-position, and scrollbar setting.
@@ -2882,16 +2896,17 @@ CountIndices(textPtr, indexPtr1, indexPtr2, type)
*/
static int
-DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate)
+DeleteIndexRange(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate)
TkSharedText *sharedTextPtr;/* Shared portion of peer widgets. */
TkText *textPtr; /* Overall information about text widget. */
CONST TkTextIndex *indexPtr1;
/* Index describing location of first
- * character to delete. */
+ * character (or other entity) to delete. */
CONST TkTextIndex *indexPtr2;
- /* Index describing location of last character
- * to delete. NULL means just delete the one
- * character given by indexPtr1. */
+ /* Index describing location of last
+ * character (or other entity) to delete.
+ * NULL means just delete the one character
+ * given by indexPtr1. */
int viewUpdate; /* Update vertical view if set. */
{
int line1, line2;
@@ -3086,7 +3101,7 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate)
sharedTextPtr->stateEpoch++;
- TkBTreeDeleteChars(sharedTextPtr->tree, &index1, &index2);
+ TkBTreeDeleteIndexRange(sharedTextPtr->tree, &index1, &index2);
resetViewCount = 0;
for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {
@@ -3409,7 +3424,7 @@ TextBlinkProc(clientData)
}
redrawInsert:
TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
- if (TkTextCharBbox(textPtr, &index, &x, &y, &w, &h, &charWidth) == 0) {
+ if (TkTextIndexBbox(textPtr, &index, &x, &y, &w, &h, &charWidth) == 0) {
if (textPtr->insertCursorType) {
/* Block cursor */
TkTextRedrawRegion(textPtr, x - textPtr->width / 2, y,
@@ -4033,6 +4048,18 @@ TextSearchFoundMatch(lineNum, searchSpecPtr, clientData, theLine, matchOffset,
}
/*
+ * If we're using strict limits checking, ensure that the match with
+ * its full length fits inside the given range.
+ */
+
+ if (searchSpecPtr->strictLimits && lineNum == searchSpecPtr->stopLine) {
+ if (searchSpecPtr->backwards ^
+ ((matchOffset + numChars) > searchSpecPtr->stopOffset)) {
+ return 0;
+ }
+ }
+
+ /*
* The index information returned by the regular expression parser only
* considers textual information: it doesn't account for embedded windows,
* elided text (when we are not searching elided text) or any other
@@ -4253,7 +4280,8 @@ TkTextGetTabs(interp, textPtr, stringPtr)
tabArrayPtr->numTabs = 0;
prevStop = 0.0;
lastStop = 0.0;
- for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < objc; i++, tabPtr++) {
+ for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < objc;
+ i++, tabPtr++) {
int index;
/*
@@ -5528,7 +5556,9 @@ SearchCore(interp, searchSpecPtr, patObj)
* We've found a multi-line match.
*/
- extraLinesSearched = extraLines - 1;
+ if (extraLines > 0) {
+ extraLinesSearched = extraLines - 1;
+ }
}
}
@@ -5756,7 +5786,9 @@ SearchCore(interp, searchSpecPtr, patObj)
}
if (match && ((firstOffset + info.matches[0].end)
>= prevFullLine)) {
- extraLinesSearched = extraLines - 1;
+ if (extraLines > 0) {
+ extraLinesSearched = extraLines - 1;
+ }
lastFullLine = prevFullLine;
}
@@ -6309,11 +6341,3 @@ ObjectIsEmpty(objPtr)
Tcl_GetStringFromObj(objPtr, &length);
return (length == 0);
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/generic/tkText.h b/generic/tkText.h
index 5d7ea0f..2ccbfa9 100644
--- a/generic/tkText.h
+++ b/generic/tkText.h
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkText.h,v 1.26 2005/02/14 23:00:44 vincentdarley Exp $
+ * RCS: @(#) $Id: tkText.h,v 1.27 2005/10/10 10:36:35 vincentdarley Exp $
*/
#ifndef _TKTEXT
@@ -421,6 +421,8 @@ typedef struct TkTextTag {
struct TkTextTabArray *tabArrayPtr;
/* Info about tabs for tag (malloc-ed)
* or NULL. Corresponds to tabString. */
+ int tabStyle; /* One of TABULAR or WORDPROCESSOR or
+ * NONE (if not specified). */
char *underlineString; /* -underline option string (malloc-ed).
* NULL means option not specified. */
int underline; /* Non-zero means draw underline underneath
@@ -493,6 +495,17 @@ typedef struct TkTextSearch {
typedef enum {LEFT, RIGHT, CENTER, NUMERIC} TkTextTabAlign;
+/*
+ * The following are the supported styles of tabbing, used for the
+ * -tabstyle option of the text widget. The last element is only
+ * used for tag options.
+ */
+typedef enum {
+ TK_TEXT_TABSTYLE_TABULAR,
+ TK_TEXT_TABSTYLE_WORDPROCESSOR,
+ TK_TEXT_TABSTYLE_NONE
+} TkTextTabStyle;
+
typedef struct TkTextTab {
int location; /* Offset in pixels of this tab stop
* from the left margin (lmargin2) of
@@ -695,6 +708,7 @@ typedef struct TkText {
/* Information about tab stops (malloc'ed).
* NULL means perform default tabbing
* behavior. */
+ int tabStyle; /* One of TABULAR or WORDPROCESSOR. */
/*
* Additional information used for displaying:
@@ -1014,7 +1028,7 @@ EXTERN void TkBTreeClientRangeChanged _ANSI_ARGS_((TkText *textPtr,
EXTERN void TkBTreeRemoveClient _ANSI_ARGS_((TkTextBTree tree,
TkText *textPtr));
EXTERN void TkBTreeDestroy _ANSI_ARGS_((TkTextBTree tree));
-EXTERN void TkBTreeDeleteChars _ANSI_ARGS_((TkTextBTree tree,
+EXTERN void TkBTreeDeleteIndexRange _ANSI_ARGS_((TkTextBTree tree,
TkTextIndex *index1Ptr, TkTextIndex *index2Ptr));
EXTERN TkTextLine * TkBTreeFindLine _ANSI_ARGS_((TkTextBTree tree,
CONST TkText *textPtr, int line));
@@ -1058,7 +1072,7 @@ EXTERN void TkTextChanged _ANSI_ARGS_((TkSharedText *sharedTextPtr,
TkText *textPtr,
CONST TkTextIndex *index1Ptr,
CONST TkTextIndex *index2Ptr));
-EXTERN int TkTextCharBbox _ANSI_ARGS_((TkText *textPtr,
+EXTERN int TkTextIndexBbox _ANSI_ARGS_((TkText *textPtr,
CONST TkTextIndex *indexPtr, int *xPtr, int *yPtr,
int *widthPtr, int *heightPtr, int *charWidthPtr));
EXTERN int TkTextCharLayoutProc _ANSI_ARGS_((TkText *textPtr,
diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c
index f8a682c..30309db 100644
--- a/generic/tkTextBTree.c
+++ b/generic/tkTextBTree.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextBTree.c,v 1.18 2005/07/29 13:43:43 dkf Exp $
+ * RCS: @(#) $Id: tkTextBTree.c,v 1.19 2005/10/10 10:36:35 vincentdarley Exp $
*/
#include "tkInt.h"
@@ -1269,7 +1269,7 @@ CleanupLine(linePtr)
/*
*----------------------------------------------------------------------
*
- * TkBTreeDeleteChars --
+ * TkBTreeDeleteIndexRange --
*
* Delete a range of characters from a B-tree. The caller must make sure
* that the final newline of the B-tree is never deleted.
@@ -1287,7 +1287,7 @@ CleanupLine(linePtr)
*/
void
-TkBTreeDeleteChars(tree, index1Ptr, index2Ptr)
+TkBTreeDeleteIndexRange(tree, index1Ptr, index2Ptr)
TkTextBTree tree; /* Tree to delete from */
register TkTextIndex *index1Ptr;
/* Indicates first character that is to be
@@ -4832,11 +4832,3 @@ ToggleCheckProc(segPtr, linePtr)
}
}
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index 5289c94..dfa7dd3 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextDisp.c,v 1.52 2005/07/28 17:20:41 dkf Exp $
+ * RCS: @(#) $Id: tkTextDisp.c,v 1.53 2005/10/10 10:36:35 vincentdarley Exp $
*/
#include "tkPort.h"
@@ -100,6 +100,7 @@ typedef struct StyleValues {
int spacing3; /* Spacing below last dline in text line. */
TkTextTabArray *tabArrayPtr;/* Locations and types of tab stops (may be
* NULL). */
+ int tabStyle; /* One of TABULAR or WORDPROCESSOR. */
int underline; /* Non-zero means draw underline underneath
* text. */
int elide; /* Zero means draw text, otherwise not */
@@ -482,8 +483,8 @@ static void YScrollByLines _ANSI_ARGS_((TkText *textPtr,
static void YScrollByPixels _ANSI_ARGS_((TkText *textPtr,
int offset));
static int SizeOfTab _ANSI_ARGS_((TkText *textPtr,
- TkTextTabArray *tabArrayPtr, int *indexPtr,
- int x, int maxX));
+ int tabStyle, TkTextTabArray *tabArrayPtr,
+ int *indexPtr, int x, int maxX));
static void TextChanged _ANSI_ARGS_((TkText *textPtr,
CONST TkTextIndex *index1Ptr,
CONST TkTextIndex *index2Ptr));
@@ -685,7 +686,7 @@ GetStyle(textPtr, indexPtr)
int underlinePrio, elidePrio, justifyPrio, offsetPrio;
int lMargin1Prio, lMargin2Prio, rMarginPrio;
int spacing1Prio, spacing2Prio, spacing3Prio;
- int overstrikePrio, tabPrio, wrapPrio;
+ int overstrikePrio, tabPrio, tabStylePrio, wrapPrio;
/*
* Find out what tags are present for the character, then compute a
@@ -699,7 +700,7 @@ GetStyle(textPtr, indexPtr)
underlinePrio = elidePrio = justifyPrio = offsetPrio = -1;
lMargin1Prio = lMargin2Prio = rMarginPrio = -1;
spacing1Prio = spacing2Prio = spacing3Prio = -1;
- overstrikePrio = tabPrio = wrapPrio = -1;
+ overstrikePrio = tabPrio = tabStylePrio = wrapPrio = -1;
memset((VOID *) &styleValues, 0, sizeof(StyleValues));
styleValues.relief = TK_RELIEF_FLAT;
styleValues.fgColor = textPtr->fgColor;
@@ -709,6 +710,7 @@ GetStyle(textPtr, indexPtr)
styleValues.spacing2 = textPtr->spacing2;
styleValues.spacing3 = textPtr->spacing3;
styleValues.tabArrayPtr = textPtr->tabArrayPtr;
+ styleValues.tabStyle = textPtr->tabStyle;
styleValues.wrapMode = textPtr->wrapMode;
styleValues.elide = 0;
@@ -817,6 +819,11 @@ GetStyle(textPtr, indexPtr)
styleValues.tabArrayPtr = tagPtr->tabArrayPtr;
tabPrio = tagPtr->priority;
}
+ if ((tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE)
+ && (tagPtr->priority > tabStylePrio)) {
+ styleValues.tabStyle = tagPtr->tabStyle;
+ tabStylePrio = tagPtr->priority;
+ }
if ((tagPtr->underlineString != NULL)
&& (tagPtr->priority > underlinePrio)) {
styleValues.underline = tagPtr->underline;
@@ -979,6 +986,10 @@ LayoutDLine(textPtr, indexPtr)
int noCharsYet; /* Non-zero means that no characters
* have been placed on the line
* yet. */
+ int paragraphStart; /* Non-zero means that we are
+ * on the first line of a
+ * paragraph (Used to choose
+ * between lmargin1, lmargin2). */
int justify; /* How to justify line: taken from
* style for the first character in
* line. */
@@ -1001,6 +1012,7 @@ LayoutDLine(textPtr, indexPtr)
TkTextTabArray *tabArrayPtr; /* Tab stops for line; taken from
* style for the first character on
* line. */
+ int tabStyle; /* One of TABULAR or WORDPROCESSOR. */
int tabSize; /* Number of pixels consumed by
* current tab stop. */
TkTextDispChunk *lastCharChunkPtr; /* Pointer to last chunk in display
@@ -1027,12 +1039,19 @@ LayoutDLine(textPtr, indexPtr)
dlPtr->flags = NEW_LAYOUT | OLD_Y_INVALID;
dlPtr->logicalLinesMerged = 0;
+ /*
+ * This is not necessarily totally correct, where we have merged
+ * logical lines. Fixing this would require a quite significant
+ * overhaul, though, so currently we make do with this.
+ */
+ paragraphStart = (indexPtr->byteIndex == 0);
+
/*
* Special case entirely elide line as there may be 1000s or more
*/
elide = TkTextIsElided(textPtr, indexPtr, &info);
- if (elide && indexPtr->byteIndex==0) {
+ if (elide && indexPtr->byteIndex == 0) {
maxBytes = 0;
for (segPtr = info.segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) {
if (segPtr->size > 0) {
@@ -1141,6 +1160,7 @@ LayoutDLine(textPtr, indexPtr)
tabIndex = -1;
tabChunkPtr = NULL;
tabArrayPtr = NULL;
+ tabStyle = TK_TEXT_TABSTYLE_TABULAR;
rMargin = 0;
wrapMode = TEXT_WRAPMODE_CHAR;
tabSize = 0;
@@ -1194,7 +1214,8 @@ LayoutDLine(textPtr, indexPtr)
if (elide && (lastChunkPtr != NULL)
&& (lastChunkPtr->displayProc == NULL /*ElideDisplayProc*/)) {
- if ((elidesize = segPtr->size - byteOffset) > 0) {
+ elidesize = segPtr->size - byteOffset;
+ if (elidesize > 0) {
curIndex.byteIndex += elidesize;
lastChunkPtr->numBytes += elidesize;
breakByteOffset = lastChunkPtr->breakIndex
@@ -1262,14 +1283,26 @@ LayoutDLine(textPtr, indexPtr)
* information for the rest of the line.
*/
- if (noCharsYet) {
+ if (!elide && noCharsYet) {
tabArrayPtr = chunkPtr->stylePtr->sValuePtr->tabArrayPtr;
+ tabStyle = chunkPtr->stylePtr->sValuePtr->tabStyle;
justify = chunkPtr->stylePtr->sValuePtr->justify;
rMargin = chunkPtr->stylePtr->sValuePtr->rMargin;
wrapMode = chunkPtr->stylePtr->sValuePtr->wrapMode;
- x = ((curIndex.byteIndex == 0)
- ? chunkPtr->stylePtr->sValuePtr->lMargin1
- : chunkPtr->stylePtr->sValuePtr->lMargin2);
+
+ /*
+ * See above - this test may not be entirely correct where
+ * we have partially elided lines (and therefore merged
+ * logical lines). In such a case a byteIndex of zero
+ * doesn't necessarily mean the beginning of a logical line.
+ */
+ if (paragraphStart) {
+ /* Beginning of logical line */
+ x = chunkPtr->stylePtr->sValuePtr->lMargin1;
+ } else {
+ /* Beginning of display line */
+ x = chunkPtr->stylePtr->sValuePtr->lMargin2;
+ }
if (wrapMode == TEXT_WRAPMODE_NONE) {
maxX = -1;
} else {
@@ -1302,7 +1335,7 @@ LayoutDLine(textPtr, indexPtr)
}
}
chunkPtr->x = x;
- if (elide && maxBytes) {
+ if (elide /*&& maxBytes*/) {
/*
* Don't free style here, as other code expects to be able to do
* that.
@@ -1349,6 +1382,16 @@ LayoutDLine(textPtr, indexPtr)
}
break;
}
+ /*
+ * We currently say we have some characters (and therefore
+ * something from which to examine tag values for the first
+ * character of the line) even if those characters are actually
+ * elided. This behaviour is not well documented, and it might
+ * be more consistent to completely ignore such elided
+ * characters and their tags. To do so change this to:
+ *
+ * if (!elide && chunkPtr->numBytes > 0).
+ */
if (!elide && chunkPtr->numBytes > 0) {
noCharsYet = 0;
lastCharChunkPtr = chunkPtr;
@@ -1382,7 +1425,8 @@ LayoutDLine(textPtr, indexPtr)
x = chunkPtr->x + chunkPtr->width;
}
tabChunkPtr = chunkPtr;
- tabSize = SizeOfTab(textPtr, tabArrayPtr, &tabIndex, x, maxX);
+ tabSize = SizeOfTab(textPtr, tabStyle, tabArrayPtr,
+ &tabIndex, x, maxX);
if ((maxX >= 0) && (tabSize >= maxX - x)) {
break;
}
@@ -6588,15 +6632,15 @@ DlineXOfIndex(textPtr, dlPtr, byteIndex)
/*
*----------------------------------------------------------------------
*
- * TkTextCharBbox --
+ * TkTextIndexBbox --
*
* Given an index, find the bounding box of the screen area occupied by
- * that character.
+ * the entity (character, window, image) at that index.
*
* Results:
- * Zero is returned if the character is on the screen. -1 means the
- * character isn't on the screen. If the return value is 0, then the
- * bounding box of the part of the character that's visible on the screen
+ * Zero is returned if the index is on the screen. -1 means the
+ * index isn't on the screen. If the return value is 0, then the
+ * bounding box of the part of the index that's visible on the screen
* is returned to *xPtr, *yPtr, *widthPtr, and *heightPtr.
*
* Side effects:
@@ -6606,17 +6650,17 @@ DlineXOfIndex(textPtr, dlPtr, byteIndex)
*/
int
-TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr, charWidthPtr)
+TkTextIndexBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr, charWidthPtr)
TkText *textPtr; /* Widget record for text widget. */
- CONST TkTextIndex *indexPtr;/* Index of character whose bounding box is
- * desired. */
- int *xPtr, *yPtr; /* Filled with character's upper-left
+ CONST TkTextIndex *indexPtr;/* Index whose bounding box is desired. */
+ int *xPtr, *yPtr; /* Filled with index's upper-left
* coordinate. */
- int *widthPtr, *heightPtr; /* Filled in with character's dimensions. */
- int *charWidthPtr; /* If the 'character' isn't really a character
- * (e.g. end of a line) and therefore takes up
- * a very large width, this is used to return
- * a smaller width */
+ int *widthPtr, *heightPtr; /* Filled in with index's dimensions. */
+ int *charWidthPtr; /* If the 'index' is at the end of
+ * a display line and therefore takes
+ * up a very large width, this is
+ * used to return the smaller width
+ * actually desired by the index. */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
DLine *dlPtr;
@@ -6686,8 +6730,19 @@ TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr, charWidthPtr)
*charWidthPtr = *widthPtr;
}
}
- if ((*xPtr + *widthPtr) <= dInfoPtr->x) {
- return -1;
+ if (*widthPtr == 0) {
+ /*
+ * With zero width (e.g. elided text) we just need to
+ * make sure it is onscreen, where the '=' case here is
+ * ok.
+ */
+ if (*xPtr < dInfoPtr->x) {
+ return -1;
+ }
+ } else {
+ if ((*xPtr + *widthPtr) <= dInfoPtr->x) {
+ return -1;
+ }
}
if ((*xPtr + *widthPtr) > dInfoPtr->maxX) {
*widthPtr = dInfoPtr->maxX - *xPtr;
@@ -7248,19 +7303,31 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
return;
}
+ x = chunkPtr->nextPtr->x;
+
/*
- * If no tab information has been given, do the usual thing: round up to
- * the next boundary of 8 average-sized characters.
+ * If no tab information has been given, assuming tab stops are
+ * at 8 average-sized characters. Still ensure we respect the
+ * tabular versus wordprocessor tab style.
*/
- x = chunkPtr->nextPtr->x;
if ((tabArrayPtr == NULL) || (tabArrayPtr->numTabs == 0)) {
/*
* No tab information has been given, so use the default
* interpretation of tabs.
*/
- desired = NextTabStop(textPtr->tkfont, x, 0);
+ if (textPtr->tabStyle == TK_TEXT_TABSTYLE_TABULAR) {
+ int tabWidth = Tk_TextWidth(textPtr->tkfont, "0", 1) * 8;
+ if (tabWidth == 0) {
+ tabWidth = 1;
+ }
+
+ desired = tabWidth * (index + 1);
+ } else {
+ desired = NextTabStop(textPtr->tkfont, x, 0);
+ }
+
goto update;
}
@@ -7399,9 +7466,11 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
*/
static int
-SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX)
+SizeOfTab(textPtr, tabStyle, tabArrayPtr, indexPtr, x, maxX)
TkText *textPtr; /* Information about the text widget as a
* whole. */
+ int tabStyle; /* One of TK_TEXT_TABSTYLE_TABULAR
+ * or TK_TEXT_TABSTYLE_WORDPROCESSOR. */
TkTextTabArray *tabArrayPtr;/* Information about the tab stops that apply
* to this line. NULL means use default
* tabbing (every 8 chars.) */
@@ -7412,29 +7481,33 @@ SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX)
int maxX; /* X-location of pixel just past the right
* edge of the line. */
{
- int tabX, result, index, spaceWidth;
+ int tabX, result, index, spaceWidth, tabWidth;
TkTextTabAlign alignment;
index = *indexPtr;
if ((tabArrayPtr == NULL) || (tabArrayPtr->numTabs == 0)) {
- tabX = NextTabStop(textPtr->tkfont, x, 0);
-
- /*
- * We used up one tab stop.
- */
-
- *indexPtr = index+1;
- return tabX - x;
+ /* We're using a default tab spacing of 8 characters */
+ tabWidth = Tk_TextWidth(textPtr->tkfont, "0", 1) * 8;
+ if (tabWidth == 0) {
+ tabWidth = 1;
+ }
+ } else {
+ tabWidth = 0; /* Avoid compiler error */
}
-
+
do {
/*
* We were given the count before this tab, so increment it first.
*/
index++;
- if (index < tabArrayPtr->numTabs) {
+
+ if ((tabArrayPtr == NULL) || (tabArrayPtr->numTabs == 0)) {
+ /* We're using a default tab spacing calculated above */
+ tabX = tabWidth * (index + 1);
+ alignment = LEFT;
+ } else if (index < tabArrayPtr->numTabs) {
tabX = tabArrayPtr->tabs[index].location;
alignment = tabArrayPtr->tabs[index].alignment;
} else {
@@ -7449,10 +7522,16 @@ SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX)
}
/*
- * If this tab stop is before the current x position, then we must
- * obviously continue until we reach the text tab stop.
+ * If this tab stop is before the current x position, then we
+ * have two cases:
+ *
+ * With 'wordprocessor' style tabs, we must obviously continue
+ * until we reach the text tab stop.
+ *
+ * With 'tabular' style tabs, we always use the index'th tab
+ * stop.
*/
- } while (tabX < x);
+ } while (tabX < x && (tabStyle == TK_TEXT_TABSTYLE_WORDPROCESSOR));
/*
* Inform our caller of how many tab stops we've used up.
@@ -7506,7 +7585,8 @@ SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX)
* Given the current position, determine where the next default tab stop
* would be located. This function is called when the current chunk in
* the text has no tabs defined and so the default tab spacing for the
- * font should be used.
+ * font should be used, provided we are using wordprocessor
+ * style tabs.
*
* Results:
* The location in pixels of the next tab stop.
@@ -7733,11 +7813,3 @@ TextGetScrollInfoObj(interp, textPtr, objc, objv, dblPtr, intPtr)
"\": must be moveto or scroll", (char *) NULL);
return TKTEXT_SCROLL_ERROR;
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/generic/tkTextImage.c b/generic/tkTextImage.c
index fa95e3c..767fef9 100644
--- a/generic/tkTextImage.c
+++ b/generic/tkTextImage.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextImage.c,v 1.15 2005/08/10 22:02:22 dkf Exp $
+ * RCS: @(#) $Id: tkTextImage.c,v 1.16 2005/10/10 10:36:35 vincentdarley Exp $
*/
#include "tk.h"
@@ -268,7 +268,7 @@ TkTextImageCmd(textPtr, interp, objc, objv)
TkTextIndex index2;
TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);
- TkBTreeDeleteChars(textPtr->sharedTextPtr->tree, &index, &index2);
+ TkBTreeDeleteIndexRange(textPtr->sharedTextPtr->tree, &index, &index2);
return TCL_ERROR;
}
TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,
@@ -834,11 +834,3 @@ EmbImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
TkTextInvalidateLineMetrics(eiPtr->body.ei.sharedTextPtr, NULL,
index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c
index 127b397..c9ddab3 100644
--- a/generic/tkTextIndex.c
+++ b/generic/tkTextIndex.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextIndex.c,v 1.22 2005/08/10 22:02:22 dkf Exp $
+ * RCS: @(#) $Id: tkTextIndex.c,v 1.23 2005/10/10 10:36:35 vincentdarley Exp $
*/
#include "default.h"
@@ -2303,11 +2303,3 @@ StartEnd(textPtr, string, indexPtr)
done:
return p;
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c
index 0c56b4a..4354ede 100644
--- a/generic/tkTextMark.c
+++ b/generic/tkTextMark.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextMark.c,v 1.14 2005/07/18 22:12:05 vincentdarley Exp $
+ * RCS: @(#) $Id: tkTextMark.c,v 1.15 2005/10/10 10:36:35 vincentdarley Exp $
*/
#include "tkInt.h"
@@ -595,7 +595,7 @@ TkTextInsertDisplayProc(textPtr, chunkPtr, x, y, height, baseline, display,
if(textPtr->insertCursorType) {
TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
- TkTextCharBbox(textPtr, &index, &ix, &iy, &iw, &ih, &charWidth);
+ TkTextIndexBbox(textPtr, &index, &ix, &iy, &iw, &ih, &charWidth);
rightSideWidth = charWidth + halfWidth;
} else {
rightSideWidth = halfWidth;
diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c
index 00d350a..540c0af 100644
--- a/generic/tkTextTag.c
+++ b/generic/tkTextTag.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextTag.c,v 1.20 2005/08/10 22:02:22 dkf Exp $
+ * RCS: @(#) $Id: tkTextTag.c,v 1.21 2005/10/10 10:36:35 vincentdarley Exp $
*/
#include "default.h"
@@ -30,6 +30,17 @@ static char *wrapStrings[] = {
"char", "none", "word", "", (char *) NULL
};
+/*
+ * The 'TkTextTabStyle' enum in tkText.h is used to define a type for
+ * the -tabstyle option of the Text widget. These values are used as
+ * indices into the string table below. Tags are allowed an empty wrap
+ * value, but the widget as a whole is not.
+ */
+
+static char *tabStyleStrings[] = {
+ "tabular", "wordprocessor", "", (char *) NULL
+};
+
static Tk_OptionSpec tagOptionSpecs[] = {
{TK_OPTION_BORDER, "-background", (char *) NULL, (char *) NULL,
NULL, -1, Tk_Offset(TkTextTag, border), TK_OPTION_NULL_OK, 0, 0},
@@ -70,6 +81,9 @@ static Tk_OptionSpec tagOptionSpecs[] = {
NULL, -1, Tk_Offset(TkTextTag, spacing3String), TK_OPTION_NULL_OK,0,0},
{TK_OPTION_STRING, "-tabs", (char *) NULL, (char *) NULL,
NULL, Tk_Offset(TkTextTag, tabStringPtr), -1, TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING_TABLE, "-tabstyle", (char *) NULL, (char *) NULL,
+ (char *) NULL, -1, Tk_Offset(TkTextTag, tabStyle),
+ TK_OPTION_NULL_OK, (ClientData) tabStyleStrings, 0},
{TK_OPTION_STRING, "-underline", (char *) NULL, (char *) NULL,
(char *) NULL, -1, Tk_Offset(TkTextTag, underlineString),
TK_OPTION_NULL_OK, 0, 0},
@@ -483,6 +497,7 @@ TkTextTagCmd(textPtr, interp, objc, objv)
|| (tagPtr->spacing2String != NULL)
|| (tagPtr->spacing3String != NULL)
|| (tagPtr->tabStringPtr != NULL)
+ || (tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE)
|| (tagPtr->wrapMode != TEXT_WRAPMODE_NULL)) {
tagPtr->affectsDisplay = 1;
tagPtr->affectsDisplayGeometry = 1;
@@ -996,6 +1011,7 @@ TkTextCreateTag(textPtr, tagName, newTag)
tagPtr->spacing3 = 0;
tagPtr->tabStringPtr = NULL;
tagPtr->tabArrayPtr = NULL;
+ tagPtr->tabStyle = TK_TEXT_TABSTYLE_NONE;
tagPtr->underlineString = NULL;
tagPtr->underline = 0;
tagPtr->elideString = NULL;
@@ -1723,11 +1739,3 @@ TagBindEvent(textPtr, eventPtr, numTags, tagArrayPtr)
ckfree((char*)nameArrPtr);
}
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/generic/tkTextWind.c b/generic/tkTextWind.c
index 95dcf03..07c4a26 100644
--- a/generic/tkTextWind.c
+++ b/generic/tkTextWind.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextWind.c,v 1.14 2004/10/05 01:26:10 hobbs Exp $
+ * RCS: @(#) $Id: tkTextWind.c,v 1.15 2005/10/10 10:36:35 vincentdarley Exp $
*/
#include "tk.h"
@@ -331,7 +331,7 @@ TkTextWindowCmd(textPtr, interp, objc, objv)
TkTextIndex index2;
TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);
- TkBTreeDeleteChars(textPtr->sharedTextPtr->tree, &index, &index2);
+ TkBTreeDeleteIndexRange(textPtr->sharedTextPtr->tree, &index, &index2);
return TCL_ERROR;
}
TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,