如何使用带有freetype字体的重音字母?(c ++)

时间:2016-03-09 00:24:20

标签: unicode fonts char ascii freetype

我正在制作c ++游戏引擎,现在我正在执行一项使用ttf字体输出特定字母的任务。字母如é,à,è等。这是为了本地化。 当然这些字符有字形,但如果我试过这个,那么只有那些已经破了。我的意思是,它打印不正确。 我找到了一些信息,他们说这可能是unicode,ascii,unsigned chars,locale ......的问题但是我试过的每一个镜头都失败了。

所以我想得到你的帮助。这是我的代码,我认为它与此问题有关。 我引用了NEHE的论坛。

void Text::font_data::SetFont(const char* font_name, unsigned int size)
{
textures = new Texture[128];
this->size = (float)size;

FT_Library library;
if (FT_Init_FreeType(&library))
    throw std::runtime_error("FT_Init_FreeType failed");

FT_Face face = 0;
if (FT_New_Face(library, font_name, 0, &face))
    throw std::runtime_error("FT_New_Face failed (there is probably a problem with your font file)");

FT_Set_Char_Size(face, size << 6, size << 6, 96, 96);
list_base = glGenLists(128);

glGenTextures(128, &(GLuint)textures->texID);
for (unsigned char i = 0; i < 128; ++i)
    Make_dlist(face, i, list_base, (GLuint*)&textures->texID);

FT_Done_Face(face);
FT_Done_FreeType(library);
}


void Text::font_data::Clean(void) 
{
glDeleteLists(list_base, 128);
glDeleteTextures(128, (GLuint*)&textures->texID);
delete[] textures;
}

void Text::font_data::Make_dlist(FT_Face face, unsigned char ch, GLuint list_base, GLuint* tex_base)
{
if (FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT))
    throw std::runtime_error("FT_Load_Glyph failed");

FT_Glyph glyph;
if (FT_Get_Glyph(face->glyph, &glyph))
    throw std::runtime_error("FT_Load_Glyph failed");

FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1);
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;

FT_Bitmap& bitmap = bitmap_glyph->bitmap;

int width = Next_p2(bitmap.width);
int height = Next_p2(bitmap.rows);

GLubyte* expanded_data = new GLubyte[2 * width * height];

for (int j = 0; j < height; ++j)
{
    for (int i = 0; i < width; ++i)
    {
        expanded_data[2 * (i + j*width)] = expanded_data[2 * (i + j*width) + 1]
            = (i >= bitmap.width || j >= bitmap.rows) ?
            0 : bitmap.buffer[i + bitmap.width*j];
    }
}

glBindTexture(GL_TEXTURE_2D, tex_base[ch]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
    GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data);

delete [] expanded_data;

glNewList(list_base + ch, GL_COMPILE);
glBindTexture(GL_TEXTURE_2D, tex_base[ch]);
glPushMatrix();
glTranslatef(float(bitmap_glyph->left), 0, 0);
glTranslatef(0.f, float(bitmap_glyph->top - bitmap.rows), 0.f);

float x = float(bitmap.width) / float(width);
float y = float(bitmap.rows) / float(height);

glBegin(GL_QUADS);
glTexCoord2d(0.f, 0.f); glVertex2f(0.f, float(bitmap.rows));
glTexCoord2d(0.f, y);   glVertex2f(0.f, 0.f);
glTexCoord2d(x, y);     glVertex2f(float(bitmap.width), 0.f);
glTexCoord2d(x, 0.f);   glVertex2f(float(bitmap.width), float(bitmap.rows));
glEnd();
glPopMatrix();
glTranslatef(float(face->glyph->advance.x >> 6), 0.f, 0.f);
glEndList();
}

void Text::SetInput(const char *fmt, ...)
{
//const Text::font_data &ft_font

m_font = m_fontInfo.list_base;

m_fontSize = m_fontInfo.size / .63f;

va_list ap;

if (fmt == NULL)
    *m_text = 0;
else {
    va_start(ap, fmt);
    vsprintf_s(m_text, fmt, ap);
    va_end(ap);
}

}

void Text::Draw(float dt)
{
UNREFERENCED_PARAMETER(dt);

m_color = GetSprite()->GetColor();
m_scale = GetSprite()->GetTransform()->GetScale();
m_position = GetSprite()->GetTransform()->GetPosition();

glLoadIdentity();
glColor4f(m_color.R, m_color.G, m_color.B, m_color.A);
glScalef(m_scale.x, m_scale.y, m_scale.z);

//PushScreenCoordMatrix();

const char* start_line = m_text;
vector<string> lines;
const char* c = m_text;

for (; *c; c++)
{
    if (*c == '\n'){
        string line;
        for (const char* n = start_line; n < c; ++n)
            line.append(1, *n);
        lines.push_back(line);
        start_line = c + 1;
    }
}

if (start_line) {
    string line;
    for (const char* n = start_line; n < c; ++n)
        line.append(1, *n);
    lines.push_back(line);
}

glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glListBase(m_font);

float modelview_matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelview_matrix);

for (unsigned int i = 0; i < lines.size(); ++i) {
    glPushMatrix();
    glLoadIdentity();
    glTranslatef(m_position.x, m_position.y - m_fontSize*i, m_position.z);
    glMultMatrixf(modelview_matrix);

    glCallLists(lines[i].length(), GL_UNSIGNED_BYTE, lines[i].c_str());

    glPopMatrix();
}

glPopAttrib();
//Pop_projection_matrix();
}

0 个答案:

没有答案