From: Piotr Caban piotr@codeweavers.com
We're checking that type is TRUETYPE_FONTTYPE before calling validate_font_metric. --- programs/conhost/window.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-)
diff --git a/programs/conhost/window.c b/programs/conhost/window.c index 9817c5fdac9..9c03bcb2212 100644 --- a/programs/conhost/window.c +++ b/programs/conhost/window.c @@ -806,30 +806,15 @@ struct font_chooser };
/* check if the font described in tm is usable as a font for the renderer */ -static BOOL validate_font_metric( struct console *console, const TEXTMETRICW *tm, - DWORD type, int pass ) +static BOOL validate_font_metric( struct console *console, const TEXTMETRICW *tm, int pass ) { switch (pass) /* we get increasingly lenient in later passes */ { case 0: - if (type & RASTER_FONTTYPE) return FALSE; - /* fall through */ - case 1: - if (type & RASTER_FONTTYPE) - { - if (tm->tmMaxCharWidth * (console->active->win.right - console->active->win.left + 1) - >= GetSystemMetrics(SM_CXSCREEN)) - return FALSE; - if (tm->tmHeight * (console->active->win.bottom - console->active->win.top + 1) - >= GetSystemMetrics(SM_CYSCREEN)) - return FALSE; - } - /* fall through */ - case 2: if (tm->tmCharSet != DEFAULT_CHARSET && tm->tmCharSet != console->window->ui_charset) return FALSE; /* fall through */ - case 3: + case 1: if (tm->tmItalic || tm->tmUnderlined || tm->tmStruckOut) return FALSE; break; } @@ -842,15 +827,13 @@ static BOOL validate_font( struct console *console, const LOGFONTW *lf, int pass switch (pass) /* we get increasingly lenient in later passes */ { case 0: - case 1: - case 2: if (lf->lfCharSet != DEFAULT_CHARSET && lf->lfCharSet != console->window->ui_charset) return FALSE; /* fall through */ - case 3: + case 1: if ((lf->lfPitchAndFamily & 3) != FIXED_PITCH) return FALSE; /* fall through */ - case 4: + case 2: if (lf->lfFaceName[0] == '@') return FALSE; break; } @@ -872,7 +855,7 @@ static int CALLBACK enum_first_font_proc( const LOGFONTW *lf, const TEXTMETRICW
TRACE( "%s\n", debugstr_textmetric( tm, font_type ));
- if (!validate_font_metric( fc->console, tm, font_type, fc->pass )) + if (!validate_font_metric( fc->console, tm, fc->pass )) return 1;
/* set default font size */ @@ -904,13 +887,13 @@ static void set_first_font( struct console *console, struct console_config *conf fc.font_width = config->cell_width; fc.done = FALSE;
- for (fc.pass = 0; fc.pass <= 5; fc.pass++) + for (fc.pass = 0; fc.pass <= 3; fc.pass++) { EnumFontFamiliesExW( console->window->mem_dc, &lf, enum_first_font_proc, (LPARAM)&fc, 0); if (fc.done) break; }
- if (fc.pass > 5) + if (fc.pass > 3) ERR("Unable to find a valid console font\n");
/* Update active configuration */
From: Piotr Caban piotr@codeweavers.com
--- programs/conhost/window.c | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-)
diff --git a/programs/conhost/window.c b/programs/conhost/window.c index 9c03bcb2212..ba96729314d 100644 --- a/programs/conhost/window.c +++ b/programs/conhost/window.c @@ -805,33 +805,20 @@ struct font_chooser BOOL done; };
-/* check if the font described in tm is usable as a font for the renderer */ -static BOOL validate_font_metric( struct console *console, const TEXTMETRICW *tm, int pass ) -{ - switch (pass) /* we get increasingly lenient in later passes */ - { - case 0: - if (tm->tmCharSet != DEFAULT_CHARSET && tm->tmCharSet != console->window->ui_charset) - return FALSE; - /* fall through */ - case 1: - if (tm->tmItalic || tm->tmUnderlined || tm->tmStruckOut) return FALSE; - break; - } - return TRUE; -} - /* check if the font family described in lf is usable as a font for the renderer */ -static BOOL validate_font( struct console *console, const LOGFONTW *lf, int pass ) +static BOOL validate_font( struct console *console, const LOGFONTW *lf, const TEXTMETRICW *tm, int pass ) { switch (pass) /* we get increasingly lenient in later passes */ { case 0: if (lf->lfCharSet != DEFAULT_CHARSET && lf->lfCharSet != console->window->ui_charset) return FALSE; + if (tm && tm->tmCharSet != DEFAULT_CHARSET && tm->tmCharSet != console->window->ui_charset) + return FALSE; /* fall through */ case 1: if ((lf->lfPitchAndFamily & 3) != FIXED_PITCH) return FALSE; + if (tm && (tm->tmItalic || tm->tmUnderlined || tm->tmStruckOut)) return FALSE; /* fall through */ case 2: if (lf->lfFaceName[0] == '@') return FALSE; @@ -849,13 +836,9 @@ static int CALLBACK enum_first_font_proc( const LOGFONTW *lf, const TEXTMETRICW if (font_type != TRUETYPE_FONTTYPE) return 1;
TRACE( "%s\n", debugstr_logfont( lf, font_type )); - - if (!validate_font( fc->console, lf, fc->pass )) - return 1; - TRACE( "%s\n", debugstr_textmetric( tm, font_type ));
- if (!validate_font_metric( fc->console, tm, fc->pass )) + if (!validate_font( fc->console, lf, tm, fc->pass )) return 1;
/* set default font size */ @@ -1589,7 +1572,7 @@ static int CALLBACK enum_list_font_proc( const LOGFONTW *lf, const TEXTMETRICW *
TRACE( "%s\n", debugstr_logfont( lf, font_type ));
- if (validate_font( di->console, lf, 0 )) + if (validate_font( di->console, lf, NULL, 0 )) SendDlgItemMessageW( di->dialog, IDC_FNT_LIST_FONT, LB_ADDSTRING, 0, (LPARAM)lf->lfFaceName );
return 1;
From: Piotr Caban piotr@codeweavers.com
Otherwise, on systems with only Wine provided fonts, we end up selecting first non-vertical font. In case I'm trying to fix it happend to be marlett (symbol) font. --- programs/conhost/window.c | 79 ++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 47 deletions(-)
diff --git a/programs/conhost/window.c b/programs/conhost/window.c index ba96729314d..a3bd8a324e4 100644 --- a/programs/conhost/window.c +++ b/programs/conhost/window.c @@ -799,59 +799,48 @@ static BOOL set_console_font( struct console *console, const LOGFONTW *logfont ) struct font_chooser { struct console *console; - int pass; - unsigned int font_height; - unsigned int font_width; - BOOL done; + unsigned int best_score; + LOGFONTW lf; };
/* check if the font family described in lf is usable as a font for the renderer */ -static BOOL validate_font( struct console *console, const LOGFONTW *lf, const TEXTMETRICW *tm, int pass ) +static BOOL validate_font( struct console *console, const LOGFONTW *lf, const TEXTMETRICW *tm, int *score ) { - switch (pass) /* we get increasingly lenient in later passes */ - { - case 0: - if (lf->lfCharSet != DEFAULT_CHARSET && lf->lfCharSet != console->window->ui_charset) - return FALSE; - if (tm && tm->tmCharSet != DEFAULT_CHARSET && tm->tmCharSet != console->window->ui_charset) - return FALSE; - /* fall through */ - case 1: - if ((lf->lfPitchAndFamily & 3) != FIXED_PITCH) return FALSE; - if (tm && (tm->tmItalic || tm->tmUnderlined || tm->tmStruckOut)) return FALSE; - /* fall through */ - case 2: - if (lf->lfFaceName[0] == '@') return FALSE; - break; - } - return TRUE; + int tmp; + + if (!score) score = &tmp; + + *score = 0x1; + if ((lf->lfCharSet == DEFAULT_CHARSET || lf->lfCharSet == console->window->ui_charset) + && (!tm || tm->tmCharSet == DEFAULT_CHARSET || tm->tmCharSet == console->window->ui_charset)) + *score |= 0x2; + if ((lf->lfPitchAndFamily & 3) == FIXED_PITCH + && (!tm || (!tm->tmItalic && !tm->tmUnderlined && !tm->tmStruckOut))) + *score |= 0x4; + if (lf->lfFaceName[0] != '@') + *score |= 0x8; + return *score == 0xf; }
static int CALLBACK enum_first_font_proc( const LOGFONTW *lf, const TEXTMETRICW *tm, DWORD font_type, LPARAM lparam ) { struct font_chooser *fc = (struct font_chooser *)lparam; - LOGFONTW mlf; + int score; + BOOL ret;
if (font_type != TRUETYPE_FONTTYPE) return 1;
TRACE( "%s\n", debugstr_logfont( lf, font_type )); TRACE( "%s\n", debugstr_textmetric( tm, font_type ));
- if (!validate_font( fc->console, lf, tm, fc->pass )) - return 1; - - /* set default font size */ - mlf = *lf; - mlf.lfHeight = fc->font_height; - mlf.lfWidth = fc->font_width; - - if (!set_console_font( fc->console, &mlf )) - return 1; - - fc->done = TRUE; - - return 0; + ret = validate_font( fc->console, lf, tm, &score ); + if (score > fc->best_score) + { + fc->best_score = score; + fc->lf = *lf; + } + return !ret; }
static void set_first_font( struct console *console, struct console_config *config ) @@ -865,18 +854,14 @@ static void set_first_font( struct console *console, struct console_config *conf lf.lfCharSet = DEFAULT_CHARSET; lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
+ memset( &fc, 0, sizeof(fc) ); fc.console = console; - fc.font_height = config->cell_height; - fc.font_width = config->cell_width; - fc.done = FALSE;
- for (fc.pass = 0; fc.pass <= 3; fc.pass++) - { - EnumFontFamiliesExW( console->window->mem_dc, &lf, enum_first_font_proc, (LPARAM)&fc, 0); - if (fc.done) break; - } + EnumFontFamiliesExW( console->window->mem_dc, &lf, enum_first_font_proc, (LPARAM)&fc, 0);
- if (fc.pass > 3) + fc.lf.lfHeight = config->cell_height; + fc.lf.lfWidth = config->cell_width; + if (!fc.best_score || !set_console_font( console, &fc.lf )) ERR("Unable to find a valid console font\n");
/* Update active configuration */ @@ -1572,7 +1557,7 @@ static int CALLBACK enum_list_font_proc( const LOGFONTW *lf, const TEXTMETRICW *
TRACE( "%s\n", debugstr_logfont( lf, font_type ));
- if (validate_font( di->console, lf, NULL, 0 )) + if (validate_font( di->console, lf, NULL, NULL )) SendDlgItemMessageW( di->dialog, IDC_FNT_LIST_FONT, LB_ADDSTRING, 0, (LPARAM)lf->lfFaceName );
return 1;
it looks like raster font pickup for first font in conhost has been dropped in 7a32bc9e32cf without any reason explained in ChangeLog (or the purpose of the change, which is unrelated to the expressed goal of the change)
I fail to see a reason for not supporting raster fonts in conhost (so I'd rather renable it rather that drop the raster code)
but that wouldn't fix the marlett.ttf pickup by default
OTOH, picking up the first font in one pass is a real improvement
but it looks like your last patch is changing the weights of the criteria (they are inverted from current logic) whereas this doesn't look fully correct (eg charset should have higher priority than fixed font)
would give a weight to FF_MODERN font family be sufficient? (looks like marlett has FF_DECORATIVE)
Sure, I can enable raster fonts instead of dropping all code related to it.
How is the last patch changing weights of the criteria? The code was already preferring fixed fonts over charset.
Giving weight to charset (as oppossed to completely ignoring it if there's no fixed width font) is already fixing the issue. While it might make sense to improve weight calculation there's probably little benefit doing so (most systems will have a font that matches all criteria anyway).