Alexandre Julliard : win32u: Support UTF-8 as the default Ansi codepage.

Alexandre Julliard julliard at winehq.org
Tue Apr 12 15:35:15 CDT 2022


Module: wine
Branch: master
Commit: 5cc2d4adc5d183ed322b48bf3a7ec8359ef2abd5
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5cc2d4adc5d183ed322b48bf3a7ec8359ef2abd5

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Apr 12 10:17:13 2022 +0200

win32u: Support UTF-8 as the default Ansi codepage.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/win32u/font.c   | 44 +++++++++++++++++++++++++++++++++++++++-----
 dlls/win32u/gdiobj.c | 40 ++++++++++++----------------------------
 2 files changed, 51 insertions(+), 33 deletions(-)

diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c
index 86786b160fb..c5a5a5806ba 100644
--- a/dlls/win32u/font.c
+++ b/dlls/win32u/font.c
@@ -199,6 +199,7 @@ static struct font_gamma_ramp font_gamma_ramp;
 static void add_face_to_cache( struct gdi_font_face *face );
 static void remove_face_from_cache( struct gdi_font_face *face );
 
+static CPTABLEINFO utf8_cp;
 static CPTABLEINFO oem_cp;
 CPTABLEINFO ansi_cp = { 0 };
 
@@ -370,6 +371,11 @@ static const struct nls_update_font_list
       "coure.fon", "serife.fon", "smalle.fon", "sserife.fon", "sseriff.fon",
       "Tahoma","Times New Roman"  /* FIXME unverified */
     },
+    /* UTF-8 */
+    { CP_UTF8, CP_UTF8, "vga850.fon", "vgafix.fon", "vgasys.fon",
+      "coure.fon", "serife.fon", "smalle.fon", "sserife.fon", "sseriff.fon",
+      "Tahoma", "Times New Roman"  /* FIXME unverified */
+    },
     /* Eastern Europe */
     { 1250, 852, "vga852.fon", "vgafixe.fon", "vgasyse.fon",
       "couree.fon", "serifee.fon", "smallee.fon", "sserifee.fon", "sseriffe.fon",
@@ -2717,6 +2723,7 @@ static void update_font_system_link_info(void)
 
 static void update_codepage( UINT screen_dpi )
 {
+    USHORT utf8_hdr[2] = { 0, CP_UTF8 };
     char value_buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[40 * sizeof(WCHAR)])];
     KEY_VALUE_PARTIAL_INFORMATION *info = (void *)value_buffer;
     char cpbuf[40];
@@ -2733,8 +2740,15 @@ static void update_codepage( UINT screen_dpi )
     if (size == sizeof(DWORD) && info->Type == REG_DWORD)
         font_dpi = *(DWORD *)info->Data;
 
-    RtlInitCodePageTable( NtCurrentTeb()->Peb->AnsiCodePageData, &ansi_cp );
-    RtlInitCodePageTable( NtCurrentTeb()->Peb->OemCodePageData, &oem_cp );
+    RtlInitCodePageTable( utf8_hdr, &utf8_cp );
+    if (NtCurrentTeb()->Peb->AnsiCodePageData)
+        RtlInitCodePageTable( NtCurrentTeb()->Peb->AnsiCodePageData, &ansi_cp );
+    else
+        ansi_cp = utf8_cp;
+    if (NtCurrentTeb()->Peb->OemCodePageData)
+        RtlInitCodePageTable( NtCurrentTeb()->Peb->OemCodePageData, &oem_cp );
+    else
+        oem_cp = utf8_cp;
     sprintf( cpbuf, "%u,%u", ansi_cp.CodePage, oem_cp.CodePage );
     asciiz_to_unicode( cpbufW, cpbuf );
 
@@ -3210,6 +3224,7 @@ CPTABLEINFO *get_cptable( WORD cp )
     SIZE_T size;
 
     if (cp == CP_ACP) return &ansi_cp;
+    if (cp == CP_UTF8) return &utf8_cp;
 
     for (i = 0; i < ARRAY_SIZE(tables) && tables[i].CodePage; i++)
         if (tables[i].CodePage == cp) return &tables[i];
