Tk Source Code

Check-in [43d696b5]
Login

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

Overview
Comment:[Bug 1961455]: Draw underlines and overstrikes when using Xft for font rendering
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-5-branch
Files: files | file ages | folders
SHA1: 43d696b5d64b4f1bd4cae970187f45ab221aa8b7
User & Date: dkf 2009-10-10 19:38:27
Context
2009-10-15
17:48
* generic/tkConsole.c: Relax the runtime version requirements on Tcl * generic/tkMain.c: so that Tk 8.5.8 can [load] into Tcl 8.6 (and * generic/tkWindow.c: later 8.*) interps. * library/tk.tcl * unix/Makefile.in: * win/Makefile.in: * win/makefile.vc:
check-in: 4e3e9d74 user: dgp tags: core-8-5-branch
2009-10-10
19:38
[Bug 1961455]: Draw underlines and overstrikes when using Xft for font rendering check-in: 43d696b5 user: dkf tags: core-8-5-branch
2009-10-08
12:42
[Patch 2870648]: Corrected cursor used in file/directory dialogs. check-in: 00efc3aa user: dkf tags: core-8-5-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ChangeLog.







1
2
3
4
5
6
7






2009-10-08  Donal K. Fellows  <[email protected]>

	* library/tkfbox.tcl (::tk::IconList_Create): [Patch 2870648]:
	Corrected cursor used in file/directory dialogs.

2009-10-07  Pat Thoyts  <[email protected]>

>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
2009-10-10  Donal K. Fellows  <[email protected]>

	* unix/tkUnixRFont.c (InitFont,TkpGetFontFromAttributes,Tk_DrawChars):
	[Bug 1961455]: Draw underlines and overstrikes when using Xft for font
	rendering.

2009-10-08  Donal K. Fellows  <[email protected]>

	* library/tkfbox.tcl (::tk::IconList_Create): [Patch 2870648]:
	Corrected cursor used in file/directory dialogs.

2009-10-07  Pat Thoyts  <[email protected]>

Changes to unix/tkUnixRFont.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tkUnixRFont.c --
 *
 *	Alternate implementation of tkUnixFont.c using Xft.
 *
 * Copyright (c) 2002-2003 Keith Packard
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tkUnixRFont.c,v 1.24.2.1 2009/09/10 12:47:15 dkf Exp $
 */

#include "tkUnixInt.h"
#include "tkFont.h"
#include <X11/Xft/Xft.h>
#include <ctype.h>











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tkUnixRFont.c --
 *
 *	Alternate implementation of tkUnixFont.c using Xft.
 *
 * Copyright (c) 2002-2003 Keith Packard
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tkUnixRFont.c,v 1.24.2.2 2009/10/10 19:38:27 dkf Exp $
 */

#include "tkUnixInt.h"
#include "tkFont.h"
#include <X11/Xft/Xft.h>
#include <ctype.h>

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    FcPattern *pattern;

    Display *display;
    int screen;
    XftDraw *ftDraw;
    XftColor color;
} UnixFtFont;


/*
 * Package initialization:
 * 	Nothing to do here except register the fact that we're using Xft in
 * 	the TIP 59 configuration database.
 */








<







31
32
33
34
35
36
37

38
39
40
41
42
43
44
    FcPattern *pattern;

    Display *display;
    int screen;
    XftDraw *ftDraw;
    XftColor color;
} UnixFtFont;


/*
 * Package initialization:
 * 	Nothing to do here except register the fact that we're using Xft in
 * 	the TIP 59 configuration database.
 */

256
257
258
259
260
261
262






































263
264
265
266
267
268
269
    /*
     * Fill in platform-specific fields of TkFont.
     */
    ftFont = GetFont(fontPtr, 0);
    fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed");
    GetTkFontAttributes(ftFont, &fontPtr->font.fa);
    GetTkFontMetrics(ftFont, &fontPtr->font.fm);







































    return fontPtr;
}

