[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19577] branches/blender2.5/blender/source /blender/blenfont: New Bitmap draw mode for Freetype2 fonts.

Diego Borghetti bdiego at gmail.com
Tue Apr 7 10:42:28 CEST 2009


Revision: 19577
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19577
Author:   bdiego
Date:     2009-04-07 10:42:28 +0200 (Tue, 07 Apr 2009)

Log Message:
-----------
New Bitmap draw mode for Freetype2 fonts.

The library can load any font supported by the Freetype2 library or
used the internal bitmap font.

With both types it's possible draw the text as texture or bitmap,
and using texture it's possible rotate, scale and clipping text.

Still have things to fix/add, but I think it's ready to move-on
and start droping the old api, most of (if it's not all) the
editors/interface/text.c will be remove, but some things still
has to be define, like:

 * Where is store the fonts ? (default font, panel font, filesel font, etc)
   I mean, every space have own fonts ? or we keep it on the context ?
   It's not a really problem from the blenfont side, because every font
   have reference number, so it's load only the first time.

 * What we do about gettext ?
   Keep the old system that call gettext inside the blenfont or replace
   it for _() in the Blender source ?
   Also things like pupmen has to be take care, if we want translate the menu.

Ok, time to sleep, back tomorrow to start moving the things :)

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/blenfont/BLF_api.h
    branches/blender2.5/blender/source/blender/blenfont/intern/blf.c
    branches/blender2.5/blender/source/blender/blenfont/intern/blf_font.c
    branches/blender2.5/blender/source/blender/blenfont/intern/blf_glyph.c
    branches/blender2.5/blender/source/blender/blenfont/intern/blf_internal.c
    branches/blender2.5/blender/source/blender/blenfont/intern/blf_internal_types.h

Modified: branches/blender2.5/blender/source/blender/blenfont/BLF_api.h
===================================================================
--- branches/blender2.5/blender/source/blender/blenfont/BLF_api.h	2009-04-07 07:46:58 UTC (rev 19576)
+++ branches/blender2.5/blender/source/blender/blenfont/BLF_api.h	2009-04-07 08:42:28 UTC (rev 19577)
@@ -37,24 +37,41 @@
 int BLF_load(char *name);
 int BLF_load_mem(char *name, unsigned char *mem, int mem_size);
 
+/*
+ * Set/Get the current font.
+ */
 void BLF_set(int fontid);
+int BLF_get(void);
+
 void BLF_aspect(float aspect);
 void BLF_position(float x, float y, float z);
 void BLF_size(int size, int dpi);
 void BLF_draw(char *str);
 
+/*
+ * This function return the bounding box of the string
+ * and are not multiplied by the aspect.
+ */
 void BLF_boundbox(char *str, struct rctf *box);
+
+/*
+ * The next both function return the width and height
+ * of the string, using the current font and both value 
+ * are multiplied by the aspect of the font.
+ */
 float BLF_width(char *str);
 float BLF_height(char *str);
+
+/*
+ * By default, rotation and clipping are disable and
+ * have to be enable/disable using BLF_enable/disable.
+ */
 void BLF_rotation(float angle);
 void BLF_clipping(float xmin, float ymin, float xmax, float ymax);
 
 void BLF_enable(int option);
 void BLF_disable(int option);
 
-/* return the id of the current font. */
-int BLF_get(void);
-
 /* Read the .Blanguages file, return 1 on success or 0 if fails. */
 int BLF_lang_init(void);
 

