SDL2中的UTF文本

时间:2017-08-16 14:30:36

标签: c++ utf-8 sdl-2

我刚刚创建了一个函数来缓存我在SDL2中构建的小型游戏引擎中的任何加载字体,以下函数完美无瑕地工作,并且每次我需要时渲染文本的速度比创建新SDL_Surface快大约12倍文本。但是,正如你所看到的,它只缓存ANSI字符,这对英语来说很好,但如果我想要翻译我的游戏(德语变音符号或西里尔字母在ANSI中不可用)则不行。

void cacheFonts(){
    for(unsigned int i = 0; i < GlobalFontAssets.size; i++){
        SDL_Colour color_font = {255, 255, 255, 255};
        std::vector<SDL_Texture*> tempVector;
        for(int j = 32; j < 128; j++){
            char temp[2];
            temp[0] = j;
            temp[1] = 0;
            SDL_Surface* glyph = TTF_RenderUTF8_Blended(GlobalFontAssets.fonts[i], temp, color_font);  
            SDL_Texture* texture = 
            SDL_CreateTextureFromSurface(renderer, glyph);
            tempVector.push_back(texture);  
            SDL_FreeSurface(glyph);
        }
        GlobalFontAssets.cache.push_back(tempVector);
    }
    printf("Global Fonts Cached!\n");
}

我已尝试使用wchar_t,并从0循环到256 ^ 2,但即使使用printfwprintfcout,也无法打印任何字符和wcout,但如果我这样做:

std::string str = "Привет, öäü"
printf("%s\n", str.c_str());

然后它在终端上打印字符串就好了。我应该提到我在Ubuntu 16.04上,所以Windows唯一的解决方案对我不起作用,理想情况下我希望以可移植的方式进行。对于那些不熟悉SDL的人来说,我需要的是一种在C字符串中获取每个UTF8字符的方法。我希望这是可能的。

1 个答案:

答案 0 :(得分:1)

仅解决问题的这一部分:

  

我需要的是一种在C字符串中获取每个UTF8字符的方法

Wikipedia has a nice table显示各种编码规则,每个覆盖的代码点范围,以及相应的UTF-8长度和数据字节。

要覆盖the first 2000-odd characters,只需生成所有单字节和双字节模式:

char s[3] = { 0 };
for(s[0] = 0x00; s[0] < 0x80u; ++s[0]) { // can start at 0x20 to skip control characters
    // one byte encodings
}
for(s[0] = 0xC0u; s[0] < 0xE0u; ++s[0]) {
   for(s[1] = 0x80u; s[1] < 0xC0u; ++s[1]) {
      // two byte encodings
   }
}

0x80u0xC0u在循环条件中出现不止一次并不是巧合 - 前导字节和后续字节之间没有重叠的事实是给出的UTF-8具有自同步特性。

我猜你依赖以下事实(引自维基百科):

  

前128个字符(US-ASCII)需要一个字节。接下来的1,920个字符需要两个字节进行编码,其中包括几乎所有拉丁字母字母的剩余部分,还包括希腊语,西里尔语,科普特语,亚美尼亚语,希伯来语,阿拉伯语,叙利亚语,塔纳语和N&#39; Ko字母表,以及结合变音符号。

由于此范围包含组合标记,因此您将有很多条目无法单独呈现。无论您是跳过它们还是仅仅处理由文本布局引擎引起的混乱,都取决于您。