Cleanup a little to add "draw to buffer" (and bring back stamp).
[blender.git] / source / blender / blenfont / intern / blf_glyph.c
index 253d21cad5bdd6b14b4bd3a30e05260f0ba27f95..78df8ff2bc668bf1b06ceec9312c328a238a0abd 100644 (file)
@@ -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;