Tk Source Code

Artifact [262f9fc5]
Login

Artifact 262f9fc54f45e65d08620d1ab7382094c9c8c9c5:

Attachment "tip145-final-c.patch" to ticket [780617ff] added by patthoyts 2008-05-14 07:57:25.
This patch is the final part of TIP #145

Tk_CreateNamedFont is placed in the public stubs.
Tk_FontAttributes is placed in tk.h

Now that the font attributes are exposed I want to declare a more general
set of font weight values that are more in keeping with the commonly 
available font systems. Pango and Win32 both use the same set of symbolic
names and values in the range 0-1000.
Xft uses a similar set of names but in a range 0-255
XLFD has similar names but they are symbolic.

This extends the possible values of the weight field in font attributes to
include normal, bold, light, ultralight, ultrabold and heavy

Index: generic/tk.decls
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tk.decls,v
retrieving revision 1.39
diff -u -r1.39 tk.decls
--- generic/tk.decls	2 Apr 2008 21:31:17 -0000	1.39
+++ generic/tk.decls	14 May 2008 00:53:20 -0000
@@ -1073,6 +1073,11 @@
 declare 273 generic {
     void Tk_CreateOldPhotoImageFormat(Tk_PhotoImageFormat *formatPtr)
 }
+# TIP#145
+declare 274 generic {
+    int Tk_CreateNamedFont(Tcl_Interp *interp, Tk_Window tkwin,
+	    const char *name, Tk_FontAttributes *faPtr)
+}
 
 # Define the platform specific public Tk interface.  These functions are
 # only available on the designated platform.
Index: generic/tk.h
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tk.h,v
retrieving revision 1.110
diff -u -r1.110 tk.h
--- generic/tk.h	1 Apr 2008 16:30:52 -0000	1.110
+++ generic/tk.h	14 May 2008 00:53:21 -0000
@@ -527,6 +527,55 @@
 } Tk_FontMetrics;
 
 /*
+ * The following structure keeps track of the attributes of a font. It can be
+ * used to keep track of either the desired attributes or the actual
+ * attributes gotten when the font was instantiated.
+ */
+
+typedef struct Tk_FontAttributes {
+    Tk_Uid family;		/* Font family, or NULL to represent plaform-
+				 * specific default system font. */
+    int size;			/* Pointsize of font, 0 for default size, or
+				 * negative number meaning pixel size. */
+    int weight;			/* Weight flag; see below for def'n. */
+    int slant;			/* Slant flag; see below for def'n. */
+    int underline;		/* Non-zero for underline font. */
+    int overstrike;		/* Non-zero for overstrike font. */
+} Tk_FontAttributes;
+
+/*
+ * Possible values for the "weight" field in a TkFontAttributes structure.
+ * Weight is a subjective term and depends on what the company that created
+ * the font considers bold.
+ */
+
+#define TK_FW_ULTRALIGHT 200
+#define TK_FW_LIGHT      300
+#define TK_FW_NORMAL     400
+#define TK_FW_BOLD       700
+#define TK_FW_ULTRABOLD  800
+#define TK_FW_HEAVY      900
+#define TK_FW_UNKNOWN	-1	/* Unknown weight. This value is used for
+				 * error checking and is never actually stored
+				 * in the weight field. */
+
+/*
+ * Possible values for the "slant" field in a TkFontAttributes structure.
+ */
+
+#define TK_FS_ROMAN	0
+#define TK_FS_ITALIC	1
+#define TK_FS_OBLIQUE	2	/* This value is only used when parsing X font
+				 * names to determine the closest match. It is
+				 * only stored in the XLFDAttributes
+				 * structure, never in the slant field of the
+				 * TkFontAttributes. */
+
+#define TK_FS_UNKNOWN	-1	/* Unknown slant. This value is used for error
+				 * checking and is never actually stored in
+				 * the slant field. */
+
+/*
  * Flags passed to Tk_MeasureChars:
  */
 
