Tk Source Code

Artifact [e835e3db]
Login

Artifact e835e3db0079c8cf0a1eadf772eb5ef77058e913:

Attachment "font.patch" to ticket [1602955f] added by kennykb 2006-11-26 08:03:09.
? NSK1KENNYKB03
? kbk
? doc/man.macros
Index: doc/font.n
===================================================================
RCS file: /cvsroot/tktoolkit/tk/doc/font.n,v
retrieving revision 1.8
diff -b -u -r1.8 font.n
--- doc/font.n	6 Apr 2005 21:11:54 -0000	1.8
+++ doc/font.n	26 Nov 2006 00:59:19 -0000
@@ -22,7 +22,7 @@
 a font.  The command has several different forms, determined by the
 first argument.  The following forms are currently supported:
 .TP
-\fBfont actual \fIfont\fR ?\fB\-displayof \fIwindow\fR? ?\fIoption\fR?  
+\fBfont actual \fIfont\fR ?\fB\-displayof \fIwindow\fR? ?\fIoption\fR? ?\fB--\fR? ?\fIchar\fR?
 .
 Returns information about the actual attributes that are obtained when
 \fIfont\fR is used on \fIwindow\fR's display; the actual attributes obtained
@@ -32,7 +32,12 @@
 \fIwindow\fR argument is omitted, it defaults to the main window.  If
 \fIoption\fR is specified, returns the value of that attribute; if it is
 omitted, the return value is a list of all the attributes and their values.
-See FONT OPTIONS below for a list of the possible attributes.
+See FONT OPTIONS below for a list of the possible attributes.  If the
+\fIchar\fR argument is supplied, it must be a single character. The font
+attributes returned will be those of the specific font used to render
+that character, which will be different from the base font if the base
+font does not contain the given character.  If \fIchar\fR may be a hyphen, it
+should be preceded by \fB--\fR to distinguish it from a misspelt \fIoption\fR.
 .TP 
 \fBfont configure \fIfontname\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?  
 .
