[Bf-blender-cvs] [ecdc8de] temp-blf-wordwrap: Initial BLF word-wrapping support
Campbell Barton
noreply at git.blender.org
Fri Aug 28 18:35:31 CEST 2015
Commit: ecdc8de661a002471f932ef1b9036e9fee78507e
Author: Campbell Barton
Date: Sat Aug 29 01:59:26 2015 +1000
Branches: temp-blf-wordwrap
https://developer.blender.org/rBecdc8de661a002471f932ef1b9036e9fee78507e
Initial BLF word-wrapping support
Avoid code duplication by using single word-wrap function
which takes a callback to do the actual work.
===================================================================
M source/blender/blenfont/BLF_api.h
M source/blender/blenfont/intern/blf.c
M source/blender/blenfont/intern/blf_font.c
M source/blender/blenfont/intern/blf_internal.h
===================================================================
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index d8dee71..49fc2be 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -210,6 +210,7 @@ void BLF_state_print(int fontid);
#define BLF_MATRIX (1 << 4)
#define BLF_ASPECT (1 << 5)
#define BLF_HINTING (1 << 6)
+#define BLF_WORDWRAP (1 << 7)
#define BLF_DRAW_STR_DUMMY_MAX 1024
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 127826f..9402a17 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -561,7 +561,12 @@ void BLF_draw(int fontid, const char *str, size_t len)
if (font && font->glyph_cache) {
blf_draw__start(font, &mode, ¶m);
- blf_font_draw(font, str, len);
+ if (font->flags & BLF_WORDWRAP) {
+ blf_font_draw__wrap(font, str, len);
+ }
+ else {
+ blf_font_draw(font, str, len, 0);
+ }
blf_draw__end(mode, param);
}
}
@@ -573,7 +578,12 @@ void BLF_draw_ascii(int fontid, const char *str, size_t len)
if (font && font->glyph_cache) {
blf_draw__start(font, &mode, ¶m);
- blf_font_draw_ascii(font, str, len);
+ if (font->flags & BLF_WORDWRAP) {
+ blf_font_draw_ascii__wrap(font, str, len);
+ }
+ else {
+ blf_font_draw_ascii(font, str, len, 0);
+ }
blf_draw__end(mode, param);
}
}
@@ -638,7 +648,7 @@ void BLF_boundbox(int fontid, const char *str, size_t len, rctf *box)
FontBLF *font = blf_get(fontid);
if (font) {
- blf_font_boundbox(font, str, len, box);
+ blf_font_boundbox(font, str, len, 0, box);
}
}
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 46e0e0e..97594f0 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -174,12 +174,12 @@ static void blf_font_ensure_ascii_table(FontBLF *font)
} \
} (void)0
-void blf_font_draw(FontBLF *font, const char *str, size_t len)
+void blf_font_draw(FontBLF *font, const char *str, size_t len, int pen_y)
{
unsigned int c;
GlyphBLF *g, *g_prev = NULL;
FT_Vector delta;
- int pen_x = 0, pen_y = 0;
+ int pen_x = 0;
size_t i = 0;
GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
@@ -206,12 +206,12 @@ void blf_font_draw(FontBLF *font, const char *str, size_t len)
}
/* faster version of blf_font_draw, ascii only for view dimensions */
-void blf_font_draw_ascii(FontBLF *font, const char *str, size_t len)
+void blf_font_draw_ascii(FontBLF *font, const char *str, size_t len, int pen_y)
{
unsigned char c;
GlyphBLF *g, *g_prev = NULL;
FT_Vector delta;
- int pen_x = 0, pen_y = 0;
+ int pen_x = 0;
GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
BLF_KERNING_VARS(font, has_kerning, kern_mode);
@@ -558,12 +558,12 @@ size_t blf_font_width_to_rstrlen(FontBLF *font, const char *str, size_t len, flo
return i_prev;
}
-void blf_font_boundbox(FontBLF *font, const char *str, size_t len, rctf *box)
+void blf_font_boundbox(FontBLF *font, const char *str, size_t len, int pen_y, rctf *box)
{
unsigned int c;
GlyphBLF *g, *g_prev = NULL;
FT_Vector delta;
- int pen_x = 0, pen_y = 0;
+ int pen_x = 0;
size_t i = 0;
GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
@@ -611,6 +611,128 @@ void blf_font_boundbox(FontBLF *font, const char *str, size_t len, rctf *box)
}
}
+
+
+/* -------------------------------------------------------------------- */
+/** \name Word-Wrap Support
+ * \{ */
+
+struct WordWrapVars {
+ int x_span;
+ size_t start, last[2];
+};
+
+#define BLF_WORDWRAP_VARS(_font, _wrap) \
+ struct WordWrapVars _wrap = {(int)_font->clip_rec.xmax - (int)_font->pos[0], 0, {0, 0}}
+
+/**
+ * Generic function to add word-wrap support for other existing functions.
+ */
+static void blf_font_wrap_apply(
+ FontBLF *font, const char *str, size_t len,
+ void (*callback)(FontBLF *font, const char *str, size_t len, int pen_y, void *userdata),
+ void *userdata)
+{
+ unsigned int c;
+ GlyphBLF *g, *g_prev = NULL;
+ FT_Vector delta;
+ int pen_x = 0, pen_y = 0;
+ size_t i = 0;
+ GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
+
+ BLF_KERNING_VARS(font, has_kerning, kern_mode);
+
+ BLF_WORDWRAP_VARS(font, wrap);
+
+ blf_font_ensure_ascii_table(font);
+
+ while ((i < len) && str[i]) {
+
+ /* wrap vars */
+ size_t i_curr = i;
+ int pen_x_next;
+ bool do_draw = false;
+
+ BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
+
+ if (UNLIKELY(c == BLI_UTF8_ERR))
+ break;
+ if (UNLIKELY(g == NULL))
+ continue;
+ if (has_kerning)
+ BLF_KERNING_STEP(font, kern_mode, g_prev, g, delta, pen_x);
+
+ pen_x_next = pen_x + g->advance_i;
+ if (UNLIKELY((pen_x_next >= wrap.x_span) && (wrap.start != wrap.last[0]))) {
+ do_draw = true;
+ }
+ else if (UNLIKELY(((i < len) && str[i]) == 0)) {
+ wrap.last[0] = i;
+ wrap.last[1] = i;
+ do_draw = true;
+ }
+ else if (UNLIKELY(g->c != ' ' && (g_prev ? g_prev->c == ' ' : false))) {
+ wrap.last[0] = i_curr;
+ wrap.last[1] = i;
+ }
+
+ if (UNLIKELY(do_draw)) {
+ callback(font, &str[wrap.start], (wrap.last[0] - wrap.start), pen_y, userdata);
+ wrap.start = wrap.last[0];
+ i = wrap.last[1];
+ pen_x = 0;
+ pen_y -= font->glyph_cache->max_glyph_height;
+ g_prev = NULL;
+ continue;
+ }
+
+ pen_x = pen_x_next;
+ g_prev = g;
+ }
+}
+
+/* blf_font_draw__wrap */
+static void blf_font_draw__wrap_cb(FontBLF *font, const char *str, size_t len, int pen_y, void *UNUSED(userdata))
+{
+ blf_font_draw(font, str, len, pen_y);
+}
+void blf_font_draw__wrap(FontBLF *font, const char *str, size_t len)
+{
+ blf_font_wrap_apply(font, str, len, blf_font_draw__wrap_cb, NULL);
+}
+
+/* blf_font_draw_ascii__wrap */
+static void blf_font_draw_ascii__wrap_cb(FontBLF *font, const char *str, size_t len, int pen_y, void *UNUSED(userdata))
+{
+ blf_font_draw_ascii(font, str, len, pen_y);
+}
+void blf_font_draw_ascii__wrap(FontBLF *font, const char *str, size_t len)
+{
+ blf_font_wrap_apply(font, str, len, blf_font_draw_ascii__wrap_cb, NULL);
+}
+
+/* blf_font_boundbox__wrap */
+static void blf_font_boundbox_wrap_cb(FontBLF *font, const char *str, size_t len, int pen_y, void *userdata)
+{
+ rctf *box = userdata;
+ rctf box_single;
+
+ blf_font_boundbox(font, str, len, pen_y, &box_single);
+ BLI_rctf_union(box, &box_single);
+}
+void blf_font_boundbox__wrap(FontBLF *font, const char *str, size_t len, rctf *box)
+{
+ box->xmin = 32000.0f;
+ box->xmax = -32000.0f;
+ box->ymin = 32000.0f;
+ box->ymax = -32000.0f;
+
+ blf_font_wrap_apply(font, str, len, blf_font_boundbox_wrap_cb, box);
+}
+
+/** \} */
+
+
void blf_font_width_and_height(FontBLF *font, const char *str, size_t len, float *width, float *height)
{
float xa, ya;
@@ -625,7 +747,12 @@ void blf_font_width_and_height(FontBLF *font, const char *str, size_t len, float
ya = 1.0f;
}
- blf_font_boundbox(font, str, len, &box);
+ if (font->flags & BLF_WORDWRAP) {
+ blf_font_boundbox__wrap(font, str, len, &box);
+ }
+ else {
+ blf_font_boundbox(font, str, len, 0, &box);
+ }
*width = (BLI_rctf_size_x(&box) * xa);
*height = (BLI_rctf_size_y(&box) * ya);
}
@@ -640,7 +767,12 @@ float blf_font_width(FontBLF *font, const char *str, size_t len)
else
xa = 1.0f;
- blf_font_boundbox(font, str, len, &box);
+ if (font->flags & BLF_WORDWRAP) {
+ blf_font_boundbox__wrap(font, str, len, &box);
+ }
+ else {
+ blf_font_boundbox(font, str, len, 0, &box);
+ }
return BLI_rctf_size_x(&box) * xa;
}
@@ -654,7 +786,12 @@ float blf_font_height(FontBLF *font, const char *str, size_t len)
else
ya = 1.0f;
- blf_font_boundbox(font, str, len, &box);
+ if (font->flags & BLF_WORDWRAP) {
+ blf_font_boundbox__wrap(font, str, len, &box);
+ }
+ else {
+ blf_font_boundbox(font, str, len, 0, &box);
+ }
return BLI_rctf_size_y(&box) * ya;
}
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index 85410a4..515e46e 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -51,13 +51,16 @@ struct FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem
void blf_font_attach_from_mem(struct FontBLF *font, const unsigned char *mem, int mem_size);
void blf_font_size(struct FontBLF *font, unsigned int size, unsigned int dpi);
-void blf_font_draw(struct FontBLF *font, const char *str, size_t len);
-void blf_font_draw_ascii(struct FontBLF *font, const char *str, size_t len);
+void blf_font_draw(struct FontBLF *font, const char *str, size_t len, int pen_y);
+void blf_font_draw__wrap(struct FontBLF *font, const char *str, size_t len);
+void blf_font_draw_ascii(struct FontBLF *font, const char *str, size_t len, int pen_y);
+void blf_font_draw_ascii__wrap(struct FontBLF *font, const char *str, size_t len);
int blf_font_draw_mono(struct FontBLF *font, const char *str, size_t len, int cwidth);
void blf_font_buffer(struct FontBLF *font, const char *str);
size_t blf_font_width_to_strlen(struct FontBLF *font, const char *str, size_t len, float width, float *r_width);
size_t blf_font_width_to_rstrlen(struct FontBLF *font, const char *str, size_t len, float width, float *r_width);
-void blf_font_boundbox(struct FontBLF *font, const char *str, size_t len, struct rctf *box);
+void blf_font_boundbox(struct FontBLF *font, const char *str, size_t len, int pen_y, struct rctf *box);
+void blf_font_boundbox__wrap(struct FontBLF *font, const char *str, size_t len, struct rctf *box);
void blf_font_width_and_height(struct FontBLF *font, const char *str, size_t len, float *width, float *height);
float blf_font_width(struct FontBLF *font, const char *str, size_t len);
float blf_font_height(struct FontBLF *font, const char *str, size_t len);
More information about the Bf-blender-cvs
mailing list