Huw Davies : gdi32: The special handling of the character codes metrics for symbol fonts should be based on the presence of the MS symbol charmap rather than whether the font is enumerated as SYMBOL_CHARSET .

Alexandre Julliard julliard at winehq.org
Wed Feb 18 10:15:30 CST 2009


Module: wine
Branch: master
Commit: 2c6ddb8030cd8e90a43c8291c7720229d3354582
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2c6ddb8030cd8e90a43c8291c7720229d3354582

Author: Huw Davies <huw at codeweavers.com>
Date:   Wed Feb 18 10:33:12 2009 +0000

gdi32: The special handling of the character codes metrics for symbol fonts should be based on the presence of the MS symbol charmap rather than whether the font is enumerated as SYMBOL_CHARSET.

---

 dlls/gdi32/freetype.c   |   14 +++++++++++++-
 dlls/gdi32/tests/font.c |   46 ++++++++++++++++++++++++++++++++++++----------
 2 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 409c92f..57bb40b 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -5257,6 +5257,17 @@ BOOL WineEngGetTextMetrics(GdiFont *font, LPTEXTMETRICW ptm)
     return TRUE;
 }
 
+static BOOL face_has_symbol_charmap(FT_Face ft_face)
+{
+    int i;
+
+    for(i = 0; i < ft_face->num_charmaps; i++)
+    {
+        if(ft_face->charmaps[i]->encoding == FT_ENCODING_MS_SYMBOL)
+            return TRUE;
+    }
+    return FALSE;
+}
 
 /*************************************************************
  * WineEngGetOutlineTextMetrics
@@ -5396,7 +5407,8 @@ UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
     /* It appears that for fonts with SYMBOL_CHARSET Windows always sets
      * symbol range to 0 - f0ff
      */
-    if (font->charset == SYMBOL_CHARSET || (pOS2->usFirstCharIndex >= 0xf000 && pOS2->usFirstCharIndex < 0xf100))
+
+    if (face_has_symbol_charmap(ft_face) || (pOS2->usFirstCharIndex >= 0xf000 && pOS2->usFirstCharIndex < 0xf100))
     {
         TM.tmFirstChar = 0;
         switch(GetACP())
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 8c0cc67..bc9d64c 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -2182,7 +2182,14 @@ static void *get_cmap(cmap_header *header, USHORT plat_id, USHORT enc_id)
     return NULL;
 }
 
-static BOOL get_first_last_from_cmap(HDC hdc, DWORD *first, DWORD *last)
+typedef enum
+{
+    cmap_none,
+    cmap_ms_unicode,
+    cmap_ms_symbol
+} cmap_type;
+
+static BOOL get_first_last_from_cmap(HDC hdc, DWORD *first, DWORD *last, cmap_type *cmap_type)
 {
     LONG size, ret;
     cmap_header *header;
@@ -2200,8 +2207,18 @@ static BOOL get_first_last_from_cmap(HDC hdc, DWORD *first, DWORD *last)
     ok(GET_BE_WORD(header->version) == 0, "got cmap version %d\n", GET_BE_WORD(header->version));
 
     cmap = get_cmap(header, 3, 1);
-    if(!cmap) cmap = get_cmap(header, 3, 0);
-    if(!cmap) goto end;
+    if(cmap)
+        *cmap_type = cmap_ms_unicode;
+    else
+    {
+        cmap = get_cmap(header, 3, 0);
+        if(cmap) *cmap_type = cmap_ms_symbol;
+    }
+    if(!cmap)
+    {
+        *cmap_type = cmap_none;
+        goto end;
+    }
 
     format = GET_BE_WORD(*(WORD *)cmap);
     switch(format)
@@ -2231,6 +2248,7 @@ static void test_text_metrics(const LOGFONTA *lf)
     LONG size, ret;
     const char *font_name = lf->lfFaceName;
     DWORD cmap_first = 0, cmap_last = 0;
+    cmap_type cmap_type;
 
     hdc = GetDC(0);
 
@@ -2260,7 +2278,7 @@ static void test_text_metrics(const LOGFONTA *lf)
     ret = GetTextMetricsA(hdc, &tmA);
     ok(ret, "GetTextMetricsA error %u\n", GetLastError());
 
-    if(!get_first_last_from_cmap(hdc, &cmap_first, &cmap_last))
+    if(!get_first_last_from_cmap(hdc, &cmap_first, &cmap_last, &cmap_type))
     {
         skip("Unable to retrieve first and last glyphs from cmap\n");
     }
@@ -2283,7 +2301,7 @@ static void test_text_metrics(const LOGFONTA *lf)
               font_name, lf->lfCharSet, os2_first_char, os2_last_char, cmap_first, cmap_last,
               default_char, break_char, version, (LPCSTR)&tt_os2.achVendID);
 