Index: generic/tkDecls.h
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkDecls.h,v
retrieving revision 1.34
diff -u -r1.34 tkDecls.h
--- generic/tkDecls.h	8 Apr 2008 15:00:37 -0000	1.34
+++ generic/tkDecls.h	14 May 2008 00:53:21 -0000
@@ -1694,6 +1694,13 @@
 EXTERN void		Tk_CreateOldPhotoImageFormat (
 				Tk_PhotoImageFormat * formatPtr);
 #endif
+#ifndef Tk_CreateNamedFont_TCL_DECLARED
+#define Tk_CreateNamedFont_TCL_DECLARED
+/* 274 */
+EXTERN int		Tk_CreateNamedFont (Tcl_Interp * interp, 
+				Tk_Window tkwin, const char * name, 
+				Tk_FontAttributes * faPtr);
+#endif
 
 typedef struct TkStubHooks {
     CONST struct TkPlatStubs *tkPlatStubs;
@@ -1980,6 +1987,7 @@
     Tcl_Interp * (*tk_Interp) (Tk_Window tkwin); /* 271 */
     void (*tk_CreateOldImageType) (Tk_ImageType * typePtr); /* 272 */
     void (*tk_CreateOldPhotoImageFormat) (Tk_PhotoImageFormat * formatPtr); /* 273 */
+    int (*tk_CreateNamedFont) (Tcl_Interp * interp, Tk_Window tkwin, const char * name, Tk_FontAttributes * faPtr); /* 274 */
 } TkStubs;
 
 #if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS)
@@ -3082,6 +3090,10 @@
 #define Tk_CreateOldPhotoImageFormat \
 	(tkStubsPtr->tk_CreateOldPhotoImageFormat) /* 273 */
 #endif
+#ifndef Tk_CreateNamedFont
+#define Tk_CreateNamedFont \
+	(tkStubsPtr->tk_CreateNamedFont) /* 274 */
+#endif
 
 #endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */
 
Index: generic/tkFont.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkFont.c,v
retrieving revision 1.43
diff -u -r1.43 tkFont.c
--- generic/tkFont.c	27 Apr 2008 22:38:56 -0000	1.43
+++ generic/tkFont.c	14 May 2008 00:53:22 -0000
@@ -108,8 +108,12 @@
  */
 
 static const TkStateMap weightMap[] = {
+    {TK_FW_ULTRALIGHT,	"ultralight"},
+    {TK_FW_LIGHT,	"light"},
     {TK_FW_NORMAL,	"normal"},
     {TK_FW_BOLD,	"bold"},
+    {TK_FW_ULTRABOLD,	"ultrabold"},
+    {TK_FW_HEAVY,	"heavy"},
     {TK_FW_UNKNOWN,	NULL}
 };
 
@@ -137,8 +141,8 @@
 static const TkStateMap xlfdWeightMap[] = {
     {TK_FW_NORMAL,	"normal"},
     {TK_FW_NORMAL,	"medium"},
-    {TK_FW_NORMAL,	"book"},
-    {TK_FW_NORMAL,	"light"},
+    {TK_FW_LIGHT,	"book"},
+    {TK_FW_LIGHT,	"light"},
     {TK_FW_BOLD,	"bold"},
     {TK_FW_BOLD,	"demi"},
     {TK_FW_BOLD,	"demibold"},
@@ -673,7 +677,7 @@
 		&fa) != TCL_OK) {
 	    return TCL_ERROR;
 	}
