diff options
author | frogbotherer <therealchriswest@hotmail.com> | 2012-07-28 00:56:31 +0100 |
---|---|---|
committer | Adam Borowski <kilobyte@angband.pl> | 2012-07-28 02:50:27 +0200 |
commit | c348bcf42667cd230c47a51cb32016090ee02e39 (patch) | |
tree | 502a20b5aeb63f7901aa7db1cab8509aa45e1887 /crawl-ref/source/fontwrapper-ft.cc | |
parent | fcc898b07d67c4f6240d5fe030cff3230c7ffcb5 (diff) | |
download | crawl-ref-c348bcf42667cd230c47a51cb32016090ee02e39.tar.gz crawl-ref-c348bcf42667cd230c47a51cb32016090ee02e39.zip |
Don't crash on font rendering when there's anything outside ascender..descender.
This worked for DejaVu Sans, but failed on a number of other fonts.
(cherry picked from commit e0ba98f9c56185d8bc650df4df9d49b4bb428e4b)
[commit message rewritten -- 1KB]
Diffstat (limited to 'crawl-ref/source/fontwrapper-ft.cc')
-rw-r--r-- | crawl-ref/source/fontwrapper-ft.cc | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/crawl-ref/source/fontwrapper-ft.cc b/crawl-ref/source/fontwrapper-ft.cc index 5ff5c19673..fa81d02947 100644 --- a/crawl-ref/source/fontwrapper-ft.cc +++ b/crawl-ref/source/fontwrapper-ft.cc @@ -43,7 +43,9 @@ FTFontWrapper::FTFontWrapper() : m_glyphs_top(0), // reinitialised to 1 in load_font m_max_advance(0, 0), m_min_offset(0), - charsz(1,1) + charsz(1,1), + m_max_width(0), + m_max_height(0) { m_buf = GLShapeBuffer::create(true, true); } @@ -101,19 +103,19 @@ bool FTFontWrapper::load_font(const char *font_name, unsigned int font_size, m_max_advance = coord_def(0,0); m_max_advance.x = metrics.max_advance >> 6; m_max_advance.y = (metrics.ascender-metrics.descender)>>6; - ascender = (metrics.ascender>>6); - int max_width = (face->bbox.xMax >> 6) - (face->bbox.xMin >> 6); - int max_height = m_max_advance.y; + m_ascender = (metrics.ascender>>6); + m_max_width = (face->bbox.xMax >> 6) - (face->bbox.xMin >> 6); + m_max_height = (face->bbox.yMax>>6)-(face->bbox.yMin>>6);//m_max_advance.y; m_min_offset = 0; m_glyphs = new GlyphInfo[MAX_GLYPHS]; if (outl) - max_width += 2, max_height += 2; + m_max_width += 2, m_max_height += 2; // Grow character size to power of 2 - while (charsz.x < max_width) + while (charsz.x < m_max_width) charsz.x *= 2; - while (charsz.y < max_height) + while (charsz.y < m_max_height) charsz.y *= 2; // Fill out texture to be (16*charsz.x) X (16*charsz.y) X (32-bit) @@ -146,14 +148,15 @@ bool FTFontWrapper::load_font(const char *font_name, unsigned int font_size, m_glyphs_mru = 0; m_glyphs[0].offset = 0; m_glyphs[0].advance = 0; + m_glyphs[0].ascender = 0; m_glyphs[0].renderable = false; m_glyphs[0].uchar = MISSING_CHAR; m_glyphs[0].prev = 0; m_glyphs[0].next = 0; - for (int x = 0; x < max_width; x++) - for (int y = 0; y < max_height; y++) + for (int x = 0; x < m_max_width; x++) + for (int y = 0; y < m_max_height; y++) { - unsigned int idx = x + y * charsz.x; + unsigned int idx = x + y * m_max_width; idx *= 4; pixels[idx] = 255; pixels[idx + 1] = 255; @@ -177,6 +180,7 @@ void FTFontWrapper::load_glyph(unsigned int c, ucs_t uchar) FT_Error error; m_glyphs[c].offset = 0; m_glyphs[c].advance = 0; + m_glyphs[c].ascender = m_ascender; m_glyphs[c].renderable = false; FT_Int glyph_index = FT_Get_Char_Index(face, uchar); @@ -194,34 +198,25 @@ void FTFontWrapper::load_glyph(unsigned int c, ucs_t uchar) int advance = face->glyph->advance.x >> 6; int bmp_width = bmp->width; - int bmp_top = ascender - face->glyph->bitmap_top; - int bmp_bottom = ascender + bmp->rows - face->glyph->bitmap_top; if (outl) - { bmp_width += 2; - bmp_top -= 1; - bmp_bottom += 1; - } m_glyphs[c].offset = face->glyph->bitmap_left; m_glyphs[c].advance = advance; + m_glyphs[c].ascender = face->glyph->bitmap_top; m_glyphs[c].width = bmp_width; // Some glyphs (e.g. ' ') don't get a buffer. - if (!bmp->buffer) - m_glyphs[c].renderable = false; - else + if (bmp->buffer) { m_glyphs[c].renderable = true; - int vert_offset = ascender - face->glyph->bitmap_top; - ASSERT(bmp->pixel_mode == FT_PIXEL_MODE_GRAY); ASSERT(bmp->num_grays == 256); // Horizontal offset stored in m_glyphs and handled when drawing const unsigned int offset_x = 0; - const unsigned int offset_y = vert_offset; + const unsigned int offset_y = 0; memset(pixels, 0, sizeof(unsigned char) * 4 * charsz.x * charsz.y); if (outl) { @@ -374,8 +369,7 @@ void FTFontWrapper::render_textblock(unsigned int x_pos, unsigned int y_pos, m_buf->clear(); n_subst = 0; - float texcoord_dy = (float)m_max_advance.y / (float)m_tex.height(); - + float texcoord_dy = (float)m_max_height / (float)m_tex.height(); for (unsigned int y = 0; y < height; y++) { for (unsigned int x = 0; x < width; x++) @@ -407,8 +401,9 @@ void FTFontWrapper::render_textblock(unsigned int x_pos, unsigned int y_pos, float tex_x2 = tex_x + (float)this_width / (float)m_tex.width(); float tex_y2 = tex_y + texcoord_dy; - GLWPrim rect(adv.x, adv.y, adv.x + this_width, - adv.y + m_max_advance.y); + GLWPrim rect(adv.x, adv.y - m_glyphs[c].ascender + m_ascender, + adv.x + this_width, adv.y + m_max_height - m_glyphs[c].ascender + m_ascender); + VColour col(term_colours[col_fg].r, term_colours[col_fg].g, term_colours[col_fg].b); @@ -793,14 +788,14 @@ void FTFontWrapper::store(FontBuffer &buf, float &x, float &y, int this_width = m_glyphs[c].width; float pos_sx = x + m_glyphs[c].offset; - float pos_sy = y; + float pos_sy = y - m_glyphs[c].ascender + m_ascender; float pos_ex = pos_sx + this_width; - float pos_ey = y + m_max_advance.y; + float pos_ey = y + m_max_height - m_glyphs[c].ascender + m_ascender; float tex_sx = (float)(c % GLYPHS_PER_ROWCOL) / (float)GLYPHS_PER_ROWCOL; float tex_sy = (float)(c / GLYPHS_PER_ROWCOL) / (float)GLYPHS_PER_ROWCOL; - float tex_ex = tex_sx + (float)this_width / (float)(GLYPHS_PER_ROWCOL*charsz.x);//(float)m_tex.width(); - float tex_ey = tex_sy + (float)m_max_advance.y / (float)(GLYPHS_PER_ROWCOL*charsz.y);//(float)m_tex.height(); + float tex_ex = tex_sx + (float)this_width / (float)(GLYPHS_PER_ROWCOL*charsz.x); + float tex_ey = tex_sy + (float)m_max_height / (float)(GLYPHS_PER_ROWCOL*charsz.y); GLWPrim rect(pos_sx, pos_sy, pos_ex, pos_ey); rect.set_tex(tex_sx, tex_sy, tex_ex, tex_ey); |