Akihiro Sagawa : gdi32: Fix text metrics used in EnumFonts families.
Alexandre Julliard
julliard at winehq.org
Wed Apr 7 15:48:31 CDT 2021
Module: wine
Branch: master
Commit: 837c4f4b87b4a810e57d7e50af2023b38d03b5cd
URL: https://source.winehq.org/git/wine.git/?a=commit;h=837c4f4b87b4a810e57d7e50af2023b38d03b5cd
Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date: Tue Apr 6 21:34:21 2021 +0900
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 at gmail.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/gdi32/font.c | 36 ++++++++++++++++++++++++++++++++++--
dlls/gdi32/tests/font.c | 19 +++++++++++++++++++
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index de50bf0de42..fd03580a754 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -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 ))
{
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index d5ae526d536..ed0acf8243a 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -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);
More information about the wine-cvs
mailing list