Tk Source Code

Check-in [b37ded85]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Experimental new function TkUtfCharComplete(), attempt to handle [6c0d7aec67] further on UNIX.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | rfe-6c0d7aec67
Files: files | file ages | folders
SHA1: b37ded8521034126ea20292104a9aa1087e8c009
User & Date: jan.nijtmans 2017-05-02 14:47:09
Context
2017-05-02
15:38
Experimental new functions TkUtfPrev/TkUtfNext check-in: 044d64f8 user: jan.nijtmans tags: rfe-6c0d7aec67
14:47
Experimental new function TkUtfCharComplete(), attempt to handle [6c0d7aec67] further on UNIX. check-in: b37ded85 user: jan.nijtmans tags: rfe-6c0d7aec67
08:41
Typo (wehter -> whether) and minor consistancy in code comment (grey -> gray) check-in: 0793552e user: jan.nijtmans tags: core-8-6-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tkInt.h.

1237
1238
1239
1240
1241
1242
1243

1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
#ifdef HAVE_XFT
MODULE_SCOPE void	TkUnixSetXftClipRegion(TkRegion clipRegion);
#endif

#if TCL_UTF_MAX > 4
#   define TkUtfToUniChar Tcl_UtfToUniChar
#   define TkUniCharToUtf Tcl_UniCharToUtf

#else
    MODULE_SCOPE int TkUtfToUniChar(const char *, int *);
    MODULE_SCOPE int TkUniCharToUtf(int, char *);

#endif

/*
 * Unsupported commands.
 */

MODULE_SCOPE int	TkUnsupported1ObjCmd(ClientData clientData,







>



>







1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
#ifdef HAVE_XFT
MODULE_SCOPE void	TkUnixSetXftClipRegion(TkRegion clipRegion);
#endif

#if TCL_UTF_MAX > 4
#   define TkUtfToUniChar Tcl_UtfToUniChar
#   define TkUniCharToUtf Tcl_UniCharToUtf
#   define TkUtfCharComplete Tcl_UtfCharComplete
#else
    MODULE_SCOPE int TkUtfToUniChar(const char *, int *);
    MODULE_SCOPE int TkUniCharToUtf(int, char *);
    MODULE_SCOPE int TkUtfCharComplete(const char *, int);
#endif

/*
 * Unsupported commands.
 */

MODULE_SCOPE int	TkUnsupported1ObjCmd(ClientData clientData,

Changes to generic/tkUtil.c.

1266
1267
1268
1269
1270
1271
1272













1273
1274
1275
1276
1277
1278
1279
	ch -= 0x10000;
	size = Tcl_UniCharToUtf(((ch >> 10) | 0xd800), buf);
	size += Tcl_UniCharToUtf(((ch & 0x3ff) | 0xdc00), buf+size);
    }
    return size;
}















#endif
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78







>
>
>
>
>
>
>
>
>
>
>
>
>







1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
	ch -= 0x10000;
	size = Tcl_UniCharToUtf(((ch >> 10) | 0xd800), buf);
	size += Tcl_UniCharToUtf(((ch & 0x3ff) | 0xdc00), buf+size);
    }
    return size;
}

int TkUtfCharComplete(const char *source, int numBytes) {
    if (Tcl_UtfCharComplete(source, numBytes) == 0) {
	return 0;
    }
    /* There are enough bytes for a high surrogate. If the first
     * 3 bytes form a high surrogate, this function should check
     * whether there are enough bytes for a low surrogate too. */
    if (((source[0]&0xFF) == 0xEB) && ((source[1]&0xF0) == 0xA0)
	    && ((source[2]&0xC0) == 0x80)) {
	return Tcl_UtfCharComplete(source+3, numBytes-3);
    }
    return 1;
}

#endif
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78

Changes to unix/tkUnixRFont.c.

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

    Tcl_RegisterConfig(mainPtr->interp, "tk", cfg, TCL_CFGVAL_ENCODING);
}

static XftFont *
GetFont(
    UnixFtFont *fontPtr,
    FcChar32 ucs4,
    double angle)
{
    int i;

    if (ucs4) {
	for (i = 0; i < fontPtr->nfaces; i++) {
	    FcCharSet *charset = fontPtr->faces[i].charset;

	    if (charset && FcCharSetHasChar(charset, ucs4)) {
		break;
	    }
	}
	if (i == fontPtr->nfaces) {
	    i = 0;
	}
    } else {







|








|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

    Tcl_RegisterConfig(mainPtr->interp, "tk", cfg, TCL_CFGVAL_ENCODING);
}

static XftFont *
GetFont(
    UnixFtFont *fontPtr,
    int ucs4,
    double angle)
{
    int i;

    if (ucs4) {
	for (i = 0; i < fontPtr->nfaces; i++) {
	    FcCharSet *charset = fontPtr->faces[i].charset;

	    if (charset && FcCharSetHasChar(charset, (FcChar32)ucs4)) {
		break;
	    }
	}
	if (i == fontPtr->nfaces) {
	    i = 0;
	}
    } else {
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,			/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
				/* Structure describing the logical font */
    FcChar32 ucs4 = (FcChar32) c;
				/* UCS-4 character to map */
    XftFont *ftFont = GetFont(fontPtr, ucs4, 0.0);
				/* Actual font used to render the character */

    GetTkFontAttributes(ftFont, faPtr);
    faPtr->underline = fontPtr->font.fa.underline;
    faPtr->overstrike = fontPtr->font.fa.overstrike;
}








<
<
|







616
617
618
619
620
621
622


623
624
625
626
627
628
629
630
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,			/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
				/* Structure describing the logical font */


    XftFont *ftFont = GetFont(fontPtr, c, 0.0);
				/* Actual font used to render the character */

    GetTkFontAttributes(ftFont, faPtr);
    faPtr->underline = fontPtr->font.fa.underline;
    faPtr->overstrike = fontPtr->font.fa.overstrike;
}

872
873
874
875
876
877
878

879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
    }
    XGetGCValues(display, gc, GCForeground, &values);
    xftcolor = LookUpColor(display, fontPtr, values.foreground);
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }
    nspec = 0;

    while (numBytes > 0 && x <= maxCoord && y <= maxCoord) {
	XftFont *ftFont;
	FcChar32 c;

	clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
	     */

	    goto doUnderlineStrikeout;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, 0.0);
	if (ftFont) {
	    specs[nspec].font = ftFont;
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);