-	if (TkCreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) {
+	if (Tk_CreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) {
 	    return TCL_ERROR;
 	}
 	Tcl_AppendResult(interp, name, NULL);
@@ -919,7 +923,7 @@
 /*
  *---------------------------------------------------------------------------
  *
- * TkCreateNamedFont --
+ * Tk_CreateNamedFont --
  *
  *	Create the specified named font with the given attributes in the named
  *	font table associated with the interp.
@@ -941,11 +945,11 @@
  */
 
 int
-TkCreateNamedFont(
+Tk_CreateNamedFont(
     Tcl_Interp *interp,		/* Interp for error return (can be NULL). */
     Tk_Window tkwin,		/* A window associated with interp. */
     const char *name,		/* Name for the new named font. */
-    TkFontAttributes *faPtr)	/* Attributes for the new named font. */
+    Tk_FontAttributes *faPtr)	/* Attributes for the new named font. */
 {
     TkFontInfo *fiPtr;
     Tcl_HashEntry *namedHashPtr;
Index: generic/tkFont.h
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkFont.h,v
retrieving revision 1.11
diff -u -r1.11 tkFont.h
--- generic/tkFont.h	2 May 2008 10:28:18 -0000	1.11
+++ generic/tkFont.h	14 May 2008 00:53:22 -0000
@@ -22,52 +22,6 @@
 #endif
 
 /*
- * The following structure keeps track of the attributes of a font. It can be
- * used to keep track of either the desired attributes or the actual
- * attributes gotten when the font was instantiated.
- */
-
-struct TkFontAttributes {
-    Tk_Uid family;		/* Font family, or NULL to represent plaform-
-				 * specific default system font. */
-    int size;			/* Pointsize of font, 0 for default size, or
-				 * negative number meaning pixel size. */
-    int weight;			/* Weight flag; see below for def'n. */
-    int slant;			/* Slant flag; see below for def'n. */
-    int underline;		/* Non-zero for underline font. */
-    int overstrike;		/* Non-zero for overstrike font. */
-};
-
-/*
- * Possible values for the "weight" field in a TkFontAttributes structure.
- * Weight is a subjective term and depends on what the company that created
- * the font considers bold.
- */
-
-#define TK_FW_NORMAL	0
-#define TK_FW_BOLD	1
-
-#define TK_FW_UNKNOWN	-1	/* Unknown weight. This value is used for
-				 * error checking and is never actually stored
-				 * in the weight field. */
-
-/*
- * Possible values for the "slant" field in a TkFontAttributes structure.
- */
-
-#define TK_FS_ROMAN	0
-#define TK_FS_ITALIC	1
-#define TK_FS_OBLIQUE	2	/* This value is only used when parsing X font
-				 * names to determine the closest match. It is
-				 * only stored in the XLFDAttributes
-				 * structure, never in the slant field of the
-				 * TkFontAttributes. */
-
-#define TK_FS_UNKNOWN	-1	/* Unknown slant. This value is used for error
-				 * checking and is never actually stored in
-				 * the slant field. */
-
-/*
  * The following structure keeps track of the metrics for an instantiated
  * font. The metrics are the physical properties of the font itself.
  */
@@ -192,7 +146,8 @@
  * Low-level API exported by generic code to platform-specific code.
  */
 
-#define TkInitFontAttributes(fa)   memset((fa), 0, sizeof(TkFontAttributes));
+#define TkInitFontAttributes(fa)   memset((fa),0,sizeof(Tk_FontAttributes)),\
+				       (fa)->weight = TK_FW_NORMAL
 #define TkInitXLFDAttributes(xa)   memset((xa), 0, sizeof(TkXLFDAttributes));
 
 MODULE_SCOPE int	TkFontParseXLFD(const char *string,
@@ -203,8 +158,6 @@
 MODULE_SCOPE int	TkFontGetPoints(Tk_Window tkwin, int size);
 MODULE_SCOPE char **	TkFontGetGlobalClass(void);
 MODULE_SCOPE char **	TkFontGetSymbolClass(void);
-MODULE_SCOPE int	TkCreateNamedFont(Tcl_Interp *interp, Tk_Window tkwin,
-			    const char *name, TkFontAttributes *faPtr);
 MODULE_SCOPE int	TkDeleteNamedFont(Tcl_Interp *interp,
 			    Tk_Window tkwin, const char *name);
 MODULE_SCOPE int	TkFontGetFirstTextLayout(Tk_TextLayout layout,
Index: generic/tkInt.h
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkInt.h,v
retrieving revision 1.83
diff -u -r1.83 tkInt.h
--- generic/tkInt.h	2 Apr 2008 21:32:32 -0000	1.83
+++ generic/tkInt.h	14 May 2008 00:53:22 -0000
@@ -96,7 +96,7 @@
  */
 
 typedef struct TkColormap TkColormap;
-typedef struct TkFontAttributes TkFontAttributes;
+typedef struct Tk_FontAttributes TkFontAttributes;
 typedef struct TkGrabEvent TkGrabEvent;
 typedef struct TkpCursor_ *TkpCursor;
 typedef struct TkRegion_ *TkRegion;
@@ -1199,7 +1199,7 @@
 			    const char *string, int numBytes, int x, int y,
 			    int firstByte, int lastByte);
 MODULE_SCOPE void	TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont,
-			    Tcl_UniChar c, struct TkFontAttributes *faPtr);
+			    Tcl_UniChar c, TkFontAttributes *faPtr);
 
 /*
  * Unsupported commands.
Index: generic/tkStubInit.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkStubInit.c,v
retrieving revision 1.63
diff -u -r1.63 tkStubInit.c
--- generic/tkStubInit.c	27 Apr 2008 22:38:58 -0000	1.63
+++ generic/tkStubInit.c	14 May 2008 00:53:22 -0000
@@ -944,6 +944,7 @@
     Tk_Interp, /* 271 */
     Tk_CreateOldImageType, /* 272 */
     Tk_CreateOldPhotoImageFormat, /* 273 */
+    Tk_CreateNamedFont, /* 274 */
 };
 
 /* !END!: Do not edit above this line. */
