Import Tk 8.6.11

This commit is contained in:
Steve Dower
2021-03-30 00:54:10 +01:00
parent 42c69189d9
commit 070b8750b0
403 changed files with 21608 additions and 16269 deletions

View File

@@ -12,7 +12,6 @@
#include "tkUnixInt.h"
#include "tkFont.h"
#include <X11/Xft/Xft.h>
#include <ctype.h>
#define MAX_CACHED_COLORS 16
@@ -61,9 +60,13 @@ static Tcl_ThreadDataKey dataKey;
* the TIP 59 configuration database.
*/
#ifndef TCL_CFGVAL_ENCODING
#define TCL_CFGVAL_ENCODING "ascii"
#endif
static int utf8ToUcs4(const char *source, FcChar32 *c, int numBytes)
{
if (numBytes >= 6) {
return TkUtfToUniChar(source, (int *)c);
}
return FcUtf8ToUcs4((const FcChar8 *)source, c, numBytes);
}
void
TkpFontPkgInit(
@@ -74,7 +77,7 @@ TkpFontPkgInit(
{ 0,0 }
};
Tcl_RegisterConfig(mainPtr->interp, "tk", cfg, TCL_CFGVAL_ENCODING);
Tcl_RegisterConfig(mainPtr->interp, "tk", cfg, "utf-8");
}
static XftFont *
@@ -247,6 +250,23 @@ GetTkFontMetrics(
*---------------------------------------------------------------------------
*/
static void
FinishedWithFont(
UnixFtFont *fontPtr);
static int
InitFontErrorProc(
ClientData clientData,
TCL_UNUSED(XErrorEvent *))
{
int *errorFlagPtr = (int *)clientData;
if (errorFlagPtr != NULL) {
*errorFlagPtr = 1;
}
return 0;
}
static UnixFtFont *
InitFont(
Tk_Window tkwin,
@@ -257,10 +277,11 @@ InitFont(
FcCharSet *charset;
FcResult result;
XftFont *ftFont;
int i, iWidth;
int i, iWidth, errorFlag;
Tk_ErrorHandler handler;
if (!fontPtr) {
fontPtr = ckalloc(sizeof(UnixFtFont));
fontPtr = (UnixFtFont *)ckalloc(sizeof(UnixFtFont));
}
FcConfigSubstitute(0, pattern, FcMatchPattern);
@@ -271,14 +292,14 @@ InitFont(
*/
set = FcFontSort(0, pattern, FcTrue, NULL, &result);
if (!set) {
if (!set || set->nfont == 0) {
ckfree(fontPtr);
return NULL;
}
fontPtr->fontset = set;
fontPtr->pattern = pattern;
fontPtr->faces = ckalloc(set->nfont * sizeof(UnixFtFace));
fontPtr->faces = (UnixFtFace *)ckalloc(set->nfont * sizeof(UnixFtFace));
fontPtr->nfaces = set->nfont;
/*
@@ -308,10 +329,25 @@ InitFont(
* Fill in platform-specific fields of TkFont.
*/
errorFlag = 0;
handler = Tk_CreateErrorHandler(Tk_Display(tkwin),
-1, -1, -1, InitFontErrorProc, (ClientData) &errorFlag);
ftFont = GetFont(fontPtr, 0, 0.0);
if ((ftFont == NULL) || errorFlag) {
Tk_DeleteErrorHandler(handler);
FinishedWithFont(fontPtr);
ckfree(fontPtr);
return NULL;
}
fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed");
GetTkFontAttributes(ftFont, &fontPtr->font.fa);
GetTkFontMetrics(ftFont, &fontPtr->font.fm);
Tk_DeleteErrorHandler(handler);
if (errorFlag) {
FinishedWithFont(fontPtr);
ckfree(fontPtr);
return NULL;
}
/*
* Fontconfig can't report any information about the position or thickness
@@ -336,7 +372,16 @@ InitFont(
TkFont *fPtr = &fontPtr->font;
fPtr->underlinePos = fPtr->fm.descent / 2;
handler = Tk_CreateErrorHandler(Tk_Display(tkwin),
-1, -1, -1, InitFontErrorProc, (ClientData) &errorFlag);
errorFlag = 0;
Tk_MeasureChars((Tk_Font) fPtr, "I", 1, -1, 0, &iWidth);
Tk_DeleteErrorHandler(handler);
if (errorFlag) {
FinishedWithFont(fontPtr);
ckfree(fontPtr);
return NULL;
}
fPtr->underlineHeight = iWidth / 3;
if (fPtr->underlineHeight == 0) {
fPtr->underlineHeight = 1;
@@ -616,7 +661,7 @@ TkpGetSubFonts(
void
TkpGetFontAttrsForChar(
Tk_Window tkwin, /* Window on the font's display */
TCL_UNUSED(Tk_Window), /* Window on the font's display */
Tk_Font tkfont, /* Font to query */
int c, /* Character of interest */
TkFontAttributes *faPtr) /* Output: Font attributes */
@@ -661,12 +706,15 @@ Tk_MeasureChars(
FcChar32 c;
XGlyphInfo extents;
int clen, curX, newX, curByte, newByte, sawNonSpace;
int termByte = 0, termX = 0;
int termByte = 0, termX = 0, errorFlag = 0;
Tk_ErrorHandler handler;
#if DEBUG_FONTSEL
char string[256];
int len = 0;
#endif /* DEBUG_FONTSEL */
handler = Tk_CreateErrorHandler(fontPtr->display,
-1, -1, -1, InitFontErrorProc, &errorFlag);
curX = 0;
curByte = 0;
sawNonSpace = 0;
@@ -702,7 +750,12 @@ Tk_MeasureChars(
#endif /* DEBUG_FONTSEL */
ftFont = GetFont(fontPtr, c, 0.0);
XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents);
if (!errorFlag) {
XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents);
} else {
extents.xOff = 0;
errorFlag = 0;
}
newX = curX + extents.xOff;
newByte = curByte + clen;
@@ -731,6 +784,7 @@ Tk_MeasureChars(
curX = newX;
curByte = newByte;
}
Tk_DeleteErrorHandler(handler);
#if DEBUG_FONTSEL
string[len] = '\0';
printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte);
@@ -824,7 +878,7 @@ LookUpColor(Display *display, /* Display to lookup colors on */
fontPtr->colors[last].color.color.red = xcolor.red;
fontPtr->colors[last].color.color.green = xcolor.green;
fontPtr->colors[last].color.color.blue = xcolor.blue;
fontPtr->colors[last].color.color.alpha = 0xffff;
fontPtr->colors[last].color.color.alpha = 0xFFFF;
fontPtr->colors[last].color.pixel = pixel;
/*
@@ -886,7 +940,7 @@ Tk_DrawChars(
}
XGetGCValues(display, gc, GCForeground, &values);
xftcolor = LookUpColor(display, fontPtr, values.foreground);
if (tsdPtr->clipRegion != None) {
if (tsdPtr->clipRegion != NULL) {
XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
}
nspec = 0;
@@ -894,7 +948,7 @@ Tk_DrawChars(
XftFont *ftFont;
FcChar32 c;
clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
clen = utf8ToUcs4(source, &c, numBytes);
if (clen <= 0) {
/*
* This should not happen, but it can.
@@ -936,7 +990,7 @@ Tk_DrawChars(
}
doUnderlineStrikeout:
if (tsdPtr->clipRegion != None) {
if (tsdPtr->clipRegion != NULL) {
XftDrawSetClip(fontPtr->ftDraw, NULL);
}
if (fontPtr->font.fa.underline != 0) {
@@ -1028,13 +1082,13 @@ TkDrawAngledChars(
nglyph = 0;
currentFtFont = NULL;
originX = originY = 0; /* lint */
originX = originY = 0;
while (numBytes > 0) {
XftFont *ftFont;
FcChar32 c;
clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
clen = utf8ToUcs4(source, &c, numBytes);
if (clen <= 0) {
/*
* This should not happen, but it can.
@@ -1130,7 +1184,7 @@ TkDrawAngledChars(
}
XGetGCValues(display, gc, GCForeground, &values);
xftcolor = LookUpColor(display, fontPtr, values.foreground);
if (tsdPtr->clipRegion != None) {
if (tsdPtr->clipRegion != NULL) {
XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
}
nspec = 0;
@@ -1138,7 +1192,7 @@ TkDrawAngledChars(
XftFont *ftFont, *ft0Font;
FcChar32 c;
clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
clen = utf8ToUcs4(source, &c, numBytes);
if (clen <= 0) {
/*
* This should not happen, but it can.
@@ -1182,7 +1236,7 @@ TkDrawAngledChars(
#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */
doUnderlineStrikeout:
if (tsdPtr->clipRegion != None) {
if (tsdPtr->clipRegion != NULL) {
XftDrawSetClip(fontPtr->ftDraw, NULL);
}
if (fontPtr->font.fa.underline || fontPtr->font.fa.overstrike) {
@@ -1241,6 +1295,89 @@ TkDrawAngledChars(
}
}
/*
*---------------------------------------------------------------------------
*
* TkpDrawCharsInContext --
*
* Draw a string of characters on the screen like Tk_DrawChars(), but
* with access to all the characters on the line for context. On X11 this
* context isn't consulted, so we just call Tk_DrawChars().
*
* Note: TK_DRAW_IN_CONTEXT being currently defined only on macOS, this
* function is unused (and possibly unfinished). See [7655f65ae7].
*
* Results:
* None.
*
* Side effects:
* Information gets drawn on the screen.
*
*---------------------------------------------------------------------------
*/
void
TkpDrawCharsInContext(
Display *display, /* Display on which to draw. */
Drawable drawable, /* Window or pixmap in which to draw. */
GC gc, /* Graphics context for drawing characters. */
Tk_Font tkfont, /* Font in which characters will be drawn;
* must be the same as font used in GC. */
const char *source, /* UTF-8 string to be displayed. Need not be
* '\0' terminated. All Tk meta-characters
* (tabs, control characters, and newlines)
* should be stripped out of the string that
* is passed to this function. If they are not
* stripped out, they will be displayed as
* regular printing characters. */
int numBytes, /* Number of bytes in string. */
int rangeStart, /* Index of first byte to draw. */
int rangeLength, /* Length of range to draw in bytes. */
int x, int y) /* Coordinates at which to place origin of the
* whole (not just the range) string when
* drawing. */
{
int widthUntilStart;
(void) numBytes; /*unused*/
Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart,
rangeLength, x+widthUntilStart, y);
}
void
TkpDrawAngledCharsInContext(
Display *display, /* Display on which to draw. */
Drawable drawable, /* Window or pixmap in which to draw. */
GC gc, /* Graphics context for drawing characters. */
Tk_Font tkfont, /* Font in which characters will be drawn; must
* be the same as font used in GC. */
const char * source, /* UTF-8 string to be displayed. Need not be
* '\0' terminated. All Tk meta-characters
* (tabs, control characters, and newlines)
* should be stripped out of the string that is
* passed to this function. If they are not
* stripped out, they will be displayed as
* regular printing characters. */
int numBytes, /* Number of bytes in string. */
int rangeStart, /* Index of first byte to draw. */
int rangeLength, /* Length of range to draw in bytes. */
double x, double y, /* Coordinates at which to place origin of the
* whole (not just the range) string when
* drawing. */
double angle) /* What angle to put text at, in degrees. */
{
int widthUntilStart;
double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);
(void) numBytes; /*unused*/
Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
TkDrawAngledChars(display, drawable, gc, tkfont, source + rangeStart,
rangeLength, x+cosA*widthUntilStart, y-sinA*widthUntilStart, angle);
}
void
TkUnixSetXftClipRegion(
TkRegion clipRegion) /* The clipping region to install. */