Skip to content

Commit

Permalink
(backport): Merge tip-706 following positive vote by the TCT
Browse files Browse the repository at this point in the history
  • Loading branch information
jan.nijtmans committed Dec 8, 2024
1 parent 97e4263 commit 65e305a
Show file tree
Hide file tree
Showing 21 changed files with 147 additions and 79 deletions.
36 changes: 29 additions & 7 deletions doc/MeasureChar.3
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,29 @@
.so man.macros
.BS
.SH NAME
Tk_MeasureChars, Tk_TextWidth, Tk_DrawChars, Tk_UnderlineChars \- routines to measure and display simple single-line strings.
Tk_MeasureChars, Tk_MeasureCharsInContext, Tk_TextWidth, Tk_DrawChars, Tk_DrawCharsInContext,
Tk_UnderlineChars, Tk_UnderlineCharsInContext \- routines to measure and display simple single-line strings.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_MeasureChars(\fItkfont, string, numBytes, maxPixels, flags, lengthPtr\fB)\fR
\fBTk_MeasureChars\fR(\fItkfont, string, numBytes, maxPixels, flags, lengthPtr\fR)
.sp
int
\fBTk_TextWidth(\fItkfont, string, numBytes\fB)\fR
\fBTk_MeasureCharsInContext\fR(\fItkfont, string, numBytes, rangeStart, rangeLength, maxPixels, flags, lengthPtr\fR)
.sp
\fBTk_DrawChars(\fIdisplay, drawable, gc, tkfont, string, numBytes, x, y\fB)\fR
int
\fBTk_TextWidth\fR(\fItkfont, string, numBytes\fR)
.sp
\fBTk_DrawChars\fR(\fIdisplay, drawable, gc, tkfont, string, numBytes, x, y\fR)
.sp
\fBTk_UnderlineChars(\fIdisplay, drawable, gc, tkfont, string, x, y, firstByte, lastByte\fB)\fR
\fBTk_DrawCharsInContext\fR(\fIdisplay, drawable, gc, tkfont, string, numBytes, rangeStart, rangeLength, x, y\fR)
.sp
\fBTk_UnderlineChars\fR(\fIdisplay, drawable, gc, tkfont, string, x, y, firstByte, lastByte\fR)
.sp
\fBTk_UnderlineCharsInContext\fR(\fIdisplay, drawable, gc, tkfont, string, numBytes, x, y, firstByte, lastByte\fR)
.fi
.SH ARGUMENTS
.AS "const char" firstChar
.AP Tk_Font tkfont in
Expand All @@ -48,10 +56,13 @@ otherwise, a character must fit completely to be considered.
\fBTK_WHOLE_WORDS\fR means stop on a word boundary, if possible. If
\fBTK_AT_LEAST_ONE\fR is set, it means return at least one character even if no
characters could fit in the length given by \fImaxPixels\fR. If
\fBTK_AT_LEAST_ONE\fR is set and \fBTK_WHOLE_WORDS\fR is also set, it means that if
not even one word fits on the line, return the first few letters of the
\fBTK_AT_LEAST_ONE\fR is set and \fBTK_WHOLE_WORDS\fR is also set, it means
that if not even one word fits on the line, return the first few letters of the
word that did fit; if not even one letter of the word fit, then the first
letter will still be returned.
\fBTK_ISOLATE_END\fR means that the last character should not be considered in
context with the rest of the string (used for breaking lines, with the
Tk_*InContext variants of the functions only).
.AP int *lengthPtr out
Filled with the number of pixels occupied by the number of characters
returned as the result of \fBTk_MeasureChars\fR.
Expand All @@ -72,6 +83,10 @@ The index of the first byte of the first character to underline in the
The index of the first byte of the last character up to which the
underline will be drawn. The character specified by \fIlastByte\fR
will not itself be underlined.
.AP int rangeStart in
Index of first byte to draw or to measure.
.AP int rangeLength in
Length of range to draw or to measure, in bytes.
.BE
.SH DESCRIPTION
.PP
Expand Down Expand Up @@ -121,6 +136,13 @@ have been displayed previously by \fBTk_DrawChars\fR); it just draws the
underline. This procedure is used to underline a few characters without
having to construct an underlined font. To produce natively underlined
text, the appropriate underlined font should be constructed and used.
.PP
\fBTk_MeasureCharsInContext\fR, \fBTk_DrawCharsInContext\fR,
\fBTk_UnderlineCharsInContext\fR are variants of respectively
\fBTk_MeasureChars\fR, \fBTk_DrawChars\fR and \fBTk_UnderlineChars\fR,
but with access to all the characters on the line for context. Except
on macOS, this context isn't actually consulted (meaning the out of
context variants are called).
.SH "SEE ALSO"
font(n), FontId(3)
.SH KEYWORDS
Expand Down
30 changes: 30 additions & 0 deletions generic/tk.decls
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,9 @@ declare 273 {
void Tk_CreateOldPhotoImageFormat(const Tk_PhotoImageFormat *formatPtr)
}