Modified: branches/blender2.5/blender/source/blender/blenfont/intern/blf.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenfont/intern/blf.c	2009-04-07 07:46:58 UTC (rev 19576)
+++ branches/blender2.5/blender/source/blender/blenfont/intern/blf.c	2009-04-07 08:42:28 UTC (rev 19577)
@@ -284,14 +284,25 @@
 {
 	FontBLF *font;
 
+	/*
+	 * The pixmap alignment hack is handle
+	 * in BLF_position (old ui_rasterpos_safe).
+	 */
+
 	font= global_font[global_font_cur];
 	if (font && font->draw) {
 		if (font->mode == BLF_MODE_BITMAP) {
-			/* the pixmap alignment is handle
-			 * in BLF_position (old ui_rasterpos_safe).
-			 */
+			glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
+			glPushAttrib(GL_ENABLE_BIT);
+			glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
+			glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
+			glDisable(GL_BLEND);
 			glRasterPos3f(font->pos[0], font->pos[1], font->pos[2]);
+
 			(*font->draw)(font, str);
+
+			glPopAttrib();
+			glPopClientAttrib();
 		}
 		else {
 			glEnable(GL_BLEND);

Modified: branches/blender2.5/blender/source/blender/blenfont/intern/blf_font.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenfont/intern/blf_font.c	2009-04-07 07:46:58 UTC (rev 19576)
+++ branches/blender2.5/blender/source/blender/blenfont/intern/blf_font.c	2009-04-07 08:42:28 UTC (rev 19577)
@@ -135,6 +135,17 @@
 		if (!g)
 			continue;
 
+		/*
+		 * This happen if we change the mode of the
+		 * font, we don't drop the glyph cache, so it's
+		 * possible that some glyph don't have the
+		 * bitmap or texture information.
+		 */
+		if (font->mode == BLF_MODE_BITMAP && (!g->bitmap_data))
+			g= blf_glyph_add(font, glyph_index, c);
+		else if (font->mode == BLF_MODE_TEXTURE && (!g->tex_data))
+			g= blf_glyph_add(font, glyph_index, c);
+
 		if (has_kerning && g_prev) {
 			delta.x= 0;
 			delta.y= 0;
@@ -194,6 +205,17 @@
 		if (!g)
 			continue;
 
+		/*
+		 * This happen if we change the mode of the
+		 * font, we don't drop the glyph cache, so it's
+		 * possible that some glyph don't have the
+		 * bitmap or texture information.
+		 */
+		if (font->mode == BLF_MODE_BITMAP && (!g->bitmap_data))
+			g= blf_glyph_add(font, glyph_index, c);
+		else if (font->mode == BLF_MODE_TEXTURE && (!g->tex_data))
+			g= blf_glyph_add(font, glyph_index, c);
+
 		if (has_kerning && g_prev) {
 			delta.x= 0;
 			delta.y= 0;

Modified: branches/blender2.5/blender/source/blender/blenfont/intern/blf_glyph.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenfont/intern/blf_glyph.c	2009-04-07 07:46:58 UTC (rev 19576)
+++ branches/blender2.5/blender/source/blender/blenfont/intern/blf_glyph.c	2009-04-07 08:42:28 UTC (rev 19577)
@@ -197,20 +197,30 @@
 	return(NULL);
 }
 
-GlyphBLF *blf_glyph_add(FontBLF *font, FT_UInt index, unsigned int c)
+GlyphBLF *blf_glyph_texture_add(FontBLF *font, FT_UInt index, unsigned int c)
 {
 	FT_GlyphSlot slot;
 	GlyphCacheBLF *gc;
 	GlyphBLF *g;
+	GlyphTextureBLF *gt;
 	FT_Face face;
 	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)
+
+	/* The glyph can be add on Bitmap mode, so we have the
+	 * glyph, but not the texture data.
+	 */
+	if (g && g->tex_data)
 		return(g);
+	else if (g)
+		do_new= 0;
+	else
+		do_new= 1;
 
 	face= (FT_Face)font->engine;
 	err= FT_Load_Glyph(face, index, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
@@ -224,12 +234,18 @@
 	if (err || slot->format != FT_GLYPH_FORMAT_BITMAP)
 		return(NULL);
 
-	g= (GlyphBLF *)MEM_mallocN(sizeof(GlyphBLF), "blf_glyph_add");
-	g->next= NULL;
-	g->prev= NULL;
-	g->c= c;
+	if (do_new) {
+		g= (GlyphBLF *)MEM_mallocN(sizeof(GlyphBLF), "blf_glyph_add");
+		g->next= NULL;
+		g->prev= NULL;
+		g->tex_data= NULL;
+		g->bitmap_data= NULL;
+		g->c= c;
+	}
 
+	gt= (GlyphTextureBLF *)MEM_mallocN(sizeof(GlyphTextureBLF), "blf_glyph_texture_add");
 	gc= font->glyph_cache;
+
 	if (gc->cur_tex == -1) {
 		blf_glyph_cache_texture(font, gc);
 		gc->x_offs= gc->pad;
@@ -247,27 +263,27 @@
 	}
 
 	bitmap= slot->bitmap;
-	g->tex= gc->textures[gc->cur_tex];
+	gt->tex= gc->textures[gc->cur_tex];
 
-	g->xoff= gc->x_offs;
-	g->yoff= gc->y_offs;
-	g->width= bitmap.width;
-	g->height= bitmap.rows;
+	gt->xoff= gc->x_offs;
+	gt->yoff= gc->y_offs;
+	gt->width= bitmap.width;
+	gt->height= bitmap.rows;
 
-	if (g->width && g->height) {
+	if (gt->width && gt->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);
+		glBindTexture(GL_TEXTURE_2D, gt->tex);
+		glTexSubImage2D(GL_TEXTURE_2D, 0, gt->xoff, gt->yoff, gt->width, gt->height, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.buffer);
 		glPopClientAttrib();
 	}
 
 	g->advance= ((float)slot->advance.x) / 64.0f;
-	g->pos_x= slot->bitmap_left;
-	g->pos_y= slot->bitmap_top;
+	gt->pos_x= slot->bitmap_left;
+	gt->pos_y= slot->bitmap_top;
 
 	FT_Outline_Get_CBox(&(slot->outline), &bbox);
 	g->box.xmin= ((float)bbox.xMin) / 64.0f;
@@ -275,38 +291,160 @@
 	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);
+	gt->uv[0][0]= ((float)gt->xoff) / ((float)gc->p2_width);
+	gt->uv[0][1]= ((float)gt->yoff) / ((float)gc->p2_height);
+	gt->uv[1][0]= ((float)(gt->xoff + gt->width)) / ((float)gc->p2_width);
+	gt->uv[1][1]= ((float)(gt->yoff + gt->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);
 
-	key= blf_hash(g->c);
-	BLI_addhead(&(gc->bucket[key]), g);
-	gc->rem_glyphs--;
+	if (do_new) {
+		key= blf_hash(g->c);
+		BLI_addhead(&(gc->bucket[key]), g);
+		gc->rem_glyphs--;
+	}
+
+	/* and attach the texture information. */
+	g->tex_data= gt;
+
 	return(g);
 }
 
+GlyphBLF *blf_glyph_bitmap_add(FontBLF *font, FT_UInt index, unsigned int c)
+{
+	FT_GlyphSlot slot;
+	GlyphCacheBLF *gc;
+	GlyphBLF *g;
+	GlyphBitmapBLF *gt;
+	FT_Face face;
+	FT_Error err;
+	FT_Bitmap bitmap;
+	FT_BBox bbox;
+	unsigned char *dest, *src;
+	unsigned int key, y;
+	unsigned int src_width, src_height, src_pitch;
+	int do_new;
+
+	g= blf_glyph_search(font->glyph_cache, c);
+
+	/*
+	 * The glyph can be add on Texture mode, so we have the
+	 * glyph, but not the bitmap data.
+	 */
+	if (g && g->bitmap_data)
+		return(g);
+	else if (g)
+		do_new= 0;
+	else
+		do_new= 1;
+
+	face= (FT_Face)font->engine;
+	err= FT_Load_Glyph(face, index, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
+	if (err)
+		return(NULL);
+
+	/* get the glyph. */
+	slot= face->glyph;
+
+	err= FT_Render_Glyph(slot, FT_RENDER_MODE_MONO);
+	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->tex_data= NULL;
+		g->bitmap_data= NULL;
+		g->c= c;
+	}
+
+	gt= (GlyphBitmapBLF *)MEM_mallocN(sizeof(GlyphBitmapBLF), "blf_glyph_bitmap_add");
+	gc= font->glyph_cache;
+
+	bitmap= slot->bitmap;
+
+	src_width= bitmap.width;
+	src_height= bitmap.rows;
+	src_pitch= bitmap.pitch;
+
+	gt->width= src_width;
+	gt->height= src_height;
+	gt->pitch= src_pitch;
+	gt->image= NULL;
+
+	if (gt->width && gt->height) {
+		gt->image= (unsigned char *)malloc(gt->pitch * gt->height);
+
+		dest= gt->image + ((gt->height - 1) * gt->pitch);
+		src= bitmap.buffer;
+
+		for (y= 0; y < src_height; ++y) {
+			memcpy((void *)dest, (void *)src, src_pitch);
+			dest -= gt->pitch;
+			src += src_pitch;
+		}
+	}
+
+	g->advance= ((float)slot->advance.x) / 64.0f;
+	gt->pos_x= slot->bitmap_left;
+	gt->pos_y= ((int)src_height) - slot->bitmap_top;
+
+	FT_Outline_Get_CBox(&(slot->outline), &bbox);
+	g->box.xmin= ((float)bbox.xMin) / 64.0f;
+	g->box.xmax= ((float)bbox.xMax) / 64.0f;
+	g->box.ymin= ((float)bbox.yMin) / 64.0f;
+	g->box.ymax= ((float)bbox.yMax) / 64.0f;
+
+	if (do_new) {
+		key= blf_hash(g->c);
+		BLI_addhead(&(gc->bucket[key]), g);
+		gc->rem_glyphs--;
+	}
+
+	/* and attach the bitmap information. */
+	g->bitmap_data= gt;
+
+	return(g);
+}
+
+GlyphBLF *blf_glyph_add(FontBLF *font, FT_UInt index, unsigned int c)
+{
+	if (font->mode == BLF_MODE_BITMAP)
+		return(blf_glyph_bitmap_add(font, index, c));
+	return(blf_glyph_texture_add(font, index, c));
+}
+
 void blf_glyph_free(GlyphBLF *g)
 {
+	if (g->tex_data)
+		MEM_freeN(g->tex_data);
+
+	if (g->bitmap_data) {
+		if (g->bitmap_data->image)
+			free((void *)g->bitmap_data->image);
+		MEM_freeN(g->bitmap_data);
+	}
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list