summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/fontwrapper-ft.cc
diff options
context:
space:
mode:
authorAdam Borowski <kilobyte@angband.pl>2012-07-09 00:26:28 +0200
committerAdam Borowski <kilobyte@angband.pl>2012-07-09 00:26:28 +0200
commit1901d993033786e03722223e195d61a2b1322329 (patch)
tree8af3339281fe504f6144676f4afb62f2b911e29a /crawl-ref/source/fontwrapper-ft.cc
parentcdb410cd78b4ef84d5461911c68a1763250c8783 (diff)
downloadcrawl-ref-1901d993033786e03722223e195d61a2b1322329.tar.gz
crawl-ref-1901d993033786e03722223e195d61a2b1322329.zip
Evict glyph loading to a separate function.
It got unmanageably large.
Diffstat (limited to 'crawl-ref/source/fontwrapper-ft.cc')
-rw-r--r--crawl-ref/source/fontwrapper-ft.cc208
1 files changed, 108 insertions, 100 deletions
diff --git a/crawl-ref/source/fontwrapper-ft.cc b/crawl-ref/source/fontwrapper-ft.cc
index 40ec8cb423..539420b72a 100644
--- a/crawl-ref/source/fontwrapper-ft.cc
+++ b/crawl-ref/source/fontwrapper-ft.cc
@@ -171,6 +171,110 @@ bool FTFontWrapper::load_font(const char *font_name, unsigned int font_size,
return true;
}
+void FTFontWrapper::load_glyph(int c, ucs_t uchar)
+{
+ // get on with rendering the new glyph
+ FT_Error error;
+ m_glyphs[c].offset = 0;
+ m_glyphs[c].advance = 0;
+ m_glyphs[c].renderable = false;
+
+ FT_Int glyph_index = FT_Get_Char_Index(face, uchar);
+
+ if (!glyph_index)
+ glyph_index = FT_Get_Char_Index(face, MISSING_CHAR);
+
+ error = FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER |
+ (Options.tile_font_ft_light ? FT_LOAD_TARGET_LIGHT : 0));
+ ASSERT(!error);
+
+ FT_Bitmap *bmp = &face->glyph->bitmap;
+ ASSERT(bmp);
+
+ 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].width = bmp_width;
+
+ // Some glyphs (e.g. ' ') don't get a buffer.
+ if (!bmp->buffer)
+ m_glyphs[c].renderable = false;
+ else
+ {
+ 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;
+ memset(pixels, 0, sizeof(unsigned char) * 4 * charsz.x * charsz.y);
+ if (outl)
+ {
+ const int charw = bmp->width;
+ for (int x = 0; x < bmp->width; x++)
+ for (int y = 0; y < bmp->rows; y++)
+ {
+ unsigned int idx = offset_x+x+1 + (offset_y+y+1) * charsz.x;
+ idx *= 4;
+
+ unsigned char orig = bmp->buffer[x + charw * y];
+
+ unsigned char edge = 0;
+ if (x > 0)
+ edge = std::max(bmp->buffer[(x-1) + charw * y], edge);
+ if (y > 0)
+ edge = std::max(bmp->buffer[x + charw * (y-1)], edge);
+ if (x < bmp->width - 1)
+ edge = std::max(bmp->buffer[(x+1) + charw * y], edge);
+ if (y < bmp->rows - 1)
+ edge = std::max(bmp->buffer[x + charw * (y+1)], edge);
+
+ pixels[idx] = orig;
+ pixels[idx + 1] = orig;
+ pixels[idx + 2] = orig;
+ pixels[idx + 3] = std::min((int)orig + edge, 255);
+ }
+ }
+ else
+ {
+ for (int x = 0; x < bmp->width; x++)
+ for (int y = 0; y < bmp->rows; y++)
+ {
+ unsigned int idx = offset_x + x + (offset_y + y) * charsz.x;
+ idx *= 4;
+ if (x < bmp->width && y < bmp->rows)
+ {
+ unsigned char alpha = bmp->buffer[x + bmp->width * y];
+ pixels[idx] = 255;
+ pixels[idx + 1] = 255;
+ pixels[idx + 2] = 255;
+ pixels[idx + 3] = alpha;
+ }
+ }
+ }
+ bool success = m_tex.load_texture(pixels, charsz.x, charsz.y,
+ MIPMAP_NONE,
+ (c % GLYPHS_PER_ROWCOL) * charsz.x,
+ (c / GLYPHS_PER_ROWCOL) * charsz.y);
+ ASSERT(success);
+ }
+}
+
ucs_t FTFontWrapper::map_unicode(ucs_t uchar)
{
ucs_t c; // index in m_glyphs
@@ -199,6 +303,7 @@ ucs_t FTFontWrapper::map_unicode(ucs_t uchar)
// move top index on
m_glyphs_top++;
}
+
// set some default prev/next values
m_glyphs[c].prev = m_glyphs_mru;
m_glyphs[m_glyphs_mru].next = c;
@@ -207,106 +312,8 @@ ucs_t FTFontWrapper::map_unicode(ucs_t uchar)
m_glyphs[c].uchar = uchar;
m_glyphmap[uchar] = c;
- // get on with rendering the new glyph
- FT_Error error;
- m_glyphs[c].offset = 0;
- m_glyphs[c].advance = 0;
- m_glyphs[c].renderable = false;
-
- FT_Int glyph_index = FT_Get_Char_Index(face, uchar);
-
- if (!glyph_index)
- glyph_index = FT_Get_Char_Index(face, MISSING_CHAR);
-
- error = FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER |
- (Options.tile_font_ft_light ? FT_LOAD_TARGET_LIGHT : 0));
- ASSERT(!error);
-
- FT_Bitmap *bmp = &face->glyph->bitmap;
- ASSERT(bmp);
-
- 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].width = bmp_width;
-
- // Some glyphs (e.g. ' ') don't get a buffer.
- if (!bmp->buffer)
- m_glyphs[c].renderable = false;
- else
- {
- 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);
+ load_glyph(c, uchar);
- // Horizontal offset stored in m_glyphs and handled when drawing
- const unsigned int offset_x = 0;
- const unsigned int offset_y = vert_offset;
- memset(pixels, 0, sizeof(unsigned char) * 4 * charsz.x * charsz.y);
- if (outl)
- {
- const int charw = bmp->width;
- for (int x = 0; x < bmp->width; x++)
- for (int y = 0; y < bmp->rows; y++)
- {
- unsigned int idx = offset_x+x+1 + (offset_y+y+1) * charsz.x;
- idx *= 4;
-
- unsigned char orig = bmp->buffer[x + charw * y];
-
- unsigned char edge = 0;
- if (x > 0)
- edge = std::max(bmp->buffer[(x-1) + charw * y], edge);
- if (y > 0)
- edge = std::max(bmp->buffer[x + charw * (y-1)], edge);
- if (x < bmp->width - 1)
- edge = std::max(bmp->buffer[(x+1) + charw * y], edge);
- if (y < bmp->rows - 1)
- edge = std::max(bmp->buffer[x + charw * (y+1)], edge);
-
- pixels[idx] = orig;
- pixels[idx + 1] = orig;
- pixels[idx + 2] = orig;
- pixels[idx + 3] = std::min((int)orig + edge, 255);
- }
- }
- else
- {
- for (int x = 0; x < bmp->width; x++)
- for (int y = 0; y < bmp->rows; y++)
- {
- unsigned int idx = offset_x + x + (offset_y + y) * charsz.x;
- idx *= 4;
- if (x < bmp->width && y < bmp->rows)
- {
- unsigned char alpha = bmp->buffer[x + bmp->width * y];
- pixels[idx] = 255;
- pixels[idx + 1] = 255;
- pixels[idx + 2] = 255;
- pixels[idx + 3] = alpha;
- }
- }
- }
- bool success = m_tex.load_texture(pixels, charsz.x, charsz.y,
- MIPMAP_NONE,
- (c % GLYPHS_PER_ROWCOL) * charsz.x,
- (c / GLYPHS_PER_ROWCOL) * charsz.y);
- ASSERT(success);
- }
dprintf("mapped %d (%x; %lc) to %d\n", uchar, uchar, uchar, c);
}
else // we found uchar in glyphmap
@@ -324,8 +331,9 @@ ucs_t FTFontWrapper::map_unicode(ucs_t uchar)
m_glyphs[m_glyphs[c].prev].next = m_glyphs[c].next;
m_glyphs[m_glyphs[c].next].prev = m_glyphs[c].prev;
}
- } // regardless of how we came about 'c'
+ }
+ // regardless of how we came about 'c'
if (m_glyphs_mru != c)
{
// point the last character we wrote out to the one we're writing