/** * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2009 Blender Foundation. * All rights reserved. * * * Contributor(s): Blender Foundation * * ***** END GPL LICENSE BLOCK ***** */ #include #include #include #include #include #include FT_FREETYPE_H #include FT_GLYPH_H #include "MEM_guardedalloc.h" #include "DNA_listBase.h" #include "DNA_vec_types.h" #include "BIF_gl.h" #include "BLF_api.h" #include "blf_internal_types.h" #include "blf_internal.h" /* Max number of font in memory. * Take care that now every font have a glyph cache per size/dpi, * so we don't need load the same font with different size, just * load one and call BLF_size. */ #define BLF_MAX_FONT 16 /* Font array. */ FontBLF *global_font[BLF_MAX_FONT]; /* Number of font. */ int global_font_num= 0; /* Current font. */ int global_font_cur= 0; /* Default size and dpi, for BLF_draw_default. */ int global_font_default= -1; int global_font_points= 11; int global_font_dpi= 72; int BLF_init(int points, int dpi) { int i; for (i= 0; i < BLF_MAX_FONT; i++) global_font[i]= NULL; global_font_points= points; global_font_dpi= dpi; return(blf_font_init()); } void BLF_exit(void) { FontBLF *font; int i; for (i= 0; i < global_font_num; i++) { font= global_font[i]; if (font) blf_font_free(font); } blf_font_exit(); } static int blf_search(char *name) { FontBLF *font; int i; for (i= 0; i < BLF_MAX_FONT; i++) { font= global_font[i]; if (font && (!strcmp(font->name, name))) return(i); } return(-1); } int BLF_load(char *name) { FontBLF *font; char *filename; int i; if (!name) return(-1); /* check if we already load this font. */ i= blf_search(name); if (i >= 0) { font= global_font[i]; return(i); } if (global_font_num+1 >= BLF_MAX_FONT) { printf("Too many fonts!!!\n"); return(-1); } filename= blf_dir_search(name); if (!filename) { printf("Can't find font: %s\n", name); return(-1); } font= blf_font_new(name, filename); MEM_freeN(filename); if (!font) { printf("Can't load font: %s\n", name); return(-1); } global_font[global_font_num]= font; i= global_font_num; global_font_num++; return(i); } void BLF_metrics_attach(unsigned char *mem, int mem_size) { FontBLF *font; font= global_font[global_font_cur]; if (font) blf_font_attach_from_mem(font, mem, mem_size); } int BLF_load_mem(char *name, unsigned char *mem, int mem_size) { FontBLF *font; int i; if (!name) return(-1); i= blf_search(name); if (i >= 0) { font= global_font[i]; return(i); } if (global_font_num+1 >= BLF_MAX_FONT) { printf("Too many fonts!!!\n"); return(-1); } if (!mem || !mem_size) { printf("Can't load font: %s from memory!!\n", name); return(-1); } font= blf_font_new_from_mem(name, mem, mem_size); if (!font) { printf("Can't load font: %s from memory!!\n", name); return(-1); } global_font[global_font_num]= font; i= global_font_num; global_font_num++; return(i); } void BLF_set(int fontid) { if (fontid >= 0 && fontid < BLF_MAX_FONT) global_font_cur= fontid; } int BLF_get(void) { return(global_font_cur); } void BLF_enable(int option) { FontBLF *font; font= global_font[global_font_cur]; if (font) font->flags |= option; } void BLF_disable(int option) { FontBLF *font; font= global_font[global_font_cur]; if (font) font->flags &= ~option; } void BLF_aspect(float aspect) { FontBLF *font; font= global_font[global_font_cur]; if (font) font->aspect= aspect; } void BLF_position(float x, float y, float z) { FontBLF *font; float remainder; font= global_font[global_font_cur]; if (font) { remainder= x - floor(x); if (remainder > 0.4 && remainder < 0.6) { if (remainder < 0.5) x -= 0.1 * font->aspect; else x += 0.1 * font->aspect; } remainder= y - floor(y); if (remainder > 0.4 && remainder < 0.6) { if (remainder < 0.5) y -= 0.1 * font->aspect; else y += 0.1 * font->aspect; } font->pos[0]= x; font->pos[1]= y; font->pos[2]= z; } } void BLF_size(int size, int dpi) { FontBLF *font; font= global_font[global_font_cur]; if (font) blf_font_size(font, size, dpi); } void BLF_blur(int size) { FontBLF *font; font= global_font[global_font_cur]; if (font) font->blur= size; } void BLF_draw_default(float x, float y, float z, char *str) { FontBLF *font; int old_font=0, old_point=0, old_dpi=0; 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; } font= global_font[global_font_cur]; if (font) { old_font= global_font_cur; old_point= font->size; old_dpi= font->dpi; } global_font_cur= global_font_default; BLF_size(global_font_points, global_font_dpi); BLF_position(x, y, z); BLF_draw(str); /* restore the old font. */ if (font) { global_font_cur= old_font; BLF_size(old_point, old_dpi); } } void BLF_default_rotation(float angle) { if (global_font_default>=0) { global_font[global_font_default]->angle= angle; if(angle) global_font[global_font_default]->flags |= BLF_ROTATION; else global_font[global_font_default]->flags &= ~BLF_ROTATION; } } 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) { 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_font_draw(font, str); glPopMatrix(); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); } } void BLF_boundbox(char *str, rctf *box) { FontBLF *font; font= global_font[global_font_cur]; if (font) blf_font_boundbox(font, str, box); } void BLF_width_and_height(char *str, float *width, float *height) { FontBLF *font; font= global_font[global_font_cur]; if (font) blf_font_width_and_height(font, str, width, height); } float BLF_width(char *str) { FontBLF *font; font= global_font[global_font_cur]; if (font) return(blf_font_width(font, str)); return(0.0f); } float BLF_fixed_width(void) { FontBLF *font; font= global_font[global_font_cur]; if (font) return(blf_font_fixed_width(font)); return(0.0f); } float BLF_width_default(char *str) { FontBLF *font; float width; int old_font=0, old_point=0, old_dpi=0; if (global_font_default == -1) global_font_default= blf_search("default"); if (global_font_default == -1) { printf("Error: Can't found default font!!\n"); return(0.0f); } font= global_font[global_font_cur]; if (font) { old_font= global_font_cur; old_point= font->size; old_dpi= font->dpi; } global_font_cur= global_font_default; BLF_size(global_font_points, global_font_dpi); width= BLF_width(str); /* restore the old font. */ if (font) { global_font_cur= old_font; BLF_size(old_point, old_dpi); } return(width); } float BLF_height(char *str) { FontBLF *font; font= global_font[global_font_cur]; if (font) return(blf_font_height(font, str)); return(0.0f); } float BLF_height_default(char *str) { FontBLF *font; float height; int old_font=0, old_point=0, old_dpi=0; if (global_font_default == -1) global_font_default= blf_search("default"); if (global_font_default == -1) { printf("Error: Can't found default font!!\n"); return(0.0f); } font= global_font[global_font_cur]; if (font) { old_font= global_font_cur; old_point= font->size; old_dpi= font->dpi; } global_font_cur= global_font_default; BLF_size(global_font_points, global_font_dpi); height= BLF_height(str); /* restore the old font. */ if (font) { global_font_cur= old_font; BLF_size(old_point, old_dpi); } return(height); } void BLF_rotation(float angle) { FontBLF *font; font= global_font[global_font_cur]; if (font) font->angle= angle; } void BLF_clipping(float xmin, float ymin, float xmax, float ymax) { FontBLF *font; font= global_font[global_font_cur]; if (font) { font->clip_rec.xmin= xmin; font->clip_rec.ymin= ymin; font->clip_rec.xmax= xmax; font->clip_rec.ymax= ymax; } } void BLF_shadow(int level, float r, float g, float b, float a) { FontBLF *font; font= global_font[global_font_cur]; if (font) { font->shadow= level; font->shadow_col[0]= r; font->shadow_col[1]= g; font->shadow_col[2]= b; font->shadow_col[3]= a; } } void BLF_shadow_offset(int x, int y) { FontBLF *font; font= global_font[global_font_cur]; if (font) { font->shadow_x= x; font->shadow_y= y; } } void BLF_buffer(float *fbuf, unsigned char *cbuf, unsigned int w, unsigned int h, int nch) { FontBLF *font; font= global_font[global_font_cur]; if (font) { font->b_fbuf= fbuf; font->b_cbuf= cbuf; font->bw= w; font->bh= h; font->bch= nch; } } void BLF_buffer_col(float r, float g, float b, float a) { FontBLF *font; font= global_font[global_font_cur]; if (font) { font->b_col[0]= r; font->b_col[1]= g; font->b_col[2]= b; font->b_col[3]= a; } } void BLF_draw_buffer(char *str) { FontBLF *font; font= global_font[global_font_cur]; if (font) blf_font_buffer(font, str); }