Index: macosx/tkMacOSXFont.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/macosx/tkMacOSXFont.c,v
retrieving revision 1.37
diff -u -r1.37 tkMacOSXFont.c
--- macosx/tkMacOSXFont.c	13 Dec 2007 15:27:09 -0000	1.37
+++ macosx/tkMacOSXFont.c	14 May 2008 00:53:23 -0000
@@ -381,7 +381,7 @@
     TkFontAttributes *faPtr)
 {
     TkDeleteNamedFont(NULL, tkwin, name);
-    return TkCreateNamedFont(interp, tkwin, name, faPtr);
+    return Tk_CreateNamedFont(interp, tkwin, name, faPtr);
 }
 
 /*
Index: unix/tkUnixRFont.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/unix/tkUnixRFont.c,v
retrieving revision 1.25
diff -u -r1.25 tkUnixRFont.c
--- unix/tkUnixRFont.c	27 Apr 2008 22:39:13 -0000	1.25
+++ unix/tkUnixRFont.c	14 May 2008 00:53:23 -0000
@@ -110,6 +110,49 @@
 }
 
 /*
+ * Convert Tk font weights into equivalent Xft font weights.
+ * Note we make the change halfway between each symbolic name.
+ */
+
+static int
+XftWeightFromTk(int weight)
+{
+    int xft_weight = 0;
+    if (weight < (TK_FW_NORMAL + TK_FW_LIGHT) / 2) {
+	xft_weight = XFT_WEIGHT_LIGHT;
+    } else if (weight < (TK_FW_NORMAL + TK_FW_BOLD) / 2) {
+	xft_weight = XFT_WEIGHT_MEDIUM;
+    } else if (weight < (TK_FW_BOLD + TK_FW_ULTRABOLD) / 2) {
+	xft_weight = XFT_WEIGHT_BOLD;
+    } else {
+	xft_weight = XFT_WEIGHT_BLACK;
+    }
+    return xft_weight;
+}
+
+/*
+ * Convert Xft font weights into equivalent Tk font weights
+ */
+
+static int
+TkWeightFromXft(int xft_weight)
+{
+    int weight = 0;
+    if (xft_weight < XFT_WEIGHT_LIGHT) {
+	weight = TK_FW_ULTRALIGHT;
+    } else if (xft_weight < (XFT_WEIGHT_LIGHT + XFT_WEIGHT_MEDIUM) / 2) {
+	weight = TK_FW_LIGHT;
+    } else if (xft_weight < (XFT_WEIGHT_MEDIUM + XFT_WEIGHT_BOLD) / 2) {
+	weight = TK_FW_NORMAL;
+    } else if (xft_weight < (XFT_WEIGHT_BOLD + XFT_WEIGHT_BLACK) / 2) {
+	weight = TK_FW_BOLD;
+    } else {
+	weight = TK_FW_HEAVY;
+    }
+    return weight;
+}
+
+/*
  *---------------------------------------------------------------------------
  *
  * GetTkFontAttributes --
@@ -151,7 +194,7 @@
 
     faPtr->family = Tk_GetUid(family);
     faPtr->size = size;
-    faPtr->weight = (weight > XFT_WEIGHT_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
+    faPtr->weight = TkWeightFromXft(weight);
     faPtr->slant = (slant > XFT_SLANT_ROMAN) ? TK_FS_ITALIC : TK_FS_ROMAN;
     faPtr->underline = 0;
     faPtr->overstrike = 0;
@@ -359,15 +402,7 @@
     } else {
 	XftPatternAddDouble(pattern, XFT_SIZE, 12.0);
     }
-    switch (faPtr->weight) {
-    case TK_FW_NORMAL:
-    default:
-	weight = XFT_WEIGHT_MEDIUM;
-	break;
-    case TK_FW_BOLD:
-	weight = XFT_WEIGHT_BOLD;
-	break;
-    }
+    weight = XftWeightFromTk(faPtr->weight);
     XftPatternAddInteger(pattern, XFT_WEIGHT, weight);
     switch (faPtr->slant) {
     case TK_FS_ROMAN:
Index: win/tkWinFont.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/win/tkWinFont.c,v
retrieving revision 1.39
diff -u -r1.39 tkWinFont.c
--- win/tkWinFont.c	27 Apr 2008 22:39:17 -0000	1.39
+++ win/tkWinFont.c	14 May 2008 00:53:23 -0000
@@ -373,7 +373,7 @@
     
     TkDeleteNamedFont(NULL, tkwin, name);
     InitFont(tkwin, hFont, 0, &winfont);
-    r = TkCreateNamedFont(interp, tkwin, name, &winfont.font.fa);
+    r = Tk_CreateNamedFont(interp, tkwin, name, &winfont.font.fa);
     TkpDeleteFont((TkFont *)&winfont);
     return r;
 }
@@ -755,7 +755,7 @@
     faPtr->family = familyPtr->faceName;
     faPtr->size = TkFontGetPoints(tkwin,
 	    tm.tmInternalLeading - tm.tmHeight);
-    faPtr->weight = (tm.tmWeight > FW_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
+    faPtr->weight = tm.tmWeight;
     faPtr->slant = tm.tmItalic ? TK_FS_ITALIC : TK_FS_ROMAN;
     faPtr->underline = (tm.tmUnderlined != 0);
     faPtr->overstrike = fontPtr->font.fa.overstrike;
@@ -1410,8 +1410,7 @@
 
     faPtr->size =
 	    TkFontGetPoints(tkwin, -(fontPtr->pixelSize));
-    faPtr->weight =
-	    (tm.tmWeight > FW_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
+    faPtr->weight = tm.tmWeight;
     faPtr->slant	= (tm.tmItalic != 0) ? TK_FS_ITALIC : TK_FS_ROMAN;
     faPtr->underline	= (tm.tmUnderlined != 0) ? 1 : 0;
     faPtr->overstrike	= overstrike;
@@ -2293,7 +2292,7 @@
     lf.lfWidth		= 0;
     lf.lfEscapement	= 0;
     lf.lfOrientation	= 0;
-    lf.lfWeight = (faPtr->weight == TK_FW_NORMAL) ? FW_NORMAL : FW_BOLD;
+    lf.lfWeight = faPtr->weight;
     lf.lfItalic		= faPtr->slant;
     lf.lfUnderline	= faPtr->underline;
     lf.lfStrikeOut	= faPtr->overstrike;