Stamp info back only for float buffer. (next commit add unsigned char).
authorDiego Borghetti <bdiego@gmail.com>
Tue, 18 Aug 2009 19:26:53 +0000 (19:26 +0000)
committerDiego Borghetti <bdiego@gmail.com>
Tue, 18 Aug 2009 19:26:53 +0000 (19:26 +0000)
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.

source/blender/blenfont/BLF_api.h
source/blender/blenfont/intern/blf.c
source/blender/blenfont/intern/blf_font.c
source/blender/blenfont/intern/blf_glyph.c
source/blender/blenfont/intern/blf_internal.h
source/blender/blenfont/intern/blf_internal_types.h
source/blender/blenkernel/intern/Makefile
source/blender/blenkernel/intern/image.c

index 05df927f9215f5e0066fee23836bbfc608f7b39e..760b7059bc794ac176ae98f75eb8ffa6b5afa901 100644 (file)
@@ -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
@@ -116,6 +121,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.
index ded89d18387fb96a5b2a31a28c48d54d5b890af9..8cb237a19ac489b204dbca66ae7feaa7b83eb003 100644 (file)
@@ -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);
+}
index 7521b7815f1ad6bd1eff0b3cc4a1422e3966c0fe..432c3b5f854d101f5f427257e268d35d2cc01be9 100644 (file)
@@ -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)
index 78df8ff2bc668bf1b06ceec9312c328a238a0abd..f3db3ddc9a5c10dca5a75c533f3332070beb843b 100644 (file)
@@ -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;
index 30d5c8ede658afa251732a61b21eb920c5422747..2a69b8652ea748674a7a3d07eb6d7bc720b6c978 100644 (file)
@@ -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);
index d457225662f3955d66de178440f64f5207f5b0ca..fb4a2e6a9e517131434614e0d4bfe21295d817ea 100644 (file)
@@ -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 {
index 60ffdc78726f6b3926c2569ecb271b84051d20be..d6d41d6579ea4f8734461705b72eff3eff85062f 100644 (file)
@@ -51,6 +51,7 @@ CPPFLAGS += -I../../imbuf
 CPPFLAGS += -I../../blenlib
 CPPFLAGS += -I../../blenloader
 CPPFLAGS += -I../../python
+CPPFLAGS += -I../../blenfont
 # also avi is used
 CPPFLAGS += -I../../avi
 CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
index 62af05fbc9ae6a69a2a48490c779f357dff3645d..eb8872c43a57201beca225f1d76992523cbda899 100644 (file)
@@ -73,6 +73,8 @@
 
 //XXX #include "BIF_editseq.h"
 
+#include "BLF_api.h"
+
 #include "PIL_time.h"
 
 #include "RE_pipeline.h"
@@ -978,7 +980,6 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
                        if (do_prefix)          strcpy(stamp_data->file, "File <untitled>");
                        else                            strcpy(stamp_data->file, "<untitled>");
                }
-               stamp_data->note[0] = '\0';
        } else {
                stamp_data->file[0] = '\0';
        }
@@ -1046,8 +1047,8 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
        
        if (scene->r.stamp & R_STAMP_FRAME) {
                char format[32];
-               if (do_prefix)          sprintf(format, "Frame %%0%di\n", 1 + (int) log10(scene->r.efra));
-               else                            sprintf(format, "%%0%di\n", 1 + (int) log10(scene->r.efra));
+               if (do_prefix)          sprintf(format, "Frame %%0%di", 1 + (int) log10(scene->r.efra));
+               else                            sprintf(format, "%%0%di", 1 + (int) log10(scene->r.efra));
                sprintf (stamp_data->frame, format, scene->r.cfra);
        } else {
                stamp_data->frame[0] = '\0';
@@ -1083,131 +1084,172 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
        }
 }
 
