Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何处理大小为>;=utf-8字符的渲染2B正确吗?_C++_Text_Utf 8_Freetype_Freetype2 - Fatal编程技术网

C++ 如何处理大小为>;=utf-8字符的渲染2B正确吗?

C++ 如何处理大小为>;=utf-8字符的渲染2B正确吗?,c++,text,utf-8,freetype,freetype2,C++,Text,Utf 8,Freetype,Freetype2,我想呈现utf-8大小>=2字节的字符。我已经把一切都做完了。不过,有一个问题。当绘制一个字符时,后面还有一个东西 为了获得字形数据,我使用freetype。这是一个非常简单的实现,实际的代码包含内核处理、SDF等 我认为需要移植的是一个地图集。方法“TextureAtlas::PackTexture(数据,w,h)”打包纹理数据并返回atlas w和h范围内的位置、原点(左上角)。因此,第一个字符的原点为[0,0],下一个字符的宽度为50的原点为[50,0]。简短地说 enum { DPI=7

我想呈现utf-8大小>=2字节的字符。我已经把一切都做完了。不过,有一个问题。当绘制一个字符时,后面还有一个东西

为了获得字形数据,我使用freetype。这是一个非常简单的实现,实际的代码包含内核处理、SDF等

我认为需要移植的是一个地图集。方法“TextureAtlas::PackTexture(数据,w,h)”打包纹理数据并返回atlas w和h范围内的位置、原点(左上角)。因此,第一个字符的原点为[0,0],下一个字符的宽度为
50
的原点为[50,0]。简短地说

enum
{
DPI=72,
高分辨率=64
};
结构图示符
{
uint32码点=-1;
uint32宽度=0;
uint32高度=0;
矢量2轴承=0;
矢量2前进=0.0f;
浮子s0、t0、s1、t1;
};
类纹理
{
公众:
TextureFont()=默认值;
bool初始化();
void LoadFromFile(const std::string和filePath,float fontSize);
Glyph*getGlyph(常量字符8*codepoint);
字形*FindGlyph(常量字符8_t*代码点);
uint32加载图示符(常量字符8_t*代码点);
int InitFreeType(浮点大小);
字符*文件名;
矢量字形;
地图集;
英国电信大学图书馆;
面部;
浮动字体大小=0.0f;
浮动上升器=0.0f;
浮动下降器=0.0f;
浮动高度=0.0f;
};  
int charfromfrutf8(无符号int*out\u char、const char*in\u text、const char*in\u text\u end)
{
无符号整数c=(无符号整数)-1;
const unsigned char*str=(const unsigned char*)在文本中;
如果(!(*str&0x80)){
c=(无符号整数)(*str++);
*out_char=c;
返回1;
}
如果((*str&0xe0)==0xc0){
*out_char=0xFFFD;
if(in_text_end&&in_text_end-(const char*)str<2)返回1;
if(*str<0xc2)返回2;
c=(unsigned int)((*str++&0x1f)0xbf))返回3;
if(*str==0xed&&str[1]>0x9f)返回3;
c=(unsigned int)((*str++&0x0f)0xbf))返回4;
if(*str==0xf4&&str[1]>0x8f)返回4;
c=(无符号整数)((*str++&0x07)>6)/100.0f;
下降器=(metrics.downer>>6)/100.0f;
高度=(metrics.height>>6)/100.0f;
FT_Done_面(面);
FT_Done_FreeType(库);
返回true;
}
int-TextureFont::InitFreeType(浮点大小)
{
FT_矩阵={
静态(1.0/高分辨率)*0x10000L),
静态铸造((0.0)*0x10000L),
静态铸造((0.0)*0x10000L),
静态铸造((1.0)*0x10000L)};
FT_误差;
错误=FT_Init_FreeType(&library);
如果(错误){
EngineLogError(“自由类型错误:无法初始化自由类型!\n”);
FT_Done_FreeType(库);
返回0;
}
错误=FT\u新面(库、文件名、0和面);
如果(错误){
EngineLogError(“自由类型错误:无法创建新面!\n”);
FT_Done_FreeType(库);
返回0;
}
错误=FT\u选择字符映射(面,FT\u编码\u UNICODE);
如果(错误){
EngineLogError(“自由类型错误:无法选择字符映射!\n”);
FT_Done_面(面);
返回0;
}
错误=FT\u Set\u Char\u Size(面、静态投影(大小*高分辨率)、0、DPI*高分辨率、DPI);
如果(错误){
EngineLogError(“释放类型错误:无法设置字符大小!\n”);
FT_Done_面(面);
返回0;
}
FT_集_变换(面、矩阵、空);
返回1;
}
void TextureFont::LoadFromFile(常量std::字符串和文件路径,浮点字体大小)
{
创建(512,1);
std::fill(atlas.buffer.begin(),atlas.buffer.end(),0);
此->fontSize=fontSize;
这个->文件名=strdup(filePath.c_str());
初始化();
}
Glyph*TextureFont::getGlyph(常量字符8\u t*代码点)
{
if(Glyph*Glyph=FindGlyph(代码点)){
返回标志符号;
}
if(加载图示符(代码点)){
返回FindGlyph(代码点);
}
返回空ptr;
}
Glyph*TextureFont::FindGlyph(常量字符8_t*代码点)
{
Glyph*Glyph=nullptr;
uint32停车场;
CharFromUtf8(&ucodepoint,(char*)码点,NULL);
对于(uint32 i=0;icodepoint==ucodepoint){
返回标志符号;
}
}
返回空ptr;
}
uint32 TextureFont::LoadGlyph(常量字符8\u t*代码点)
{
FT_Error=NULL;
FT_Glyph ftGlyph=nullptr;
FT_插槽插槽=空PTR;
FT_位图;
如果(!InitFreeType(fontSize)){
返回0;
}
if(FindGlyph(代码点)){
FT_Done_面(面);
FT_Done_FreeType(库);
返回1;
}
无符号整数cp;
CharFromUtf8(&cp,(char*)码点,NULL);
uint32 glyphIndex=FT\u Get\u Char\u索引(面,cp);
int标志=0;
标志|=FT|u加载|u渲染;
标志|=英尺负载力自动提示;
错误=英尺\负载\字形(面、字形索引、标志);
如果(错误){
EngineLogError(“自由类型错误:无法加载图示符(第{}行)!\n”,“第{行错误”);
FT_Done_面(面);
FT_Done_FreeType(库);
返回0;
}
槽=面->字形;
位图=插槽->位图;
int glyphTop=插槽->位图\u顶部;
int glyph left=插槽->位图_left;
无符号整型
for (const auto& c : string)
for (size_t i = 0; i < string.size(); /* nothing */) {
    // Here you need to get the number of bytes for the current character
    // Then you should increment the index by that amount
    i += byte_count_for_current_character;

    // ... rest of code
}
for (const auto& c : string) {
    if ((c & 0b1100'0000) == 0b1000'0000) {
        continue;
    }
// ...
}
auto tv = make_text_view<utf8_encoding>(string);
for (const auto& cp : tv) {
  ...
}