@@ -3227,7 +3242,11 @@ DWORD win32u_wctomb( CPTABLEINFO *info, char *dst, DWORD dstlen, const WCHAR *sr
 {
     DWORD ret;
 
-    RtlUnicodeToCustomCPN( info, dst, dstlen, &ret, src, srclen * sizeof(WCHAR) );
+    if (info->CodePage == CP_UTF8)
+        RtlUnicodeToUTF8N( dst, dstlen, &ret, src, srclen * sizeof(WCHAR) );
+    else
+        RtlUnicodeToCustomCPN( info, dst, dstlen, &ret, src, srclen * sizeof(WCHAR) );
+
     return ret;
 }
 
@@ -3235,7 +3254,11 @@ DWORD win32u_mbtowc( CPTABLEINFO *info, WCHAR *dst, DWORD dstlen, const char *sr
 {
     DWORD ret;
 
-    RtlCustomCPToUnicodeN( info, dst, dstlen * sizeof(WCHAR), &ret, src, srclen );
+    if (info->CodePage == CP_UTF8)
+        RtlUTF8ToUnicodeN( dst, dstlen * sizeof(WCHAR), &ret, src, srclen );
+    else
+        RtlCustomCPToUnicodeN( info, dst, dstlen * sizeof(WCHAR), &ret, src, srclen );
+
     return ret / sizeof(WCHAR);
 }
 
@@ -3245,7 +3268,18 @@ static BOOL wc_to_index( UINT cp, WCHAR wc, unsigned char *dst, BOOL allow_defau
 
     if (!(info = get_cptable( cp ))) return FALSE;
 
-    if (info->DBCSCodePage)
+    if (info->CodePage == CP_UTF8)
+    {
+        if (wc < 0x80)
+        {
+            *dst = wc;
+            return TRUE;
+        }
+        if (!allow_default) return FALSE;
+        *dst = info->DefaultChar;
+        return TRUE;
+    }
+    else if (info->DBCSCodePage)
     {
         WCHAR *uni2cp = info->WideCharTable;
         if (uni2cp[wc] & 0xff00) return FALSE;
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c
index 78fab0189c9..d71807c8c04 100644
--- a/dlls/win32u/gdiobj.c
+++ b/dlls/win32u/gdiobj.c
@@ -464,38 +464,22 @@ void make_gdi_object_system( HGDIOBJ handle, BOOL set)
 /******************************************************************************
  *      get_default_fonts
  */
-static const struct DefaultFontInfo* get_default_fonts(UINT charset)
+static const struct DefaultFontInfo* get_default_fonts(void)
 {
-        unsigned int n;
+    unsigned int n;
+    CHARSETINFO csi;
 
-        for(n = 0; n < ARRAY_SIZE( default_fonts ); n++)
-        {
-                if ( default_fonts[n].charset == charset )
-                        return &default_fonts[n];
-        }
-
-        FIXME( "unhandled charset 0x%08x - use ANSI_CHARSET for default stock objects\n", charset );
-        return &default_fonts[0];
-}
-
-
-/******************************************************************************
- *      get_default_charset    (internal)
- *
- * get the language-dependent charset that can handle CP_ACP correctly.
- */
-static UINT get_default_charset( void )
-{
-    CHARSETINFO     csi;
+    if (ansi_cp.CodePage == CP_UTF8) return &default_fonts[0];
 
     csi.ciCharset = ANSI_CHARSET;
-    if ( !translate_charset_info( ULongToPtr(ansi_cp.CodePage), &csi, TCI_SRCCODEPAGE ) )
-    {
-        FIXME( "unhandled codepage %u - use ANSI_CHARSET for default stock objects\n", ansi_cp.CodePage );
-        return ANSI_CHARSET;
-    }
+    translate_charset_info( ULongToPtr(ansi_cp.CodePage), &csi, TCI_SRCCODEPAGE );
+
+    for(n = 0; n < ARRAY_SIZE( default_fonts ); n++)
+        if ( default_fonts[n].charset == csi.ciCharset )
+            return &default_fonts[n];
 
-    return csi.ciCharset;
+    FIXME( "unhandled charset 0x%08x - use ANSI_CHARSET for default stock objects\n", csi.ciCharset );
+    return &default_fonts[0];
 }
 
 
@@ -654,7 +638,7 @@ static void init_stock_objects( unsigned int dpi )
     create_font( &AnsiVarFont );
 
     /* language-dependent stock fonts */
-    deffonts = get_default_fonts(get_default_charset());
+    deffonts = get_default_fonts();
     create_font( &deffonts->SystemFont );
     create_font( &deffonts->DeviceDefaultFont );
 




More information about the wine-cvs mailing list