wine 跑 Source Insight【支持阅读 UTF-8 中文】

最新ubuntu/linux/开源新闻或者其它IT相关资讯
回复
头像
ptpt52
帖子: 717
注册时间: 2008-07-27 8:51
系统: Ubuntu/Windows
来自: 广西玉林|广东深圳
联系:

wine 跑 Source Insight【支持阅读 UTF-8 中文】

#1

帖子 ptpt52 » 2012-04-18 1:24

:em06

本来我就不用这个程序,这个东东不支持UTF-8编码的代码文本,所以阅读代码,如果是UTF-8编码的中文注释都显示为乱码!

本人突发奇想,通过修改Wine来让这个鸟东西能显示UTF-8编码的中文

调试发现它显示代码调用的是Windows 的API ExtTextOut(),因此,我特地修改了wine对应的API代码。

ExtTextOut() 这个API的作用就是将一段文字输出
我在这个函数加了个钩子,识别出文本是UTF-8编码的,就转化为宽字符输出,这样就能正常显示中文了

这是给Wine的补丁

代码: 全选

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index f5c44d8..a67dd76 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -1979,6 +1979,78 @@ BOOL nulldrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *rect
     return TRUE;
 }

+static int IsUTF8(const void* pBuffer, int size)
+{
+    int IsUTF8 = 1;
+    unsigned char* start = (unsigned char*)pBuffer;
+    unsigned char* end = (unsigned char*)pBuffer + size;
+
+    while (start < end)
+    {
+        /* (10000000): 值小于0x80的为ASCII字符 */
+        if (*start < 0x80)
+        {
+            start++;
+        }
+        /* (11000000): 值介于0x80与0xC0之间的为无效UTF-8字符 */
+        else if (*start < (0xC0))
+        {
+            IsUTF8 = 0;
+            break;
+        }
+        /* (11100000): 此范围内为2字节UTF-8字符 */
+        else if (*start < (0xE0))
+        {
+            if (start >= end - 1)
+                break;
+            if ((start[1] & (0xC0)) != 0x80)
+            {
+                IsUTF8 = 0;
+                break;
+            }
+            start += 2;
+        }
+        /* (11110000): 此范围内为3字节UTF-8字符 */
+        else if (*start < (0xF0))
+        {
+            if (start >= end - 2)
+                break;
+            if ((start[1] & (0xC0)) != 0x80 || (start[2] & (0xC0)) != 0x80)
+            {
+                IsUTF8 = 0;
+                break;
+            }
+            start += 3;
+        }
+        else
+        {
+            IsUTF8 = 0;
+            break;
+        }
+    }
+    return IsUTF8;
+}
+
+static WCHAR* AtoW( const char* p, INT count, UINT *olen)
+{
+    WCHAR* buffer;
+    INT len;
+
+    if (!IsUTF8(p, count))
+    {
+        return NULL;
+    }
+
+    len = MultiByteToWideChar( CP_UTF8, 0, p, count, NULL, 0 );
+    if (!len)
+    {
+        return NULL;
+    }
+
+    buffer = malloc( len * sizeof(WCHAR) );
+    *olen = MultiByteToWideChar( CP_UTF8, 0, p, count, buffer, len );
+    return buffer;
+}

 /***********************************************************************
  *           ExtTextOutA    (GDI32.@)
@@ -1993,6 +2065,15 @@ BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
     LPWSTR p;
     BOOL ret;
     LPINT lpDxW = NULL;
+    LPCWSTR wstr = NULL;
+
+    wstr = (LPCSTR)AtoW(str, count, &count);
+    if (wstr)
+    {
+        ret = ExtTextOutW( hdc, x, y, flags, lprect, (LPCWSTR)wstr, count, lpDx );
+        free((void *)wstr);
+        return ret;
+    }

     if (flags & ETO_GLYPH_INDEX)
         return ExtTextOutW( hdc, x, y, flags, lprect, (LPCWSTR)str, count, lpDx );
存在问题:
1. 转化后的文本和原来的文本很可能不等长,故现实的中文估计会“看起来”多几个空格
2. 只能显示,实际还是乱码
走过去了也便有了路
http://www.ptpt52.com/
qq-yxf
帖子: 10
注册时间: 2009-04-16 14:53

Re: wine 跑 Source Insight【支持阅读 UTF-8 中文】

#2

帖子 qq-yxf » 2012-04-18 11:24

消灭0回复
头像
qy117121
论坛版主
帖子: 50587
注册时间: 2007-12-14 13:40
系统: Winbuntu
来自: 志虚国乌由市
联系:

Re: wine 跑 Source Insight【支持阅读 UTF-8 中文】

#3

帖子 qy117121 » 2012-04-18 11:27

为什么发新闻区?
渠月 · QY   
本人只会灌水,不负责回答问题
无聊可以点一下→ http://u.nu/ubuntu

邮箱 [email protected]
回复