>
|

|

<
<
<
<
<
|
<
<







870
871
872
873
874
875
876
877
878
879
880
881





882


883
884
885
886
887
888
889
    }
    XGetGCValues(display, gc, GCForeground, &values);
    xftcolor = LookUpColor(display, fontPtr, values.foreground);
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }
    nspec = 0;
    while (numBytes > 0 && TkUtfCharComplete(source, numBytes)
	    && x <= maxCoord && y <= maxCoord) {
	XftFont *ftFont;
	int c;






	clen = TkUtfToUniChar(source, &c);


	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, 0.0);
	if (ftFont) {
	    specs[nspec].font = ftFont;
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
	    }
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
    }

  doUnderlineStrikeout:
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, None);
    }
    if (fontPtr->font.fa.underline != 0) {
	XFillRectangle(display, drawable, gc, xStart,
		y + fontPtr->font.underlinePos, (unsigned) (x - xStart),
		(unsigned) fontPtr->font.underlineHeight);







<







901
902
903
904
905
906
907

908
909
910
911
912
913
914
	    }
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
    }


    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, None);
    }
    if (fontPtr->font.fa.underline != 0) {
	XFillRectangle(display, drawable, gc, xStart,
		y + fontPtr->font.underlinePos, (unsigned) (x - xStart),
		(unsigned) fontPtr->font.underlineHeight);
1004
1005
1006
1007
1008
1009
1010

1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }

    nglyph = 0;
    currentFtFont = NULL;
    originX = originY = 0;		/* lint */


    while (numBytes > 0 && x <= maxCoord && x >= minCoord && y <= maxCoord
	    && y >= minCoord) {
	XftFont *ftFont;
	FcChar32 c;

	clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
	     */

	    goto doUnderlineStrikeout;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	if (!ftFont) {
	    continue;
	}







>
|
<

|

<
<
<
<
<
|
<
<







995
996
997
998
999
1000
1001
1002
1003

1004
1005
1006





1007


1008
1009
1010
1011
1012
1013
1014
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }

    nglyph = 0;
    currentFtFont = NULL;
    originX = originY = 0;		/* lint */

    while (numBytes > 0 && TkUtfCharComplete(source, numBytes)
	    && x <= maxCoord && x >= minCoord && y <= maxCoord && y >= minCoord) {

	XftFont *ftFont;
	int c;






	clen = TkUtfToUniChar(source, &c);


	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	if (!ftFont) {
	    continue;
	}
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
    }
    XGetGCValues(display, gc, GCForeground, &values);
    xftcolor = LookUpColor(display, fontPtr, values.foreground);
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }
    nspec = 0;
    while (numBytes > 0 && x <= maxCoord && x >= minCoord
	    && y <= maxCoord && y >= minCoord) {
	XftFont *ftFont, *ft0Font;
	FcChar32 c;

	clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
	     */

	    goto doUnderlineStrikeout;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	ft0Font = GetFont(fontPtr, c, 0.0);
	if (ftFont && ft0Font) {
	    specs[nspec].font = ftFont;







|
|

|

<
<
<
<
<
|
<
<







1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075





1076


1077
1078
1079
1080
1081
1082
1083
    }
    XGetGCValues(display, gc, GCForeground, &values);
    xftcolor = LookUpColor(display, fontPtr, values.foreground);
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }
    nspec = 0;
    while (numBytes > 0 && TkUtfCharComplete(source, numBytes)
	    && x <= maxCoord && x >= minCoord && y <= maxCoord && y >= minCoord) {
	XftFont *ftFont, *ft0Font;
	int c;






	clen = TkUtfToUniChar(source, &c);


	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	ft0Font = GetFont(fontPtr, c, 0.0);
	if (ftFont && ft0Font) {
	    specs[nspec].font = ftFont;
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
    }
#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */

  doUnderlineStrikeout:
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, None);
    }
    if (fontPtr->font.fa.underline || fontPtr->font.fa.overstrike) {
	XPoint points[5];
	double width = (x - xStart) * cosA + (yStart - y) * sinA;
	double barHeight = fontPtr->font.underlineHeight;







<







1097
1098
1099
1100
1101
1102
1103

1104
1105
1106
1107
1108
1109
1110
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
    }
#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */


    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, None);
    }
    if (fontPtr->font.fa.underline || fontPtr->font.fa.overstrike) {
	XPoint points[5];
	double width = (x - xStart) * cosA + (yStart - y) * sinA;
	double barHeight = fontPtr->font.underlineHeight;