static void
FinishedWithFont(
    UnixFtFont *fontPtr)







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







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
    /*
     * Fill in platform-specific fields of TkFont.
     */
    ftFont = GetFont(fontPtr, 0);
    fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed");
    GetTkFontAttributes(ftFont, &fontPtr->font.fa);
    GetTkFontMetrics(ftFont, &fontPtr->font.fm);

    /*
     * Fontconfig can't report any information about the position or thickness
     * of underlines or overstrikes. Thus, we use some defaults that are
     * hacked around from backup defaults in tkUnixFont.c, which are in turn
     * based on recommendations in the X manual. The comments from that file
     * leading to these computations were:
     *
     *	    If the XA_UNDERLINE_POSITION property does not exist, the X manual
     *	    recommends using half the descent.
     *
     *	    If the XA_UNDERLINE_THICKNESS property does not exist, the X
     *	    manual recommends using the width of the stem on a capital letter.
     *	    I don't know of a way to get the stem width of a letter, so guess
     *	    and use 1/3 the width of a capital I.
     *
     * Note that nothing corresponding to *either* property is reported by
     * Fontconfig at all. [Bug 1961455]
     */

    {
	TkFont *fPtr = &fontPtr->font;
	int iWidth;

	fPtr->underlinePos = fPtr->fm.descent / 2;
	Tk_MeasureChars((Tk_Font) fPtr, "I", 1, -1, 0, &iWidth);
	fPtr->underlineHeight = iWidth / 3;
	if (fPtr->underlineHeight == 0) {
	    fPtr->underlineHeight = 1;
	}
	if (fPtr->underlineHeight + fPtr->underlinePos > fPtr->fm.descent) {
	    fPtr->underlineHeight = fPtr->fm.descent - fPtr->underlinePos;
	    if (fPtr->underlineHeight == 0) {
		fPtr->underlinePos--;
		fPtr->underlineHeight = 1;
	    }
	}
    }

    return fontPtr;
}

static void
FinishedWithFont(
    UnixFtFont *fontPtr)
400
401
402
403
404
405
406



407
408
409
410
411
412
413
	fontPtr = InitFont(tkwin, pattern, fontPtr);
    }

    if (!fontPtr) {
	FcPatternDestroy(pattern);
	return NULL;
    }



    return &fontPtr->font;
}

void
TkpDeleteFont(
    TkFont *tkFontPtr)		/* Token of font to be deleted. */
{







>
>
>







437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
	fontPtr = InitFont(tkwin, pattern, fontPtr);
    }

    if (!fontPtr) {
	FcPatternDestroy(pattern);
	return NULL;
    }

    fontPtr->font.fa.underline = faPtr->underline;
    fontPtr->font.fa.overstrike = faPtr->overstrike;
    return &fontPtr->font;
}

void
TkpDeleteFont(
    TkFont *tkFontPtr)		/* Token of font to be deleted. */
{
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XColor xcolor;
    int clen, nspec;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;

    if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */







|







707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XColor xcolor;
    int clen, nspec, xStart = x;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;

    if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721

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

	    return;
	}
	source += clen;
	numBytes -= clen;

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







|







747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

	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);
	if (ftFont) {
	    specs[nspec].font = ftFont;
733
734
735
736
737
738
739
740













		nspec = 0;
	    }
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, specs, nspec);
    }
}




















|
>
>
>
>
>
>
>
>
>
>
>
>
>
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
		nspec = 0;
	    }
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, specs, nspec);
    }

  doUnderlineStrikeout:
    if (fontPtr->font.fa.underline != 0) {
	XFillRectangle(display, drawable, gc, xStart,
		y + fontPtr->font.underlinePos, (unsigned) (x - xStart),
		(unsigned) fontPtr->font.underlineHeight);
    }
    if (fontPtr->font.fa.overstrike != 0) {
	y -= fontPtr->font.fm.descent + (fontPtr->font.fm.ascent) / 10;
	XFillRectangle(display, drawable, gc, xStart, y,
		(unsigned) (x - xStart),
		(unsigned) fontPtr->font.underlineHeight);
    }
}