diff options
Diffstat (limited to 'source/blender/blenfont/intern')
-rw-r--r-- | source/blender/blenfont/intern/blf.c | 45 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_font.c | 169 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_glyph.c | 2 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_internal.h | 2 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_internal_types.h | 20 |
5 files changed, 224 insertions, 14 deletions
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index ded89d18387..8cb237a19ac 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -371,6 +371,15 @@ void BLF_boundbox(char *str, rctf *box) blf_font_boundbox(font, str, box); } +void BLF_width_and_height(char *str, float *width, float *height) +{ + FontBLF *font; + + font= global_font[global_font_cur]; + if (font) + blf_font_width_and_height(font, str, width, height); +} + float BLF_width(char *str) { FontBLF *font; @@ -513,3 +522,39 @@ void BLF_shadow_offset(int x, int y) font->shadow_y= y; } } + +void BLF_buffer(float *fbuf, unsigned char *cbuf, unsigned int w, unsigned int h, int nch) +{ + FontBLF *font; + + font= global_font[global_font_cur]; + if (font) { + font->b_fbuf= fbuf; + font->b_cbuf= cbuf; + font->bw= w; + font->bh= h; + font->bch= nch; + } +} + +void BLF_buffer_col(float r, float g, float b, float a) +{ + FontBLF *font; + + font= global_font[global_font_cur]; + if (font) { + font->b_col[0]= r; + font->b_col[1]= g; + font->b_col[2]= b; + font->b_col[3]= a; + } +} + +void BLF_draw_buffer(char *str) +{ + FontBLF *font; + + font= global_font[global_font_cur]; + if (font) + blf_font_buffer(font, str); +} diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 7521b7815f1..432c3b5f854 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -100,7 +100,7 @@ void blf_font_draw(FontBLF *font, char *str) unsigned int c; GlyphBLF *g, *g_prev; FT_Vector delta; - FT_UInt glyph_index, g_prev_index; + FT_UInt glyph_index; int pen_x, pen_y; int i, has_kerning, st; @@ -112,17 +112,17 @@ void blf_font_draw(FontBLF *font, char *str) pen_y= 0; has_kerning= FT_HAS_KERNING(font->face); g_prev= NULL; - g_prev_index= 0; while (str[i]) { c= blf_utf8_next((unsigned char *)str, &i); if (c == 0) break; - glyph_index= FT_Get_Char_Index(font->face, c); g= blf_glyph_search(font->glyph_cache, c); - if (!g) + if (!g) { + glyph_index= FT_Get_Char_Index(font->face, c); g= blf_glyph_add(font, glyph_index, c); + } /* if we don't found a glyph, skip it. */ if (!g) @@ -133,9 +133,9 @@ void blf_font_draw(FontBLF *font, char *str) delta.y= 0; if (font->flags & BLF_KERNING_DEFAULT) - st= FT_Get_Kerning(font->face, g_prev_index, glyph_index, ft_kerning_default, &delta); + st= FT_Get_Kerning(font->face, g_prev->idx, g->idx, ft_kerning_default, &delta); else - st= FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta); + st= FT_Get_Kerning(font->face, g_prev->idx, g->idx, FT_KERNING_UNFITTED, &delta); if (st == 0) pen_x += delta.x >> 6; @@ -146,7 +146,129 @@ void blf_font_draw(FontBLF *font, char *str) pen_x += g->advance; g_prev= g; - g_prev_index= glyph_index; + } +} + +void blf_font_buffer(FontBLF *font, char *str) +{ + unsigned char *data; + unsigned int c; + GlyphBLF *g, *g_prev; + FT_Vector delta; + FT_UInt glyph_index; + float a, *fbuf; + int pen_x, pen_y, y, x, yb, diff; + int i, has_kerning, st, chx, chy; + + if (!font->glyph_cache) + return; + + i= 0; + pen_x= (int)font->pos[0]; + pen_y= (int)font->pos[1]; + has_kerning= FT_HAS_KERNING(font->face); + g_prev= NULL; + + while (str[i]) { + c= blf_utf8_next((unsigned char *)str, &i); + if (c == 0) + break; + + g= blf_glyph_search(font->glyph_cache, c); + if (!g) { + glyph_index= FT_Get_Char_Index(font->face, c); + g= blf_glyph_add(font, glyph_index, c); + } + + /* if we don't found a glyph, skip it. */ + if (!g) + continue; + + if (has_kerning && g_prev) { + delta.x= 0; + delta.y= 0; + + if (font->flags & BLF_KERNING_DEFAULT) + st= FT_Get_Kerning(font->face, g_prev->idx, g->idx, ft_kerning_default, &delta); + else + st= FT_Get_Kerning(font->face, g_prev->idx, g->idx, FT_KERNING_UNFITTED, &delta); + + if (st == 0) + pen_x += delta.x >> 6; + } + + if (font->b_fbuf) { + chx= pen_x + ((int)g->pos_x); + + diff= g->height - ((int)g->pos_y); + + if (diff > 0) { + if (g->pitch < 0) + pen_y += diff; + else + pen_y -= diff; + } + else if (diff < 0) { + if (g->pitch < 0) + pen_y -= diff; + else + pen_y += diff; + } + + + if (g->pitch < 0) + chy= pen_y - ((int)g->pos_y); + else + chy= pen_y + ((int)g->pos_y); + + if (chx >= 0 && chx < font->bw && pen_y >= 0 && pen_y < font->bh) { + if (g->pitch < 0) + yb= 0; + else + yb= g->height-1; + + for (y= 0; y < g->height; y++) { + for (x= 0; x < g->width; x++) { + fbuf= font->b_fbuf + font->bch * ((chx + x) + ((pen_y + y)*font->bw)); + data= g->bitmap + x + (yb * g->pitch); + a= data[0]/255.0f; + + if (a == 1.0) { + fbuf[0]= font->b_col[0]; + fbuf[1]= font->b_col[1]; + fbuf[2]= font->b_col[2]; + } + else { + fbuf[0]= (font->b_col[0]*a) + (fbuf[0] * (1-a)); + fbuf[1]= (font->b_col[1]*a) + (fbuf[1] * (1-a)); + fbuf[2]= (font->b_col[2]*a) + (fbuf[2] * (1-a)); + } + } + + if (g->pitch < 0) + yb++; + else + yb--; + } + } + + if (diff > 0) { + if (g->pitch < 0) + pen_x -= diff; + else + pen_y += diff; + } + else if (diff < 0) { + if (g->pitch < 0) + pen_x += diff; + else + pen_y -= diff; + } + + } + + pen_x += g->advance; + g_prev= g; } } @@ -155,7 +277,7 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box) unsigned int c; GlyphBLF *g, *g_prev; FT_Vector delta; - FT_UInt glyph_index, g_prev_index; + FT_UInt glyph_index; rctf gbox; int pen_x, pen_y; int i, has_kerning, st; @@ -173,17 +295,17 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box) pen_y= 0; has_kerning= FT_HAS_KERNING(font->face); g_prev= NULL; - g_prev_index= 0; while (str[i]) { c= blf_utf8_next((unsigned char *)str, &i); if (c == 0) break; - glyph_index= FT_Get_Char_Index(font->face, c); g= blf_glyph_search(font->glyph_cache, c); - if (!g) + if (!g) { + glyph_index= FT_Get_Char_Index(font->face, c); g= blf_glyph_add(font, glyph_index, c); + } /* if we don't found a glyph, skip it. */ if (!g) @@ -194,9 +316,9 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box) delta.y= 0; if (font->flags & BLF_KERNING_DEFAULT) - st= FT_Get_Kerning(font->face, g_prev_index, glyph_index, ft_kerning_default, &delta); + st= FT_Get_Kerning(font->face, g_prev->idx, g->idx, ft_kerning_default, &delta); else - st= FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta); + st= FT_Get_Kerning(font->face, g_prev->idx, g->idx, FT_KERNING_UNFITTED, &delta); if (st == 0) pen_x += delta.x >> 6; @@ -219,7 +341,6 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box) pen_x += g->advance; g_prev= g; - g_prev_index= glyph_index; } if (box->xmin > box->xmax) { @@ -230,6 +351,17 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box) } } +void blf_font_width_and_height(FontBLF *font, char *str, float *width, float *height) +{ + rctf box; + + if (font->glyph_cache) { + blf_font_boundbox(font, str, &box); + *width= ((box.xmax - box.xmin) * font->aspect); + *height= ((box.ymax - box.ymin) * font->aspect); + } +} + float blf_font_width(FontBLF *font, char *str) { rctf box; @@ -311,6 +443,15 @@ void blf_font_fill(FontBLF *font) font->glyph_cache= NULL; font->blur= 0; font->max_tex_size= -1; + font->b_fbuf= NULL; + font->b_cbuf= NULL; + font->bw= 0; + font->bh= 0; + font->bch= 0; + font->b_col[0]= 0; + font->b_col[1]= 0; + font->b_col[2]= 0; + font->b_col[3]= 0; } FontBLF *blf_font_new(char *name, char *filename) diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 78df8ff2bc6..f3db3ddc9a5 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -217,6 +217,7 @@ GlyphBLF *blf_glyph_add(FontBLF *font, FT_UInt index, unsigned int c) g->next= NULL; g->prev= NULL; g->c= c; + g->idx= index; g->tex= 0; g->build_tex= 0; g->bitmap= NULL; @@ -238,6 +239,7 @@ GlyphBLF *blf_glyph_add(FontBLF *font, FT_UInt index, unsigned int c) g->advance= ((float)slot->advance.x) / 64.0f; g->pos_x= slot->bitmap_left; g->pos_y= slot->bitmap_top; + g->pitch= slot->bitmap.pitch; FT_Outline_Get_CBox(&(slot->outline), &bbox); g->box.xmin= ((float)bbox.xMin) / 64.0f; diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h index 30d5c8ede65..2a69b8652ea 100644 --- a/source/blender/blenfont/intern/blf_internal.h +++ b/source/blender/blenfont/intern/blf_internal.h @@ -45,7 +45,9 @@ void blf_font_attach_from_mem(FontBLF *font, const unsigned char *mem, int mem_s void blf_font_size(FontBLF *font, int size, int dpi); void blf_font_draw(FontBLF *font, char *str); +void blf_font_buffer(FontBLF *font, char *str); void blf_font_boundbox(FontBLF *font, char *str, rctf *box); +void blf_font_width_and_height(FontBLF *font, char *str, float *width, float *height); float blf_font_width(FontBLF *font, char *str); float blf_font_height(FontBLF *font, char *str); float blf_font_fixed_width(FontBLF *font); diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index d457225662f..fb4a2e6a9e5 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -85,6 +85,9 @@ typedef struct GlyphBLF { /* and the character, as UTF8 */ unsigned int c; + /* freetype2 index, to speed-up the search. */ + FT_UInt idx; + /* glyph box. */ rctf box; @@ -106,6 +109,7 @@ typedef struct GlyphBLF { /* glyph width and height. */ int width; int height; + int pitch; /* uv coords. */ float uv[2][2]; @@ -176,6 +180,22 @@ typedef struct FontBLF { /* freetype2 face. */ FT_Face face; + + /* for draw to buffer, always set this to NULL after finish! */ + float *b_fbuf; + + /* the same but unsigned char */ + unsigned char *b_cbuf; + + /* buffer size. */ + unsigned int bw; + unsigned int bh; + + /* number of channels. */ + int bch; + + /* and the color, the alphas is get from the glyph! */ + float b_col[4]; } FontBLF; typedef struct DirBLF { |