Akihiro Sagawa : gdi32: Ignore the lfHeight value when it exceeds the limit .
Alexandre Julliard
julliard at winehq.org
Wed May 8 15:48:20 CDT 2013
Module: wine
Branch: master
Commit: 8f8363ede62c74aa3369fa4c1e5f9da7eafb18a7
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8f8363ede62c74aa3369fa4c1e5f9da7eafb18a7
Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date: Wed May 8 21:11:20 2013 +0900
gdi32: Ignore the lfHeight value when it exceeds the limit.
---
dlls/gdi32/freetype.c | 11 ++++++++-
dlls/gdi32/tests/font.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 69 insertions(+), 1 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index c30a358..141238b 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -3983,6 +3983,7 @@ static LONG calc_ppem_for_height(FT_Face ft_face, LONG height)
TT_HoriHeader *pHori;
LONG ppem;
+ const LONG MAX_PPEM = (1 << 16) - 1;
pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
pHori = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_hhea);
@@ -4010,9 +4011,17 @@ static LONG calc_ppem_for_height(FT_Face ft_face, LONG height)
else
ppem = MulDiv(ft_face->units_per_EM, height,
pOS2->usWinAscent + pOS2->usWinDescent);
+ if(ppem > MAX_PPEM) {
+ WARN("Ignoring too large height %d, ppem %d\n", height, ppem);
+ ppem = 1;
+ }
}
- else
+ else if(height >= -MAX_PPEM)
ppem = -height;
+ else {
+ WARN("Ignoring too large height %d\n", height);
+ ppem = 1;
+ }
return ppem;
}
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index bc4e614..876b312 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -5028,6 +5028,64 @@ static void test_stock_fonts(void)
}
}
+static void test_max_height(void)
+{
+ HDC hdc;
+ LOGFONT lf;
+ HFONT hfont, hfont_old;
+ TEXTMETRICA tm1, tm;
+ BOOL r;
+ LONG invalid_height[] = { -65536, -123456, 123456 };
+ size_t i;
+
+ memset(&tm1, 0, sizeof(tm1));
+ memset(&lf, 0, sizeof(lf));
+ strcpy(lf.lfFaceName, "Tahoma");
+ lf.lfHeight = -1;
+
+ hdc = GetDC(NULL);
+
+ /* get 1 ppem value */
+ hfont = CreateFontIndirect(&lf);
+ hfont_old = SelectObject(hdc, hfont);
+ r = GetTextMetrics(hdc, &tm1);
+ ok(r, "GetTextMetrics failed\n");
+ ok(tm1.tmHeight > 0, "expected a positive value, got %d\n", tm1.tmHeight);
+ ok(tm1.tmAveCharWidth > 0, "expected a positive value, got %d\n", tm1.tmHeight);
+ DeleteObject(SelectObject(hdc, hfont_old));
+
+ /* test the largest value */
+ lf.lfHeight = -((1 << 16) - 1);
+ hfont = CreateFontIndirect(&lf);
+ hfont_old = SelectObject(hdc, hfont);
+ memset(&tm, 0, sizeof(tm));
+ r = GetTextMetrics(hdc, &tm);
+ ok(r, "GetTextMetrics failed\n");
+ ok(tm.tmHeight > tm1.tmHeight,
+ "expected greater than 1 ppem value (%d), got %d\n", tm1.tmHeight, tm.tmHeight);
+ ok(tm.tmAveCharWidth > tm1.tmAveCharWidth,
+ "expected greater than 1 ppem value (%d), got %d\n", tm1.tmAveCharWidth, tm.tmAveCharWidth);
+ DeleteObject(SelectObject(hdc, hfont_old));
+
+ /* test an invalid value */
+ for (i = 0; i < sizeof(invalid_height)/sizeof(invalid_height[0]); i++) {
+ lf.lfHeight = invalid_height[i];
+ hfont = CreateFontIndirect(&lf);
+ hfont_old = SelectObject(hdc, hfont);
+ memset(&tm, 0, sizeof(tm));
+ r = GetTextMetrics(hdc, &tm);
+ ok(r, "GetTextMetrics failed\n");
+ ok(tm.tmHeight == tm1.tmHeight,
+ "expected 1 ppem value (%d), got %d\n", tm1.tmHeight, tm.tmHeight);
+ ok(tm.tmAveCharWidth == tm1.tmAveCharWidth,
+ "expected 1 ppem value (%d), got %d\n", tm1.tmAveCharWidth, tm.tmAveCharWidth);
+ DeleteObject(SelectObject(hdc, hfont_old));
+ }
+
+ ReleaseDC(NULL, hdc);
+ return;
+}
+
START_TEST(font)
{
init();
@@ -5084,6 +5142,7 @@ START_TEST(font)
test_fullname();
test_fullname2();
test_east_asian_font_selection();
+ test_max_height();
/* These tests should be last test until RemoveFontResource
* is properly implemented.
More information about the wine-cvs
mailing list