+// XXX - Bad level call.
+extern int datatoc_bmonofont_ttf_size;
+extern char datatoc_bmonofont_ttf[];
+
+// XXX - copied from text_font_begin
+static void stamp_font_begin(int size)
+{
+       static int mono= -1;
+
+       if (mono == -1)
+               mono= BLF_load_mem("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
+
+       BLF_set(mono);
+       BLF_aspect(1.0);
+       BLF_size(size, 72);
+}
+
 void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, int height, int channels)
 {
-#if 0
-// XXX
-// This go back when BLF_draw_buffer is implemented - Diego
        struct StampData stamp_data;
-       
-       int x=1,y=1;
-       int font_height;
-       int text_width;
-       int text_pad;
-       struct BMF_Font *font;
+       float w, h, pad;
+       int x, y;
        
        if (!rect && !rectf)
                return;
        
        stampdata(scene, &stamp_data, 1);
-       
-       switch (scene->r.stamp_font_id) {
-       case 1: /* tiny */
-               font = BMF_GetFont(BMF_kHelveticaBold8);
-               break;
-       case 2: /* small */
-               font = BMF_GetFont(BMF_kHelveticaBold10);
-               break;
-       case 3: /* medium */
-               font = BMF_GetFont(BMF_kScreen12);
-               break;
-       case 0: /* large - default */
-               font = BMF_GetFont(BMF_kScreen15);
-               break;
-       case 4: /* huge */
-               font = BMF_GetFont(BMF_kHelveticaBold14);
-               break;
-       default:
-               font = NULL;
-               break;
-       }
-       
-       font_height = BMF_GetFontHeight(font);
-       /* All texts get halfspace+1 pixel on each side and 1 pix
-       above and below as padding against their backing rectangles */
-       text_pad = BMF_GetStringWidth(font, " ");
-       
-       x = 1; /* Inits for everyone, text position, so 1 for padding, not 0 */
-       y = height - font_height - 1; /* Also inits for everyone, notice padding pixel */
-       
+       stamp_font_begin(12);
+
+       BLF_buffer(rectf, rect, width, height, channels);
+       BLF_buffer_col(scene->r.fg_stamp[0], scene->r.fg_stamp[1], scene->r.fg_stamp[2], 1.0);
+       pad= BLF_width("--");
+
+       x= 0;
+       y= height;
+
        if (stamp_data.file[0]) {
                /* Top left corner */
-               text_width = BMF_GetStringWidth(font, stamp_data.file);
-               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-               BMF_DrawStringBuf(font, stamp_data.file, x+(text_pad/2), y, scene->r.fg_stamp, rect, rectf, width, height, channels);
-               y -= font_height+2; /* Top and bottom 1 pix padding each */
+               BLF_width_and_height(stamp_data.file, &w, &h);
+               y -= h;
+
+               /* also a little of space to the background. */
+               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y-3, w+3, y+h+3);
+
+               /* and draw the text. */
+               BLF_position(x, y, 0.0);
+               BLF_draw_buffer(stamp_data.file);
+
+               /* the extra pixel for background. */
+               y -= 4;
        }
 
        /* Top left corner, below File */
        if (stamp_data.note[0]) {
-               text_width = BMF_GetStringWidth(font, stamp_data.note);
-               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-               BMF_DrawStringBuf(font, stamp_data.note, x+(text_pad/2), y, scene->r.fg_stamp, rect, rectf, width, height, channels);
-               y -= font_height+2; /* Top and bottom 1 pix padding each */
+               BLF_width_and_height(stamp_data.note, &w, &h);
+               y -= h;
+
+               /* and space for background. */
+               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-2, w+3, y+h+2);
+
+               BLF_position(x, y+1, 0.0);
+               BLF_draw_buffer(stamp_data.note);
+
+               /* the extra pixel for background. */
+               y -= 4;
        }
        
        /* Top left corner, below File (or Note) */
        if (stamp_data.date[0]) {
-               text_width = BMF_GetStringWidth(font, stamp_data.date);
-               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-               BMF_DrawStringBuf(font, stamp_data.date, x+(text_pad/2), y, scene->r.fg_stamp, rect, rectf, width, height, channels);
+               BLF_width_and_height(stamp_data.date, &w, &h);
+               y -= h;
+
+               /* and space for background. */
+               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+3);
+
+               BLF_position(x, y, 0.0);
+               BLF_draw_buffer(stamp_data.date);
        }
 
