Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Borghetti <bdiego@gmail.com>2009-08-18 23:26:53 +0400
committerDiego Borghetti <bdiego@gmail.com>2009-08-18 23:26:53 +0400
commit7d812822bd9c522efc0730a4f219ccec9cfb4a57 (patch)
treeabd0a537d339cb3f4c63a05ab9016b96312671ca /source/blender/blenfont
parent94511c672920e8ae0ebca4fca2a563a46d07b85b (diff)
Stamp info back only for float buffer. (next commit add unsigned char).
A couple of new functions: BLF_width_and_height - Merge of BLF_width and BLF_height in one call to avoid freetype2 stuff. BLF_buffer - Set the buffer, size and number of channel. BLF_buffer_col - Set the text color (the alpha is not used right now). BLF_draw_buffer - Draw the text in the current buffer. Also tweak a little the boundbox and draw function to avoid access the freetype2 and use the cache info. By default the font size is 12, the UI still need work to allow change the font and size.
Diffstat (limited to 'source/blender/blenfont')
-rw-r--r--source/blender/blenfont/BLF_api.h27
-rw-r--r--source/blender/blenfont/intern/blf.c45
-rw-r--r--source/blender/blenfont/intern/blf_font.c169
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c2
-rw-r--r--source/blender/blenfont/intern/blf_internal.h2
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h20
6 files changed, 251 insertions, 14 deletions
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 05df927f921..760b7059bc7 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -70,6 +70,11 @@ void BLF_boundbox(char *str, struct rctf *box);
float BLF_width(char *str);
float BLF_height(char *str);
+/*
+ * The following function return the width and height of the string, but
+ * just in one call, so avoid extra freetype2 stuff.
+ */
+void BLF_width_and_height(char *str, float *width, float *height);
/*
* For fixed width fonts only, returns the width of a
@@ -117,6 +122,28 @@ void BLF_shadow(int level, float r, float g, float b, float a);
void BLF_shadow_offset(int x, int y);
/*
+ * Set the buffer, size and number of channels to draw, one thing to take care is call
+ * this function with NULL pointer when we finish, for example:
+ * BLF_buffer(my_fbuf, my_cbuf, 100, 100, 4);
+ *
+ * ... set color, position and draw ...
+ *
+ * BLF_buffer(NULL, NULL, 0, 0, 0);
+ */
+void BLF_buffer(float *fbuf, unsigned char *cbuf, unsigned int w, unsigned int h, int nch);
+
+/*
+ * Set the color to be used for text.
+ */
+void BLF_buffer_col(float r, float g, float b, float a);
+
+/*
+ * Draw the string into the buffer, this function draw in both buffer, float and unsigned char _BUT_
+ * it's not necessary set both buffer, NULL is valid here.
+ */
+void BLF_draw_buffer(char *str);
+
+/*
* Search the path directory to the locale files, this try all
* the case for Linux, Win and Mac.
*/
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 {