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