Tk Source Code

Artifact [cee2c953]
Login

Artifact cee2c95314604eab463a040abe9161a4fd4851176e5fb8002ea48472d74f7ef2:

Attachment "tkFont.diff" to ticket [c81e0cce] added by chw 2025-06-06 05:46:22.
Index: generic/tkFont.c
==================================================================
--- generic/tkFont.c
+++ generic/tkFont.c
@@ -343,11 +343,12 @@
 			    Tcl_Obj *objPtr, TkFontAttributes *faPtr);
 static void		RecomputeWidgets(TkWindow *winPtr);
 static int		SetFontFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
 static void		TheWorldHasChanged(ClientData clientData);
 static void		UpdateDependentFonts(TkFontInfo *fiPtr,
-			    Tk_Window tkwin, Tcl_HashEntry *namedHashPtr);
+			    Tk_Window tkwin, Tcl_HashEntry *namedHashPtr,
+			    int isNew);
 
 /*
  * The following structure defines the implementation of the "font" Tcl
  * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of each
  * font object points to the TkFont structure for the font, or NULL.
@@ -640,15 +641,15 @@
     	} else if (objc == 4) {
     	    objPtr = objv[3];
     	} else {
     	    result = ConfigAttributesObj(interp, tkwin, objc - 3, objv + 3,
     		    &nfPtr->fa);
-    	    UpdateDependentFonts(fiPtr, tkwin, namedHashPtr);
+    	    UpdateDependentFonts(fiPtr, tkwin, namedHashPtr, 0);
     	    return result;
     	}
     	return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr);
-     }
+    }
     case FONT_CREATE: {
 	int skip = 3, i;
 	const char *name;
 	char buf[16 + TCL_INTEGER_SPACE];
 	TkFontAttributes fa;
@@ -845,39 +846,54 @@
 
 static void
 UpdateDependentFonts(
     TkFontInfo *fiPtr,		/* Info about application's fonts. */
     Tk_Window tkwin,		/* A window in the application. */
-    Tcl_HashEntry *namedHashPtr)/* The named font that is changing. */
+    Tcl_HashEntry *namedHashPtr,/* The named font that is changing. */
+    int isNew)			/* The font was newly created. */
 {
     Tcl_HashEntry *cacheHashPtr;
     Tcl_HashSearch search;
     TkFont *fontPtr;
     NamedFont *nfPtr = (NamedFont *)Tcl_GetHashValue(namedHashPtr);
+    char *name = NULL;
+    int doUpdate = 0;
 
-    if (nfPtr->refCount == 0) {
+    if (!isNew && (nfPtr->refCount == 0)) {
 	/*
 	 * Well nobody's using this named font, so don't have to tell any
 	 * widgets to recompute themselves.
 	 */
 
 	return;
     }
-
+    if (isNew) {
+	name = (char *)Tcl_GetHashKey(&fiPtr->namedTable, namedHashPtr);
+    }
     cacheHashPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search);
     while (cacheHashPtr != NULL) {
 	for (fontPtr = (TkFont *)Tcl_GetHashValue(cacheHashPtr);
 		fontPtr != NULL; fontPtr = fontPtr->nextPtr) {
 	    if (fontPtr->namedHashPtr == namedHashPtr) {
 		TkpGetFontFromAttributes(fontPtr, tkwin, &nfPtr->fa);
-		if (!fiPtr->updatePending) {
-		    fiPtr->updatePending = 1;
-		    Tcl_DoWhenIdle(TheWorldHasChanged, fiPtr);
+		doUpdate++;
+	    } else if (isNew && (fontPtr->namedHashPtr == NULL)) {
+		char *otherName = (char *)Tcl_GetHashKey(&fiPtr->fontCache,
+			cacheHashPtr);
+		if (strcmp(otherName, name) == 0) {
+		    fontPtr->namedHashPtr = namedHashPtr;
+		    nfPtr->refCount++;
+		    TkpGetFontFromAttributes(fontPtr, tkwin, &nfPtr->fa);
+		    doUpdate++;
 		}
 	    }
 	}
 	cacheHashPtr = Tcl_NextHashEntry(&search);
+    }
+    if (doUpdate && !fiPtr->updatePending) {
+	fiPtr->updatePending = 1;
+	Tcl_DoWhenIdle(TheWorldHasChanged, fiPtr);
     }
 }
 
 static void
 TheWorldHasChanged(
@@ -997,20 +1013,19 @@
 	 * to get redisplayed.
 	 */
 
 	nfPtr->fa = *faPtr;
 	nfPtr->deletePending = 0;
-	UpdateDependentFonts(fiPtr, tkwin, namedHashPtr);
-	return TCL_OK;
+    } else {
+	nfPtr = (NamedFont *)ckalloc(sizeof(NamedFont));
+	nfPtr->deletePending = 0;
+	Tcl_SetHashValue(namedHashPtr, nfPtr);
+	nfPtr->fa = *faPtr;
+	nfPtr->refCount = 0;
+	nfPtr->deletePending = 0;
     }
-
-    nfPtr = (NamedFont *)ckalloc(sizeof(NamedFont));
-    nfPtr->deletePending = 0;
-    Tcl_SetHashValue(namedHashPtr, nfPtr);
-    nfPtr->fa = *faPtr;
-    nfPtr->refCount = 0;
-    nfPtr->deletePending = 0;
+    UpdateDependentFonts(fiPtr, tkwin, namedHashPtr, isNew);
     return TCL_OK;
 }
 
 /*
  *---------------------------------------------------------------------------