[PATCH] gdi32/freetype: Handle fonts with broken usWinDescent values
Nikolay Sivov
nsivov at codeweavers.com
Sun Sep 27 14:52:56 CDT 2015
---
-------------- next part --------------
From 48b9b7ab9943da9f5ae7b2c12321c146b67258e9 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sun, 27 Sep 2015 22:47:38 +0300
Subject: [PATCH] gdi32/freetype: Handle fonts with broken usWinDescent values
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/gdi32/freetype.c | 20 +++++++++++++++-----
dlls/gdi32/tests/font.c | 2 +-
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 60ffc45..8e89cc5 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -4185,6 +4185,13 @@ BOOL WineEngInit(void)
return TRUE;
}
+/* Some fonts have large usWinDescent values, as a result of storing signed short
+ in unsigned field. That's probably caused by sTypoDescent vs usWinDescent confusion in
+ some font generation tools. */
+static inline USHORT get_fixed_windescent(USHORT windescent)
+{
+ return abs((SHORT)windescent);
+}
static LONG calc_ppem_for_height(FT_Face ft_face, LONG height)
{
@@ -4214,12 +4221,13 @@ static LONG calc_ppem_for_height(FT_Face ft_face, LONG height)
*/
if(height > 0) {
- if(pOS2->usWinAscent + pOS2->usWinDescent == 0)
+ USHORT windescent = get_fixed_windescent(pOS2->usWinDescent);
+ if(pOS2->usWinAscent + windescent == 0)
ppem = MulDiv(ft_face->units_per_EM, height,
pHori->Ascender - pHori->Descender);
else
ppem = MulDiv(ft_face->units_per_EM, height,
- pOS2->usWinAscent + pOS2->usWinDescent);
+ pOS2->usWinAscent + windescent);
if(ppem > MAX_PPEM) {
WARN("Ignoring too large height %d, ppem %d\n", height, ppem);
ppem = 1;
@@ -7340,6 +7348,7 @@ static BOOL get_outline_text_metrics(GdiFont *font)
WCHAR *family_nameW, *style_nameW, *face_nameW, *full_nameW;
char *cp;
INT ascent, descent;
+ USHORT windescent;
TRACE("font=%p\n", font);
@@ -7408,7 +7417,7 @@ static BOOL get_outline_text_metrics(GdiFont *font)
pPost = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_post); /* we can live with this failing */
- TRACE("OS/2 winA = %d winD = %d typoA = %d typoD = %d typoLG = %d avgW %d FT_Face a = %d, d = %d, h = %d: HORZ a = %d, d = %d lg = %d maxY = %ld minY = %ld\n",
+ TRACE("OS/2 winA = %u winD = %u typoA = %d typoD = %d typoLG = %d avgW %d FT_Face a = %d, d = %d, h = %d: HORZ a = %d, d = %d lg = %d maxY = %ld minY = %ld\n",
pOS2->usWinAscent, pOS2->usWinDescent,
pOS2->sTypoAscender, pOS2->sTypoDescender, pOS2->sTypoLineGap,
pOS2->xAvgCharWidth,
@@ -7421,12 +7430,13 @@ static BOOL get_outline_text_metrics(GdiFont *font)
#define TM font->potm->otmTextMetrics
- if(pOS2->usWinAscent + pOS2->usWinDescent == 0) {
+ windescent = get_fixed_windescent(pOS2->usWinDescent);
+ if(pOS2->usWinAscent + windescent == 0) {
ascent = pHori->Ascender;
descent = -pHori->Descender;
} else {
ascent = pOS2->usWinAscent;
- descent = pOS2->usWinDescent;
+ descent = windescent;
}
font->ntmCellHeight = ascent + descent;
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index cdc7726..e04ee1e 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -3718,7 +3718,7 @@ static void test_text_metrics(const LOGFONTA *lf, const NEWTEXTMETRICA *ntm)
TEXTMETRICW tmW;
ascent = GET_BE_WORD(tt_os2.usWinAscent);
- descent = GET_BE_WORD(tt_os2.usWinDescent);
+ descent = abs((SHORT)GET_BE_WORD(tt_os2.usWinDescent));
cell_height = ascent + descent;
ok(ntm->ntmCellHeight == cell_height, "%s: ntmCellHeight %u != %u, os2.usWinAscent/os2.usWinDescent %u/%u\n",
font_name, ntm->ntmCellHeight, cell_height, ascent, descent);
--
2.5.3
More information about the wine-patches
mailing list