+       x= 0;
+       y= 0;
+
        /* Bottom left corner, leaving space for timing */
        if (stamp_data.marker[0]) {
-               x = 1;
-               y = font_height+2+1; /* 2 for padding in TIME|FRAME fields below and 1 for padding in this one */
-               text_width = BMF_GetStringWidth(font, stamp_data.marker);
-               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-               BMF_DrawStringBuf(font, stamp_data.marker, x+(text_pad/2), y, scene->r.fg_stamp, rect, rectf, width, height, channels);
+               BLF_width_and_height(stamp_data.marker, &w, &h);
+
+               /* extra space for background. */
+               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, w+2, y+h+3);
+
+               /* and pad the text. */
+               BLF_position(x, y+3, 0.0);
+               BLF_draw_buffer(stamp_data.marker);
+
+               /* space width. */
+               x += w + pad;
        }
        
        /* Left bottom corner */
        if (stamp_data.time[0]) {
-               x = 1;
-               y = 1;
-               text_width = BMF_GetStringWidth(font, stamp_data.time);
-               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-               BMF_DrawStringBuf(font, stamp_data.time, x+(text_pad/2), y, scene->r.fg_stamp, rect, rectf, width, height, channels);
-               x += text_width+text_pad+2; /* Both sides have 1 pix additional padding each */
+               BLF_width_and_height(stamp_data.time, &w, &h);
+
+               /* extra space for background */
+               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+3);
+
+               /* and pad the text. */
+               BLF_position(x, y+3, 0.0);
+               BLF_draw_buffer(stamp_data.time);
+
+               /* space width. */
+               x += w + pad;
        }
        
        if (stamp_data.frame[0]) {
-               text_width = BMF_GetStringWidth(font, stamp_data.frame);
-               /* Left bottom corner (after SMPTE if exists) */
-               if (!stamp_data.time[0])        x = 1;
-               y = 1;
-               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-               BMF_DrawStringBuf(font, stamp_data.frame, x+(text_pad/2), y, scene->r.fg_stamp, rect, rectf, width, height, channels);
+               BLF_width_and_height(stamp_data.frame, &w, &h);
+
+               /* extra space for background. */
+               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+3);
+
+               /* and pad the text. */
+               BLF_position(x, y+3, 0.0);
+
+               BLF_draw_buffer(stamp_data.frame);
+
+               /* space width. */
+               x += w + pad;
        }
 
        if (stamp_data.camera[0]) {
-               text_width = BMF_GetStringWidth(font, stamp_data.camera);
-               /* Center of bottom edge */
-               x = (width/2) - (BMF_GetStringWidth(font, stamp_data.camera)/2);
-               y = 1;
-               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-               BMF_DrawStringBuf(font, stamp_data.camera, x+(text_pad/2), y, scene->r.fg_stamp, rect, rectf, width, height, channels);
+               BLF_width_and_height(stamp_data.camera, &w, &h);
+
+               /* extra space for background. */
+               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+3);
+               BLF_position(x, y+3, 0.0);
+               BLF_draw_buffer(stamp_data.camera);
        }
        
        if (stamp_data.scene[0]) {
-               text_width = BMF_GetStringWidth(font, stamp_data.scene);
-               /* Bottom right corner */
-               x = width - (text_width+1+text_pad);
-               y = 1;
-               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-               BMF_DrawStringBuf(font, stamp_data.scene, x+(text_pad/2), y, scene->r.fg_stamp, rect, rectf, width, height, channels);
+               BLF_width_and_height(stamp_data.scene, &w, &h);
+
+               /* Bottom right corner, with an extra space because blenfont is too strict! */
+               x= width - w - 2;
+
+               /* extra space for background. */
+               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+3, y+h+3);
+
+               /* and pad the text. */
+               BLF_position(x, y+3, 0.0);
+               BLF_draw_buffer(stamp_data.scene);
        }
        
        if (stamp_data.strip[0]) {
-               text_width = BMF_GetStringWidth(font, stamp_data.strip);
-               /* Top right corner */
-               x = width - (text_width+1+text_pad);
-               y = height - font_height - 1;
-               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-               BMF_DrawStringBuf(font, stamp_data.strip, x+(text_pad/2), y, scene->r.fg_stamp, rect, rectf, width, height, channels);
-       }
-#endif // 0 XXX        
+               BLF_width_and_height(stamp_data.scene, &w, &h);
+
+               /* Top right corner, with an extra space because blenfont is too strict! */
+               x= width - w - pad;
+               y= height - h;
+
+               /* extra space for background. */
+               buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y-3, x+w+pad, y+h+3);
+
+               BLF_position(x, y, 0.0);
+               BLF_draw_buffer(stamp_data.strip);
+       }
+
+       /* cleanup the buffer. */
+       BLF_buffer(NULL, NULL, 0, 0, 0);
 }
 
 void BKE_stamp_info(Scene *scene, struct ImBuf *ibuf)