# ----- BASELINE -- FOR -- 8.6.0 ----- #


# TIP#580
declare 274 {
int Tk_AlwaysShowSelection(Tk_Window tkwin)
Expand Down Expand Up @@ -1134,6 +1137,33 @@ declare 290 {
Window Tk_MakeWindow(Tk_Window tkwin, Window parent)
}

# ----- BASELINE -- FOR -- 9.0.0 ----- #

# TIP#706
declare 291 {
void Tk_UnderlineCharsInContext(Display *display,
Drawable drawable, GC gc, Tk_Font tkfont,
const char *string, Tcl_Size numBytes, int x, int y,
Tcl_Size firstByte, Tcl_Size lastByte)
}
declare 292 {
void Tk_DrawCharsInContext(Display * display,
Drawable drawable, GC gc, Tk_Font tkfont,
const char *string, Tcl_Size numBytes, Tcl_Size rangeStart,
Tcl_Size rangeLength, int x, int y)
}
declare 293 {
int Tk_MeasureCharsInContext(Tk_Font tkfont,
const char *string, Tcl_Size numBytes, Tcl_Size rangeStart,
Tcl_Size rangeLength, int maxPixels, int flags,
int *lengthPtr)
}

# ----- BASELINE -- FOR -- 8.7.0 / 9.0.1 ----- #

declare 294 {
void TkUnusedStubEntry(void)
}

# Define the platform specific public Tk interface. These functions are
# only available on the designated platform.
Expand Down
5 changes: 3 additions & 2 deletions generic/tk.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#define _TK

#include <tcl.h>
#if (TCL_MAJOR_VERSION < 8) || (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)
#if (TCL_MAJOR_VERSION < 8) || (defined(TCL_MINOR_VERSION) && (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6))
# error Tk 8.7 must be compiled with tcl.h from Tcl 8.6 or better
#endif

Expand Down Expand Up @@ -146,7 +146,7 @@ typedef struct Tk_StyledElement_ *Tk_StyledElement;

typedef const char *Tk_Uid;

#if (TCL_MAJOR_VERSION < 9) && (TCL_MINOR_VERSION < 7)
#if (TCL_MAJOR_VERSION < 9) && defined(TCL_MINOR_VERSION) && (TCL_MINOR_VERSION < 7)
# ifndef Tcl_Size
# define Tcl_Size int
# endif
Expand Down Expand Up @@ -585,6 +585,7 @@ typedef struct Tk_FontMetrics {
#define TK_WHOLE_WORDS 1
#define TK_AT_LEAST_ONE 2
#define TK_PARTIAL_OK 4
#define TK_ISOLATE_END 32

/*
* Flags passed to Tk_ComputeTextLayout:
Expand Down
30 changes: 30 additions & 0 deletions generic/tkDecls.h
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,24 @@ EXTERN void Tk_Get3DBorderColors(Tk_3DBorder border,
XColor *lightColorPtr);
/* 290 */
EXTERN Window Tk_MakeWindow(Tk_Window tkwin, Window parent);
/* 291 */
EXTERN void Tk_UnderlineCharsInContext(Display *display,
Drawable drawable, GC gc, Tk_Font tkfont,
const char *string, Tcl_Size numBytes, int x,
int y, Tcl_Size firstByte, Tcl_Size lastByte);
/* 292 */
EXTERN void Tk_DrawCharsInContext(Display *display,
Drawable drawable, GC gc, Tk_Font tkfont,
const char *string, Tcl_Size numBytes,
Tcl_Size rangeStart, Tcl_Size rangeLength,
int x, int y);
/* 293 */
EXTERN int Tk_MeasureCharsInContext(Tk_Font tkfont,
const char *string, Tcl_Size numBytes,
Tcl_Size rangeStart, Tcl_Size rangeLength,
int maxPixels, int flags, int *lengthPtr);
/* 294 */
EXTERN void TkUnusedStubEntry(void);

typedef struct {
const struct TkPlatStubs *tkPlatStubs;
Expand Down Expand Up @@ -1228,6 +1246,10 @@ typedef struct TkStubs {
Tk_Window (*tk_GetOtherWindow) (Tk_Window tkwin); /* 288 */
void (*tk_Get3DBorderColors) (Tk_3DBorder border, XColor *bgColorPtr, XColor *darkColorPtr, XColor *lightColorPtr); /* 289 */
Window (*tk_MakeWindow) (Tk_Window tkwin, Window parent); /* 290 */
void (*tk_UnderlineCharsInContext) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *string, Tcl_Size numBytes, int x, int y, Tcl_Size firstByte, Tcl_Size lastByte); /* 291 */
void (*tk_DrawCharsInContext) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *string, Tcl_Size numBytes, Tcl_Size rangeStart, Tcl_Size rangeLength, int x, int y); /* 292 */
int (*tk_MeasureCharsInContext) (Tk_Font tkfont, const char *string, Tcl_Size numBytes, Tcl_Size rangeStart, Tcl_Size rangeLength, int maxPixels, int flags, int *lengthPtr); /* 293 */
void (*tkUnusedStubEntry) (void); /* 294 */
} TkStubs;

extern const TkStubs *tkStubsPtr;
Expand Down Expand Up @@ -1822,6 +1844,14 @@ extern const TkStubs *tkStubsPtr;
(tkStubsPtr->tk_Get3DBorderColors) /* 289 */
#define Tk_MakeWindow \
(tkStubsPtr->tk_MakeWindow) /* 290 */
#define Tk_UnderlineCharsInContext \
(tkStubsPtr->tk_UnderlineCharsInContext) /* 291 */
#define Tk_DrawCharsInContext \
(tkStubsPtr->tk_DrawCharsInContext) /* 292 */
#define Tk_MeasureCharsInContext \
(tkStubsPtr->tk_MeasureCharsInContext) /* 293 */
#define TkUnusedStubEntry \
(tkStubsPtr->tkUnusedStubEntry) /* 294 */

#endif /* defined(USE_TK_STUBS) */

Expand Down
14 changes: 7 additions & 7 deletions generic/tkFont.c
Original file line number Diff line number Diff line change
Expand Up @@ -1855,7 +1855,7 @@ Tk_TextWidth(
/*
*---------------------------------------------------------------------------
*
* Tk_UnderlineChars, TkUnderlineCharsInContext --
* Tk_UnderlineChars, Tk_UnderlineCharsInContext --
*
* These procedures draw an underline for a given range of characters in
* a given string. They don't draw the characters (which are assumed to
Expand Down Expand Up @@ -1891,12 +1891,12 @@ Tk_UnderlineChars(
Tcl_Size lastByte) /* Index of first byte after the last
* character. */
{
TkUnderlineCharsInContext(display, drawable, gc, tkfont, string,
Tk_UnderlineCharsInContext(display, drawable, gc, tkfont, string,
lastByte, x, y, firstByte, lastByte);
}

void
TkUnderlineCharsInContext(
Tk_UnderlineCharsInContext(
Display *display, /* Display on which to draw. */
Drawable drawable, /* Window or pixmap in which to draw. */
GC gc, /* Graphics context for actually drawing
Expand All @@ -1916,9 +1916,9 @@ TkUnderlineCharsInContext(
TkFont *fontPtr = (TkFont *) tkfont;
int startX, endX;

TkpMeasureCharsInContext(tkfont, string, numBytes, 0, firstByte, -1, 0,
Tk_MeasureCharsInContext(tkfont, string, numBytes, 0, firstByte, -1, 0,
&startX);
TkpMeasureCharsInContext(tkfont, string, numBytes, 0, lastByte, -1, 0,
Tk_MeasureCharsInContext(tkfont, string, numBytes, 0, lastByte, -1, 0,
&endX);

XFillRectangle(display, drawable, gc, x + startX,
Expand Down Expand Up @@ -2342,7 +2342,7 @@ Tk_DrawTextLayout(
}
lastByte = TkUtfAtIndex(chunkPtr->start, numDisplayChars);
#ifdef TK_DRAW_IN_CONTEXT
TkpDrawCharsInContext(display, drawable, gc, layoutPtr->tkfont,
Tk_DrawCharsInContext(display, drawable, gc, layoutPtr->tkfont,
chunkPtr->start, chunkPtr->numBytes,
firstByte - chunkPtr->start, lastByte - firstByte,
x+chunkPtr->x, y+chunkPtr->y);
Expand Down Expand Up @@ -2415,7 +2415,7 @@ TkDrawAngledTextLayout(
dx = cosA * (chunkPtr->x) + sinA * (chunkPtr->y);
dy = -sinA * (chunkPtr->x) + cosA * (chunkPtr->y);
if (angle == 0.0) {
TkpDrawCharsInContext(display, drawable, gc,
Tk_DrawCharsInContext(display, drawable, gc,
layoutPtr->tkfont, chunkPtr->start, chunkPtr->numBytes,
firstByte - chunkPtr->start, lastByte - firstByte,
(int)(x + dx), (int)(y + dy));
Expand Down
24 changes: 2 additions & 22 deletions generic/tkInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
# endif
#endif

#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 7)
#if (TCL_MAJOR_VERSION == 8) && defined(TCL_MINOR_VERSION) && (TCL_MINOR_VERSION < 7)
# define Tcl_WCharToUtfDString ((char * (*)(const WCHAR *, int, Tcl_DString *))Tcl_UniCharToUtfDString)
# define Tcl_UtfToWCharDString ((WCHAR * (*)(const char *, int, Tcl_DString *))Tcl_UtfToUniCharDString)
# define Tcl_Char16ToUtfDString Tcl_UniCharToUtfDString
Expand Down Expand Up @@ -118,7 +118,7 @@
# define TKFLEXARRAY 1
#endif

#if !defined(Tcl_GetParent) && (TCL_MAJOR_VERSION < 9) && (TCL_MINOR_VERSION < 7)
#if !defined(Tcl_GetParent) && (TCL_MAJOR_VERSION < 9) && defined(TCL_MINOR_VERSION) && (TCL_MINOR_VERSION < 7)
# define Tcl_GetParent Tcl_GetMaster
#endif

Expand Down Expand Up @@ -1057,14 +1057,6 @@ typedef struct TkpClipMask {
#define TK_GRAB_ANCESTOR 2
#define TK_GRAB_EXCLUDED 3

/*
* Additional flag for TkpMeasureCharsInContext. Coordinate with other flags
* for this routine, but don't make public until TkpMeasureCharsInContext is
* made public, too.
*/

#define TK_ISOLATE_END 32

/*
* The macro below is used to modify a "char" value (e.g. by casting it to an
* unsigned character) so that it can be used safely with macros such as
Expand Down Expand Up @@ -1309,22 +1301,10 @@ MODULE_SCOPE int TkParsePadAmount(Tcl_Interp *interp,
int *pad1Ptr, int *pad2Ptr);
MODULE_SCOPE void TkFocusSplit(TkWindow *winPtr);
MODULE_SCOPE void TkFocusJoin(TkWindow *winPtr);
MODULE_SCOPE void TkpDrawCharsInContext(Display * display,
Drawable drawable, GC gc, Tk_Font tkfont,
const char *source, Tcl_Size numBytes, Tcl_Size rangeStart,
Tcl_Size rangeLength, int x, int y);
MODULE_SCOPE void TkpDrawAngledCharsInContext(Display * display,
Drawable drawable, GC gc, Tk_Font tkfont,
const char *source, Tcl_Size numBytes, Tcl_Size rangeStart,
Tcl_Size rangeLength, double x, double y, double angle);
MODULE_SCOPE int TkpMeasureCharsInContext(Tk_Font tkfont,
const char *source, Tcl_Size numBytes, Tcl_Size rangeStart,
Tcl_Size rangeLength, int maxLength, int flags,
int *lengthPtr);
MODULE_SCOPE void TkUnderlineCharsInContext(Display *display,
Drawable drawable, GC gc, Tk_Font tkfont,
const char *string, Tcl_Size numBytes, int x, int y,
Tcl_Size firstByte, Tcl_Size lastByte);
MODULE_SCOPE void TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont,
int c, struct TkFontAttributes *faPtr);
MODULE_SCOPE void TkpDrawFrameEx(Tk_Window tkwin, Drawable drawable,
Expand Down
2 changes: 1 addition & 1 deletion generic/tkMessage.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ static const Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL,
0, TCL_INDEX_NONE, 0, "-background", 0},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_MESSAGE_BORDER_WIDTH, TCL_INDEX_NONE,
DEF_MESSAGE_BORDER_WIDTH, TCL_INDEX_NONE,
offsetof(Message, borderWidth), 0, 0, 0},
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
DEF_MESSAGE_CURSOR, TCL_INDEX_NONE, offsetof(Message, cursor),
Expand Down
2 changes: 1 addition & 1 deletion generic/tkObj.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ extern const TclIntStubs *tclIntStubsPtr;
# define Tcl_GetIntForIndex(interp, obj, max, ptr) ((tclIntStubsPtr->tclGetIntForIndex == NULL)? \
((int (*)(Tcl_Interp*, Tcl_Obj *, int, int*))(void *)((&(tclStubsPtr->tcl_PkgProvideEx))[645]))((interp), (obj), (max), (ptr)): \
tclIntStubsPtr->tclGetIntForIndex((interp), (obj), (max), (ptr)))
#elif TCL_MINOR_VERSION < 7
#elif defined(TCL_MINOR_VERSION) && (TCL_MINOR_VERSION < 7)
extern int TclGetIntForIndex(Tcl_Interp*, Tcl_Obj *, int, int*);
# define Tcl_GetIntForIndex(interp, obj, max, ptr) TclGetIntForIndex(interp, obj, max, ptr)
#endif
Expand Down
5 changes: 5 additions & 0 deletions generic/tkStubInit.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ MODULE_SCOPE const TkStubs tkStubs;
#define TkMacOSXIsCharacterMissing (int (*)(Tk_Font, unsigned int))(void *)doNothing
#undef TkMacOSXSetDrawingEnabled
#define TkMacOSXSetDrawingEnabled (void (*)(TkWindow *, int))(void *)doNothing
#define TkUnusedStubEntry 0


#if defined(_WIN32) && !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
Expand Down Expand Up @@ -1345,6 +1346,10 @@ const TkStubs tkStubs = {
Tk_GetOtherWindow, /* 288 */
Tk_Get3DBorderColors, /* 289 */
Tk_MakeWindow, /* 290 */
Tk_UnderlineCharsInContext, /* 291 */
Tk_DrawCharsInContext, /* 292 */
Tk_MeasureCharsInContext, /* 293 */
TkUnusedStubEntry, /* 294 */
};

/* !END!: Do not edit above this line. */
Expand Down
10 changes: 5 additions & 5 deletions generic/tkTextDisp.c
Original file line number Diff line number Diff line change
Expand Up @@ -8036,13 +8036,13 @@ CharDisplayProc(
return;
}

TkpDrawCharsInContext(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
Tk_DrawCharsInContext(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
string, numBytes, start, len,
ciPtr->baseChunkPtr->x + xDisplacement,
y + baseline - sValuePtr->offset);

if (sValuePtr->underline) {
TkUnderlineCharsInContext(display, dst, stylePtr->ulGC,
Tk_UnderlineCharsInContext(display, dst, stylePtr->ulGC,
sValuePtr->tkfont, string, numBytes,
ciPtr->baseChunkPtr->x + xDisplacement,
y + baseline - sValuePtr->offset,
Expand All @@ -8052,7 +8052,7 @@ CharDisplayProc(
Tk_FontMetrics fm;

Tk_GetFontMetrics(sValuePtr->tkfont, &fm);
TkUnderlineCharsInContext(display, dst, stylePtr->ovGC,
Tk_UnderlineCharsInContext(display, dst, stylePtr->ovGC,
sValuePtr->tkfont, string, numBytes,
ciPtr->baseChunkPtr->x + xDisplacement,
y + baseline - sValuePtr->offset
Expand Down Expand Up @@ -8698,7 +8698,7 @@ MeasureChars(
break;
}
#ifdef TK_DRAW_IN_CONTEXT
start += TkpMeasureCharsInContext(tkfont, source, maxBytes,
start += Tk_MeasureCharsInContext(tkfont, source, maxBytes,
start - source, special - start,
maxX >= 0 ? maxX - curX : -1, flags, &width);
#else
Expand Down Expand Up @@ -8982,7 +8982,7 @@ FreeBaseChunk(
* elide, "offset" and foreground stipple. Do *not* consider: background
* color, border, relief or background stipple.
*
* If we use TkpDrawCharsInContext(), we also don't need to check
* If we use Tk_DrawCharsInContext(), we also don't need to check
* foreground color, font decorations, elide, offset and foreground
* stipple, so all that is left is font (including font size and font
* style) and "offset".
Expand Down
2 changes: 1 addition & 1 deletion macosx/tkMacOSXDraw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1482,7 +1482,7 @@ TkMacOSXRestoreDrawingContext(
* Mark the view as needing to be redisplayed, since we have drawn on its
* backing layer.
*/

[dcPtr->view setNeedsDisplay:YES];

#ifdef TK_MAC_DEBUG
Expand Down
Loading

0 comments on commit 65e305a

Please sign in to comment.