diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index c804fb6399d..7521b7815f1 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -310,7 +310,7 @@ void blf_font_fill(FontBLF *font) font->cache.last= NULL; font->glyph_cache= NULL; font->blur= 0; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&font->max_tex_size); + font->max_tex_size= -1; } 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 253d21cad5b..78df8ff2bc6 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -192,19 +192,15 @@ GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c) GlyphBLF *blf_glyph_add(FontBLF *font, FT_UInt index, unsigned int c) { FT_GlyphSlot slot; - GlyphCacheBLF *gc; GlyphBLF *g; FT_Error err; FT_Bitmap bitmap; FT_BBox bbox; unsigned int key; - int do_new; g= blf_glyph_search(font->glyph_cache, c); if (g) - do_new= 0; - else - do_new= 1; + return(g); err= FT_Load_Glyph(font->face, index, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP); if (err) @@ -217,47 +213,26 @@ GlyphBLF *blf_glyph_add(FontBLF *font, FT_UInt index, unsigned int c) if (err || slot->format != FT_GLYPH_FORMAT_BITMAP) return(NULL); - if (do_new) { - g= (GlyphBLF *)MEM_mallocN(sizeof(GlyphBLF), "blf_glyph_add"); - g->next= NULL; - g->prev= NULL; - g->c= c; - } - - gc= font->glyph_cache; - if (gc->cur_tex == -1) { - blf_glyph_cache_texture(font, gc); - gc->x_offs= gc->pad; - gc->y_offs= gc->pad; - } - - if (gc->x_offs > (gc->p2_width - gc->max_glyph_width)) { - gc->x_offs= gc->pad; - gc->y_offs += gc->max_glyph_height; - - if (gc->y_offs > (gc->p2_height - gc->max_glyph_height)) { - gc->y_offs= gc->pad; - blf_glyph_cache_texture(font, gc); - } - } - + g= (GlyphBLF *)MEM_mallocN(sizeof(GlyphBLF), "blf_glyph_add"); + g->next= NULL; + g->prev= NULL; + g->c= c; + g->tex= 0; + g->build_tex= 0; + g->bitmap= NULL; + g->xoff= -1; + g->yoff= -1; + g->uv[0][0]= 0.0f; + g->uv[0][1]= 0.0f; + g->uv[1][0]= 0.0f; + g->uv[1][1]= 0.0f; bitmap= slot->bitmap; - g->tex= gc->textures[gc->cur_tex]; - - g->xoff= gc->x_offs; - g->yoff= gc->y_offs; g->width= bitmap.width; g->height= bitmap.rows; if (g->width && g->height) { - glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); - glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - glBindTexture(GL_TEXTURE_2D, g->tex); - glTexSubImage2D(GL_TEXTURE_2D, 0, g->xoff, g->yoff, g->width, g->height, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.buffer); - glPopClientAttrib(); + g->bitmap= (unsigned char *)MEM_mallocN(g->width * g->height, "glyph bitmap"); + memcpy((void *)g->bitmap, (void *)bitmap.buffer, g->width * g->height); } g->advance= ((float)slot->advance.x) / 64.0f; @@ -270,20 +245,8 @@ GlyphBLF *blf_glyph_add(FontBLF *font, FT_UInt index, unsigned int c) g->box.ymin= ((float)bbox.yMin) / 64.0f; g->box.ymax= ((float)bbox.yMax) / 64.0f; - g->uv[0][0]= ((float)g->xoff) / ((float)gc->p2_width); - g->uv[0][1]= ((float)g->yoff) / ((float)gc->p2_height); - g->uv[1][0]= ((float)(g->xoff + g->width)) / ((float)gc->p2_width); - g->uv[1][1]= ((float)(g->yoff + g->height)) / ((float)gc->p2_height); - - /* update the x offset for the next glyph. */ - gc->x_offs += (int)(g->box.xmax - g->box.xmin + gc->pad); - - if (do_new) { - key= blf_hash(g->c); - BLI_addhead(&(gc->bucket[key]), g); - gc->rem_glyphs--; - } - + key= blf_hash(g->c); + BLI_addhead(&(font->glyph_cache->bucket[key]), g); return(g); } @@ -292,6 +255,8 @@ void blf_glyph_free(GlyphBLF *g) /* don't need free the texture, the GlyphCache already * have a list of all the texture and free it. */ + if (g->bitmap) + MEM_freeN(g->bitmap); MEM_freeN(g); } @@ -358,12 +323,63 @@ static void blf_texture3_draw(float uv[2][2], float x1, float y1, float x2, floa int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y) { + GlyphCacheBLF *gc; GLint cur_tex; float dx, dx1; float y1, y2; float xo, yo; float color[4]; + if ((!g->width) || (!g->height)) + return(1); + + if (g->build_tex == 0) { + gc= font->glyph_cache; + + if (font->max_tex_size == -1) + glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&font->max_tex_size); + + if (gc->cur_tex == -1) { + blf_glyph_cache_texture(font, gc); + gc->x_offs= gc->pad; + gc->y_offs= gc->pad; + } + + if (gc->x_offs > (gc->p2_width - gc->max_glyph_width)) { + gc->x_offs= gc->pad; + gc->y_offs += gc->max_glyph_height; + + if (gc->y_offs > (gc->p2_height - gc->max_glyph_height)) { + gc->y_offs= gc->pad; + blf_glyph_cache_texture(font, gc); + } + } + + g->tex= gc->textures[gc->cur_tex]; + g->xoff= gc->x_offs; + g->yoff= gc->y_offs; + + glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); + glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glBindTexture(GL_TEXTURE_2D, g->tex); + glTexSubImage2D(GL_TEXTURE_2D, 0, g->xoff, g->yoff, g->width, g->height, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap); + glPopClientAttrib(); + + g->uv[0][0]= ((float)g->xoff) / ((float)gc->p2_width); + g->uv[0][1]= ((float)g->yoff) / ((float)gc->p2_height); + g->uv[1][0]= ((float)(g->xoff + g->width)) / ((float)gc->p2_width); + g->uv[1][1]= ((float)(g->yoff + g->height)) / ((float)gc->p2_height); + + /* update the x offset for the next glyph. */ + gc->x_offs += (int)(g->box.xmax - g->box.xmin + gc->pad); + + gc->rem_glyphs--; + g->build_tex= 1; + } + xo= 0.0f; yo= 0.0f; diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index 60c2933eb61..d457225662f 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -98,6 +98,11 @@ typedef struct GlyphBLF { int xoff; int yoff; + /* Bitmap data, from freetype. Take care that this + * can be NULL. + */ + unsigned char *bitmap; + /* glyph width and height. */ int width; int height; @@ -111,6 +116,9 @@ typedef struct GlyphBLF { */ float pos_x; float pos_y; + + /* with value of zero mean that we need build the texture. */ + short build_tex; } GlyphBLF; typedef struct FontBLF {