Index: generic/tkFont.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkFont.c,v
retrieving revision 1.28
diff -b -u -r1.28 tkFont.c
--- generic/tkFont.c	22 Mar 2006 00:21:16 -0000	1.28
+++ generic/tkFont.c	26 Nov 2006 00:59:19 -0000
@@ -503,31 +503,88 @@
     switch ((enum options) index) {
     case FONT_ACTUAL: {
 	int skip, result;
+	int n;
+	const char* s;
 	Tk_Font tkfont;
-	Tcl_Obj *objPtr;
+	Tcl_Obj *optPtr;
+	Tcl_Obj *charPtr;
+	Tcl_Obj *resultPtr;
+	Tcl_UniChar uniChar;
 	CONST TkFontAttributes *faPtr;
+	TkFontAttributes fa;
 
+	/* 
+	 * Params 0 and 1 are 'font actual'.  Param 2 is the
+	 * font name. 3-4 may be '-displayof $window'
+	 */
 	skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
 	if (skip < 0) {
 	    return TCL_ERROR;
 	}
-	if ((objc < 3) || (objc - skip > 4)) {
+
+	/* Next parameter may be an option */
+	n = skip + 3;
+	optPtr = NULL;
+	charPtr = NULL;
+	if (n < objc) {
+	    s = Tcl_GetString(objv[n]);
+	    if (s[0] == '-' && s[1] != '-') {
+		optPtr = objv[n];
+		++n;
+	    } else {
+		optPtr = NULL;
+	    }
+	}
+
+	/* Next parameter may be '--' to mark end of options */
+	if (n < objc) {
+	    if (!strcmp(Tcl_GetString(objv[n]), "--")) {
+		++n;
+	    }
+	}
+
+	/* Next parameter is the character to get font information for */
+	if (n < objc) {
+	    charPtr = objv[n];
+	    ++n;
+	}
+
+	/* If there were fewer than 3 args, or args remain, that's an error */
+	if (objc < 3 || n < objc) {
 	    Tcl_WrongNumArgs(interp, 2, objv,
-		    "font ?-displayof window? ?option?");
+		    "font ?-displayof window? ?option? ?--? ?char?");
 	    return TCL_ERROR;
 	}
+
+	/* The 'charPtr' arg must be a single Unicode */
+	if (charPtr != NULL) {
+	    if (Tcl_GetCharLength(charPtr) != 1) {
+		resultPtr =  Tcl_NewStringObj("expected a single character "
+					      "but got \"", -1);
+		Tcl_AppendLimitedToObj(resultPtr, Tcl_GetString(charPtr),
+				       -1, 40, "...");
+		Tcl_AppendToObj(resultPtr, "\"", -1);
+		Tcl_SetObjResult(interp, resultPtr);
+		return TCL_ERROR;
+	    }
+	    uniChar = Tcl_GetUniChar(charPtr, 0);
+	}
+
+	/* Find the font */
 	tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
 	if (tkfont == NULL) {
 	    return TCL_ERROR;
 	}
-	objc -= skip;
-	objv += skip;
+	
+	/* Determine the font attributes */
+	if (charPtr == NULL) {
 	faPtr = GetFontAttributes(tkfont);
-	objPtr = NULL;
-	if (objc > 3) {
-	    objPtr = objv[3];
+	} else {
+	    TkpGetFontAttrsForChar(tkwin, tkfont, uniChar, &fa);
+	    faPtr = &fa;
 	}
-	result = GetAttributeInfoObj(interp, faPtr, objPtr);
+	result = GetAttributeInfoObj(interp, faPtr, optPtr);
+
 	Tk_FreeFont(tkfont);
 	return result;
     }
Index: generic/tkFont.h
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkFont.h,v
retrieving revision 1.8
diff -b -u -r1.8 tkFont.h
--- generic/tkFont.h	22 Mar 2006 00:21:16 -0000	1.8
+++ generic/tkFont.h	26 Nov 2006 00:59:19 -0000
@@ -27,7 +27,7 @@
  * attributes gotten when the font was instantiated.
  */
 
-typedef struct TkFontAttributes {
+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
@@ -36,7 +36,7 @@
     int slant;			/* Slant flag; see below for def'n. */
     int underline;		/* Non-zero for underline font. */
     int overstrike;		/* Non-zero for overstrike font. */
-} TkFontAttributes;
+};
 
 /*
  * Possible values for the "weight" field in a TkFontAttributes structure.
Index: generic/tkInt.h
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkInt.h,v
retrieving revision 1.74
diff -b -u -r1.74 tkInt.h
--- generic/tkInt.h	31 Oct 2006 01:42:25 -0000	1.74
+++ generic/tkInt.h	26 Nov 2006 00:59:20 -0000
@@ -71,6 +71,7 @@
  */
 
 typedef struct TkColormap TkColormap;
+typedef struct TkFontAttributes TkFontAttributes;
 typedef struct TkGrabEvent TkGrabEvent;
 typedef struct TkpCursor_ *TkpCursor;
 typedef struct TkRegion_ *TkRegion;
@@ -1180,6 +1181,9 @@
 			    Drawable drawable, GC gc, Tk_Font tkfont,
 			    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);
 
 /*
  * Unsupported commands.
Index: macosx/tkMacOSXFont.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/macosx/tkMacOSXFont.c,v
retrieving revision 1.19
diff -b -u -r1.19 tkMacOSXFont.c
--- macosx/tkMacOSXFont.c	20 Jul 2006 06:25:19 -0000	1.19
+++ macosx/tkMacOSXFont.c	26 Nov 2006 00:59:20 -0000
@@ -465,6 +465,38 @@
 }
 
 /*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetFontAttrsForChar --
+ *
+ *	Retrieve the font attributes of the actual font used to render
+ *	a given character.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The font attributes are stored in *faPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpGetFontAttrsForChar(
+    Tk_Window tkwin,		/* Window on the font's display */
+    Tk_Font tkfont,		/* Font to query */
+    Tcl_UniChar c,		/* Character of interest */
+    TkFontAttributes* faPtr)	/* Output: Font attributes */
+{
+    /* 
+     * Once again, we don't know what ATSU is doing for us. Simply
+     * return the attributes of the base font.
+     */
+    TkMacOSXFont* fontPtr = (TkMacOSXFont*) tkfont;
+    *faPtr = fontPtr->font.fa;
+}
+
+/*
  *---------------------------------------------------------------------------
  *
  *  Tk_MeasureChars --
Index: tests/font.test
===================================================================
RCS file: /cvsroot/tktoolkit/tk/tests/font.test,v
retrieving revision 1.13
diff -b -u -r1.13 font.test
--- tests/font.test	22 Mar 2006 00:21:18 -0000	1.13
+++ tests/font.test	26 Nov 2006 00:59:20 -0000
@@ -115,11 +115,11 @@
 test font-4.2 {font command: actual: arguments} {
     # (objc < 3) 
     list [catch {font actual} msg] $msg
-} {1 {wrong # args: should be "font actual font ?-displayof window? ?option?"}}
+} {1 {wrong # args: should be "font actual font ?-displayof window? ?option? ?--? ?char?"}}
 test font-4.3 {font command: actual: arguments} {
     # (objc - skip > 4) when skip == 0
     list [catch {font actual xyz abc def} msg] $msg
-} {1 {wrong # args: should be "font actual font ?-displayof window? ?option?"}}
+} {1 {wrong # args: should be "font actual font ?-displayof window? ?option? ?--? ?char?"}}
 test font-4.4 {font command: actual: displayof specified, so skip to next} {
     catch {font actual xyz -displayof . -size}
 } {0}
@@ -129,7 +129,7 @@
 test font-4.6 {font command: actual: arguments} {
     # (objc - skip > 4) when skip == 2
     list [catch {font actual xyz -displayof . abc def} msg] $msg
-} {1 {wrong # args: should be "font actual font ?-displayof window? ?option?"}}
+} {1 {wrong # args: should be "font actual font ?-displayof window? ?option? ?--? ?char?"}}
 test font-4.7 {font command: actual: arguments} {noExceed} {
     # (tkfont == NULL)
     list [catch {font actual "\{xyz"} msg] $msg
@@ -1334,6 +1334,28 @@
     font actual {{times new roman} 10} -family
 } [font actual {times 10} -family]
 
+test font-46.1 {font actual, with character, no option, no --} {
+    font actual {times 10} a
+} [font actual {times 10}]
+
+test font-46.2 {font actual, with character introduced by --} {
+    font actual {times 10} -- -
+} [font actual {times 10}]
+
+test font-46.3 {font actual, with character and option} {
+    font actual {times 10} -family a
+} [font actual {times 10} -family]
+
+test font-46.4 {font actual, with character, option and --} {
+    font actual {times 10} -family -- -
+} [font actual {times 10} -family]
+
+test font-46.5 {font actual, too many chars} {
+    list [catch {
+	font actual {times 10} 123456789012345678901234567890123456789012345678901
+    } result] $result
+} {1 {expected a single character but got "1234567890123456789012345678901234567..."}}
+
 setup
 
 destroy .b
Index: unix/tkUnixFont.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/unix/tkUnixFont.c,v
retrieving revision 1.29
diff -b -u -r1.29 tkUnixFont.c
--- unix/tkUnixFont.c	5 Oct 2006 21:27:43 -0000	1.29
+++ unix/tkUnixFont.c	26 Nov 2006 00:59:21 -0000
@@ -930,6 +930,44 @@
 }
 
 /*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetFontAttrsForChar --
+ *
+ *	Retrieve the font attributes of the actual font used to render
+ *	a given character.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The font attributes are stored in *faPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpGetFontAttrsForChar(
+    Tk_Window tkwin,		/* Window on the font's display */
+    Tk_Font tkfont,		/* Font to query */
+    Tcl_UniChar c,		/* Character of interest */
+    TkFontAttributes* faPtr)	/* Output: Font attributes */
+{
+    FontAttributes atts;
+    UnixFont *fontPtr = (UnixFont *) tkfont;
+				/* Structure describing the logical font */
+    SubFont *lastSubFontPtr = &fontPtr->subFontArray[0];
+				/* Pointer to subfont array in case
+				 * FindSubFontForChar needs to fix up the
+				 * memory allocation */
+    SubFont *thisSubFontPtr = FindSubFontForChar(fontPtr, c, &lastSubFontPtr);
+				/* Pointer to the subfont to use for the
+				 * given character */
+    GetFontAttributes(Tk_Display(tkwin), thisSubFontPtr->fontStructPtr, &atts);
+    *faPtr = atts.fa;
+}
+
+/*
  *---------------------------------------------------------------------------
  *
  * Tk_MeasureChars --
Index: unix/tkUnixRFont.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/unix/tkUnixRFont.c,v
retrieving revision 1.13
diff -b -u -r1.13 tkUnixRFont.c
--- unix/tkUnixRFont.c	23 Mar 2006 22:08:51 -0000	1.13
+++ unix/tkUnixRFont.c	26 Nov 2006 00:59:21 -0000
@@ -469,6 +469,66 @@
     Tcl_SetObjResult(interp, resultPtr);
 }
 
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetFontAttrsForChar --
+ *
+ *	Retrieve the font attributes of the actual font used to render
+ *	a given character.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The font attributes are stored in *faPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpGetFontAttrsForChar(
+    Tk_Window tkwin,		/* Window on the font's display */
+    Tk_Font tkfont,		/* Font to query */
+    Tcl_UniChar 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 *xftFontPtr = GetFont(fontPtr, ucs4);
+				/* Actual font used to render the character */
+    const char* family;		/* Font family name */
+    double size;		/* Font size */
+    int weight;			/* Font weight */
+    int slant;			/* Font slant */
+    
+    if (XftPatternGetString(xftFontPtr->pattern, XFT_FAMILY, 0,
+			    &family) != XftResultMatch) {
+	family = "Unknown";
+    }
+    if (XftPatternGetDouble(xftFontPtr->pattern, XFT_SIZE, 0,
+			    &size) != XftResultMatch) {
+	size = 12.0;
+    }
+    if (XftPatternGetInteger(xftFontPtr->pattern, XFT_WEIGHT, 0,
+			     &weight) != XftResultMatch) {
+	weight = XFT_WEIGHT_MEDIUM;
+    }
+    if (XftPatternGetInteger(xftFontPtr->pattern, XFT_SLANT, 0,
+			     &slant) != XftResultMatch) {
+	slant = XFT_SLANT_ROMAN;
+    }
+    faPtr->family = Tk_GetUid(family);
+    faPtr->size = (int) size;
+    faPtr->weight = (weight > XFT_WEIGHT_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
+    faPtr->slant = (slant > XFT_SLANT_ROMAN) ? TK_FS_ITALIC : TK_FS_ROMAN;
+    faPtr->underline = fontPtr->font.fa.underline;
+    faPtr->overstrike = fontPtr->font.fa.overstrike;
+
+}
+
 int
 Tk_MeasureChars(
     Tk_Font tkfont,		/* Font in which characters will be drawn. */
Index: win/tkWinFont.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/win/tkWinFont.c,v
retrieving revision 1.27
diff -b -u -r1.27 tkWinFont.c
--- win/tkWinFont.c	22 Mar 2006 00:21:20 -0000	1.27
+++ win/tkWinFont.c	26 Nov 2006 00:59:22 -0000
@@ -561,6 +561,62 @@
 }
 
 /*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetFontAttrsForChar --
+ *
+ *	Retrieve the font attributes of the actual font used to render
+ *	a given character.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The font attributes are stored in *faPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpGetFontAttrsForChar(
+    Tk_Window tkwin,		/* Window on the font's display */
+    Tk_Font tkfont,		/* Font to query */
+    Tcl_UniChar c,		/* Character of interest */
+    TkFontAttributes* faPtr)	/* Output: Font attributes */
+{
+    WinFont *fontPtr = (WinFont *) tkfont;
+				/* Structure describing the logical font */
+    HDC hdc = GetDC(fontPtr->hwnd);
+				/* GDI device context */
+    SubFont *lastSubFontPtr = &fontPtr->subFontArray[0];
+				/* Pointer to subfont array in case
+				 * FindSubFontForChar needs to fix up
+				 * the memory allocation */
+    SubFont *thisSubFontPtr = FindSubFontForChar(fontPtr, c,
+						 &lastSubFontPtr);
+				/* Pointer to the subfont to use for
+				 * the given character */
+    FontFamily *familyPtr = thisSubFontPtr->familyPtr;
+    HFONT oldfont;		/* Saved font from the device context */
+    TEXTMETRIC tm;		/* Font metrics of the selected subfont */
+
+  
+    /* Get the font attributes */
+
+    oldfont = SelectObject(hdc, thisSubFontPtr->hFont);
+    GetTextMetrics(hdc, &tm);
+    SelectObject(hdc, oldfont);
+    ReleaseDC(fontPtr->hwnd, hdc);
+    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->slant = tm.tmItalic ? TK_FS_ITALIC : TK_FS_ROMAN;
+    faPtr->underline = (tm.tmUnderlined != 0);
+    faPtr->overstrike = fontPtr->font.fa.overstrike;
+}
+
+/*
  *---------------------------------------------------------------------------
  *
  *  Tk_MeasureChars --