• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 96  文章 - 255  trackbacks - 0
            <2008年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            E-mail:zbln426@163.com QQ:85132383 長期尋找對戰略游戲感興趣的合作伙伴。

            常用鏈接

            留言簿(21)

            隨筆分類

            隨筆檔案

            SDL相關網站

            我的個人網頁

            我的小游戲

            資源下載

            搜索

            •  

            積分與排名

            • 積分 - 492144
            • 排名 - 38

            最新評論

            閱讀排行榜

            評論排行榜

            作者:龍飛

            4.1:為什么iconv不能完全正確的轉換Unicode?

                    我不是先知,教程里面是整理過的思路和邏輯順序,在我研究這個問題的時候,頭緒遠遠比教程里面亂得多。我完全是從Wesnoth的源代碼去分析問題的,所以,為什么會扯上UTF-8和FriBidi,那也是因為在源代碼中找到了線索。
                    iconv不能完全正確的獲得Unicode,也就是我們剛才遇到的純漢字轉換沒問題,而有英文就不行了。我并不清楚這是win32下的問題,還是在Linux下也這樣,我也不清楚具體的算法和問題的根本原因,我只是通過試驗得到一個算是表面原因的結論:我們知道,GB2312和Unicode漢字都使用2個字節(在UTF-8中是3個字節),英文和數字等用1個字節。iconv在得到兩個字節(unsigned char即一個字節大小)代碼的時候可以正確的將GB2312轉化為Unicode(或者UTF-8),但是只有1個字節的時候則在轉化Unicode的時候終止了,幸運的是,如果是轉化為UTF-8則可以正確的進行,并且也轉化為1個字節的UTF-8(只限于英文,數字等)。
                    所以,我們可以先通過iconv將原來的GB2312轉化為UTF-8——漢字用3個字節(3個單位的unsigned char),英文、數字和基本符號用1個字節(1個單位的unsigned char)。然后,我們需要一個函數,將這種形式的UTF-8轉換為SDL所需要的Uint16的Unicode。什么樣的函數可以實現這種轉換呢?

            4.2:其它編碼與Unicode之間的雙向轉換,GNU FriBidi
            http://fribidi.freedesktop.org/wiki/
                    FriBidi是一個致力于Unicode編碼與其它編碼相互轉換的開源項目,到目前為止,還是一個尚未完成的項目。我在研究Wesnoth源代碼的時候看到這樣的函數:fribidi_utf8_to_unicode(),所以,我想在這個函數中可能應該包含UTF-8到Unicode的算法——希望不要太復雜。在FriBidi項目中找到這個函數,它在文件fribidi_char_sets_utf8.c下面:

            int
            fribidi_utf8_to_unicode (
            char *s, int len, FriBidiChar *us)
            /* warning: the length of input string may exceed the length of the output */
            {
              
            int length;
              
            char *= s;

              length 
            = 0;
              
            while (s - t < len)
                {
                  
            if (*(unsigned char *) s <= 0x7f)    /* one byte */
                {
                  
            *us++ = *s++;        /* expand with 0s */
                }
                  
            else if (*(unsigned char *) s <= 0xdf)    /* 2 byte */
                {
                  
            *us++ =
                    ((
            *(unsigned char *) s & 0x1f<< 6+
                    ((
            *(unsigned char *) (s + 1)) & 0x3f);
                  s 
            += 2;
                }
                  
            else            /* 3 byte */
                {
                  
            *us++ =
                    ((
            int) (*(unsigned char *) s & 0x0f<< 12+
                    ((
            *(unsigned char *) (s + 1& 0x3f<< 6+
                    (
            *(unsigned char *) (s + 2& 0x3f);
                  s 
            += 3;
                }
                  length
            ++;
                }
              
            *us = 0;
              
            return (length);
            }
            其中,我們找到FriBidiChar的定義,類似Uint32的類型;另外,函數用char表示1字節的單位。根據我的試驗,至少在VC2008下是有錯誤的,我們一直用的是unsigned char表示1字節的單位,所以,我們需要對這個函數做些修改:
            int myUTF8_to_UNICODE(Uint16* unicode, unsigned char* utf8, int len)
            {
                
            int length;
                unsigned 
            char* t = utf8;

                length 
            = 0;
                
            while (utf8 - t < len){
                    
            //one byte.ASCII as a, b, c, 1, 2, 3 ect
                    if ( *(unsigned char *) utf8 <= 0x7f ) {
                        
            //expand with 0s.
                        *unicode++ = *utf8++;
                    }
                    
            //2 byte.
                    else if ( *(unsigned char *) utf8 <= 0xdf ) {
                        
            *unicode++ = ((*(unsigned char *) utf8 & 0x1f<< 6+ ((*(unsigned char *) (utf8 + 1)) & 0x3f);
                        utf8 
            += 2;
                    }
                    
            //3 byte.Chinese may use 3 byte.
                    else {
                        
            *unicode++ = ((int) (*(unsigned char *) utf8 & 0x0f<< 12+
                            ((
            *(unsigned char *) (utf8 + 1& 0x3f<< 6+
                            (
            *(unsigned char *) (utf8 + 2& 0x3f);
                        utf8 
            += 3;
                    }
                    length
            ++;
                }

                
            *unicode = 0;
                
                
            return (length);
            }

            4.3:將漢字,英文,數字和符號都正確的轉換為16位的Unicode

                    有了iconv和上面這個函數,我們終于可以將GB2312的編碼正確的轉換為Unicode了。
            //FileName: gb2312_to_Unicode.h
            #ifndef GB2312_TO_UNICODE_H_
            #define GB2312_TO_UNICODE_H_

            #include 
            <iostream>
            #include 
            <vector>
            #include 
            "GNU/iconv.h"
            #include 
            "SDL/SDL.h"

            std::vector
            <Uint16> getUnicode(const std::string& str);

            #endif
            實現文件中包含我們上面寫的從UTF-8到Unicode的函數:
            #include "gb2312_to_Unicode.h"

            int myUTF8_to_UNICODE(Uint16* unicode, unsigned char* utf8, int len);

            std::vector
            <Uint16> getUnicode(const std::string& str)
            {
                
            const int CHAR_SIZE = 256;
                
            //GB2312 src
                const unsigned char* src = (const unsigned char*)(str.c_str());
                size_t src_len 
            = strlen((char*)src);
                
            //Unicode dst to get
                unsigned char dst[CHAR_SIZE] = {0};
                size_t dst_len 
            = sizeof(dst);
                
            //iconv arg
                const unsigned char* in = src;
                unsigned 
            char* out = dst;

                iconv_t cd;
                
            //GB2312 to UTF-8
                cd = iconv_open("UTF-8""GB2312");
                
            if ((iconv_t)-1 == cd){
                    exit (
            -1);
                }
                
            //conversion
                iconv(cd, (const char**)&in&src_len, (char**)&out&dst_len);

                
            //UTF-8 to Unicode
                int utf8Len = strlen((char*)dst);
                Uint16 unicodeData[CHAR_SIZE] 
            = {0};
                
            int unicodeLen = myUTF8_to_UNICODE(unicodeData, dst, utf8Len);
                std::vector
            <Uint16> unicodeVectorArray;
                
            for (int i = 0; i < unicodeLen; i++) {
                    unicodeVectorArray.push_back(unicodeData[i]);
                }
                
                iconv_close(cd); 
                
            return unicodeVectorArray;
            }
            函數把一個std::string轉換位Uint16的vector數組并返回,這正是SDL所需要的Unicode格式。
            posted on 2008-03-31 11:00 lf426 閱讀(5526) 評論(0)  編輯 收藏 引用 所屬分類: SDL入門教程跨平臺與GNU
            久久精品国产亚洲5555| 久久综合狠狠综合久久综合88| 国产精品99久久久久久猫咪| 久久夜色撩人精品国产| 99蜜桃臀久久久欧美精品网站| 久久九九有精品国产23百花影院| 日本久久中文字幕| 99久久婷婷国产综合亚洲| 久久久久久A亚洲欧洲AV冫| 少妇久久久久久久久久| 色99久久久久高潮综合影院| 久久天堂AV综合合色蜜桃网| 欧美伊人久久大香线蕉综合69| 久久综合狠狠综合久久| 久久精品人妻中文系列| 久久久久久久国产免费看| 久久久久免费看成人影片| 亚洲国产高清精品线久久 | 亚洲婷婷国产精品电影人久久| 久久精品国产亚洲AV麻豆网站| 伊人色综合久久天天人守人婷| AAA级久久久精品无码区| 久久精品aⅴ无码中文字字幕不卡| 亚洲欧美日韩精品久久亚洲区 | 精品久久久久久无码人妻蜜桃| 亚洲va久久久噜噜噜久久天堂| 香蕉99久久国产综合精品宅男自| 26uuu久久五月天| 久久精品中文无码资源站| 久久天天躁夜夜躁狠狠| 性做久久久久久久久| 日韩精品无码久久一区二区三| 国产精品一区二区久久精品无码 | 人妻无码中文久久久久专区| 热99RE久久精品这里都是精品免费| 精品国产婷婷久久久| 国产免费久久精品丫丫| 97久久精品人人澡人人爽| 久久精品中文字幕久久| 99热成人精品免费久久| 久久久久这里只有精品|