我刚刚创建了一个函数来缓存我在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,但即使使用printf
,wprintf
,cout
,也无法打印任何字符和wcout
,但如果我这样做:
std::string str = "Привет, öäü"
printf("%s\n", str.c_str());
然后它在终端上打印字符串就好了。我应该提到我在Ubuntu 16.04上,所以Windows唯一的解决方案对我不起作用,理想情况下我希望以可移植的方式进行。对于那些不熟悉SDL的人来说,我需要的是一种在C字符串中获取每个UTF8字符的方法。我希望这是可能的。
答案 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
}
}
值0x80u
和0xC0u
在循环条件中出现不止一次并不是巧合 - 前导字节和后续字节之间没有重叠的事实是给出的UTF-8具有自同步特性。
我猜你依赖以下事实(引自维基百科):
前128个字符(US-ASCII)需要一个字节。接下来的1,920个字符需要两个字节进行编码,其中包括几乎所有拉丁字母字母的剩余部分,还包括希腊语,西里尔语,科普特语,亚美尼亚语,希伯来语,阿拉伯语,叙利亚语,塔纳语和N&#39; Ko字母表,以及结合变音符号。
由于此范围包含组合标记,因此您将有很多条目无法单独呈现。无论您是跳过它们还是仅仅处理由文本布局引擎引起的混乱,都取决于您。