
本来我就不用这个程序,这个东东不支持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. 只能显示,实际还是乱码