gdi32: Fix text metrics used in EnumFonts families.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50818
Signed-off-by: Akihiro Sagawa <sagawa.aki@gmail.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Akihiro Sagawa 2021-04-06 21:34:21 +09:00 committed by Alexandre Julliard
parent 8f6f1c8f7a
commit 837c4f4b87
2 changed files with 53 additions and 2 deletions

View File

@ -2685,7 +2685,9 @@ static UINT get_font_type( const NEWTEXTMETRICEXW *ntm )
static BOOL get_face_enum_data( struct gdi_font_face *face, ENUMLOGFONTEXW *elf, NEWTEXTMETRICEXW *ntm )
{
struct gdi_font *font;
LOGFONTW lf = { .lfHeight = 100 };
LOGFONTW lf = { .lfHeight = -4096 /* preferable EM Square size */ };
if (!face->scalable) lf.lfHeight = 0;
if (!(font = create_gdi_font( face, NULL, &lf ))) return FALSE;
@ -2695,12 +2697,42 @@ static BOOL get_face_enum_data( struct gdi_font_face *face, ENUMLOGFONTEXW *elf,
return FALSE;
}
if (font->scalable && -lf.lfHeight % font->otm.otmEMSquare != 0)
{
/* reload with the original EM Square size */
lf.lfHeight = -font->otm.otmEMSquare;
free_gdi_font( font );
if (!(font = create_gdi_font( face, NULL, &lf ))) return FALSE;
if (!font_funcs->load_font( font ))
{
free_gdi_font( font );
return FALSE;
}
}
if (font_funcs->set_outline_text_metrics( font ))
{
memcpy( &ntm->ntmTm, &font->otm.otmTextMetrics, sizeof(TEXTMETRICW) );
static const DWORD ntm_ppem = 32;
#define TM font->otm.otmTextMetrics
#define SCALE_NTM(value) (MulDiv( ntm->ntmTm.tmHeight, (value), TM.tmHeight ))
ntm->ntmTm.tmHeight = MulDiv( ntm_ppem, font->ntmCellHeight, font->otm.otmEMSquare );
ntm->ntmTm.tmAscent = SCALE_NTM( TM.tmAscent );
ntm->ntmTm.tmDescent = ntm->ntmTm.tmHeight - ntm->ntmTm.tmAscent;
ntm->ntmTm.tmInternalLeading = SCALE_NTM( TM.tmInternalLeading );
ntm->ntmTm.tmExternalLeading = SCALE_NTM( TM.tmExternalLeading );
ntm->ntmTm.tmAveCharWidth = SCALE_NTM( TM.tmAveCharWidth );
ntm->ntmTm.tmMaxCharWidth = SCALE_NTM( TM.tmMaxCharWidth );
memcpy((char *)&ntm->ntmTm + offsetof( TEXTMETRICW, tmWeight ),
(const char *)&TM + offsetof( TEXTMETRICW, tmWeight ),
sizeof(TEXTMETRICW) - offsetof( TEXTMETRICW, tmWeight ));
ntm->ntmTm.ntmSizeEM = font->otm.otmEMSquare;
ntm->ntmTm.ntmCellHeight = font->ntmCellHeight;
ntm->ntmTm.ntmAvgWidth = font->ntmAvgWidth;
#undef SCALE_NTM
#undef TM
}
else if (font_funcs->set_bitmap_text_metrics( font ))
{

View File

@ -3923,6 +3923,25 @@ static void test_text_metrics(const LOGFONTA *lf, const NEWTEXTMETRICA *ntm)
ok(ntm->ntmCellHeight == cell_height, "%s: ntmCellHeight %u != %u, os2.usWinAscent/os2.usWinDescent %u/%u\n",
font_name, ntm->ntmCellHeight, cell_height, ascent, descent);
/* NEWTEXTMETRIC's scaling method is different from TEXTMETRIC's */
#define SCALE_NTM(value) (MulDiv(ntm->tmHeight, (value), cell_height))
size = MulDiv(32, ntm->ntmCellHeight, ntm->ntmSizeEM);
ok(ntm->tmHeight == size, "%s: ntm->tmHeight %d != %d (%u/%u)\n",
font_name, ntm->tmHeight, size, ntm->ntmCellHeight, ntm->ntmSizeEM);
size = SCALE_NTM(ntm->ntmAvgWidth);
ok(ntm->tmAveCharWidth == size, "%s: ntm->tmAveCharWidth %d != %d (%u/%u,%d)\n",
font_name, ntm->tmAveCharWidth, size, ntm->ntmAvgWidth, cell_height, ntm->tmHeight);
size = SCALE_NTM(ascent);
ok(ntm->tmAscent == size, "%s: ntm->tmAscent %d != %d (%u/%u,%d)\n",
font_name, ntm->tmAscent, size, ascent, cell_height, ntm->tmHeight);
size = ntm->tmHeight - ntm->tmAscent;
ok(ntm->tmDescent == size, "%s: ntm->tmDescent %d != %d (%u/%u,%d)\n",
font_name, ntm->tmDescent, size, descent, cell_height, ntm->tmHeight);
size = SCALE_NTM(cell_height - ntm->ntmSizeEM);
ok(ntm->tmInternalLeading == size, "%s: ntm->tmInternalLeading %d != %d (%u/%u,%d)\n",
font_name, ntm->tmInternalLeading, size, cell_height - ntm->ntmSizeEM, cell_height, ntm->tmHeight);
#undef SCALE_NTM
version = GET_BE_WORD(tt_os2.version);
os2_first_char = GET_BE_WORD(tt_os2.usFirstCharIndex);