Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorDiego Borghetti <bdiego@gmail.com>2009-04-07 12:42:28 +0400
committerDiego Borghetti <bdiego@gmail.com>2009-04-07 12:42:28 +0400
commit59190778a8606079644b91992a3c90b7723e0adf (patch)
tree5c85797ca089fb34bab6ae4edc5f778538636692 /source
parent44877d0add0101e92bdfc48d065df83a7b541063 (diff)
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 :)
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenfont/BLF_api.h23
-rw-r--r--source/blender/blenfont/intern/blf.c17
-rw-r--r--source/blender/blenfont/intern/blf_font.c22
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c229
-rw-r--r--source/blender/blenfont/intern/blf_internal.c8
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h46
6 files changed, 292 insertions, 53 deletions
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index a5c4e037a2d..d6f0cf38558 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -37,24 +37,41 @@ void BLF_exit(void);
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);
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index b04e0efe94a..686e54e4986 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -284,14 +284,25 @@ void BLF_draw(char *str)
{
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);
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 3e17b26bc6c..b510832cbdd 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -135,6 +135,17 @@ void blf_font_draw(FontBLF *font, char *str)
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 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box)
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;
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 7212deff8c8..628e5f3e6af 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -197,20 +197,30 @@ GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
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 @@ GlyphBLF *blf_glyph_add(FontBLF *font, FT_UInt index, unsigned int c)
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 @@ GlyphBLF *blf_glyph_add(FontBLF *font, FT_UInt index, unsigned int c)
}
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 @@ 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);
+ 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);
+ }
+
/* don't need free the texture, the GlyphCache already
* have a list of all the texture and free it.
*/
MEM_freeN(g);
}
-int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
+int blf_glyph_texture_render(FontBLF *font, GlyphBLF *g, float x, float y)
{
+ GlyphTextureBLF *gt;
GLint cur_tex;
float dx, dx1;
float y1, y2;
- dx= floor(x + g->pos_x);
- dx1= dx + g->width;
- y1= y + g->pos_y;
- y2= y + g->pos_y - g->height;
+ gt= g->tex_data;
+ dx= floor(x + gt->pos_x);
+ dx1= dx + gt->width;
+ y1= y + gt->pos_y;
+ y2= y + gt->pos_y - gt->height;
if (font->flags & BLF_CLIPPING) {
if (!BLI_in_rctf(&font->clip_rec, dx + font->pos[0], y1 + font->pos[1]))
@@ -320,24 +458,47 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
}
glGetIntegerv(GL_TEXTURE_2D_BINDING_EXT, &cur_tex);
- if (cur_tex != g->tex)
- glBindTexture(GL_TEXTURE_2D, g->tex);
+ if (cur_tex != gt->tex)
+ glBindTexture(GL_TEXTURE_2D, gt->tex);
glBegin(GL_QUADS);
- glTexCoord2f(g->uv[0][0], g->uv[0][1]);
+ glTexCoord2f(gt->uv[0][0], gt->uv[0][1]);
glVertex2f(dx, y1);
- glTexCoord2f(g->uv[0][0], g->uv[1][1]);
+ glTexCoord2f(gt->uv[0][0], gt->uv[1][1]);
glVertex2f(dx, y2);
- glTexCoord2f(g->uv[1][0], g->uv[1][1]);
+ glTexCoord2f(gt->uv[1][0], gt->uv[1][1]);
glVertex2f(dx1, y2);
- glTexCoord2f(g->uv[1][0], g->uv[0][1]);
+ glTexCoord2f(gt->uv[1][0], gt->uv[0][1]);
glVertex2f(dx1, y1);
glEnd();
return(1);
}
+int blf_glyph_bitmap_render(FontBLF *font, GlyphBLF *g, float x, float y)
+{
+ GlyphBitmapBLF *gt;
+ GLubyte null_bitmap= 0;
+
+ gt= g->bitmap_data;
+ if (!gt->image)
+ return(1);
+
+ glBitmap(0, 0, 0.0, 0.0, x + font->pos[0], y - font->pos[1], (const GLubyte *)&null_bitmap);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, gt->pitch * 8);
+ glBitmap(gt->width, gt->height, 0.0, gt->pos_y, 0.0, 0.0, (const GLubyte *)gt->image);
+ glBitmap(0, 0, 0.0, 0.0, -x - font->pos[0], -y + font->pos[1], (const GLubyte *)&null_bitmap);
+ return(1);
+}
+
+int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
+{
+ if (font->mode == BLF_MODE_BITMAP)
+ return(blf_glyph_bitmap_render(font, g, x, y));
+ return(blf_glyph_texture_render(font, g, x, y));
+}
+
#endif /* WITH_FREETYPE2 */
diff --git a/source/blender/blenfont/intern/blf_internal.c b/source/blender/blenfont/intern/blf_internal.c
index 04968f05ded..2788332a492 100644
--- a/source/blender/blenfont/intern/blf_internal.c
+++ b/source/blender/blenfont/intern/blf_internal.c
@@ -291,6 +291,14 @@ float blf_internal_height(FontBLF *font, char *str)
void blf_internal_free(FontBLF *font)
{
+ FontDataBLF *data;
+
+ data= (FontDataBLF *)font->engine;
+ if (data->texid != 0) {
+ glDeleteTextures(1, &data->texid);
+ data->texid= 0;
+ }
+
MEM_freeN(font->name);
MEM_freeN(font);
}
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index dba4c34c6bb..e176eb2040b 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -78,13 +78,7 @@ typedef struct GlyphCacheBLF {
float descender;
} GlyphCacheBLF;
-typedef struct GlyphBLF {
- struct GlyphBLF *next;
- struct GlyphBLF *prev;
-
- /* and the character, as UTF8 */
- unsigned int c;
-
+typedef struct GlyphTextureBLF {
/* texture id where this glyph is store. */
GLuint tex;
@@ -96,21 +90,47 @@ typedef struct GlyphBLF {
int width;
int height;
- /* glyph bounding box. */
- rctf box;
-
/* uv coords. */
float uv[2][2];
- /* advance value. */
- float advance;
-
/* X and Y bearing of the glyph.
* The X bearing is from the origin to the glyph left bbox edge.
* The Y bearing is from the baseline to the top of the glyph edge.
*/
float pos_x;
float pos_y;
+} GlyphTextureBLF;
+
+typedef struct GlyphBitmapBLF {
+ /* image data. */
+ unsigned char *image;
+
+ int width;
+ int height;
+ int pitch;
+
+ float pos_x;
+ float pos_y;
+} GlyphBitmapBLF;
+
+typedef struct GlyphBLF {
+ struct GlyphBLF *next;
+ struct GlyphBLF *prev;
+
+ /* and the character, as UTF8 */
+ unsigned int c;
+
+ /* glyph box. */
+ rctf box;
+
+ /* advance size. */
+ float advance;
+
+ /* texture information. */
+ GlyphTextureBLF *tex_data;
+
+ /* bitmap information. */
+ GlyphBitmapBLF *bitmap_data;
} GlyphBLF;
typedef struct FontBLF {