gdi32: Prevent font glyphs from accidentally violating maximum, ascent.

Sam Edwards cfsworks at gmail.com
Sat Jun 23 00:04:49 CDT 2012


Sometimes Freetype likes to return glyphs with a glyph origin 
y-coordinate greater than the text metrics' ascent.
This causes memory corruption in certain programs (e.g. Source games) 
that assume that glyph y-coordinates will never exceed the ascent.
While this is probably a bug in Freetype, it would be best to add a 
sanity check to Wine to correct this problem so it doesn't go through 
all the way to the programs.
This resolves bugs #7698 and #12044.
---
  dlls/gdi32/freetype.c |   10 ++++++++--
  1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 35ba2c9..2196b3a 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -5686,6 +5686,7 @@ static DWORD get_glyph_outline(GdiFont 
*incoming_font, UINT glyph, UINT format,
      FT_Bitmap ft_bitmap;
      FT_Error err;
      INT left, right, top = 0, bottom = 0, adv, lsb, bbx;
+    TEXTMETRICW tm;
      FT_Angle angle = 0;
      FT_Int load_flags = FT_LOAD_DEFAULT | 
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
      double widthRatio = 1.0;
@@ -5743,8 +5744,6 @@ static DWORD get_glyph_outline(GdiFont 
*incoming_font, UINT glyph, UINT format,
      /* Scaling factor */
      if (font->aveWidth)
      {
-        TEXTMETRICW tm;
-
          get_text_metrics(font, &tm);

          widthRatio = (double)font->aveWidth;
@@ -5898,6 +5897,13 @@ static DWORD get_glyph_outline(GdiFont 
*incoming_font, UINT glyph, UINT format,
            wine_dbgstr_point(&lpgm->gmptGlyphOrigin),
            lpgm->gmCellIncX, lpgm->gmCellIncY);

+    get_text_metrics(font, &tm);
+    if(lpgm->gmptGlyphOrigin.y > tm.tmAscent) {
+        WARN("gmptGlyphOrigin.y (= %d) exceeded tmAscent (= %d)\n",
+             lpgm->gmptGlyphOrigin.y, tm.tmAscent);
+        lpgm->gmptGlyphOrigin.y = tm.tmAscent;
+    }
+
      if ((format == GGO_METRICS || format == GGO_BITMAP || format ==  
WINE_GGO_GRAY16_BITMAP) &&
          is_identity_MAT2(lpmat)) /* don't cache custom transforms */
      {
-- 
1.7.9.5




More information about the wine-patches mailing list