迭代utf-8格式的字符块

iterate over characters blocks in utf-8

本文关键字:字符 格式 utf-8 迭代      更新时间:2023-10-16

我的任务是遍历与给定语言(区域设置)对应的所有utf-8字符代码。我想这并不容易,我必须遍历字符块(例如,"ru_RU"的整个西里尔字母)。我可以在维基页面https://en.wikipedia.org/wiki/UTF-8上找到字符块,但我希望有比自己发明自行车更好的方法。

我已经看了一下icu项目,但是我不知道我是否能做我需要的。

我想要的结果是这样的:

for (unsignet int=UBLOCK_GREEK_EXTENDED; i<UBLOCK_GREEK_EXTENDED_SIZE; i++) {
    // do stuff
}

icu-project是一个非常强大的工具,所以我希望有人知道如何做到这一点:)

更新:我正在为移动设备制作3D框架的本地化选项。它栅格化和编码真字体,所以他们可以很容易地通过选择所需的图像从栅格化字体文件呈现。由于我必须关心内存量,我想在不同的文件中拆分光栅化字体,以适应不同的语言环境(或语言,或字符块,如ciryllic或greek),所以我不必一直在内存中保留整个utf-8字体,而只在检测到语言环境后加载相应的文件。

谢谢!

所以,我终于找到了正确使用icu-project库http://site.icu-project.org的方法。

这里是一个示例解决方案。指定语言环境或语言并获得包含相对于语言环境/语言的符号的utf-8字符块数组。然后,您可以为每个字符块设置开始和结束。

UErrorCode err = U_ZERO_ERROR;
const int32_t capacity = 10;
const char* shortname = NULL;
int32_t num, j;
int32_t strLength = 4;
UScriptCode script[10] = {USCRIPT_INVALID_CODE};
num = uscript_getCode("en", script, capacity, &err);
UnicodeString temp = UnicodeString("[", 1, US_INV);
UnicodeString pattern;
for(j=0; j<num; j++) {
    shortname = uscript_getShortName(script[j]);
    UnicodeString str(shortname, strLength, US_INV);
    temp.append("[:");
    temp.append(str);
    temp.append(":]+");
}
pattern = temp.remove(temp.length()-1,1);
pattern.append("]");
UnicodeSet cnvSet(pattern, err);
printf("Number of script code associated are : %d n", num);
printf("Range count: %dn", cnvSet.getRangeCount());
printf("Set size: %dn", cnvSet.size());
for(int32_t i=0; i<cnvSet.getRangeCount(); i++) {
    printf("Range start: %xn", cnvSet.getRangeStart(i));
    printf("Range end: %xn", cnvSet.getRangeEnd(i));
}

语言"en"从这个例子中:

关联的脚本代码数为:1

范围计数:30

Set size: 1272

Range start: 41

范围结束:5a

Range start: 61

Range end: 7a

Range start: ff41

Range end: ff5a

表示与拉丁块对应的所有字符范围。

这不是很清楚你的意思,虽然在UTF映射中有专门针对某些语言的部分-例如,正如你所说的希腊语-有很多语言的字符被划分在许多不同的区域-例如,许多欧洲语言使用ASCII字母- a - z等-并且还从160-240区域的"extended Latin1"设置中选择字符。

因此,任何要"遍历"罗马尼亚语的工具都必须首先确定哪些是罗马尼亚语字符,然后在UTF中识别它们,然后打印它们。

如果你不是这个意思,而是想从UTF打印出特定的分组,我建议你考虑使用UTF32作为你的基本编码,在这种情况下打印字符会容易得多。

这里列出了unicode中语言块的位置,因此您可以将大多数字符拆分为字符到自己的文件中。

您需要列出在每个呈现的字体文件中可用的字符,然后为呈现的每个字符串中的字符加载适当的字体文件。

然而,动态执行此操作可能不是一个好主意,因为它可能很慢(检查每个字符),并且当字符不在任何字符集中时容易出错。

反过来做可能会更好;当有人初始化你的引擎时,他们会列出你应该加载哪些语言块,并加载适当的文件。然后,当您渲染字符串时,只需删除当前不可用的任何字符。

语言中实际使用的字符可以在CLDR中定义的范例集中找到。

而不是建立一个复杂的UnicodeSet,我将只是在u+0000…u+10fff上迭代并测试由uscript_getScript (UChar32 codepoint, UErrorCode *err)返回的脚本- UnicodeSet将在内部做同样的事情,对于您给出的示例代码作为您的答案