static HFONT createFontIndirectAndGetWinName(const String& family, LOGFONT* winfont, String* winName) { int len = min(static_cast<int>(family.length()), LF_FACESIZE - 1); memcpy(winfont->lfFaceName, family.characters(), len * sizeof(WORD)); winfont->lfFaceName[len] = '\0'; HFONT hfont = CreateFontIndirect(winfont); if (!hfont) return 0; HDC dc = GetDC(0); HGDIOBJ oldFont = static_cast<HFONT>(SelectObject(dc, hfont)); WCHAR name[LF_FACESIZE]; unsigned resultLength = GetTextFace(dc, LF_FACESIZE, name); if (resultLength > 0) resultLength--; // ignore the null terminator SelectObject(dc, oldFont); ReleaseDC(0, dc); *winName = String(name, resultLength); return hfont; }
static void CreateStaticFont(HDC dc, HFONT* hyperlink_font) { TEXTMETRIC tm; LOGFONT lf; if (*hyperlink_font != NULL) return; GetTextMetrics(dc, &tm); lf.lfHeight = tm.tmHeight; lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; lf.lfWeight = tm.tmWeight; lf.lfItalic = tm.tmItalic; lf.lfUnderline = TRUE; lf.lfStrikeOut = tm.tmStruckOut; lf.lfCharSet = tm.tmCharSet; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = tm.tmPitchAndFamily; GetTextFace(dc, LF_FACESIZE, lf.lfFaceName); *hyperlink_font = CreateFontIndirect(&lf); }
const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) { String familyName; WCHAR name[LF_FACESIZE]; UChar character = characters[0]; const FontPlatformData& origFont = font.primaryFont()->fontDataForCharacter(character)->platformData(); unsigned unicodeRange = findCharUnicodeRange(character); #if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) if (IMLangFontLink2* langFontLink = getFontLinkInterface()) { #else if (IMLangFontLink* langFontLink = getFontLinkInterface()) { #endif HGDIOBJ oldFont = GetCurrentObject(g_screenDC, OBJ_FONT); HFONT hfont = 0; DWORD codePages = 0; UINT codePage = 0; // Try MLang font linking first. langFontLink->GetCharCodePages(character, &codePages); if (codePages && unicodeRange == cRangeSetCJK) { // The CJK character may belong to multiple code pages. We want to // do font linking against a single one of them, preferring the default // code page for the user's locale. const Vector<DWORD, 4>& CJKCodePageMasks = getCJKCodePageMasks(); unsigned numCodePages = CJKCodePageMasks.size(); for (unsigned i = 0; i < numCodePages; ++i) { #if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) hfont = createMLangFont(langFontLink, g_screenDC, CJKCodePageMasks[i]); #else hfont = createMLangFont(langFontLink, g_screenDC, origFont, CJKCodePageMasks[i]); #endif if (!hfont) continue; SelectObject(g_screenDC, hfont); GetTextFace(g_screenDC, LF_FACESIZE, name); if (hfont && !(codePages & CJKCodePageMasks[i])) { // We asked about a code page that is not one of the code pages // returned by MLang, so the font might not contain the character. #if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) if (!currentFontContainsCharacter(langFontLink, g_screenDC, character)) { #else if (!currentFontContainsCharacter(langFontLink, g_screenDC, hfont, character, name)) { #endif SelectObject(g_screenDC, oldFont); langFontLink->ReleaseFont(hfont); hfont = 0; continue; } } break; } } else { #if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2) hfont = createMLangFont(langFontLink, g_screenDC, codePages, character); #else hfont = createMLangFont(langFontLink, g_screenDC, origFont, codePages); #endif SelectObject(g_screenDC, hfont); GetTextFace(g_screenDC, LF_FACESIZE, name); } SelectObject(g_screenDC, oldFont); if (hfont) { familyName = name; langFontLink->ReleaseFont(hfont); } else FontPlatformData::mapKnownFont(codePages, familyName); } if (familyName.isEmpty()) familyName = FontPlatformData::defaultFontFamily(); if (!familyName.isEmpty()) { // FIXME: temporary workaround for Thai font problem FontDescription fontDescription(font.fontDescription()); if (unicodeRange == cRangeThai && fontDescription.weight() > FontWeightNormal) fontDescription.setWeight(FontWeightNormal); FontPlatformData* result = getCachedFontPlatformData(fontDescription, familyName); if (result && result->hash() != origFont.hash()) { if (SimpleFontData* fontData = getCachedFontData(result, DoNotRetain)) return fontData; } } return 0; }
static int win_choose_font (ClientData cd, Tcl_Interp *interp, int argc, char **argv) { char *deffont; Tk_Window parent; int i, oldMode; CHOOSEFONT cf; LOGFONT lf; HDC hdc; HFONT hfont; char facebuf[LF_FACESIZE]; TEXTMETRIC tm; int pointsize; char *s; Tcl_DString resultStr; /* used to translate result in UTF8 in Tcl/Tk8.1 */ deffont = NULL; parent = Tk_MainWindow (interp); for (i = 1; i < argc; i += 2) { if (i + 1 >= argc) { Tcl_ResetResult (interp); Tcl_AppendStringsToObj (Tcl_GetObjResult (interp), "value for \"", argv[i], "\" missing", (char *) NULL); return TCL_ERROR; } if (strcmp (argv[i], "-default") == 0) deffont = argv[i + 1]; else if (strcmp (argv[i], "-parent") == 0) { parent = Tk_NameToWindow (interp, argv[i + 1], Tk_MainWindow (interp)); if (parent == NULL) return TCL_ERROR; } else { Tcl_ResetResult (interp); Tcl_AppendStringsToObj (Tcl_GetObjResult (interp), "unknown option \"", argv[i], "\"", (char *) NULL); return TCL_ERROR; } } memset (&cf, 0, sizeof (CHOOSEFONT)); cf.lStructSize = sizeof (CHOOSEFONT); if (Tk_WindowId (parent) == None) Tk_MakeWindowExist (parent); cf.hwndOwner = Tk_GetHWND (Tk_WindowId (parent)); cf.lpLogFont = &lf; cf.Flags = CF_SCREENFONTS | CF_FORCEFONTEXIST; memset (&lf, 0, sizeof (LOGFONT)); if (deffont != NULL) { Tk_Font tkfont; const TkFontAttributes *fa; tkfont = Tk_GetFont (interp, parent, deffont); if (tkfont == NULL) return TCL_ERROR; cf.Flags |= CF_INITTOLOGFONTSTRUCT; /* In order to initialize LOGFONT, we need to extract the real font attributes from the Tk internal font information. */ fa = &((TkFont *) tkfont)->fa; /* This code is taken from TkpGetFontFromAttributes. It converts a TkFontAttributes structure into a LOGFONT structure. */ #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) lf.lfHeight = - fa->size; #else lf.lfHeight = - fa->pointsize; #endif if (lf.lfHeight < 0) lf.lfHeight = MulDiv (lf.lfHeight, 254 * WidthOfScreen (Tk_Screen (parent)), 720 * WidthMMOfScreen (Tk_Screen (parent))); lf.lfWeight = fa->weight == TK_FW_NORMAL ? FW_NORMAL : FW_BOLD; lf.lfItalic = fa->slant; lf.lfUnderline = fa->underline; lf.lfStrikeOut = fa->overstrike; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; if (fa->family == NULL) lf.lfFaceName[0] = '\0'; else strncpy (lf.lfFaceName, fa->family, sizeof (lf.lfFaceName)); Tk_FreeFont (tkfont); } oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); if (! ChooseFont (&cf)) { DWORD code; code = CommDlgExtendedError (); if (code == 0) { /* The user pressed cancel. */ Tcl_ResetResult (interp); return TCL_OK; } else { char buf[200]; sprintf (buf, "Windows common dialog error 0x%lx", (unsigned long) code); Tcl_ResetResult (interp); #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, buf, -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr, buf, -1); #endif Tcl_AppendStringsToObj (Tcl_GetObjResult (interp), Tcl_DStringValue(&resultStr), (char *) NULL); Tcl_DStringFree(&resultStr); return TCL_ERROR; } } Tcl_SetServiceMode(oldMode); /* We now have a LOGFONT structure. We store it into a device context, and then extract enough information to build a Tk font specification. With luck, when Tk interprets the font specification it will wind up with the font that the user expects to see. Some of this code is taken from AllocFont. */ hfont = CreateFontIndirect (&lf); if (hfont == NULL) { /* This should be impossible. */ #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, "CreateFontIndirect failed on chosen font", -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr, "CreateFontIndirect failed on chosen font", -1); #endif Tcl_SetResult (interp, Tcl_DStringValue(&resultStr), TCL_STATIC); Tcl_DStringFree(&resultStr); return TCL_ERROR; } hdc = GetDC (cf.hwndOwner); hfont = SelectObject (hdc, hfont); GetTextFace (hdc, sizeof (facebuf), facebuf); GetTextMetrics (hdc, &tm); Tcl_ResetResult (interp); #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, facebuf, -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr,facebuf,-1); #endif if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) { Tcl_DStringFree(&resultStr); return TCL_ERROR; } Tcl_DStringFree(&resultStr); pointsize = MulDiv (tm.tmHeight - tm.tmInternalLeading, 720 * WidthMMOfScreen (Tk_Screen (parent)), 254 * WidthOfScreen (Tk_Screen (parent))); if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewIntObj (pointsize)) != TCL_OK) { return TCL_ERROR; } if (tm.tmWeight > FW_MEDIUM) s = "bold"; else s = "normal"; #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, s, -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr, s, -1); #endif if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) { Tcl_DStringFree(&resultStr); return TCL_ERROR; } Tcl_DStringFree(&resultStr); if (tm.tmItalic) s = "italic"; else s = "roman"; #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, s, -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr, s, -1); #endif if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) { Tcl_DStringFree(&resultStr); return TCL_ERROR; } Tcl_DStringFree(&resultStr); if (tm.tmUnderlined) { #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, "underline", -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr,"underline",-1); #endif if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) { Tcl_DStringFree(&resultStr); return TCL_ERROR; } Tcl_DStringFree(&resultStr); } if (tm.tmStruckOut) { #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, "overstrike", -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr, "overstrike", -1); #endif if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) { Tcl_DStringFree(&resultStr); return TCL_ERROR; } Tcl_DStringFree(&resultStr); } hfont = SelectObject (hdc, hfont); ReleaseDC (cf.hwndOwner, hdc); DeleteObject (hfont); return TCL_OK; }
PassRefPtr<SimpleFontData> FontCache::systemFallbackForCharacters(const FontDescription& description, const SimpleFontData* originalFontData, bool, const UChar* characters, int length) { String familyName; WCHAR name[LF_FACESIZE]; UChar character = characters[0]; const FontPlatformData& origFont = originalFontData->platformData(); if (IMLangFontLinkType* langFontLink = getFontLinkInterface()) { HGDIOBJ oldFont = GetCurrentObject(g_screenDC, OBJ_FONT); HFONT hfont = 0; DWORD codePages = 0; UINT codePage = 0; // Try MLang font linking first. langFontLink->GetCharCodePages(character, &codePages); if (codePages && u_getIntPropertyValue(character, UCHAR_UNIFIED_IDEOGRAPH)) { // The CJK character may belong to multiple code pages. We want to // do font linking against a single one of them, preferring the default // code page for the user's locale. const Vector<DWORD, 4>& CJKCodePageMasks = getCJKCodePageMasks(); unsigned numCodePages = CJKCodePageMasks.size(); for (unsigned i = 0; i < numCodePages; ++i) { hfont = createMLangFont(langFontLink, g_screenDC, origFont, CJKCodePageMasks[i]); if (!hfont) continue; SelectObject(g_screenDC, hfont); GetTextFace(g_screenDC, LF_FACESIZE, name); if (hfont && !(codePages & CJKCodePageMasks[i])) { // We asked about a code page that is not one of the code pages // returned by MLang, so the font might not contain the character. if (!currentFontContainsCharacter(langFontLink, g_screenDC, hfont, character, name)) { SelectObject(g_screenDC, oldFont); langFontLink->ReleaseFont(hfont); hfont = 0; continue; } } break; } } else { hfont = createMLangFont(langFontLink, g_screenDC, origFont, codePages, character); SelectObject(g_screenDC, hfont); GetTextFace(g_screenDC, LF_FACESIZE, name); } SelectObject(g_screenDC, oldFont); if (hfont) { familyName = name; langFontLink->ReleaseFont(hfont); } else FontPlatformData::mapKnownFont(codePages, familyName); } if (familyName.isEmpty()) familyName = FontPlatformData::defaultFontFamily(); if (!familyName.isEmpty()) { // FIXME: temporary workaround for Thai font problem FontDescription fontDescription(description); if (ublock_getCode(c) == UBLOCK_THAI && fontDescription.weight() > FontWeightNormal) fontDescription.setWeight(FontWeightNormal); FontPlatformData* result = getCachedFontPlatformData(fontDescription, familyName); if (result && result->hash() != origFont.hash()) { if (RefPtr<SimpleFontData> fontData = getCachedFontData(result, DoNotRetain)) return fontData.release(); } } return 0; }
BOOL PrintWindowDriver( HINSTANCE hInst, HWND hwnd, LPSTR szTitleName) { BOOL bSuccess, deleteFont = FALSE; LPCTSTR pstrBuffer ; int yChar, iLinesPerPage, iTotalLines = 0; long iCharsPerLine; int displayStart = 0; int iTotalPages; TEXTMETRIC tm ; HFONT hfont, ofont; HDC dc; LOGFONT lf; HWND hwndEdit; struct statusWindowData *theStatusData; struct displayWindowData *theDisplayData; /*===========================*/ /* Display the print dialog. */ /*===========================*/ if (! PrintDlg(&PrintDialog)) { return TRUE ; } /*===========================================*/ /* If there is nothing to print then return. */ /*===========================================*/ if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == EditAtomClass) { hwndEdit = GetDlgItem(hwnd,ID_EDIT_CONTROL); iTotalLines = (short) SendMessage(hwndEdit,EM_GETLINECOUNT,0,0L); ofont = GetWindowFont(hwndEdit); } else if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == StatusAtomClass) { theStatusData = (struct statusWindowData *) GetWindowLongPtr(hwnd,GWLP_USERDATA); if (theStatusData == NULL) { return TRUE; } iTotalLines = (*theStatusData->getCount)(GetCurrentEnvironment()); memset(&lf,0,sizeof(LOGFONT)); lf.lfHeight = -13; strcpy(lf.lfFaceName,"Courier New"); ofont = CreateFontIndirect(&lf); deleteFont = TRUE; } else if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == DisplayAtomClass) { theDisplayData = (struct displayWindowData *) GetWindowLongPtr(hwnd,GWLP_USERDATA); if (theDisplayData == NULL) { return TRUE; } DisplayLineCountAndStart(hwnd,&iTotalLines,&displayStart); memset(&lf,0,sizeof(LOGFONT)); lf.lfHeight = -13; strcpy(lf.lfFaceName,"Courier New"); ofont = CreateFontIndirect(&lf); deleteFont = TRUE; } else { iTotalLines = 0; } if (iTotalLines == 0) { return TRUE; } /*=================================================*/ /* Create a logical font for use with the printer. */ /*=================================================*/ memset(&lf,0,sizeof(LOGFONT)); dc = GetDC(hwnd); SelectObject(dc,ofont); GetTextFace(dc,LF_FACESIZE,lf.lfFaceName); GetTextMetrics(dc,&tm); lf.lfHeight = tm.tmHeight * (GetDeviceCaps(PrintDialog.hDC,LOGPIXELSY) / GetDeviceCaps(dc,LOGPIXELSY)); lf.lfPitchAndFamily = tm.tmPitchAndFamily; hfont = CreateFontIndirect(&lf); if (hfont != NULL) { SelectObject(PrintDialog.hDC,hfont); } ReleaseDC(hwnd,dc); if (deleteFont) { DeleteFont(ofont); } GetTextMetrics(PrintDialog.hDC,&tm); yChar = tm.tmHeight + tm.tmExternalLeading; iCharsPerLine = GetDeviceCaps(PrintDialog.hDC,HORZRES) / tm.tmAveCharWidth; iLinesPerPage = GetDeviceCaps(PrintDialog.hDC,VERTRES) / yChar; iTotalPages = (iTotalLines + iLinesPerPage - 1) / iLinesPerPage; pstrBuffer = (LPCTSTR) HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, (unsigned long) iCharsPerLine + 1); /*=============================================*/ /* Disable the parent window of the dialog so */ /* all messages go to the cancel print dialog. */ /*=============================================*/ EnableWindow(hwnd,FALSE); /*=============================*/ /* Set the success/abort flags */ /* to their initial value. */ /*=============================*/ bUserAbort = FALSE; /*=================================*/ /* Create the cancel print dialog. */ /*=================================*/ hDlgPrint = CreateDialog(hInst,(LPCTSTR) "PrintDlgBox",hwnd,PrintDlgProc); SetDlgItemText(hDlgPrint,IDD_FNAME,szTitleName); /*=========================================*/ /* Set the abort procedure which handles */ /* dispatching of messages while printing. */ /*=========================================*/ SetAbortProc(PrintDialog.hDC,AbortProc); GetWindowText(hwnd,(PTSTR) di.lpszDocName,sizeof (PTSTR)); if (StartDoc (PrintDialog.hDC, &di) > 0) { bSuccess = PrintIt(iTotalPages,iLinesPerPage,iTotalLines,iCharsPerLine, yChar,pstrBuffer,hwnd); } else { bSuccess = FALSE; } if (bSuccess) { EndDoc(PrintDialog.hDC); } if (! bUserAbort) { EnableWindow(hwnd,TRUE); DestroyWindow (hDlgPrint) ; } HeapFree(GetProcessHeap(),0,(LPVOID) pstrBuffer); DeleteDC(PrintDialog.hDC); if (hfont != NULL) { DeleteFont(hfont); } return (bSuccess && (! bUserAbort)); }
Bool window_subsystem_init( char * error_buf) { WNDCLASSW wc; HDC dc; HBITMAP hbm; OSVERSIONINFO os = { sizeof( OSVERSIONINFO)}; guts. version = GetVersion(); GetVersionEx( &os); guts. alloc_utf8_to_wchar_visual = (( os.dwMajorVersion > 5) || (os.dwMajorVersion == 5 && os.dwMinorVersion > 1)) ? alloc_utf8_to_wchar_visual : alloc_utf8_to_wchar; guts. mainThreadId = GetCurrentThreadId(); guts. errorMode = SetErrorMode( SEM_FAILCRITICALERRORS); guts. desktopWindow = GetDesktopWindow(); memset( &wc, 0, sizeof( wc)); wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wc.lpfnWndProc = ( WNDPROC) generic_app_handler; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = guts. instance; wc.hIcon = LoadIcon( guts. instance, IDI_APPLICATION); wc.hCursor = LoadCursor( NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)NULL; wc.lpszClassName = L"GenericApp"; RegisterClassW( &wc); memset( &wc, 0, sizeof( wc)); wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wc.lpfnWndProc = ( WNDPROC) generic_frame_handler; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = guts. instance; wc.hIcon = LoadIcon( guts. instance, IDI_APPLICATION); wc.hCursor = LoadCursor( NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)NULL; wc.lpszClassName = L"GenericFrame"; RegisterClassW( &wc); memset( &wc, 0, sizeof( wc)); wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wc.lpfnWndProc = ( WNDPROC) generic_view_handler; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = guts. instance; wc.hIcon = LoadIcon( guts. instance, IDI_APPLICATION); wc.hCursor = NULL; // LoadCursor( NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)NULL; wc.lpszClassName = L"Generic"; RegisterClassW( &wc); stylusMan = hash_create(); fontMan = hash_create(); patMan = hash_create(); menuMan = hash_create(); imageMan = hash_create(); regnodeMan = hash_create(); create_font_hash(); { LOGBRUSH b = { BS_HOLLOW, 0, 0}; Font f; hPenHollow = CreatePen( PS_NULL, 0, 0); hBrushHollow = CreateBrushIndirect( &b); hPatHollow. dotsCount = 0; hPatHollow. dotsPtr = nil; FONTSTRUCSIZE = (char *)(&(f. name)) - (char *)(&f); } if (!( dc = dc_alloc())) return false; guts. displayResolution. x = GetDeviceCaps( dc, LOGPIXELSX); guts. displayResolution. y = GetDeviceCaps( dc, LOGPIXELSY); { LOGFONT lf; HFONT sfont; // getting most common font name memset( &lf, 0, sizeof( lf)); lf. lfCharSet = OEM_CHARSET; lf. lfOutPrecision = OUT_DEFAULT_PRECIS; lf. lfClipPrecision = CLIP_DEFAULT_PRECIS; lf. lfQuality = PROOF_QUALITY; lf. lfPitchAndFamily = DEFAULT_PITCH; sfont = SelectObject( dc, CreateFontIndirect( &lf)); GetTextFace( dc, 256, guts. defaultSystemFont); // getting common fixed font name lf. lfHeight = 320; lf. lfPitchAndFamily = FIXED_PITCH; DeleteObject( SelectObject( dc, CreateFontIndirect( &lf))); GetTextFace( dc, 256, guts. defaultFixedFont); // getting common variable font name lf. lfPitchAndFamily = VARIABLE_PITCH; DeleteObject( SelectObject( dc, CreateFontIndirect( &lf))); GetTextFace( dc, 256, guts. defaultVariableFont); DeleteObject( SelectObject( dc, sfont)); // getting system font presets memset( &guts. windowFont, 0, sizeof( Font)); strcpy( guts. windowFont. name, DEFAULT_WIDGET_FONT); guts. windowFont. size = DEFAULT_WIDGET_FONT_SIZE; guts. windowFont. width = guts. windowFont. height = C_NUMERIC_UNDEF; #ifdef FONT_CHECK guts. windowFont. size = 12; #endif apc_font_pick( nilHandle, &guts. windowFont, &guts. windowFont); guts. ncmData. cbSize = sizeof( NONCLIENTMETRICS); SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof( NONCLIENTMETRICS), ( PVOID) &guts. ncmData, 0); font_logfont2font( &guts. ncmData. lfMenuFont, &guts. menuFont, &guts. displayResolution); font_logfont2font( &guts. ncmData. lfMessageFont, &guts. msgFont, &guts. displayResolution); font_logfont2font( &guts. ncmData. lfCaptionFont, &guts. capFont, &guts. displayResolution); } memset( &guts. displayBMInfo, 0, sizeof( guts. displayBMInfo)); guts. displayBMInfo. bmiHeader. biSize = sizeof( BITMAPINFO); if ( !( hbm = GetCurrentObject( dc, OBJ_BITMAP))) { apiErr; dc_free(); return false; } if ( !GetDIBits( dc, hbm, 0, 0, NULL, &guts. displayBMInfo, DIB_PAL_COLORS)) { guts. displayBMInfo. bmiHeader. biBitCount = GetDeviceCaps( dc, BITSPIXEL); guts. displayBMInfo. bmiHeader. biPlanes = GetDeviceCaps( dc, PLANES); } dc_free(); guts. insertMode = true; guts. iconSizeSmall. x = GetSystemMetrics( SM_CXSMICON); guts. iconSizeSmall. y = GetSystemMetrics( SM_CYSMICON); guts. iconSizeLarge. x = GetSystemMetrics( SM_CXICON); guts. iconSizeLarge. y = GetSystemMetrics( SM_CYICON); guts. pointerSize. x = GetSystemMetrics( SM_CXCURSOR); guts. pointerSize. y = GetSystemMetrics( SM_CYCURSOR); list_create( &guts. transp, 8, 8); list_create( &guts. files, 8, 8); list_create( &guts. sockets, 8, 8); // selecting locale layout, more or less latin-like { char buf[ KL_NAMELENGTH * 2] = ""; HKL current = GetKeyboardLayout( 0); int i, j, size = GetKeyboardLayoutList( 0, nil); HKL * kl = ( HKL *) malloc( sizeof( HKL) * size); guts. keyLayout = nil; if ( !GetKeyboardLayoutName( buf)) apiErr; for ( j = 0; j < ( sizeof( keyLayouts) / sizeof( char*)); j++) { if ( strncmp( buf + 4, keyLayouts[ j], 4) == 0) { guts. keyLayout = current; goto found_1; } } if ( kl) { GetKeyboardLayoutList( size, kl); for ( i = 0; i < size; i++) { ActivateKeyboardLayout( kl[ i], 0); if ( !GetKeyboardLayoutName( buf)) apiErr; for ( j = 0; j < ( sizeof( keyLayouts) / sizeof( char*)); j++) { if ( strncmp( buf + 4, keyLayouts[ j], 4) == 0) { guts. keyLayout = kl[ i]; goto found_2; } } } found_2:; ActivateKeyboardLayout( current, 0); } found_1:; free( kl); } guts. currentKeyState = guts. keyState; memset( guts. emptyKeyState, 0, sizeof( guts. emptyKeyState)); guts. smDblClk. x = GetSystemMetrics( SM_CXDOUBLECLK); guts. smDblClk. y = GetSystemMetrics( SM_CYDOUBLECLK); return true; }
void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID, LPCTSTR propName, float invScale) { HGDIOBJ font = GetStockObject(fontID); if (font != NULL && SelectObject(dc, font) != NULL) { int length = GetTextFace(dc, 0, NULL); if (length > 0) { LPTSTR face = new TCHAR[length]; if (GetTextFace(dc, length, face) > 0) { TEXTMETRIC metrics; if (GetTextMetrics(dc, &metrics) > 0) { jstring fontName = NULL; if (!wcscmp(face, L"MS Shell Dlg")) { // MS Shell Dlg is an indirect font name, find the // real face name from the registry. LPTSTR shellDialogFace = resolveShellDialogFont(); if (shellDialogFace != NULL) { fontName = JNU_NewStringPlatform(GetEnv(), shellDialogFace); free(shellDialogFace); } else { // Couldn't determine mapping for MS Shell Dlg, // fall back to Microsoft Sans Serif fontName = JNU_NewStringPlatform(GetEnv(), L"Microsoft Sans Serif"); } } else { fontName = JNU_NewStringPlatform(GetEnv(), face); } if (fontName == NULL) { delete[] face; throw std::bad_alloc(); } jint pointSize = rescale(metrics.tmHeight - metrics.tmInternalLeading, invScale); jint style = java_awt_Font_PLAIN; if (metrics.tmWeight >= FW_BOLD) { style = java_awt_Font_BOLD; } if (metrics.tmItalic ) { style |= java_awt_Font_ITALIC; } jstring key = JNU_NewStringPlatform(GetEnv(), propName); if (key == NULL) { GetEnv()->DeleteLocalRef(fontName); delete[] face; throw std::bad_alloc(); } GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setFontPropertyID, key, fontName, style, pointSize); GetEnv()->DeleteLocalRef(key); GetEnv()->DeleteLocalRef(fontName); } } delete[] face; } } }
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) { LOGFONT winfont; // The size here looks unusual. The negative number is intentional. The logical size constant is 32. winfont.lfHeight = -fontDescription.computedPixelSize() * 32; winfont.lfWidth = 0; winfont.lfEscapement = 0; winfont.lfOrientation = 0; winfont.lfUnderline = false; winfont.lfStrikeOut = false; winfont.lfCharSet = DEFAULT_CHARSET; #if PLATFORM(CG) winfont.lfOutPrecision = OUT_TT_ONLY_PRECIS; #else winfont.lfOutPrecision = OUT_TT_PRECIS; #endif winfont.lfQuality = 5; // Force cleartype. winfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; winfont.lfItalic = fontDescription.italic(); // FIXME: Support weights for real. Do our own enumeration of the available weights. // We can't rely on Windows here, since we need to follow the CSS2 algorithm for how to fill in // gaps in the weight list. // FIXME: Hardcoding Lucida Grande for now. It uses different weights than typical Win32 fonts // (500/600 instead of 400/700). static AtomicString lucidaStr("Lucida Grande"); if (equalIgnoringCase(family, lucidaStr)) winfont.lfWeight = fontDescription.bold() ? 600 : 500; else winfont.lfWeight = fontDescription.bold() ? 700 : 400; int len = min(family.length(), (unsigned int)LF_FACESIZE - 1); memcpy(winfont.lfFaceName, family.characters(), len * sizeof(WORD)); winfont.lfFaceName[len] = '\0'; HFONT hfont = CreateFontIndirect(&winfont); // Windows will always give us a valid pointer here, even if the face name is non-existent. We have to double-check // and see if the family name was really used. HDC dc = GetDC((HWND)0); SaveDC(dc); SelectObject(dc, hfont); WCHAR name[LF_FACESIZE]; GetTextFace(dc, LF_FACESIZE, name); RestoreDC(dc, -1); ReleaseDC(0, dc); if (_wcsicmp(winfont.lfFaceName, name)) { DeleteObject(hfont); return 0; } FontPlatformData* result = new FontPlatformData(hfont, fontDescription.computedPixelSize(), fontDescription.bold(), fontDescription.italic()); if (!result->cgFont()) { // The creation of the CGFontRef failed for some reason. We already asserted in debug builds, but to make // absolutely sure that we don't use this font, go ahead and return 0 so that we can fall back to the next // font. delete result; DeleteObject(hfont); return 0; } return result; }
void CArchConsoleWindows::threadMainLoop() { LoadLibrary("RICHED32.DLL"); // get the app icons HICON largeIcon, smallIcon; CArchMiscWindows::getIcons(largeIcon, smallIcon); // register a window class WNDCLASSEX classInfo; classInfo.cbSize = sizeof(classInfo); classInfo.style = 0; classInfo.lpfnWndProc = &CArchConsoleWindows::staticWndProc; classInfo.cbClsExtra = 0; classInfo.cbWndExtra = sizeof(CArchConsoleWindows*); classInfo.hInstance = s_appInstance; classInfo.hIcon = largeIcon; classInfo.hCursor = NULL; classInfo.hbrBackground = NULL; classInfo.lpszMenuName = NULL; classInfo.lpszClassName = TEXT("SynergyConsole"); classInfo.hIconSm = smallIcon; ATOM windowClass = RegisterClassEx(&classInfo); // create frame window m_frame = CreateWindowEx(0, reinterpret_cast<LPCTSTR>(windowClass), TEXT("Synergy Log"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, NULL, s_appInstance, NULL); // create log window m_hwnd = CreateWindowEx(0, "RichEdit", TEXT(""), WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_READONLY, 0, 0, 1, 1, m_frame, (HMENU)1, s_appInstance, NULL); // select font and get info HDC hdc = GetDC(m_hwnd); HGDIOBJ oldFont = SelectObject(hdc, GetStockObject(ANSI_FIXED_FONT)); TEXTMETRIC metrics; GetTextMetrics(hdc, &metrics); CHARFORMAT format; format.cbSize = sizeof(format); format.dwMask = CFM_CHARSET | CFM_COLOR | CFM_FACE | CFM_OFFSET | CFM_SIZE | CFM_PROTECTED | CFM_BOLD | CFM_ITALIC | CFM_STRIKEOUT | CFM_UNDERLINE; format.dwEffects = 0; format.yHeight = metrics.tmHeight; format.yOffset = 0; format.crTextColor = RGB(0, 0, 0); format.bCharSet = DEFAULT_CHARSET; format.bPitchAndFamily = FIXED_PITCH | FF_MODERN; GetTextFace(hdc, sizeof(format.szFaceName), format.szFaceName); SelectObject(hdc, oldFont); ReleaseDC(m_hwnd, hdc); // prep window SendMessage(m_hwnd, EM_EXLIMITTEXT, 0, m_maxCharacters); SendMessage(m_hwnd, EM_SETCHARFORMAT, 0, reinterpret_cast<LPARAM>(&format)); SendMessage(m_hwnd, EM_SETBKGNDCOLOR, 0, RGB(255, 255, 255)); m_wChar = metrics.tmAveCharWidth; m_hChar = metrics.tmHeight + metrics.tmExternalLeading; setSize(80, 25); // signal ready ARCH->lockMutex(m_mutex); m_ready = true; ARCH->broadcastCondVar(m_condVar); ARCH->unlockMutex(m_mutex); // handle failure if (m_hwnd == NULL) { UnregisterClass(reinterpret_cast<LPCTSTR>(windowClass), s_appInstance); return; } // main loop MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // clean up DestroyWindow(m_hwnd); UnregisterClass(reinterpret_cast<LPCTSTR>(windowClass), s_appInstance); }
status ws_create_font(FontObj f, DisplayObj d) { WsFont wsf = alloc(sizeof(ws_font)); #ifdef __WINDOWS__ int widths[FONTTABLESIZE]; #else short widths[FONTTABLESIZE]; #endif HDC hdc; HFONT old; int n; TEXTMETRIC tm; int stock; if ( sscanf(strName(f->x_name), STOCKFMT, &stock) == 1 ) { wsf->hfont = GetStockObject(stock); wsf->from_stock = TRUE; } else { LOGFONT lfont; Real scale = getClassVariableValueObject(f, NAME_scale); float fscale = (scale ? valReal(scale) : 1.4); memset(&lfont, 0, sizeof(lfont)); lfont.lfHeight = (int)((float) valInt(f->points) * fscale); lfont.lfWeight = (f->style == NAME_bold ? FW_BOLD : FW_NORMAL); lfont.lfItalic = ((f->style == NAME_italic || f->style == NAME_oblique) ? 1 : 0); lfont.lfPitchAndFamily = (f->family == NAME_screen ? FIXED_PITCH : DEFAULT_PITCH); lfont.lfPitchAndFamily |= (f->family == NAME_helvetica ? FF_SWISS : f->family == NAME_times ? FF_ROMAN : f->family == NAME_screen ? FF_MODERN : FF_DONTCARE); if ( f->family == NAME_symbol ) strcpy(lfont.lfFaceName, "symbol"); if ( instanceOfObject(f->x_name, ClassCharArray) ) { strcpy(lfont.lfFaceName, strName(f->family)); parse_font(strName(f->x_name), &lfont); } else { lfont.lfOutPrecision = OUT_TT_ONLY_PRECIS; lfont.lfQuality = PROOF_QUALITY; } if ( !(wsf->hfont = CreateFontIndirect(&lfont)) ) { Cprintf("Failed to create logical font; replacing with stock font\n"); if ( f->family == NAME_screen ) { if ( f->style == NAME_bold ) stock = SYSTEM_FIXED_FONT; else stock = ANSI_FIXED_FONT; } else { if ( f->style == NAME_bold ) stock = SYSTEM_FONT; else stock = ANSI_VAR_FONT; } wsf->hfont = GetStockObject(stock); wsf->from_stock = TRUE; } else wsf->from_stock = FALSE; } wsf->widths = alloc(FONTTABLESIZE * sizeof(cwidth)); assign(f, iswide, OFF); hdc = GetDC(NULL); old = SelectObject(hdc, wsf->hfont); GetCharWidth(hdc, 0, FONTTABLESIZE-1, widths); for(n=0; n<FONTTABLESIZE; n++) wsf->widths[n] = widths[n]; GetTextMetrics(hdc, &tm); wsf->ascent = tm.tmAscent + tm.tmExternalLeading; wsf->descent = tm.tmDescent; /*if ( !(tm.tmPitchAndFamily & TMPF_TRUETYPE) && f->family != NAME_win ) Cprintf("%s (%s/%s): not a TrueType font\n", pp(f), pp(f->family), pp(f->style)); */ if ( isDefault(f->x_name) ) { char buf[256]; if ( GetTextFace(hdc, sizeof(buf), buf) ) assign(f, x_name, CtoName(buf)); } SelectObject(hdc, old); ReleaseDC(NULL, hdc); if ( wsf->widths['i'] == wsf->widths['w'] ) assign(f, fixed_width, ON); else assign(f, fixed_width, OFF); registerXrefObject(f, d, wsf); succeed; }
void map_font() { HDC hDC = GetDC( NULL ); //errno_t err ; //err = _wfopen_s(&out, L"font_dump.txt", L"w, ccs=UNICODE" ) ; //LOGFONT lf = { 0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, //0, NULL }; //EnumFontFamiliesEx( hDC, &lf, (FONTENUMPROC)EnumFontFamiliesExProc, 0, 0 ); //fclose( out ); HFONT hfont; TEXTMETRIC tm; LOGFONTA lf; TCHAR szFaceName[LF_FACESIZE]; CHOOSEFONTA choose_font; LPCTSTR lpszFilename = "c:\\Code39Barcode.ttf"; int err; bool success; // load font err = AddFontResourceA(lpszFilename); SendMessageA(HWND_BROADCAST,WM_FONTCHANGE,0,0); choose_font.lStructSize = sizeof(CHOOSEFONT); choose_font.hwndOwner = NULL; choose_font.lpLogFont = &lf; choose_font.Flags = CF_SCREENFONTS; success = ChooseFontA( &choose_font ); /* for( indx=0; indx<num_fonts; indx++) { hfont = CreateFontA(0,0,0,0,0,0,0,0,DEFAULT_CHARSET, 0,0,0,0, font_table[indx]); SelectObject(hDC, hfont); GetObjectA( GetCurrentObject( hdc, OBJ_FONT ), sizeof(lf), (LPVOID) &lf ); // Get the info for the currently realized font. //GetTextMetrics( hdc, &tm ); GetTextFace( hdc, sizeof(szFaceName), szFaceName ); cout << "Font: " << font_table[indx] << " Mapping: " << szFaceName << endl; */ /* // get logical font information hfont = CreateFontA(0,0,0,0,0,0,0,0,DEFAULT_CHARSET, 0,0,0,0, "Code39Barcode"); SelectObject(hDC, hfont); GetObjectA( GetCurrentObject( hDC, OBJ_FONT ), sizeof(lf), (LPVOID) &lf ); GetTextFace( hDC, sizeof(szFaceName), szFaceName ); */ // unload font err = RemoveFontResourceA(lpszFilename); SendMessageA(HWND_BROADCAST,WM_FONTCHANGE,0,0); hfont = CreateFontIndirectA(&lf); SelectObject(hDC, hfont); GetObjectA( GetCurrentObject( hDC, OBJ_FONT ), sizeof(lf), (LPVOID) &lf ); GetTextFace( hDC, sizeof(szFaceName), szFaceName ); GetTextMetrics( hDC, &tm ); //cout << "Font: " << "Arial" << " Mapping: " << szFaceName << endl; ReleaseDC( NULL, hDC ); return; }
LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static struct { int idStockFont ; TCHAR * szStockFont ; } stockfont [] = { OEM_FIXED_FONT, "OEM_FIXED_FONT", ANSI_FIXED_FONT, "ANSI_FIXED_FONT", ANSI_VAR_FONT, "ANSI_VAR_FONT", SYSTEM_FONT, "SYSTEM_FONT", DEVICE_DEFAULT_FONT,"DEVICE_DEFAULT_FONT", SYSTEM_FIXED_FONT, "SYSTEM_FIXED_FONT", DEFAULT_GUI_FONT, "DEFAULT_GUI_FONT" } ; static int iFont, cFonts = sizeof stockfont / sizeof stockfont[0] ; HDC hdc ; int i, x, y, cxGrid, cyGrid ; PAINTSTRUCT ps ; TCHAR szFaceName [LF_FACESIZE], szBuffer [LF_FACESIZE + 64] ; TEXTMETRIC tm ; switch (message) { case WM_CREATE: SetScrollRange (hwnd, SB_VERT, 0, cFonts - 1, TRUE) ; return 0 ; case WM_DISPLAYCHANGE: InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; case WM_VSCROLL: switch (LOWORD (wParam)) { case SB_TOP: iFont = 0 ; break ; case SB_BOTTOM: iFont = cFonts - 1 ; break ; case SB_LINEUP: case SB_PAGEUP: iFont -= 1 ; break ; case SB_LINEDOWN: case SB_PAGEDOWN: iFont += 1 ; break ; case SB_THUMBPOSITION:iFont = HIWORD (wParam) ; break ; } iFont = max (0, min (cFonts - 1, iFont)) ; SetScrollPos (hwnd, SB_VERT, iFont, TRUE) ; InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; case WM_KEYDOWN: switch (wParam) { case VK_HOME: SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0) ; break ; case VK_END: SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0) ; break ; case VK_PRIOR: case VK_LEFT: case VK_UP: SendMessage (hwnd, WM_VSCROLL, SB_LINEUP, 0) ; break ; case VK_NEXT: case VK_RIGHT: case VK_DOWN: SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0) ; break ; } return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; SelectObject (hdc, GetStockObject (stockfont[iFont].idStockFont)) ; GetTextFace (hdc, LF_FACESIZE, szFaceName) ; GetTextMetrics (hdc, &tm) ; cxGrid = max (3 * tm.tmAveCharWidth, 2 * tm.tmMaxCharWidth) ; cyGrid = tm.tmHeight + 3 ; TextOut (hdc, 0, 0, szBuffer, wsprintf ( szBuffer, TEXT (" %s: Face Name = %s, CharSet = %i"), stockfont[iFont].szStockFont, szFaceName, tm.tmCharSet)) ; SetTextAlign (hdc, TA_TOP | TA_CENTER) ; // vertical and horizontal lines for (i = 0 ; i < 17 ; i++) { MoveToEx (hdc, (i + 2) * cxGrid, 2 * cyGrid, NULL) ; LineTo (hdc, (i + 2) * cxGrid, 19 * cyGrid) ; MoveToEx (hdc, cxGrid, (i + 3) * cyGrid, NULL) ; LineTo (hdc, 18 * cxGrid, (i + 3) * cyGrid) ; } // vertical and horizontal headings for (i = 0 ; i < 16 ; i++) { TextOut (hdc, (2 * i + 5) * cxGrid / 2, 2 * cyGrid + 2, szBuffer, wsprintf (szBuffer, TEXT ("%X-"), i)) ; TextOut (hdc, 3 * cxGrid / 2, (i + 3) * cyGrid + 2, szBuffer, wsprintf (szBuffer, TEXT ("-%X"), i)) ; } // characters for (y = 0 ; y < 16 ; y++) for (x = 0 ; x < 16 ; x++) { TextOut (hdc, (2 * x + 5) * cxGrid / 2, (y + 3) * cyGrid + 2, szBuffer, wsprintf (szBuffer, TEXT ("%c"), 16 * x + y)) ; } EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
void CPreviewDC::MirrorFont() { if (m_hAttribDC == NULL) return; // Can't do anything without Attrib DC if (m_hPrinterFont == NULL) { SelectStockObject(DEVICE_DEFAULT_FONT); // will recurse return; } if (m_hDC == NULL) return; // can't mirror font without a screen DC LOGFONT logFont; // Fill the logFont structure with the original info ::GetObject(m_hPrinterFont, sizeof(LOGFONT), (LPVOID)&logFont); TEXTMETRIC tm; GetTextFace(LF_FACESIZE, (LPTSTR)&logFont.lfFaceName[0]); GetTextMetrics(&tm); // Set real values based on the Printer's text metrics. if (tm.tmHeight < 0) logFont.lfHeight = tm.tmHeight; else logFont.lfHeight = -(tm.tmHeight - tm.tmInternalLeading); logFont.lfWidth = 0; logFont.lfWeight = tm.tmWeight; logFont.lfItalic = tm.tmItalic; logFont.lfUnderline = tm.tmUnderlined; logFont.lfStrikeOut = tm.tmStruckOut; logFont.lfCharSet = tm.tmCharSet; logFont.lfPitchAndFamily = tm.tmPitchAndFamily; HFONT hNewFont = ::CreateFontIndirect(&logFont); ::SelectObject(m_hDC, hNewFont); ::GetTextMetrics(m_hDC, &tm); // Is the displayed font too large? int cyDesired = -logFont.lfHeight; int cyActual; if (tm.tmHeight < 0) cyActual = -tm.tmHeight; else cyActual = tm.tmHeight - tm.tmInternalLeading; CSize sizeWinExt; VERIFY(::GetWindowExtEx(m_hDC, &sizeWinExt)); CSize sizeVpExt; VERIFY(::GetViewportExtEx(m_hDC, &sizeVpExt)); // Only interested in Extent Magnitudes, not direction if (sizeWinExt.cy < 0) sizeWinExt.cy = -sizeWinExt.cy; if (sizeVpExt.cy < 0) sizeVpExt.cy = -sizeVpExt.cy; // Convert to screen device coordinates to eliminate rounding // errors as a source of SmallFont aliasing cyDesired = MulDiv(cyDesired, sizeVpExt.cy, sizeWinExt.cy); cyActual = MulDiv(cyActual, sizeVpExt.cy, sizeWinExt.cy); ASSERT(cyDesired >= 0 && cyActual >= 0); if (cyDesired < cyActual) { logFont.lfFaceName[0] = 0; // let the mapper find a good fit if ((logFont.lfPitchAndFamily & 0xf0) == FF_DECORATIVE) logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DECORATIVE; else logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; HFONT hTempFont = ::CreateFontIndirect(&logFont); ::SelectObject(m_hDC, hTempFont); // Select it in. ::DeleteObject(hNewFont); hNewFont = hTempFont; } AfxDeleteObject((HGDIOBJ*)&m_hFont); // delete the old logical font m_hFont = hNewFont; // save the new one #ifdef _MAC VERIFY(::GetCharWidth(m_hDC, 0, 255, m_aCharWidthsDraw)); VERIFY(::GetCharWidth(m_hAttribDC, 0, 255, m_aCharWidthsAttrib)); #endif }