From 866f986898cf6c35e8b4d5190853e453a3eb1714 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 12 Aug 2012 22:18:20 +0000 Subject: [PATCH] fix for stamp text drawing into a color buffer not taking color management into account. --- source/blender/blenfont/BLF_api.h | 2 +- source/blender/blenfont/intern/blf.c | 23 ++--- source/blender/blenfont/intern/blf_font.c | 83 +++++++++++-------- .../blenfont/intern/blf_internal_types.h | 39 +++++---- source/blender/blenkernel/intern/image.c | 4 +- source/blender/blenkernel/intern/image_gen.c | 4 +- 6 files changed, 89 insertions(+), 66 deletions(-) diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index 364d5f90af3..7f50e157f09 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -151,7 +151,7 @@ void BLF_shadow_offset(int fontid, int x, int y); * * BLF_buffer(NULL, NULL, 0, 0, 0); */ -void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch); +void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch, int is_linear); /* Set the color to be used for text. */ void BLF_buffer_col(int fontid, float r, float g, float b, float a); diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 683ef3f821c..6857ec7874d 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -746,16 +746,17 @@ void BLF_shadow_offset(int fontid, int x, int y) } } -void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch) +void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch, int is_linear) { FontBLF *font = BLF_get(fontid); if (font) { - font->b_fbuf = fbuf; - font->b_cbuf = cbuf; - font->bw = w; - font->bh = h; - font->bch = nch; + font->buf_info.fbuf = fbuf; + font->buf_info.cbuf = cbuf; + font->buf_info.w = w; + font->buf_info.h = h; + font->buf_info.ch = nch; + font->buf_info.is_linear = is_linear; } } @@ -764,10 +765,10 @@ void BLF_buffer_col(int fontid, float r, float g, float b, float a) FontBLF *font = BLF_get(fontid); if (font) { - font->b_col[0] = r; - font->b_col[1] = g; - font->b_col[2] = b; - font->b_col[3] = a; + font->buf_info.col[0] = r; + font->buf_info.col[1] = g; + font->buf_info.col[2] = b; + font->buf_info.col[3] = a; } } @@ -775,7 +776,7 @@ void BLF_draw_buffer(int fontid, const char *str) { FontBLF *font = BLF_get(fontid); - if (font && font->glyph_cache && (font->b_fbuf || font->b_cbuf)) { + if (font && font->glyph_cache && (font->buf_info.fbuf || font->buf_info.cbuf)) { blf_font_buffer(font, str); } } diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 945565e22a9..97b88028868 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -225,11 +225,14 @@ void blf_font_buffer(FontBLF *font, const char *str) size_t i = 0; GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table; - /* buffer specific vars*/ - const unsigned char b_col_char[4] = {font->b_col[0] * 255, - font->b_col[1] * 255, - font->b_col[2] * 255, - font->b_col[3] * 255}; + /* buffer specific vars */ + FontBufInfoBLF *buf_info = &font->buf_info; + float b_col_float[4]; + const unsigned char b_col_char[4] = {buf_info->col[0] * 255, + buf_info->col[1] * 255, + buf_info->col[2] * 255, + buf_info->col[3] * 255}; + unsigned char *cbuf; int chx, chy; int y, x; @@ -239,6 +242,14 @@ void blf_font_buffer(FontBLF *font, const char *str) blf_font_ensure_ascii_table(font); + /* another buffer spesific call for color conversion */ + if (buf_info->is_linear) { + srgb_to_linearrgb_v4(b_col_float, buf_info->col); + } + else { + copy_v4_v4(b_col_float, buf_info->col); + } + while (str[i]) { BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table); @@ -259,16 +270,16 @@ void blf_font_buffer(FontBLF *font, const char *str) pen_y = (int)font->pos[1] - (g->height - (int)g->pos_y); } - if ((chx + g->width) >= 0 && chx < font->bw && (pen_y + g->height) >= 0 && pen_y < font->bh) { + if ((chx + g->width) >= 0 && chx < buf_info->w && (pen_y + g->height) >= 0 && pen_y < buf_info->h) { /* don't draw beyond the buffer bounds */ int width_clip = g->width; int height_clip = g->height; int yb_start = g->pitch < 0 ? 0 : g->height - 1; - if (width_clip + chx > font->bw) - width_clip -= chx + width_clip - font->bw; - if (height_clip + pen_y > font->bh) - height_clip -= pen_y + height_clip - font->bh; + if (width_clip + chx > buf_info->w) + width_clip -= chx + width_clip - buf_info->w; + if (height_clip + pen_y > buf_info->h) + height_clip -= pen_y + height_clip - buf_info->h; /* drawing below the image? */ if (pen_y < 0) { @@ -277,7 +288,7 @@ void blf_font_buffer(FontBLF *font, const char *str) pen_y = 0; } - if (font->b_fbuf) { + if (buf_info->fbuf) { int yb = yb_start; for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) { for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) { @@ -285,18 +296,18 @@ void blf_font_buffer(FontBLF *font, const char *str) if (a > 0.0f) { float alphatest; - fbuf = font->b_fbuf + font->bch * ((chx + x) + ((pen_y + y) * font->bw)); + fbuf = buf_info->fbuf + buf_info->ch * ((chx + x) + ((pen_y + y) * buf_info->w)); if (a >= 1.0f) { - fbuf[0] = font->b_col[0]; - fbuf[1] = font->b_col[1]; - fbuf[2] = font->b_col[2]; - fbuf[3] = (alphatest = (fbuf[3] + (font->b_col[3]))) < 1.0f ? alphatest : 1.0f; + fbuf[0] = b_col_float[0]; + fbuf[1] = b_col_float[1]; + fbuf[2] = b_col_float[2]; + fbuf[3] = (alphatest = (fbuf[3] + (b_col_float[3]))) < 1.0f ? alphatest : 1.0f; } 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)); - fbuf[3] = (alphatest = (fbuf[3] + (font->b_col[3] * a))) < 1.0f ? alphatest : 1.0f; + fbuf[0] = (b_col_float[0] * a) + (fbuf[0] * (1 - a)); + fbuf[1] = (b_col_float[1] * a) + (fbuf[1] * (1 - a)); + fbuf[2] = (b_col_float[2] * a) + (fbuf[2] * (1 - a)); + fbuf[3] = (alphatest = (fbuf[3] + (b_col_float[3] * a))) < 1.0f ? alphatest : 1.0f; } } } @@ -308,7 +319,7 @@ void blf_font_buffer(FontBLF *font, const char *str) } } - if (font->b_cbuf) { + if (buf_info->cbuf) { int yb = yb_start; for (y = 0; y < height_clip; y++) { for (x = 0; x < width_clip; x++) { @@ -316,7 +327,7 @@ void blf_font_buffer(FontBLF *font, const char *str) if (a > 0.0f) { int alphatest; - cbuf = font->b_cbuf + font->bch * ((chx + x) + ((pen_y + y) * font->bw)); + cbuf = buf_info->cbuf + buf_info->ch * ((chx + x) + ((pen_y + y) * buf_info->w)); if (a >= 1.0f) { cbuf[0] = b_col_char[0]; cbuf[1] = b_col_char[1]; @@ -324,10 +335,10 @@ void blf_font_buffer(FontBLF *font, const char *str) cbuf[3] = (alphatest = ((int)cbuf[3] + (int)b_col_char[3])) < 255 ? alphatest : 255; } else { - cbuf[0] = (b_col_char[0] * a) + (cbuf[0] * (1 - a)); - cbuf[1] = (b_col_char[1] * a) + (cbuf[1] * (1 - a)); - cbuf[2] = (b_col_char[2] * a) + (cbuf[2] * (1 - a)); - cbuf[3] = (alphatest = ((int)cbuf[3] + (int)((font->b_col[3] * a) * 255.0f))) < + cbuf[0] = (b_col_char[0] * a) + (cbuf[0] * (1.0f - a)); + cbuf[1] = (b_col_char[1] * a) + (cbuf[1] * (1.0f - a)); + cbuf[2] = (b_col_char[2] * a) + (cbuf[2] * (1.0f - a)); + cbuf[3] = (alphatest = ((int)cbuf[3] + (int)((b_col_float[3] * a) * 255.0f))) < 255 ? alphatest : 255; } } @@ -507,15 +518,17 @@ static 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; + + font->buf_info.fbuf = NULL; + font->buf_info.cbuf = NULL; + font->buf_info.w = 0; + font->buf_info.h = 0; + font->buf_info.ch = 0; + font->buf_info.col[0] = 0; + font->buf_info.col[1] = 0; + font->buf_info.col[2] = 0; + font->buf_info.col[3] = 0; + font->ft_lib = ft_lib; } diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index bf9b9858348..177b02a9598 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -131,6 +131,28 @@ typedef struct GlyphBLF { short build_tex; } GlyphBLF; +typedef struct FontBufInfoBLF { + /* for draw to buffer, always set this to NULL after finish! */ + float *fbuf; + + /* the same but unsigned char */ + unsigned char *cbuf; + + /* buffer size, keep signed so comparisons with negative values work */ + int w; + int h; + + /* number of channels. */ + int ch; + + /* is the float buffer linear */ + int is_linear; + + /* and the color, the alphas is get from the glyph! + * color is srgb space */ + float col[4]; +} FontBufInfoBLF; + typedef struct FontBLF { /* font name. */ char *name; @@ -198,21 +220,8 @@ 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, keep signed so comparisons with negative values work */ - int bw; - int bh; - - /* number of channels. */ - int bch; - - /* and the color, the alphas is get from the glyph! */ - float b_col[4]; + /* data for buffer usage (drawing into a texture buffer) */ + FontBufInfoBLF buf_info; } FontBLF; typedef struct DirBLF { diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 1adf2c891e3..4bd47f391af 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1491,7 +1491,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* set before return */ BLF_size(mono, scene->r.stamp_font_id, 72); - BLF_buffer(mono, rectf, rect, width, height, channels); + BLF_buffer(mono, rectf, rect, width, height, channels, (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) != 0); BLF_buffer_col(mono, scene->r.fg_stamp[0], scene->r.fg_stamp[1], scene->r.fg_stamp[2], 1.0); pad = BLF_width_max(mono); @@ -1668,7 +1668,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec } /* cleanup the buffer. */ - BLF_buffer(mono, NULL, NULL, 0, 0, 0); + BLF_buffer(mono, NULL, NULL, 0, 0, 0, FALSE); #undef BUFF_MARGIN_X #undef BUFF_MARGIN_Y diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c index d460368784a..4d7013b9f73 100644 --- a/source/blender/blenkernel/intern/image_gen.c +++ b/source/blender/blenkernel/intern/image_gen.c @@ -289,7 +289,7 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width BLF_size(mono, 54, 72); /* hard coded size! */ - BLF_buffer(mono, rect_float, rect, width, height, 4); + BLF_buffer(mono, rect_float, rect, width, height, 4, TRUE); for (y = 0; y < height; y += step) { text[1] = '1'; @@ -330,7 +330,7 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width } /* cleanup the buffer. */ - BLF_buffer(mono, NULL, NULL, 0, 0, 0); + BLF_buffer(mono, NULL, NULL, 0, 0, 0, FALSE); } void BKE_image_buf_fill_checker_color(unsigned char *rect, float *rect_float, int width, int height)