-        if (lf->lfCharSet == SYMBOL_CHARSET || (cmap_first >= 0xf000 && cmap_first < 0xf100))
+        if (cmap_type == cmap_ms_symbol || (cmap_first >= 0xf000 && cmap_first < 0xf100))
         {
             expect_first_W    = 0;
             switch(GetACP())
@@ -2316,9 +2334,15 @@ static void test_text_metrics(const LOGFONTA *lf)
         expect_break_A    = expect_break_W;
         expect_default_A  = expect_default_W;
 
-        ok(tmA.tmFirstChar == expect_first_A ||
-           tmA.tmFirstChar == expect_first_A + 1 /* win9x */,
-           "A: tmFirstChar for %s got %02x expected %02x\n", font_name, tmA.tmFirstChar, expect_first_A);
+        /* Wine currently uses SYMBOL_CHARSET to identify whether the ANSI metrics need special handling */
+        if(cmap_type != cmap_ms_symbol && tmA.tmCharSet == SYMBOL_CHARSET && expect_first_A != 0x1e)
+            todo_wine ok(tmA.tmFirstChar == expect_first_A ||
+                         tmA.tmFirstChar == expect_first_A + 1 /* win9x */,
+                         "A: tmFirstChar for %s got %02x expected %02x\n", font_name, tmA.tmFirstChar, expect_first_A);
+        else
+            ok(tmA.tmFirstChar == expect_first_A ||
+               tmA.tmFirstChar == expect_first_A + 1 /* win9x */,
+               "A: tmFirstChar for %s got %02x expected %02x\n", font_name, tmA.tmFirstChar, expect_first_A);
         ok(tmA.tmLastChar == expect_last_A ||
            tmA.tmLastChar == 0xff /* win9x */,
            "A: tmLastChar for %s got %02x expected %02x\n", font_name, tmA.tmLastChar, expect_last_A);
@@ -2334,14 +2358,16 @@ static void test_text_metrics(const LOGFONTA *lf)
            "GetTextMetricsW error %u\n", GetLastError());
         if (ret)
         {
-            if(cmap_first != os2_first_char && tmW.tmCharSet != SYMBOL_CHARSET)
+            /* Wine uses the os2 first char */
+            if(cmap_first != os2_first_char && cmap_type != cmap_ms_symbol)
                 todo_wine ok(tmW.tmFirstChar == expect_first_W, "W: tmFirstChar for %s got %02x expected %02x\n",
                              font_name, tmW.tmFirstChar, expect_first_W);
             else
                 ok(tmW.tmFirstChar == expect_first_W, "W: tmFirstChar for %s got %02x expected %02x\n",
                    font_name, tmW.tmFirstChar, expect_first_W);
 
-            if(expect_last_W != os2_last_char && tmW.tmCharSet != SYMBOL_CHARSET)
+            /* Wine uses the os2 last char */
+            if(expect_last_W != os2_last_char && cmap_type != cmap_ms_symbol)
                 todo_wine ok(tmW.tmLastChar == expect_last_W, "W: tmLastChar for %s got %02x expected %02x\n",
                              font_name, tmW.tmLastChar, expect_last_W);
             else




More information about the wine-cvs mailing list