From be9268a4ca24fdfe9468195a9e311c514e5bacae Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Sat, 23 Mar 2002 20:14:04 +0000 Subject: [PATCH] Wineconsole is now able to handle non raster fonts (vector, true type). --- programs/wineconsole/dialog.c | 189 ++++++++++++------ programs/wineconsole/user.c | 287 +++++++++++++++++----------- programs/wineconsole/winecon_user.h | 10 +- 3 files changed, 318 insertions(+), 168 deletions(-) diff --git a/programs/wineconsole/dialog.c b/programs/wineconsole/dialog.c index f448d9316ed..79e7fe8dd67 100644 --- a/programs/wineconsole/dialog.c +++ b/programs/wineconsole/dialog.c @@ -42,8 +42,9 @@ struct dialog_info int nFont; /* number of font size in size LB */ struct font_info { - TEXTMETRIC tm; - LOGFONT lf; + UINT height; + UINT weight; + WCHAR faceName[LF_FACESIZE]; } *font; /* array of nFont. index sync'ed with SIZE LB */ void (*apply)(struct dialog_info*, HWND, enum WCUSER_ApplyTo, DWORD); }; @@ -71,7 +72,15 @@ static void WCUSER_ApplyDefault(struct dialog_info* di, HWND hDlg, enum WCUSER_A di->config->quick_edit = val; break; case WCUSER_ApplyToFont: - WCUSER_CopyFont(di->config, &di->font[val].lf); + { + LOGFONT lf; + HFONT hFont; + + WCUSER_FillLogFont(&lf, di->font[val].faceName, + di->font[val].height, di->font[val].weight); + hFont = WCUSER_CopyFont(di->config, PRIVATE(di->data)->hWnd, &lf); + DeleteObject(hFont); + } break; case WCUSER_ApplyToAttribute: di->config->def_attr = val; @@ -112,7 +121,12 @@ static void WCUSER_ApplyCurrent(struct dialog_info* di, HWND hDlg, enum WCUSER_A di->config->quick_edit = val; break; case WCUSER_ApplyToFont: - WCUSER_SetFont(di->data, &di->font[val].lf); + { + LOGFONT lf; + WCUSER_FillLogFont(&lf, di->font[val].faceName, + di->font[val].height, di->font[val].weight); + WCUSER_SetFont(di->data, &lf); + } break; case WCUSER_ApplyToAttribute: di->config->def_attr = val; @@ -228,12 +242,32 @@ static LRESULT WINAPI WCUSER_FontPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, { switch (msg) { + case WM_CREATE: + SetWindowLong(hWnd, 0, 0); + break; + case WM_GETFONT: + return GetWindowLong(hWnd, 0); + case WM_SETFONT: + SetWindowLong(hWnd, 0, wParam); + if (LOWORD(lParam)) + { + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + break; + case WM_DESTROY: + { + HFONT hFont = (HFONT)GetWindowLong(hWnd, 0L); + if (hFont) DeleteObject(hFont); + } + break; case WM_PAINT: { PAINTSTRUCT ps; int font_idx; int size_idx; struct dialog_info* di; + HFONT hFont, hOldFont; di = (struct dialog_info*)GetWindowLong(GetParent(hWnd), DWL_USER); BeginPaint(hWnd, &ps); @@ -241,29 +275,27 @@ static LRESULT WINAPI WCUSER_FontPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L); size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L); - if (font_idx >= 0 && size_idx >= 0 && size_idx < di->nFont) + hFont = (HFONT)GetWindowLong(hWnd, 0L); + if (hFont) { - HFONT hFont, hOldFont; WCHAR buf1[256]; WCHAR buf2[256]; int len1, len2; - - hFont = CreateFontIndirect(&di->font[size_idx].lf); + len1 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_1, buf1, sizeof(buf1) / sizeof(WCHAR)); len2 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_2, buf2, sizeof(buf2) / sizeof(WCHAR)); buf1[len1] = buf2[len2] = 0; - if (hFont && len1) + if (len1) { hOldFont = SelectObject(ps.hdc, hFont); SetBkColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_BK), 0)]); SetTextColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_FG), 0)]); TextOut(ps.hdc, 0, 0, buf1, len1); if (len2) - TextOut(ps.hdc, 0, di->font[size_idx].tm.tmHeight, buf2, len2); + TextOut(ps.hdc, 0, di->font[size_idx].height, buf2, len2); SelectObject(ps.hdc, hOldFont); - DeleteObject(hFont); } } EndPaint(hWnd, &ps); @@ -360,10 +392,11 @@ static int CALLBACK font_enum_size2(const LOGFONT* lf, const TEXTMETRIC* tm, { struct dialog_info* di = (struct dialog_info*)lParam; - if (WCUSER_ValidateFontMetric(di->data, tm)) + if (WCUSER_ValidateFontMetric(di->data, tm, FontType)) { di->nFont++; } + return 1; } @@ -375,16 +408,22 @@ static int CALLBACK font_enum(const LOGFONT* lf, const TEXTMETRIC* tm, if (WCUSER_ValidateFont(di->data, lf) && (hdc = GetDC(di->hDlg))) { - di->nFont = 0; - EnumFontFamilies(hdc, lf->lfFaceName, font_enum_size2, (LPARAM)di); - if (di->nFont) + if (FontType & RASTER_FONTTYPE) + { + di->nFont = 0; + EnumFontFamilies(hdc, lf->lfFaceName, font_enum_size2, (LPARAM)di); + } + else + di->nFont = 1; + + if (di->nFont) { - int idx; - idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING, - 0, (LPARAM)lf->lfFaceName); - } + SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING, + 0, (LPARAM)lf->lfFaceName); + } ReleaseDC(di->hDlg, hdc); } + return 1; } @@ -397,46 +436,61 @@ static int CALLBACK font_enum_size(const LOGFONT* lf, const TEXTMETRIC* tm, DWORD FontType, LPARAM lParam) { struct dialog_info* di = (struct dialog_info*)lParam; + WCHAR buf[32]; + static const WCHAR fmt[] = {'%','l','d',0}; - if (WCUSER_ValidateFontMetric(di->data, tm)) + if (di->nFont == 0 && !(FontType & RASTER_FONTTYPE)) + { + static const int sizes[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72}; + int i; + + di->nFont = sizeof(sizes) / sizeof(sizes[0]); + di->font = HeapAlloc(GetProcessHeap(), 0, di->nFont * sizeof(di->font[0])); + for (i = 0; i < di->nFont; i++) + { + /* drop sizes where window size wouldn't fit on screen */ + if (sizes[i] * di->data->curcfg.win_height > GetSystemMetrics(SM_CYSCREEN)) + { + di->nFont = i; + break; + } + di->font[i].height = sizes[i]; + di->font[i].weight = 400; + lstrcpy(di->font[i].faceName, lf->lfFaceName); + wsprintf(buf, fmt, sizes[i]); + SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, i, (LPARAM)buf); + } + /* don't need to enumerate other */ + return 0; + } + + if (WCUSER_ValidateFontMetric(di->data, tm, FontType)) { - WCHAR buf[32]; - static const WCHAR fmt[] = {'%','l','d',0}; int idx; /* we want the string to be sorted with a numeric order, not a lexicographic... * do the job by hand... get where to insert the new string */ - for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].tm.tmHeight; idx++); - if (idx < di->nFont && - tm->tmHeight == di->font[idx].tm.tmHeight && - tm->tmMaxCharWidth == di->font[idx].tm.tmMaxCharWidth) - { - /* we already have an entry with the same width & height... - * try to see which TEXTMETRIC (old or new) we should keep... - */ - if (di->font[idx].tm.tmWeight != tm->tmWeight) - { - /* get the weight closer to 400, the default value */ - if (abs(tm->tmWeight - 400) < abs(di->font[idx].tm.tmWeight - 400)) - { - di->font[idx].tm = *tm; - } - } - /* else FIXME: skip the new tm for now */ - } - else + for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].height; idx++); + while (idx < di->nFont && + tm->tmHeight == di->font[idx].height && + tm->tmWeight > di->font[idx].weight) + idx++; + if (idx == di->nFont || + tm->tmHeight != di->font[idx].height || + tm->tmWeight < di->font[idx].weight) { /* here we need to add the new entry */ - wsprintfW(buf, fmt, tm->tmHeight); + wsprintf(buf, fmt, tm->tmHeight); SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf); - /* now grow our arrays and insert to values at the same index than in the list box */ + /* now grow our arrays and insert the values at the same index than in the list box */ di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1)); if (idx != di->nFont) memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font)); - di->font[idx].tm = *tm; - di->font[idx].lf = *lf; + di->font[idx].height = tm->tmHeight; + di->font[idx].weight = tm->tmWeight; + lstrcpy(di->font[idx].faceName, lf->lfFaceName); di->nFont++; } } @@ -450,19 +504,37 @@ static int CALLBACK font_enum_size(const LOGFONT* lf, const TEXTMETRIC* tm, */ static BOOL select_font(struct dialog_info* di) { - int idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L); + int font_idx, size_idx; WCHAR buf[256]; WCHAR fmt[128]; + LOGFONT lf; + HFONT hFont, hOldFont; + struct config_data config; - if (idx < 0 || idx >= di->nFont) + font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L); + size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L); + + if (font_idx < 0 || size_idx < 0 || size_idx >= di->nFont) return FALSE; + + WCUSER_FillLogFont(&lf, di->font[size_idx].faceName, + di->font[size_idx].height, di->font[size_idx].weight); + hFont = WCUSER_CopyFont(&config, PRIVATE(di->data)->hWnd, &lf); + if (!hFont) return FALSE; + + if (config.cell_height != di->font[size_idx].height) + Trace(0, "select_font: mismatched heights (%u<>%u)\n", + config.cell_height, di->font[size_idx].height); + hOldFont = (HFONT)SendDlgItemMessage(di->hDlg, IDC_FNT_PREVIEW, WM_GETFONT, 0L, 0L); + + SendDlgItemMessage(di->hDlg, IDC_FNT_PREVIEW, WM_SETFONT, (DWORD)hFont, TRUE); + if (hOldFont) DeleteObject(hOldFont); LoadString(GetModuleHandle(NULL), IDS_FNT_DISPLAY, fmt, sizeof(fmt) / sizeof(WCHAR)); - wsprintfW(buf, fmt, di->font[idx].tm.tmMaxCharWidth, di->font[idx].tm.tmHeight); + wsprintf(buf, fmt, config.cell_width, config.cell_height); SendDlgItemMessage(di->hDlg, IDC_FNT_FONT_INFO, WM_SETTEXT, 0, (LPARAM)buf); - InvalidateRect(GetDlgItem(di->hDlg, IDC_FNT_PREVIEW), NULL, TRUE); - UpdateWindow(GetDlgItem(di->hDlg, IDC_FNT_PREVIEW)); + return TRUE; } @@ -494,12 +566,19 @@ static BOOL fill_list_size(struct dialog_info* di, BOOL doInit) if (doInit) { + int ref = -1; + for (idx = 0; idx < di->nFont; idx++) { - if (WCUSER_AreFontsEqual(di->config, &di->font[idx].lf)) - break; + if (!lstrcmp(di->font[idx].faceName, di->config->face_name) && + di->font[idx].height == di->config->cell_height && + di->font[idx].weight == di->config->font_weight) + { + if (ref == -1) ref = idx; + else Trace(0, "Several matches found: ref=%d idx=%d\n", ref, idx); + } } - if (idx == di->nFont) idx = 0; + idx = (ref == -1) ? 0 : ref; } else idx = 0; @@ -545,6 +624,8 @@ static BOOL WINAPI WCUSER_FontDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam; di->hDlg = hDlg; SetWindowLong(hDlg, DWL_USER, (DWORD)di); + /* remove dialog from this control, font will be reset when listboxes are filled */ + SendDlgItemMessage(hDlg, IDC_FNT_PREVIEW, WM_SETFONT, 0L, 0L); fill_list_font(di); SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0, (di->config->def_attr >> 4) & 0x0F); SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0, di->config->def_attr & 0x0F); @@ -704,7 +785,7 @@ BOOL WCUSER_GetProperties(struct inner_data* data, BOOL current) wndclass.style = 0; wndclass.lpfnWndProc = WCUSER_FontPreviewProc; wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = 0; + wndclass.cbWndExtra = 4; /* for hFont */ wndclass.hInstance = GetModuleHandle(NULL); wndclass.hIcon = 0; wndclass.hCursor = LoadCursor(0, IDC_ARROW); diff --git a/programs/wineconsole/user.c b/programs/wineconsole/user.c index badf23bff78..e2a2023462c 100644 --- a/programs/wineconsole/user.c +++ b/programs/wineconsole/user.c @@ -258,57 +258,166 @@ static void WCUSER_SetTitle(const struct inner_data* data) BOOL WCUSER_AreFontsEqual(const struct config_data* config, const LOGFONT* lf) { return lf->lfHeight == config->cell_height && - lf->lfWidth == config->cell_width && lf->lfWeight == config->font_weight && !lf->lfItalic && !lf->lfUnderline && !lf->lfStrikeOut && - !lstrcmpW(lf->lfFaceName, config->face_name); + !lstrcmp(lf->lfFaceName, config->face_name); +} + +struct font_chooser { + struct inner_data* data; + int done; +}; + +/****************************************************************** + * WCUSER_ValidateFontMetric + * + * Returns true if the font described in tm is usable as a font for the renderer + */ +BOOL WCUSER_ValidateFontMetric(const struct inner_data* data, const TEXTMETRIC* tm, DWORD fontType) +{ + BOOL ret = TRUE; + + if (fontType & RASTER_FONTTYPE) + ret = (tm->tmMaxCharWidth * data->curcfg.win_width < GetSystemMetrics(SM_CXSCREEN) && + tm->tmHeight * data->curcfg.win_height < GetSystemMetrics(SM_CYSCREEN)); + return ret && !tm->tmItalic && !tm->tmUnderlined && !tm->tmStruckOut && + (tm->tmCharSet == DEFAULT_CHARSET /*|| tm->tmCharSet == ANSI_CHARSET*/); +} + +/****************************************************************** + * WCUSER_ValidateFont + * + * Returns true if the font family described in lf is usable as a font for the renderer + */ +BOOL WCUSER_ValidateFont(const struct inner_data* data, const LOGFONT* lf) +{ + return (lf->lfPitchAndFamily & 3) == FIXED_PITCH && + /* (lf->lfPitchAndFamily & 0xF0) == FF_MODERN && */ + (lf->lfCharSet == DEFAULT_CHARSET || lf->lfCharSet == ANSI_CHARSET); +} + +/****************************************************************** + * get_first_font_enum_2 + * get_first_font_enum + * + * Helper functions to get a decent font for the renderer + */ +static int CALLBACK get_first_font_enum_2(const LOGFONT* lf, const TEXTMETRIC* tm, + DWORD FontType, LPARAM lParam) +{ + struct font_chooser* fc = (struct font_chooser*)lParam; + + if (WCUSER_ValidateFontMetric(fc->data, tm, FontType)) + { + WCUSER_SetFont(fc->data, lf); + fc->done = 1; + return 0; + } + return 1; +} + +static int CALLBACK get_first_font_enum(const LOGFONT* lf, const TEXTMETRIC* tm, + DWORD FontType, LPARAM lParam) +{ + struct font_chooser* fc = (struct font_chooser*)lParam; + + if (WCUSER_ValidateFont(fc->data, lf)) + { + EnumFontFamilies(PRIVATE(fc->data)->hMemDC, lf->lfFaceName, get_first_font_enum_2, lParam); + return !fc->done; /* we just need the first matching one... */ + } + return 1; } /****************************************************************** * CopyFont * - * + * get the relevant information from the font described in lf and store them + * in config */ -void WCUSER_CopyFont(struct config_data* config, const LOGFONT* lf) +HFONT WCUSER_CopyFont(struct config_data* config, HWND hWnd, const LOGFONT* lf) { - config->cell_width = lf->lfWidth; - config->cell_height = lf->lfHeight; - config->font_weight = lf->lfWeight; - lstrcpyW(config->face_name, lf->lfFaceName); + TEXTMETRIC tm; + HDC hDC; + HFONT hFont, hOldFont; + int w, i, buf[256]; + + if (!(hDC = GetDC(hWnd))) return (HFONT)0; + if (!(hFont = CreateFontIndirect(lf))) goto err1; + + hOldFont = SelectObject(hDC, hFont); + GetTextMetrics(hDC, &tm); + + /* FIXME: + * the current freetype engine (at least 2.0.x with x <= 8) and its implementation + * in Wine don't return adequate values for fixed fonts + * In Windows, those fonts are expectes to return the same value for + * - the average width + * - the largest width + * - the width of all characters in the font + * This isn't true in Wine. As a temporary workaound, we get as the width of the + * cell, the width of the first character in the font, after checking that all + * characters in the font have the same width (I hear paranoļa coming) + * when this gets fixed, the should be using tm.tmAveCharWidth or tm.tmMaxCharWidth + * as the cell width. + */ + GetCharWidth32(hDC, tm.tmFirstChar, tm.tmFirstChar, &w); + for (i = tm.tmFirstChar + 1; i <= tm.tmLastChar; i += sizeof(buf) / sizeof(buf[0])) + { + int j, l; + + l = min(tm.tmLastChar - i, sizeof(buf) / sizeof(buf[0]) - 1); + GetCharWidth32(hDC, i, i + l, buf); + for (j = 0; j <= l; j++) + { + if (buf[j] != w) + { + Trace(0, "Non uniform cell width: [%d]=%d [%d]=%d\n", + i + j, buf[j], tm.tmFirstChar, w); + goto err; + } + } + } + + SelectObject(hDC, hOldFont); + ReleaseDC(hWnd, hDC); + + config->cell_width = w; + config->cell_height = tm.tmHeight; + config->font_weight = tm.tmWeight; + lstrcpy(config->face_name, lf->lfFaceName); + + return hFont; + err: + if (hDC && hOldFont) SelectObject(hDC, hOldFont); + if (hFont) DeleteObject(hFont); + err1: + if (hDC) ReleaseDC(hWnd, hDC); + + return (HFONT)0; } /****************************************************************** - * WCUSER_InitFont + * WCUSER_FillLogFont + * * - * create a hFont from the settings saved in registry... - * (called on init, assuming no font has been created before) */ -BOOL WCUSER_InitFont(struct inner_data* data) +void WCUSER_FillLogFont(LOGFONT* lf, const WCHAR* name, UINT height, UINT weight) { - LOGFONT lf; - - lf.lfHeight = -data->curcfg.cell_height; - lf.lfWidth = data->curcfg.cell_width; - lf.lfEscapement = 0; - lf.lfOrientation = 0; - lf.lfWeight = data->curcfg.font_weight; - lf.lfItalic = FALSE; - lf.lfUnderline = FALSE; - lf.lfStrikeOut = FALSE; - lf.lfCharSet = DEFAULT_CHARSET; - lf.lfOutPrecision = OUT_DEFAULT_PRECIS; - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfQuality = DEFAULT_QUALITY; - lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE; - lstrcpy(lf.lfFaceName, data->curcfg.face_name); - PRIVATE(data)->hFont = CreateFontIndirect(&lf); - if (!PRIVATE(data)->hFont) return FALSE; - - WCUSER_ComputePositions(data); - WCUSER_NewBitmap(data, TRUE); - InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE); - UpdateWindow(PRIVATE(data)->hWnd); - return TRUE; + lf->lfHeight = height; + lf->lfWidth = 0; + lf->lfEscapement = 0; + lf->lfOrientation = 0; + lf->lfWeight = weight; + lf->lfItalic = FALSE; + lf->lfUnderline = FALSE; + lf->lfStrikeOut = FALSE; + lf->lfCharSet = DEFAULT_CHARSET; + lf->lfOutPrecision = OUT_DEFAULT_PRECIS; + lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf->lfQuality = DEFAULT_QUALITY; + lf->lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE; + lstrcpy(lf->lfFaceName, name); } /****************************************************************** @@ -320,17 +429,44 @@ BOOL WCUSER_SetFont(struct inner_data* data, const LOGFONT* logfont) { if (WCUSER_AreFontsEqual(&data->curcfg, logfont)) return TRUE; if (PRIVATE(data)->hFont) DeleteObject(PRIVATE(data)->hFont); - PRIVATE(data)->hFont = CreateFontIndirect(logfont); + + PRIVATE(data)->hFont = WCUSER_CopyFont(&data->curcfg, PRIVATE(data)->hWnd, logfont); if (!PRIVATE(data)->hFont) {Trace(0, "wrong font\n");return FALSE;} - WCUSER_CopyFont(&data->curcfg, logfont); WCUSER_ComputePositions(data); WCUSER_NewBitmap(data, TRUE); InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE); UpdateWindow(PRIVATE(data)->hWnd); + return TRUE; } +/****************************************************************** + * WCUSER_InitFont + * + * create a hFont from the settings saved in registry... + * (called on init, assuming no font has been created before) + */ +static BOOL WCUSER_InitFont(struct inner_data* data) +{ + LOGFONT lf; + struct font_chooser fc; + + WCUSER_FillLogFont(&lf, data->curcfg.face_name, + data->curcfg.cell_height, data->curcfg.font_weight); + data->curcfg.face_name[0] = 0; + data->curcfg.cell_height = data->curcfg.font_weight = 0; + + if (WCUSER_SetFont(data, &lf)) return TRUE; + + /* try to find an acceptable font */ + Trace(0, "Couldn't match the font from registry... trying to find one\n"); + fc.data = data; + fc.done = 0; + EnumFontFamilies(PRIVATE(data)->hMemDC, NULL, get_first_font_enum, (LPARAM)&fc); + return fc.done; +} + /****************************************************************** * WCUSER_GetCell * @@ -563,68 +699,6 @@ static void WCUSER_Scroll(struct inner_data* data, int pos, BOOL horz) InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE); } -struct font_chooser { - struct inner_data* data; - int done; -}; - -/****************************************************************** - * WCUSER_ValidateFontMetric - * - * Returns true if the font described in tm is usable as a font for the renderer - */ -BOOL WCUSER_ValidateFontMetric(const struct inner_data* data, const TEXTMETRIC* tm) -{ - return tm->tmMaxCharWidth * data->curcfg.win_width < GetSystemMetrics(SM_CXSCREEN) && - tm->tmHeight * data->curcfg.win_height < GetSystemMetrics(SM_CYSCREEN) && - !tm->tmItalic && !tm->tmUnderlined && !tm->tmStruckOut; -} - -/****************************************************************** - * WCUSER_ValidateFont - * - * Returns true if the font family described in lf is usable as a font for the renderer - */ -BOOL WCUSER_ValidateFont(const struct inner_data* data, const LOGFONT* lf) -{ - return (lf->lfPitchAndFamily & 3) == FIXED_PITCH && - (lf->lfPitchAndFamily & 0xF0) == FF_MODERN && - lf->lfCharSet != SYMBOL_CHARSET; -} - -/****************************************************************** - * get_first_font_enum_2 - * get_first_font_enum - * - * Helper functions to get a decent font for the renderer - */ -static int CALLBACK get_first_font_enum_2(const LOGFONT* lf, const TEXTMETRIC* tm, - DWORD FontType, LPARAM lParam) -{ - struct font_chooser* fc = (struct font_chooser*)lParam; - - if (WCUSER_ValidateFontMetric(fc->data, tm)) - { - WCUSER_SetFont(fc->data, lf); - fc->done = 1; - return 0; - } - return 1; -} - -static int CALLBACK get_first_font_enum(const LOGFONT* lf, const TEXTMETRIC* tm, - DWORD FontType, LPARAM lParam) -{ - struct font_chooser* fc = (struct font_chooser*)lParam; - - if (WCUSER_ValidateFont(fc->data, lf)) - { - EnumFontFamilies(PRIVATE(fc->data)->hMemDC, lf->lfFaceName, get_first_font_enum_2, lParam); - return !fc->done; /* we just need the first matching one... */ - } - return 1; -} - /****************************************************************** * WCUSER_FillMenu * @@ -1257,17 +1331,8 @@ BOOL WCUSER_InitBackend(struct inner_data* data) /* force update of current data */ if (!WINECON_GrabChanges(data)) return FALSE; - if (!WCUSER_InitFont(data)) - { - struct font_chooser fc; - /* try to find an acceptable font */ - fc.data = data; - fc.done = 0; - EnumFontFamilies(PRIVATE(data)->hMemDC, NULL, get_first_font_enum, (LPARAM)&fc); - return fc.done; - } + if (!WCUSER_InitFont(data)) return FALSE; + return TRUE; } - - diff --git a/programs/wineconsole/winecon_user.h b/programs/wineconsole/winecon_user.h index 03375dc669e..b0181d85488 100644 --- a/programs/wineconsole/winecon_user.h +++ b/programs/wineconsole/winecon_user.h @@ -45,7 +45,11 @@ extern COLORREF WCUSER_ColorMap[16]; extern BOOL WCUSER_GetProperties(struct inner_data*, BOOL); extern BOOL WCUSER_SetFont(struct inner_data* data, const LOGFONT* font); extern BOOL WCUSER_ValidateFont(const struct inner_data* data, const LOGFONT* lf); -extern BOOL WCUSER_ValidateFontMetric(const struct inner_data* data, const TEXTMETRIC* tm); -extern BOOL WCUSER_AreFontsEqual(const struct config_data* config, const LOGFONT* lf); -extern void WCUSER_CopyFont(struct config_data* config, const LOGFONT* lf); +extern BOOL WCUSER_ValidateFontMetric(const struct inner_data* data, + const TEXTMETRIC* tm, DWORD fontType); +extern BOOL WCUSER_AreFontsEqual(const struct config_data* config, + const LOGFONT* lf); +extern HFONT WCUSER_CopyFont(struct config_data* config, HWND hWnd, const LOGFONT* lf); +extern void WCUSER_FillLogFont(LOGFONT* lf, const WCHAR* name, + UINT height, UINT weight);