28
17
#ifdef USE_XFT_FONTS
19
#ifdef NEED_FT2BUILD_H
30
22
#include <X11/Xft/Xft.h>
33
typedef struct _UnixFtFace {
39
typedef struct _UnixFtFont {
40
TkFont font; /* Stuff used by generic font package. Must
41
* be first in structure. */
32
TkFont font; /* Stuff used by generic font package. Must be
33
* first in structure. */
47
* Forward declarations...
50
static void FinishedWithFont(UnixFtFont *fontPtr);
51
static XftFont * GetFont(UnixFtFont *fontPtr, FcChar32 ucs4);
52
static UnixFtFont * InitFont(Tk_Window tkwin, FcPattern *pattern,
56
* Package initialization:
57
* Nothing to do here except register the fact that we're using Xft in
58
* the TIP 59 configuration database.
61
#ifndef TCL_CFGVAL_ENCODING
62
#define TCL_CFGVAL_ENCODING "ascii"
55
TkpFontPkgInit(mainPtr)
56
TkMainInfo *mainPtr; /* The application being created. */
67
TkMainInfo *mainPtr) /* The application being created. */
70
static Tcl_Config cfg[] = {
71
{ "fontsystem", "xft" },
75
Tcl_RegisterConfig(mainPtr->interp, "tk", cfg, TCL_CFGVAL_ENCODING);
61
GetFont (UnixFtFont *fontPtr, FcChar32 ucs4)
67
for (i = 0; i < fontPtr->nfaces; i++)
69
FcCharSet *charset = fontPtr->faces[i].charset;
70
if (charset && FcCharSetHasChar (charset, ucs4))
87
for (i = 0; i < fontPtr->nfaces; i++) {
88
FcCharSet *charset = fontPtr->faces[i].charset;
89
if (charset && FcCharSetHasChar(charset, ucs4)) {
73
if (i == fontPtr->nfaces)
93
if (i == fontPtr->nfaces) {
78
if (!fontPtr->faces[i].ftFont)
80
FcPattern *pat = FcFontRenderPrepare (0, fontPtr->pattern,
81
fontPtr->faces[i].source);
83
fontPtr->faces[i].ftFont = XftFontOpenPattern (fontPtr->display,
99
if (!fontPtr->faces[i].ftFont) {
100
FcPattern *pat = FcFontRenderPrepare(0, fontPtr->pattern,
101
fontPtr->faces[i].source);
103
fontPtr->faces[i].ftFont = XftFontOpenPattern(fontPtr->display, pat);
86
105
return fontPtr->faces[i].ftFont;
90
FiniFont (UnixFtFont *fontPtr)
92
Display *display = fontPtr->display;
93
Tk_ErrorHandler handler;
96
handler = Tk_CreateErrorHandler(display, -1, -1, -1,
97
(Tk_ErrorProc *) NULL, (ClientData) NULL);
98
for (i = 0; i < fontPtr->nfaces; i++)
100
if (fontPtr->faces[i].ftFont) {
101
XftFontClose (fontPtr->display, fontPtr->faces[i].ftFont);
103
/* Doing this clears a leak but can also core ... */
104
FcPatternDestroy (fontPtr->faces[i].ftFont->pattern);
107
if (fontPtr->faces[i].source)
108
FcPatternDestroy (fontPtr->faces[i].source);
109
if (fontPtr->faces[i].charset)
110
FcCharSetDestroy (fontPtr->faces[i].charset);
114
if (fontPtr->faces) {
115
ckfree((char *) fontPtr->faces);
116
fontPtr->faces = NULL;
119
if (fontPtr->charset) {
120
FcCharSetDestroy (fontPtr->charset);
121
fontPtr->charset = NULL;
124
if (fontPtr->pattern) {
125
FcPatternDestroy (fontPtr->pattern);
126
fontPtr->pattern = NULL;
130
if (fontPtr->ftDraw) {
131
XftDrawDestroy (fontPtr->ftDraw);
132
fontPtr->ftDraw = NULL;
135
if (fontPtr->font.fid) {
136
XUnloadFont (fontPtr->display, fontPtr->font.fid);
137
fontPtr->font.fid = None;
140
Tk_DeleteErrorHandler(handler);
109
*---------------------------------------------------------------------------
113
* Initializes the fields of a UnixFtFont structure. If fontPtr is NULL,
114
* also allocates a new UnixFtFont.
117
* On error, frees fontPtr and returns NULL, otherwise returns fontPtr.
119
*---------------------------------------------------------------------------
143
122
static UnixFtFont *
144
InitFont (UnixFtFont *fontPtr, Tk_Window tkwin, FcPattern *pattern)
146
TkFontAttributes *faPtr;
147
TkFontMetrics *fmPtr;
153
FcFontSet *set = NULL;
154
FcCharSet *charset = NULL;
157
XftFont *ftFont = NULL;
158
UnixFtFace *faces = NULL;
160
FcConfigSubstitute (0, pattern, FcMatchPattern);
161
XftDefaultSubstitute (Tk_Display (tkwin),
162
Tk_ScreenNumber (tkwin),
128
TkFontAttributes *faPtr;
129
TkFontMetrics *fmPtr;
131
int weight, slant, spacing, i;
140
fontPtr = (UnixFtFont *) ckalloc(sizeof(UnixFtFont));
143
FcConfigSubstitute(0, pattern, FcMatchPattern);
144
XftDefaultSubstitute(Tk_Display(tkwin), Tk_ScreenNumber(tkwin), pattern);
166
147
* Generate the list of fonts
168
set = FcFontSort (0, pattern, FcTrue, &charset, &result);
177
FcPatternPrint(pattern);
180
faces = (UnixFtFace *) ckalloc (set->nfont * sizeof (UnixFtFace));
184
FcFontSetDestroy (set);
186
FcCharSetDestroy (charset);
187
FcPatternDestroy (pattern);
150
set = FcFontSort(0, pattern, FcTrue, &charset, &result);
152
FcPatternDestroy(pattern);
153
ckfree((char *) fontPtr);
199
fontPtr = (UnixFtFont *) ckalloc (sizeof (UnixFtFont));
203
ckfree((char *) faces);
207
157
fontPtr->charset = charset;
208
158
fontPtr->pattern = pattern;
209
fontPtr->faces = faces;
210
fontPtr->nfaces = set->nfont;
159
fontPtr->faces = (UnixFtFace *) ckalloc(set->nfont * sizeof(UnixFtFace));
160
fontPtr->nfaces = set->nfont;
213
163
* Fill in information about each returned font
215
for (i = 0; i < set->nfont; i++)
166
for (i = 0; i < set->nfont; i++) {
217
167
fontPtr->faces[i].ftFont = 0;
218
168
fontPtr->faces[i].source = set->fonts[i];
219
if (FcPatternGetCharSet (set->fonts[i], FC_CHARSET, 0, &charset) == FcResultMatch)
220
fontPtr->faces[i].charset = FcCharSetCopy (charset);
169
if (FcPatternGetCharSet(set->fonts[i], FC_CHARSET, 0,
170
&charset) == FcResultMatch) {
171
fontPtr->faces[i].charset = FcCharSetCopy(charset);
222
173
fontPtr->faces[i].charset = 0;
225
FcFontSetDestroy (set);
227
fontPtr->font.fid = XLoadFont (Tk_Display (tkwin), "fixed");
229
fontPtr->display = Tk_Display (tkwin);
230
fontPtr->screen = Tk_ScreenNumber (tkwin);
232
fontPtr->drawable = 0;
233
fontPtr->color.color.red = 0;
234
fontPtr->color.color.green= 0;
177
fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed");
178
fontPtr->display = Tk_Display(tkwin);
179
fontPtr->screen = Tk_ScreenNumber(tkwin);
181
fontPtr->drawable = 0;
182
fontPtr->color.color.red = 0;
183
fontPtr->color.color.green = 0;
235
184
fontPtr->color.color.blue = 0;
236
fontPtr->color.color.alpha= 0xffff;
185
fontPtr->color.color.alpha = 0xffff;
237
186
fontPtr->color.pixel = 0xffffffff;
239
faPtr = &fontPtr->font.fa;
241
/* Now get 0'th font */
242
ftFont = GetFont (fontPtr, 0);
244
/* And set Tk's actuals from its pattern */
245
pattern = ftFont->pattern;
188
ftFont = GetFont(fontPtr, 0);
248
191
* Build the Tk font structure
250
if (XftPatternGetString (pattern, XFT_FAMILY, 0, &family) != XftResultMatch)
194
if (XftPatternGetString(ftFont->pattern, XFT_FAMILY, 0,
195
&family) != XftResultMatch) {
251
196
family = "Unknown";
253
if (XftPatternGetInteger (pattern, XFT_WEIGHT, 0, &weight) != XftResultMatch)
199
if (XftPatternGetInteger(ftFont->pattern, XFT_WEIGHT, 0,
200
&weight) != XftResultMatch) {
254
201
weight = XFT_WEIGHT_MEDIUM;
255
if (weight <= XFT_WEIGHT_MEDIUM)
203
if (weight <= XFT_WEIGHT_MEDIUM) {
256
204
weight = TK_FW_NORMAL;
258
206
weight = TK_FW_BOLD;
260
if (XftPatternGetInteger (pattern, XFT_SLANT, 0, &slant) != XftResultMatch)
209
if (XftPatternGetInteger(ftFont->pattern, XFT_SLANT, 0,
210
&slant) != XftResultMatch) {
261
211
slant = XFT_SLANT_ROMAN;
262
if (slant <= XFT_SLANT_ROMAN)
213
if (slant <= XFT_SLANT_ROMAN) {
263
214
slant = TK_FS_ROMAN;
265
216
slant = TK_FS_ITALIC;
267
if (XftPatternGetDouble (pattern, XFT_PIXEL_SIZE, 0, &dSize)
269
if (XftPatternGetDouble (pattern, XFT_SIZE, 0, &dSize)
219
/* Different font size handling in Tcl/Tk and Perl/Tk */
220
if (XftPatternGetDouble(pattern, XFT_PIXEL_SIZE, 0,
221
&dSize) != XftResultMatch) {
222
if (XftPatternGetDouble(pattern, XFT_SIZE, 0, &dSize)
274
226
size = (int)(dSize+0.5);
278
229
size = -(int)(dSize+0.5);
281
if (XftPatternGetInteger (pattern, XFT_SPACING, 0, &spacing) != XftResultMatch)
232
if (XftPatternGetInteger(ftFont->pattern, XFT_SPACING, 0,
233
&spacing) != XftResultMatch) {
282
234
spacing = XFT_PROPORTIONAL;
283
if (spacing == XFT_PROPORTIONAL)
236
if (spacing == XFT_PROPORTIONAL) {
288
printf ("%p family %s size %g=>%d weight %d slant %d id=%d\n",
289
fontPtr, family, dSize, size, weight, slant, fontPtr->font.fid);
292
faPtr->family = family;
294
faPtr->weight = weight;
295
faPtr->slant = slant;
296
faPtr->underline = 0;
297
faPtr->overstrike = 0;
299
fmPtr = &fontPtr->font.fm;
300
fmPtr->ascent = ftFont->ascent;
301
fmPtr->descent = ftFont->descent;
302
fmPtr->maxWidth = ftFont->max_advance_width;
303
fmPtr->fixed = spacing;
242
printf("family %s size %g weight %d slant %d\n",
243
family, size, weight, slant);
244
#endif /* DEBUG_FONTSEL */
246
faPtr = &fontPtr->font.fa;
247
faPtr->family = family;
249
faPtr->weight = weight;
250
faPtr->slant = slant;
251
faPtr->underline = 0;
252
faPtr->overstrike = 0;
254
fmPtr = &fontPtr->font.fm;
255
fmPtr->ascent = ftFont->ascent;
256
fmPtr->descent = ftFont->descent;
257
fmPtr->maxWidth = ftFont->max_advance_width;
258
fmPtr->fixed = spacing;
267
Display *display = fontPtr->display;
268
Tk_ErrorHandler handler;
271
handler = Tk_CreateErrorHandler(display, -1, -1, -1, NULL,
273
for (i = 0; i < fontPtr->nfaces; i++) {
274
if (fontPtr->faces[i].ftFont) {
275
XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
277
if (fontPtr->faces[i].source) {
278
FcPatternDestroy(fontPtr->faces[i].source);
280
if (fontPtr->faces[i].charset) {
281
FcCharSetDestroy(fontPtr->faces[i].charset);
284
if (fontPtr->ftDraw) {
285
XftDrawDestroy(fontPtr->ftDraw);
287
if (fontPtr->font.fid) {
288
XUnloadFont(fontPtr->display, fontPtr->font.fid);
290
Tk_DeleteErrorHandler(handler);
309
TkpGetNativeFont(tkwin, name)
310
Tk_Window tkwin; /* For display where font will be used. */
311
CONST char *name; /* Platform-specific font name. */
295
Tk_Window tkwin, /* For display where font will be used. */
296
CONST char *name) /* Platform-specific font name. */
313
UnixFtFont *fontPtr = NULL;
314
FcPattern *pattern = NULL;
316
printf ("TkpGetNativeFont '%s'\n", name);
301
printf("TkpGetNativeFont %s\n", name);
302
#endif /* DEBUG_FONTSEL */
305
* The font handling in Perl/Tk differs here:
306
* TkFontParseXLFD and FcNameParse are used before trying XftXlfdParse
318
308
if (*name == '-') {
320
/* This parses full names ok, but result is mis-scaled for some reason */
321
pattern = XftXlfdParse (name, FcFalse, FcFalse);
326
if (TkFontParseXLFD(name, &fa, &xa) != TCL_OK) {
330
return TkpGetFontFromAttributes(NULL, tkwin, &fa);
311
if (TkFontParseXLFD(name, &fa, &xa) != TCL_OK) {
314
return TkpGetFontFromAttributes(NULL, tkwin, &fa);
334
else if (strpbrk(name,":,=") || !strpbrk(name," {")) {
316
} else if (strpbrk(name,":,=") || !strpbrk(name," {")) {
335
317
pattern = FcNameParse (name);
338
fontPtr = InitFont (NULL, tkwin, pattern);
344
return &fontPtr->font;
320
pattern = XftXlfdParse(name, FcFalse, FcFalse);
327
* Should also try: pattern = FcNameParse(name); but generic/tkFont.c
328
* expects TkpGetNativeFont() to only work on XLFD names under Unix.
331
fontPtr = InitFont(tkwin, pattern, NULL);
335
return &fontPtr->font;
350
TkpGetFontFromAttributes(tkFontPtr, tkwin, faPtr)
351
TkFont *tkFontPtr; /* If non-NULL, store the information in
352
* this existing TkFont structure, rather than
339
TkpGetFontFromAttributes(
340
TkFont *tkFontPtr, /* If non-NULL, store the information in this
341
* existing TkFont structure, rather than
353
342
* allocating a new structure to hold the
354
343
* font; the existing contents of the font
355
* will be released. If NULL, a new TkFont
344
* will be released. If NULL, a new TkFont
356
345
* structure is allocated. */
357
Tk_Window tkwin; /* For display where font will be used. */
358
CONST TkFontAttributes *faPtr;
346
Tk_Window tkwin, /* For display where font will be used. */
347
CONST TkFontAttributes *faPtr)
359
348
/* Set of attributes to match. */
363
UnixFtFont *fontPtr = (UnixFtFont *)tkFontPtr;
365
pattern = XftPatternBuild (0,
366
XFT_FAMILY, XftTypeString, faPtr->family,
369
XftPatternAddInteger (pattern, XFT_SIZE, faPtr->size);
371
XftPatternAddInteger (pattern, XFT_PIXEL_SIZE, -faPtr->size);
355
printf("TkpGetFontFromAttributes %s-%d %d %d\n", faPtr->family,
356
faPtr->size, faPtr->weight, faPtr->slant);
357
#endif /* DEBUG_FONTSEL */
358
pattern = XftPatternCreate();
360
XftPatternAddString(pattern, XFT_FAMILY, faPtr->family);
362
if (faPtr->size > 0) {
363
XftPatternAddInteger(pattern, XFT_SIZE, faPtr->size);
364
} else if (faPtr->size < 0) {
365
XftPatternAddInteger(pattern, XFT_PIXEL_SIZE, -faPtr->size);
367
XftPatternAddInteger(pattern, XFT_SIZE, 12);
372
369
switch (faPtr->weight) {
373
370
case TK_FW_NORMAL:
391
388
slant = XFT_SLANT_OBLIQUE;
394
XftPatternAddInteger (pattern, XFT_SLANT, slant);
391
XftPatternAddInteger(pattern, XFT_SLANT, slant);
396
fontPtr = InitFont (fontPtr, tkwin, pattern);
398
printf ("%p TkpGetFontFromAttributes %s-%d %d %d\n", fontPtr,
399
faPtr->family, faPtr->size, faPtr->weight, faPtr->slant);
393
fontPtr = (UnixFtFont *) tkFontPtr;
394
if (fontPtr != NULL) {
395
FinishedWithFont(fontPtr);
397
fontPtr = InitFont(tkwin, pattern, fontPtr);
403
401
return &fontPtr->font;
407
TkpDeleteFont(tkFontPtr)
408
TkFont *tkFontPtr; /* Token of font to be deleted. */
406
TkFont *tkFontPtr) /* Token of font to be deleted. */
410
UnixFtFont *fontPtr = (UnixFtFont *) tkFontPtr;
408
UnixFtFont *fontPtr = (UnixFtFont *) tkFontPtr;
410
FinishedWithFont(fontPtr);
413
411
/* XXX tkUnixFont.c doesn't free tkFontPtr... */
415
*---------------------------------------------------------------------------
417
* TkpGetFontFamilies --
419
* Return information about the font families that are available on the
420
* display of the given window.
423
* Modifies interp's result object to hold a list of all the available
426
*---------------------------------------------------------------------------
417
TkpGetFontFamilies(interp, tkwin)
418
Tcl_Interp *interp; /* Interp to hold result. */
419
Tk_Window tkwin; /* For display to query. */
431
Tcl_Interp *interp, /* Interp to hold result. */
432
Tk_Window tkwin) /* For display to query. */
421
Tcl_Obj *resultPtr, *strPtr;
426
resultPtr = Tcl_GetObjResult(interp);
428
list = XftListFonts (Tk_Display (tkwin),
429
Tk_ScreenNumber (tkwin),
433
for (i = 0; i < list->nfont; i++)
435
if (XftPatternGetString (list->fonts[i], XFT_FAMILY, 0, &family) == XftResultMatch)
437
strPtr = Tcl_NewStringObj(Tk_GetUid (family), -1);
438
Tcl_ListObjAppendElement (NULL, resultPtr, strPtr);
434
Tcl_Obj *resultPtr, *strPtr;
439
resultPtr = Tcl_NewListObj(0, NULL);
441
list = XftListFonts(Tk_Display(tkwin), Tk_ScreenNumber(tkwin), 0,
443
for (i = 0; i < list->nfont; i++) {
444
if (XftPatternGetString(list->fonts[i], XFT_FAMILY, 0,
445
&family) == XftResultMatch) {
446
strPtr = Tcl_NewStringObj(Tk_GetUid(family), -1);
447
Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
441
XftFontSetDestroy (list);
450
XftFontSetDestroy(list);
452
Tcl_SetObjResult(interp, resultPtr);
456
*-------------------------------------------------------------------------
460
* Called by [testfont subfonts] in the Tk testing package.
463
* Sets interp's result to a list of the faces used by tkfont
465
*-------------------------------------------------------------------------
445
TkpGetSubFonts(interp, tkfont)
450
Tcl_Obj *resultPtr, *listPtr;
451
UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
452
char *family, *foundry, *encoding, *file;
453
XftFont *ftFont = GetFont (fontPtr, 0);
473
Tcl_Obj *objv[5], *listPtr, *resultPtr;
474
UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
456
475
FcPattern *pattern;
458
resultPtr = Tcl_GetObjResult(interp);
459
for (i = 0; i < fontPtr->nfaces; i++) {
460
if (fontPtr->faces[i].ftFont) {
461
pattern = fontPtr->faces[i].ftFont->pattern;
465
pattern = fontPtr->faces[i].source;
470
FcPatternPrint(pattern);
472
if (XftPatternGetString (pattern, XFT_FAMILY,
473
0, &family) != XftResultMatch)
477
if (XftPatternGetString (pattern, XFT_FOUNDRY,
478
0, &foundry) != XftResultMatch)
482
if (XftPatternGetString (pattern, XFT_ENCODING,
487
if (XftPatternGetString (pattern, XFT_FILE,
476
char *family, *foundry, *encoding, *file;
479
resultPtr = Tcl_NewListObj(0, NULL);
481
for (i = 0; i < fontPtr->nfaces ; ++i) {
482
pattern = FcFontRenderPrepare(0, fontPtr->pattern,
483
fontPtr->faces[i].source);
485
if (XftPatternGetString(pattern, XFT_FAMILY, 0,
486
&family) != XftResultMatch) {
489
if (XftPatternGetString(pattern, XFT_FOUNDRY, 0,
490
&foundry) != XftResultMatch) {
493
if (XftPatternGetString(pattern, XFT_ENCODING, 0,
494
&encoding) != XftResultMatch) {
495
encoding = "Unknown";
497
if (XftPatternGetString(pattern, XFT_FILE, 0,
498
&file) != XftResultMatch) {
499
encoding = "Unknown";
492
501
objv[0] = Tcl_NewStringObj(family, -1);
493
objv[1] = Tcl_NewStringObj(file, -1);
494
objv[2] = Tcl_NewStringObj(foundry, -1);
495
objv[3] = Tcl_NewStringObj(encoding, -1);
496
listPtr = Tcl_NewListObj (4, objv);
497
Tcl_ListObjAppendElement (interp, resultPtr, listPtr);
502
objv[1] = Tcl_NewStringObj(foundry, -1);
503
objv[2] = Tcl_NewStringObj(encoding, -1);
504
objv[3] = Tcl_NewIntObj(-1); /* trigger (?), NYI, added in Perl/Tk */
505
objv[4] = Tcl_NewStringObj(file, -1); /* added in Perl/Tk */
506
listPtr = Tcl_NewListObj(5, objv);
507
Tcl_ListObjAppendElement(NULL, resultPtr, listPtr);
509
Tcl_SetObjResult(interp, resultPtr);
502
Tk_MeasureChars(tkfont, source, numBytes, maxLength, flags, lengthPtr)
503
Tk_Font tkfont; /* Font in which characters will be drawn. */
504
CONST char *source; /* UTF-8 string to be displayed. Need not be
514
Tk_Font tkfont, /* Font in which characters will be drawn. */
515
CONST char *source, /* UTF-8 string to be displayed. Need not be
505
516
* '\0' terminated. */
506
int numBytes; /* Maximum number of bytes to consider
507
* from source string. */
508
int maxLength; /* If >= 0, maxLength specifies the longest
517
int numBytes, /* Maximum number of bytes to consider from
519
int maxLength, /* If >= 0, maxLength specifies the longest
509
520
* permissible line length in pixels; don't
510
521
* consider any character that would cross
511
* this x-position. If < 0, then line length
522
* this x-position. If < 0, then line length
512
523
* is unbounded and the flags argument is
514
int flags; /* Various flag bits OR-ed together:
525
int flags, /* Various flag bits OR-ed together:
515
526
* TK_PARTIAL_OK means include the last char
516
527
* which only partially fit on this line.
517
528
* TK_WHOLE_WORDS means stop on a word
518
* boundary, if possible.
519
* TK_AT_LEAST_ONE means return at least one
520
* character even if no characters fit. */
521
int *lengthPtr; /* Filled with x-location just after the
529
* boundary, if possible. TK_AT_LEAST_ONE
530
* means return at least one character even if
531
* no characters fit. */
532
int *lengthPtr) /* Filled with x-location just after the
522
533
* terminating character. */
524
UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
532
int curByte, newByte;
535
UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
541
int termByte = 0, termX = 0;
542
int curByte, newByte, sawNonSpace;
546
#endif /* DEBUG_FONTSEL */
542
clen = FcUtf8ToUcs4 ((FcChar8 *) source, &c, numBytes);
551
while (numBytes > 0) {
554
clen = Tcl_UtfToUniChar(source, &unichar);
555
c = (FcChar32)unichar;
544
/* Not supposed to happen - did happen in Text widget
545
* abort() for now - could also take 1byte == 1 char ?
559
* This can't happen (but see #1185640)
547
LangDebug("numByte=%d s='%.*s' c=%x clen=%d\n",
548
numBytes, numBytes, source, c, clen);
552
567
numBytes -= clen;
553
if (c < 256 && isspace (c))
568
if (c < 256 && isspace(c)) { /* I18N: ??? */
557
570
termByte = curByte;
565
ftFont = GetFont (fontPtr, c);
567
XftTextExtents32 (fontPtr->display, ftFont, &c, 1, &extents);
569
newX = curX + extents.xOff;
579
string[len++] = (char) c;
580
#endif /* DEBUG_FONTSEL */
581
ftFont = GetFont(fontPtr, c);
583
XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents);
585
newX = curX + extents.xOff;
570
586
newByte = curByte + clen;
573
LangDebug("%s ch=%d x=%d+w=%d => %d out of %d, curB=%d newB=%d leaving %d\n",
574
__FUNCTION__,c,curX,extents.xOff,newX,maxLength,
575
curByte, newByte, numBytes);
578
if (maxLength >= 0 && newX > maxLength)
580
if ((flags & TK_PARTIAL_OK) ||
581
((flags & TK_AT_LEAST_ONE) && curByte == 0))
587
if (maxLength >= 0 && newX > maxLength) {
588
if (flags & TK_PARTIAL_OK ||
589
(flags & TK_AT_LEAST_ONE && curByte == 0)) {
584
591
curByte = newByte;
586
else if ((flags & TK_WHOLE_WORDS) && termByte != 0)
592
} else if (flags & TK_WHOLE_WORDS && termX != 0) {
589
594
curByte = termByte;
604
printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte);
605
#endif /* DEBUG_FONTSEL */
597
606
*lengthPtr = curX;
611
TkpMeasureCharsInContext(Tk_Font tkfont, CONST char * source, int numBytes,
612
int rangeStart, int rangeLength, int maxLength,
613
int flags, int * lengthPtr)
615
(void) numBytes; /*unused*/
616
return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength,
617
maxLength, flags, lengthPtr);
601
620
#define NUM_SPEC 1024
604
Tk_DrawChars(display, drawable, gc, tkfont, source, numBytes, x, y)
605
Display *display; /* Display on which to draw. */
606
Drawable drawable; /* Window or pixmap in which to draw. */
607
GC gc; /* Graphics context for drawing characters. */
608
Tk_Font tkfont; /* Font in which characters will be drawn;
624
Display *display, /* Display on which to draw. */
625
Drawable drawable, /* Window or pixmap in which to draw. */
626
GC gc, /* Graphics context for drawing characters. */
627
Tk_Font tkfont, /* Font in which characters will be drawn;
609
628
* must be the same as font used in GC. */
610
CONST char *source; /* UTF-8 string to be displayed. Need not be
611
* '\0' terminated. All Tk meta-characters
629
CONST char *source, /* UTF-8 string to be displayed. Need not be
630
* '\0' terminated. All Tk meta-characters
612
631
* (tabs, control characters, and newlines)
613
632
* should be stripped out of the string that
614
* is passed to this function. If they are
615
* not stripped out, they will be displayed as
633
* is passed to this function. If they are not
634
* stripped out, they will be displayed as
616
635
* regular printing characters. */
617
int numBytes; /* Number of bytes in string. */
618
int x, y; /* Coordinates at which to place origin of
636
int numBytes, /* Number of bytes in string. */
637
int x, int y) /* Coordinates at which to place origin of
619
638
* string when drawing. */
621
UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
625
XftGlyphFontSpec specs[NUM_SPEC];
630
printf("%p DrawChars '%.*s'\n",fontPtr,numBytes,source);
633
if (fontPtr->ftDraw == 0)
636
printf ("Switch to drawable 0x%x\n", drawable);
638
fontPtr->ftDraw = XftDrawCreate (display,
640
DefaultVisual (display,
642
DefaultColormap (display,
640
const int maxCoord = 0x7FFF; /* Xft coordinates are 16 bit values */
641
UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
645
XftGlyphFontSpec specs[NUM_SPEC];
649
if (fontPtr->ftDraw == 0) {
651
printf("Switch to drawable 0x%x\n", drawable);
652
#endif /* DEBUG_FONTSEL */
653
fontPtr->ftDraw = XftDrawCreate(display, drawable,
654
DefaultVisual(display, fontPtr->screen),
655
DefaultColormap(display, fontPtr->screen));
644
656
fontPtr->drawable = drawable;
646
/* Seem to need this even if drawable is same ? */
647
else /* if (fontPtr->drawable != drawable) */
649
658
Tk_ErrorHandler handler;
651
handler = Tk_CreateErrorHandler(display, -1, -1, -1,
652
(Tk_ErrorProc *) NULL, (ClientData) NULL);
653
XftDrawChange (fontPtr->ftDraw, drawable);
660
handler = Tk_CreateErrorHandler(display, -1, -1, -1, NULL,
662
XftDrawChange(fontPtr->ftDraw, drawable);
654
663
fontPtr->drawable = drawable;
655
664
Tk_DeleteErrorHandler(handler);
657
XGetGCValues (display, gc, GCForeground, &values);
658
if (values.foreground != fontPtr->color.pixel)
666
XGetGCValues(display, gc, GCForeground, &values);
667
if (values.foreground != fontPtr->color.pixel) {
660
668
xcolor.pixel = values.foreground;
661
XQueryColor (display, DefaultColormap (display,
669
XQueryColor(display, DefaultColormap(display, fontPtr->screen),
664
671
fontPtr->color.color.red = xcolor.red;
665
672
fontPtr->color.color.green = xcolor.green;
666
673
fontPtr->color.color.blue = xcolor.blue;