Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Internationalization of all Windows font handling |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
e472bebc7a2185c4e2137304b3d3845c |
User & Date: | jan.nijtmans 2011-10-13 12:36:52 |
Context
2011-10-24
| ||
19:36 | Merge TIP 382 implementation to trunk. Still need Carbon migration & Cocoa. check-in: fe657dbc user: dgp tags: trunk | |
2011-10-13
| ||
12:36 | Internationalization of all Windows font handling check-in: e472bebc user: jan.nijtmans tags: trunk | |
2011-10-11
| ||
09:11 | code cleanup (WCHAR -> TCHAR, no direct calls to *W() functions, unnecessary type casts check-in: 43378935 user: jan.nijtmans tags: trunk | |
Changes
Changes to ChangeLog.
1 2 3 4 5 6 7 | 2011-10-10 Jan Nijtmans <[email protected]> * win/tkWinDialog.c: [BUG 3163893] -initialdir option bug for tk_chooseDirectory under XP 2011-10-05 Jan Nijtmans <[email protected]> | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 | 2011-10-13 Jan Nijtmans <[email protected]> * win/tkWinDialog.c: Internationalization of all Windows font * win/tkWinFont.c: handling. 2011-10-10 Jan Nijtmans <[email protected]> * win/tkWinDialog.c: [BUG 3163893] -initialdir option bug for tk_chooseDirectory under XP 2011-10-05 Jan Nijtmans <[email protected]> |
︙ | ︙ |
Changes to win/tkWinDialog.c.
︙ | ︙ | |||
1977 1978 1979 1980 1981 1982 1983 | * Result: * A list containing a Tk font description. * * ---------------------------------------------------------------------- */ static Tcl_Obj * | | > > | > | 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 | * Result: * A list containing a Tk font description. * * ---------------------------------------------------------------------- */ static Tcl_Obj * GetFontObj(HDC hdc, LOGFONT *plf) { Tcl_DString ds; Tcl_Obj *resObj; int pt = 0; resObj = Tcl_NewListObj(0, NULL); Tcl_ExternalToUtfDString(TkWinGetUnicodeEncoding(), (char *) plf->lfFaceName, -1, &ds); Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewStringObj(Tcl_DStringValue(&ds), -1)); Tcl_DStringFree(&ds); pt = -MulDiv(plf->lfHeight, 72, GetDeviceCaps(hdc, LOGPIXELSY)); Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewIntObj(pt)); if (plf->lfWeight >= 700) { Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewStringObj("bold", -1)); } if (plf->lfItalic) { Tcl_ListObjAppendElement(NULL, resObj, |
︙ | ︙ | |||
2006 2007 2008 2009 2010 2011 2012 | Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewStringObj("overstrike", -1)); } return resObj; } static void | | | 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 | Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewStringObj("overstrike", -1)); } return resObj; } static void ApplyLogfont(Tcl_Interp *interp, Tcl_Obj *cmdObj, HDC hdc, LOGFONT *logfontPtr) { int objc; Tcl_Obj **objv, **tmpv; Tcl_ListObjGetElements(NULL, cmdObj, &objc, &objv); tmpv = ckalloc(sizeof(Tcl_Obj *) * (objc + 2)); memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc); |
︙ | ︙ | |||
2094 2095 2096 2097 2098 2099 2100 | /* * Handle apply button by calling the provided command script as a * background evaluation (ie: errors dont come back here). */ if (WM_COMMAND == msg && LOWORD(wParam) == 1026) { | | | | 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 | /* * Handle apply button by calling the provided command script as a * background evaluation (ie: errors dont come back here). */ if (WM_COMMAND == msg && LOWORD(wParam) == 1026) { LOGFONT lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0}}; HDC hdc = GetDC(hwndDlg); SendMessage(hwndDlg, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM) &lf); if (phd && phd->cmdObj) { ApplyLogfont(phd->interp, phd->cmdObj, hdc, &lf); } if (phd && phd->parent) { TkSendVirtualEvent(phd->parent, "TkFontchooserFontChanged"); } return 1; |
︙ | ︙ | |||
2327 2328 2329 2330 2331 2332 2333 2334 | static int FontchooserShowCmd( ClientData clientData, /* Main window */ Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Tk_Window tkwin = clientData, parent; | > | | | | | > | > | 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 | static int FontchooserShowCmd( ClientData clientData, /* Main window */ Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Tcl_DString ds; Tk_Window tkwin = clientData, parent; CHOOSEFONT cf; LOGFONT lf; HDC hdc; HookData *hdPtr; int r = TCL_OK, oldMode = 0; hdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser", NULL); parent = tkwin; if (hdPtr->parentObj) { parent = Tk_NameToWindow(interp, Tcl_GetString(hdPtr->parentObj), tkwin); if (parent == None) { return TCL_ERROR; } } Tk_MakeWindowExist(parent); ZeroMemory(&cf, sizeof(CHOOSEFONT)); ZeroMemory(&lf, sizeof(LOGFONT)); lf.lfCharSet = DEFAULT_CHARSET; cf.lStructSize = sizeof(CHOOSEFONT); cf.hwndOwner = Tk_GetHWND(Tk_WindowId(parent)); cf.lpLogFont = &lf; cf.nFontType = SCREEN_FONTTYPE; cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_ENABLEHOOK; cf.rgbColors = RGB(0,0,0); cf.lpfnHook = HookProc; cf.lCustData = (INT_PTR) hdPtr; hdPtr->interp = interp; hdPtr->parent = parent; hdc = GetDC(cf.hwndOwner); if (hdPtr->fontObj != NULL) { TkFont *fontPtr; Tk_Font f = Tk_AllocFontFromObj(interp, tkwin, hdPtr->fontObj); if (f == NULL) { return TCL_ERROR; } fontPtr = (TkFont *) f; cf.Flags |= CF_INITTOLOGFONTSTRUCT; Tcl_UtfToExternalDString(TkWinGetUnicodeEncoding(), fontPtr->fa.family, -1, &ds); _tcsncpy(lf.lfFaceName, (TCHAR *)Tcl_DStringValue(&ds), LF_FACESIZE-1); Tcl_DStringFree(&ds); lf.lfFaceName[LF_FACESIZE-1] = 0; lf.lfHeight = -MulDiv(TkFontGetPoints(tkwin, fontPtr->fa.size), GetDeviceCaps(hdc, LOGPIXELSY), 72); if (fontPtr->fa.weight == TK_FW_BOLD) { lf.lfWeight = FW_BOLD; } if (fontPtr->fa.slant != TK_FS_ROMAN) { |
︙ | ︙ | |||
2401 2402 2403 2404 2405 2406 2407 | if (len > 0) { cf.Flags |= CF_APPLY; } } if (TCL_OK == r) { oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); | | | 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 | if (len > 0) { cf.Flags |= CF_APPLY; } } if (TCL_OK == r) { oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); if (ChooseFont(&cf)) { if (hdPtr->cmdObj) { ApplyLogfont(hdPtr->interp, hdPtr->cmdObj, hdc, &lf); } if (hdPtr->parent) { TkSendVirtualEvent(hdPtr->parent, "TkFontchooserFontChanged"); } } |
︙ | ︙ |
Changes to win/tkWinFont.c.
︙ | ︙ | |||
209 210 211 212 213 214 215 | double angle); static void InitFont(Tk_Window tkwin, HFONT hFont, int overstrike, WinFont *tkFontPtr); static inline void InitSubFont(HDC hdc, HFONT hFont, int base, SubFont *subFontPtr); static int CreateNamedSystemLogFont(Tcl_Interp *interp, Tk_Window tkwin, const char* name, | | | | | | | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | double angle); static void InitFont(Tk_Window tkwin, HFONT hFont, int overstrike, WinFont *tkFontPtr); static inline void InitSubFont(HDC hdc, HFONT hFont, int base, SubFont *subFontPtr); static int CreateNamedSystemLogFont(Tcl_Interp *interp, Tk_Window tkwin, const char* name, LOGFONT* logFontPtr); static int CreateNamedSystemFont(Tcl_Interp *interp, Tk_Window tkwin, const char* name, HFONT hFont); static int LoadFontRanges(HDC hdc, HFONT hFont, USHORT **startCount, USHORT **endCount, int *symbolPtr); static void MultiFontTextOut(HDC hdc, WinFont *fontPtr, const char *source, int numBytes, int x, int y, double angle); static void ReleaseFont(WinFont *fontPtr); static inline void ReleaseSubFont(SubFont *subFontPtr); static int SeenName(const char *name, Tcl_DString *dsPtr); static inline HFONT SelectFont(HDC hdc, WinFont *fontPtr, SubFont *subFontPtr, double angle); static inline void SwapLong(PULONG p); static inline void SwapShort(USHORT *p); static int CALLBACK WinFontCanUseProc(ENUMLOGFONT *lfPtr, NEWTEXTMETRIC *tmPtr, int fontType, LPARAM lParam); static int CALLBACK WinFontExistProc(ENUMLOGFONT *lfPtr, NEWTEXTMETRIC *tmPtr, int fontType, LPARAM lParam); static int CALLBACK WinFontFamilyEnumProc(ENUMLOGFONT *lfPtr, NEWTEXTMETRIC *tmPtr, int fontType, LPARAM lParam); /* *------------------------------------------------------------------------- * * TkpFontPkgInit -- * |
︙ | ︙ | |||
336 337 338 339 340 341 342 | */ static int CreateNamedSystemLogFont( Tcl_Interp *interp, Tk_Window tkwin, const char* name, | | | | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | */ static int CreateNamedSystemLogFont( Tcl_Interp *interp, Tk_Window tkwin, const char* name, LOGFONT* logFontPtr) { HFONT hFont; int r; hFont = CreateFontIndirect(logFontPtr); r = CreateNamedSystemFont(interp, tkwin, name, hFont); DeleteObject((HGDIOBJ)hFont); return r; } /* *--------------------------------------------------------------------------- |
︙ | ︙ | |||
397 398 399 400 401 402 403 | void TkWinSetupSystemFonts( TkMainInfo *mainPtr) { Tcl_Interp *interp; Tk_Window tkwin; const TkStateMap *mapPtr; | | | | | | | | 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | void TkWinSetupSystemFonts( TkMainInfo *mainPtr) { Tcl_Interp *interp; Tk_Window tkwin; const TkStateMap *mapPtr; NONCLIENTMETRICS ncMetrics; ICONMETRICS iconMetrics; HFONT hFont; interp = (Tcl_Interp *) mainPtr->interp; tkwin = (Tk_Window) mainPtr->winPtr; /* force this for now */ if (((TkWindow *) tkwin)->mainPtr == NULL) { ((TkWindow *) tkwin)->mainPtr = mainPtr; } /* * If this API call fails then we will fallback to setting these named * fonts from script in ttk/fonts.tcl. So far I've only seen it fail when * WINVER has been defined for a higher platform than we are running on. * (i.e. WINVER=0x0600 and running on XP). */ ZeroMemory(&ncMetrics, sizeof(ncMetrics)); ncMetrics.cbSize = sizeof(ncMetrics); if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncMetrics), &ncMetrics, 0)) { CreateNamedSystemLogFont(interp, tkwin, "TkDefaultFont", &ncMetrics.lfMessageFont); CreateNamedSystemLogFont(interp, tkwin, "TkHeadingFont", &ncMetrics.lfMessageFont); CreateNamedSystemLogFont(interp, tkwin, "TkTextFont", &ncMetrics.lfMessageFont); CreateNamedSystemLogFont(interp, tkwin, "TkMenuFont", &ncMetrics.lfMenuFont); CreateNamedSystemLogFont(interp, tkwin, "TkTooltipFont", &ncMetrics.lfStatusFont); CreateNamedSystemLogFont(interp, tkwin, "TkCaptionFont", &ncMetrics.lfCaptionFont); CreateNamedSystemLogFont(interp, tkwin, "TkSmallCaptionFont", &ncMetrics.lfSmCaptionFont); } iconMetrics.cbSize = sizeof(iconMetrics); if (SystemParametersInfo(SPI_GETICONMETRICS, sizeof(iconMetrics), &iconMetrics, 0)) { CreateNamedSystemLogFont(interp, tkwin, "TkIconFont", &iconMetrics.lfFont); } /* * Identify an available fixed font. Equivalent to ANSI_FIXED_FONT but * more reliable on Russian Windows. */ { LOGFONT lfFixed = { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, TEXT("") }; long pointSize, dpi; HDC hdc = GetDC(NULL); dpi = GetDeviceCaps(hdc, LOGPIXELSY); pointSize = -MulDiv(ncMetrics.lfMessageFont.lfHeight, 72, dpi); lfFixed.lfHeight = -MulDiv(pointSize+1, dpi, 72); ReleaseDC(NULL, hdc); |
︙ | ︙ | |||
664 665 666 667 668 669 670 | (LPARAM) resultObj); ReleaseDC(hwnd, hdc); Tcl_SetObjResult(interp, resultObj); } static int CALLBACK WinFontFamilyEnumProc( | | | | | 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 | (LPARAM) resultObj); ReleaseDC(hwnd, hdc); Tcl_SetObjResult(interp, resultObj); } static int CALLBACK WinFontFamilyEnumProc( ENUMLOGFONT *lfPtr, /* Logical-font data. */ NEWTEXTMETRIC *tmPtr, /* Physical-font data (not used). */ int fontType, /* Type of font (not used). */ LPARAM lParam) /* Result object to hold result. */ { char *faceName = (char *) lfPtr->elfLogFont.lfFaceName; Tcl_Obj *resultObj = (Tcl_Obj *) lParam; Tcl_DString faceString; Tcl_ExternalToUtfDString(systemEncoding, faceName, -1, &faceString); Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( Tcl_DStringValue(&faceString), Tcl_DStringLength(&faceString))); Tcl_DStringFree(&faceString); |
︙ | ︙ | |||
2044 2045 2046 2047 2048 2049 2050 | } ReleaseDC(fontPtr->hwnd, hdc); return subFontPtr; } static int CALLBACK WinFontCanUseProc( | | | | | 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 | } ReleaseDC(fontPtr->hwnd, hdc); return subFontPtr; } static int CALLBACK WinFontCanUseProc( ENUMLOGFONT *lfPtr, /* Logical-font data. */ NEWTEXTMETRIC *tmPtr, /* Physical-font data (not used). */ int fontType, /* Type of font (not used). */ LPARAM lParam) /* Result object to hold result. */ { int ch; HDC hdc; WinFont *fontPtr; CanUse *canUsePtr; char *fallbackName; SubFont *subFontPtr; Tcl_DString faceString; Tcl_DString *nameTriedPtr; canUsePtr = (CanUse *) lParam; ch = canUsePtr->ch; hdc = canUsePtr->hdc; fontPtr = canUsePtr->fontPtr; nameTriedPtr = canUsePtr->nameTriedPtr; fallbackName = (char *) lfPtr->elfLogFont.lfFaceName; Tcl_ExternalToUtfDString(systemEncoding, fallbackName, -1, &faceString); fallbackName = Tcl_DStringValue(&faceString); if (SeenName(fallbackName, nameTriedPtr) == 0) { subFontPtr = CanUseFallback(hdc, fontPtr, fallbackName, ch, canUsePtr->subFontPtrPtr); if (subFontPtr != NULL) { |
︙ | ︙ | |||
2488 2489 2490 2491 2492 2493 2494 | lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_TT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; Tcl_UtfToExternalDString(systemEncoding, faceName, -1, &ds); | | < < < < < < < < | < < | < < < < | < < < < < < < < < < < < | 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 | lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_TT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; Tcl_UtfToExternalDString(systemEncoding, faceName, -1, &ds); _tcsncpy(lf.lfFaceName, (TCHAR *)Tcl_DStringValue(&ds), LF_FACESIZE-1); Tcl_DStringFree(&ds); lf.lfFaceName[LF_FACESIZE-1] = 0; hFont = CreateFontIndirect(&lf); return hFont; } /* *------------------------------------------------------------------------- * * FamilyExists, FamilyOrAliasExists, WinFontExistsProc -- |
︙ | ︙ | |||
2603 2604 2605 2606 2607 2608 2609 | } } return NULL; } static int CALLBACK WinFontExistProc( | | | | 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 | } } return NULL; } static int CALLBACK WinFontExistProc( ENUMLOGFONT *lfPtr, /* Logical-font data. */ NEWTEXTMETRIC *tmPtr, /* Physical-font data (not used). */ int fontType, /* Type of font (not used). */ LPARAM lParam) /* EnumFontData to hold result. */ { return 0; } /* |
︙ | ︙ |