diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index 933d287bcff..c01886be65e 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -48,10 +48,12 @@ void BLF_position(int fontid, float x, float y, float z); void BLF_size(int fontid, int size, int dpi); /* Draw the string using the default font, size and dpi. */ -void BLF_draw_default(float x, float y, float z, char *str); +void BLF_draw_default(float x, float y, float z, const char *str); +void BLF_draw_default_ascii(float x, float y, float z, const char *str); /* Draw the string using the current font. */ -void BLF_draw(int fontid, char *str); +void BLF_draw(int fontid, const char *str); +void BLF_draw_ascii(int fontid, const char *str); /* * This function return the bounding box of the string diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index f6b7c5f71e6..59189abf1e3 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -361,7 +361,7 @@ void BLF_blur(int fontid, int size) font->blur= size; } -void BLF_draw_default(float x, float y, float z, char *str) +void BLF_draw_default(float x, float y, float z, const char *str) { if (!str) return; @@ -378,6 +378,24 @@ void BLF_draw_default(float x, float y, float z, char *str) BLF_position(global_font_default, x, y, z); BLF_draw(global_font_default, str); } +/* same as above but call 'BLF_draw_ascii' */ +void BLF_draw_default_ascii(float x, float y, float z, const char *str) +{ + if (!str) + return; + + if (global_font_default == -1) + global_font_default= blf_search("default"); + + if (global_font_default == -1) { + printf("Warning: Can't found default font!!\n"); + return; + } + + BLF_size(global_font_default, global_font_points, global_font_dpi); + BLF_position(global_font_default, x, y, z); + BLF_draw_ascii(global_font_default, str); +} void BLF_rotation_default(float angle) { @@ -388,32 +406,49 @@ void BLF_rotation_default(float angle) font->angle= angle; } -void BLF_draw(int fontid, char *str) -{ - FontBLF *font; +static void blf_draw__start(FontBLF *font) +{ /* * The pixmap alignment hack is handle * in BLF_position (old ui_rasterpos_safe). */ - font= BLF_get(fontid); + + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glPushMatrix(); + glTranslatef(font->pos[0], font->pos[1], font->pos[2]); + glScalef(font->aspect, font->aspect, 1.0); + + if (font->flags & BLF_ROTATION) + glRotatef(font->angle, 0.0f, 0.0f, 1.0f); +} +static void blf_draw__end(void) +{ + glPopMatrix(); + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); +} + +void BLF_draw(int fontid, const char *str) +{ + FontBLF *font= BLF_get(fontid); if (font) { - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glPushMatrix(); - glTranslatef(font->pos[0], font->pos[1], font->pos[2]); - glScalef(font->aspect, font->aspect, 1.0); - - if (font->flags & BLF_ROTATION) - glRotatef(font->angle, 0.0f, 0.0f, 1.0f); - + blf_draw__start(font); blf_font_draw(font, str); + blf_draw__end(); + } +} - glPopMatrix(); - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); +void BLF_draw_ascii(int fontid, const char *str) +{ + FontBLF *font= BLF_get(fontid); + if (font) { + blf_draw__start(font); + blf_font_draw_ascii(font, str); + blf_draw__end(); } } diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 04f40ac825b..9fb40f0206d 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -92,7 +92,7 @@ void blf_font_size(FontBLF *font, int size, int dpi) } } -void blf_font_draw(FontBLF *font, char *str) +void blf_font_draw(FontBLF *font, const char *str) { unsigned int c; GlyphBLF *g, *g_prev; @@ -146,6 +146,65 @@ void blf_font_draw(FontBLF *font, char *str) } } +/* faster version of blf_font_draw, ascii only for view dimensions */ +void blf_font_draw_ascii(FontBLF *font, const char *str) +{ + char c; + GlyphBLF *g, *g_prev; + FT_Vector delta; + FT_UInt glyph_index; + int pen_x, pen_y; + int i, has_kerning, st; + + if (!font->glyph_cache) + return; + + i= 0; + pen_x= 0; + pen_y= 0; + has_kerning= FT_HAS_KERNING(font->face); + g_prev= NULL; + + /* build ascii on demand */ + if(font->glyph_ascii_table['0']==NULL) { + for(i=0; i<256; i++) { + g= blf_glyph_search(font->glyph_cache, i); + if (!g) { + glyph_index= FT_Get_Char_Index(font->face, i); + g= blf_glyph_add(font, glyph_index, i); + } + font->glyph_ascii_table[i]= g; + } + } + + while ((c= *(str++))) { + g= font->glyph_ascii_table[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; + } + + /* do not return this loop if clipped, we want every character tested */ + blf_glyph_render(font, g, (float)pen_x, (float)pen_y); + + pen_x += g->advance; + g_prev= g; + } +} + void blf_font_buffer(FontBLF *font, char *str) { unsigned char *cbuf; @@ -460,6 +519,8 @@ static void blf_font_fill(FontBLF *font) font->b_col[1]= 0; font->b_col[2]= 0; font->b_col[3]= 0; + + memset(font->glyph_ascii_table, 0, sizeof(font->glyph_ascii_table)); } FontBLF *blf_font_new(char *name, char *filename) diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h index 844a7a3c3de..c7a3cd54740 100644 --- a/source/blender/blenfont/intern/blf_internal.h +++ b/source/blender/blenfont/intern/blf_internal.h @@ -44,7 +44,8 @@ FontBLF *blf_font_new_from_mem(char *name, unsigned char *mem, int mem_size); void blf_font_attach_from_mem(FontBLF *font, const unsigned char *mem, int mem_size); void blf_font_size(FontBLF *font, int size, int dpi); -void blf_font_draw(FontBLF *font, char *str); +void blf_font_draw(FontBLF *font, const char *str); +void blf_font_draw_ascii(FontBLF *font, const 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); diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index 368eb8751de..70318c51823 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -177,6 +177,9 @@ typedef struct FontBLF { /* current glyph cache, size and dpi. */ GlyphCacheBLF *glyph_cache; + + /* fast ascii lookip */ + GlyphBLF *glyph_ascii_table[256]; /* freetype2 face. */ FT_Face face; diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c index 52bb90aa8f0..7035006ea70 100644 --- a/source/blender/editors/space_view3d/drawanimviz.c +++ b/source/blender/editors/space_view3d/drawanimviz.c @@ -31,6 +31,7 @@ #include #include +#include "BLO_sys_types.h" #include "DNA_anim_types.h" #include "DNA_armature_types.h" @@ -213,7 +214,7 @@ void draw_motion_path_instance(Scene *scene, if (i == 0) { sprintf(str, "%d", (i+sfra)); mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE); + view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII); } else if ((i > stepsize) && (i < len-stepsize)) { bMotionPathVert *mpvP = (mpv - stepsize); @@ -222,7 +223,7 @@ void draw_motion_path_instance(Scene *scene, if ((equals_v3v3(mpv->co, mpvP->co)==0) || (equals_v3v3(mpv->co, mpvN->co)==0)) { sprintf(str, "%d", (sfra+i)); mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE); + view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII); } } } @@ -280,7 +281,7 @@ void draw_motion_path_instance(Scene *scene, sprintf(str, "%d", (sfra+i)); mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE); + view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII); } } } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index d2285371667..8b9e960cdb3 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -558,10 +558,10 @@ static int CachedTextLevel= 0; typedef struct ViewCachedString { struct ViewCachedString *next, *prev; float vec[3], col[4]; - char str[128]; short mval[2]; short xoffs; short flag; + /* str is allocated past the end */ } ViewCachedString; void view3d_cached_text_draw_begin() @@ -573,15 +573,18 @@ void view3d_cached_text_draw_begin() void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag) { + int alloc_len= strlen(str) + 1; ListBase *strings= &CachedText[CachedTextLevel-1]; - ViewCachedString *vos= MEM_callocN(sizeof(ViewCachedString), "ViewCachedString"); + ViewCachedString *vos= MEM_callocN(sizeof(ViewCachedString) + alloc_len, "ViewCachedString"); BLI_addtail(strings, vos); - BLI_strncpy(vos->str, str, 128); copy_v3_v3(vos->vec, co); glGetFloatv(GL_CURRENT_COLOR, vos->col); vos->xoffs= xoffs; vos->flag= flag; + + /* allocate past the end */ + memcpy(++vos, str, alloc_len); } void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]) @@ -635,8 +638,14 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa } #endif if(vos->mval[0]!=IS_CLIPPED) { + const char *str= (char *)(vos+1); glColor3fv(vos->col); - BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, vos->str); + if(vos->flag & V3D_CACHE_TEXT_ASCII) { + BLF_draw_default_ascii((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, str); + } + else { + BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, str); + } } } @@ -1809,8 +1818,9 @@ static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int i static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol) { - unsigned char *cols[2] = {baseCol, selCol}; - + unsigned char *cols[2]; + cols[0]= baseCol; + cols[1]= selCol; dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols); } @@ -2113,7 +2123,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E else sprintf(val, conv_float, len_v3v3(v1, v2)); - view3d_cached_text_draw_add(vmid, val, 0, 0); + view3d_cached_text_draw_add(vmid, val, 0, V3D_CACHE_TEXT_ASCII); } } } @@ -2152,7 +2162,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E else sprintf(val, conv_float, area); - view3d_cached_text_draw_add(efa->cent, val, 0, 0); + view3d_cached_text_draw_add(efa->cent, val, 0, V3D_CACHE_TEXT_ASCII); } } } @@ -2194,13 +2204,13 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E /* Vec 1 */ sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v4, v1, v2))); interp_v3_v3v3(fvec, efa->cent, efa->v1->co, 0.8f); - view3d_cached_text_draw_add(fvec, val, 0, 0); + view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII); } if( (e1->f & e2->f & SELECT) || (do_moving && (efa->v2->f & SELECT)) ) { /* Vec 2 */ sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v1, v2, v3))); interp_v3_v3v3(fvec, efa->cent, efa->v2->co, 0.8f); - view3d_cached_text_draw_add(fvec, val, 0, 0); + view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII); } if( (e2->f & e3->f & SELECT) || (do_moving && (efa->v3->f & SELECT)) ) { /* Vec 3 */ @@ -2209,14 +2219,14 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E else sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v2, v3, v1))); interp_v3_v3v3(fvec, efa->cent, efa->v3->co, 0.8f); - view3d_cached_text_draw_add(fvec, val, 0, 0); + view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII); } /* Vec 4 */ if(efa->v4) { if( (e3->f & e4->f & SELECT) || (do_moving && (efa->v4->f & SELECT)) ) { sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v3, v4, v1))); interp_v3_v3v3(fvec, efa->cent, efa->v4->co, 0.8f); - view3d_cached_text_draw_add(fvec, val, 0, 0); + view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII); } } } @@ -3827,16 +3837,24 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv char *val_pos= val; val[0]= '\0'; - if(part->draw&PART_DRAW_NUM) - val_pos += sprintf(val, "%i", a); - - if((part->draw & PART_DRAW_HEALTH) && a < totpart && part->phystype==PART_PHYS_BOIDS) - sprintf(val_pos, (val_pos==val) ? "%.2f" : ":%.2f", pa_health); + if(part->draw&PART_DRAW_NUM) { + if(a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype==PART_PHYS_BOIDS)) { + sprintf(val_pos, "%d:%.2f", a, pa_health); + } + else { + sprintf(val_pos, "%d", a); + } + } + else { + if(a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype==PART_PHYS_BOIDS)) { + sprintf(val_pos, "%.2f", pa_health); + } + } /* in path drawing state.co is the end point */ /* use worldspace beause object matrix is already applied */ mul_v3_m4v3(vec_txt, ob->imat, state.co); - view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE); + view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII); } } } @@ -3925,12 +3943,10 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv for(a=0, pa=psys->particles; aimat, cache[a]->co); - view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE); + view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII); } } } @@ -5513,11 +5529,11 @@ void drawRBpivot(bRigidBodyJointConstraint *data) glVertex3fv(v); glEnd(); if (axis==0) - view3d_cached_text_draw_add(v, "px", 0, 0); + view3d_cached_text_draw_add(v, "px", 0, V3D_CACHE_TEXT_ASCII); else if (axis==1) - view3d_cached_text_draw_add(v, "py", 0, 0); + view3d_cached_text_draw_add(v, "py", 0, V3D_CACHE_TEXT_ASCII); else - view3d_cached_text_draw_add(v, "pz", 0, 0); + view3d_cached_text_draw_add(v, "pz", 0, V3D_CACHE_TEXT_ASCII); } glLineWidth (1.0f); setlinestyle(0); diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 0d8b97a66ed..92167f0f45e 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -115,8 +115,9 @@ void drawaxes(float size, char drawtype); void view3d_cached_text_draw_begin(void); void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag); void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]); -#define V3D_CACHE_TEXT_ZBUF 1 -#define V3D_CACHE_TEXT_WORLDSPACE 2 +#define V3D_CACHE_TEXT_ZBUF (1<<0) +#define V3D_CACHE_TEXT_WORLDSPACE (1<<1) +#define V3D_CACHE_TEXT_ASCII (1<<2) /* drawarmature.c */ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag);