Blender  V2.59
blf.c
Go to the documentation of this file.
00001 /*
00002  * $Id: blf.c 36487 2011-05-04 15:09:48Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version. 
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2009 Blender Foundation.
00021  * All rights reserved.
00022  *
00023  * 
00024  * Contributor(s): Blender Foundation
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <math.h>
00038 
00039 #include <ft2build.h>
00040 
00041 #include FT_FREETYPE_H
00042 #include FT_GLYPH_H
00043 
00044 #include "MEM_guardedalloc.h"
00045 
00046 #include "DNA_listBase.h"
00047 #include "DNA_vec_types.h"
00048 
00049 #include "BIF_gl.h"
00050 #include "BLF_api.h"
00051 
00052 #include "blf_internal_types.h"
00053 #include "blf_internal.h"
00054 
00055 
00056 /* Max number of font in memory.
00057  * Take care that now every font have a glyph cache per size/dpi,
00058  * so we don't need load the same font with different size, just
00059  * load one and call BLF_size.
00060  */
00061 #define BLF_MAX_FONT 16
00062 
00063 /* Font array. */
00064 static FontBLF *global_font[BLF_MAX_FONT];
00065 
00066 /* Number of font. */
00067 static int global_font_num= 0;
00068 
00069 /* Default size and dpi, for BLF_draw_default. */
00070 static int global_font_default= -1;
00071 static int global_font_points= 11;
00072 static int global_font_dpi= 72;
00073 
00074 // XXX, should these be made into global_font_'s too?
00075 int blf_mono_font= -1;
00076 int blf_mono_font_render= -1;
00077 
00078 static FontBLF *BLF_get(int fontid)
00079 {
00080         if (fontid >= 0 && fontid < BLF_MAX_FONT)
00081                 return(global_font[fontid]);
00082         return(NULL);
00083 }
00084 
00085 int BLF_init(int points, int dpi)
00086 {
00087         int i;
00088 
00089         for (i= 0; i < BLF_MAX_FONT; i++)
00090                 global_font[i]= NULL;
00091 
00092         global_font_points= points;
00093         global_font_dpi= dpi;
00094         return(blf_font_init());
00095 }
00096 
00097 void BLF_exit(void)
00098 {
00099         FontBLF *font;
00100         int i;
00101 
00102         for (i= 0; i < global_font_num; i++) {
00103                 font= global_font[i];
00104                 if (font)
00105                         blf_font_free(font);
00106         }
00107 
00108         blf_font_exit();
00109 }
00110 
00111 void BLF_cache_clear(void)
00112 {
00113         FontBLF *font;
00114         int i;
00115 
00116         for (i= 0; i < global_font_num; i++) {
00117                 font= global_font[i];
00118                 if (font)
00119                         blf_glyph_cache_clear(font);
00120         }
00121 }
00122 
00123 static int blf_search(const char *name)
00124 {
00125         FontBLF *font;
00126         int i;
00127 
00128         for (i= 0; i < BLF_MAX_FONT; i++) {
00129                 font= global_font[i];
00130                 if (font && (!strcmp(font->name, name)))
00131                         return(i);
00132         }
00133         return(-1);
00134 }
00135 
00136 int BLF_load(const char *name)
00137 {
00138         FontBLF *font;
00139         char *filename;
00140         int i;
00141 
00142         if (!name)
00143                 return(-1);
00144 
00145         /* check if we already load this font. */
00146         i= blf_search(name);
00147         if (i >= 0) {
00148                 /*font= global_font[i];*/ /*UNUSED*/
00149                 return(i);
00150         }
00151 
00152         if (global_font_num+1 >= BLF_MAX_FONT) {
00153                 printf("Too many fonts!!!\n");
00154                 return(-1);
00155         }
00156 
00157         filename= blf_dir_search(name);
00158         if (!filename) {
00159                 printf("Can't find font: %s\n", name);
00160                 return(-1);
00161         }
00162 
00163         font= blf_font_new(name, filename);
00164         MEM_freeN(filename);
00165 
00166         if (!font) {
00167                 printf("Can't load font: %s\n", name);
00168                 return(-1);
00169         }
00170 
00171         global_font[global_font_num]= font;
00172         i= global_font_num;
00173         global_font_num++;
00174         return(i);
00175 }
00176 
00177 int BLF_load_unique(const char *name)
00178 {
00179         FontBLF *font;
00180         char *filename;
00181         int i;
00182 
00183         if (!name)
00184                 return(-1);
00185 
00186         /* Don't search in the cache!! make a new
00187          * object font, this is for keep fonts threads safe.
00188          */
00189         if (global_font_num+1 >= BLF_MAX_FONT) {
00190                 printf("Too many fonts!!!\n");
00191                 return(-1);
00192         }
00193 
00194         filename= blf_dir_search(name);
00195         if (!filename) {
00196                 printf("Can't find font: %s\n", name);
00197                 return(-1);
00198         }
00199 
00200         font= blf_font_new(name, filename);
00201         MEM_freeN(filename);
00202 
00203         if (!font) {
00204                 printf("Can't load font: %s\n", name);
00205                 return(-1);
00206         }
00207 
00208         global_font[global_font_num]= font;
00209         i= global_font_num;
00210         global_font_num++;
00211         return(i);
00212 }
00213 
00214 void BLF_metrics_attach(int fontid, unsigned char *mem, int mem_size)
00215 {
00216         FontBLF *font;
00217 
00218         font= BLF_get(fontid);
00219         if (font)
00220                 blf_font_attach_from_mem(font, mem, mem_size);
00221 }
00222 
00223 int BLF_load_mem(const char *name, unsigned char *mem, int mem_size)
00224 {
00225         FontBLF *font;
00226         int i;
00227 
00228         if (!name)
00229                 return(-1);
00230 
00231         i= blf_search(name);
00232         if (i >= 0) {
00233                 /*font= global_font[i];*/ /*UNUSED*/
00234                 return(i);
00235         }
00236 
00237         if (global_font_num+1 >= BLF_MAX_FONT) {
00238                 printf("Too many fonts!!!\n");
00239                 return(-1);
00240         }
00241 
00242         if (!mem || !mem_size) {
00243                 printf("Can't load font: %s from memory!!\n", name);
00244                 return(-1);
00245         }
00246 
00247         font= blf_font_new_from_mem(name, mem, mem_size);
00248         if (!font) {
00249                 printf("Can't load font: %s from memory!!\n", name);
00250                 return(-1);
00251         }
00252 
00253         global_font[global_font_num]= font;
00254         i= global_font_num;
00255         global_font_num++;
00256         return(i);
00257 }
00258 
00259 int BLF_load_mem_unique(const char *name, unsigned char *mem, int mem_size)
00260 {
00261         FontBLF *font;
00262         int i;
00263 
00264         if (!name)
00265                 return(-1);
00266 
00267         /*
00268          * Don't search in the cache, make a new object font!
00269          * this is to keep the font thread safe.
00270          */
00271         if (global_font_num+1 >= BLF_MAX_FONT) {
00272                 printf("Too many fonts!!!\n");
00273                 return(-1);
00274         }
00275 
00276         if (!mem || !mem_size) {
00277                 printf("Can't load font: %s from memory!!\n", name);
00278                 return(-1);
00279         }
00280 
00281         font= blf_font_new_from_mem(name, mem, mem_size);
00282         if (!font) {
00283                 printf("Can't load font: %s from memory!!\n", name);
00284                 return(-1);
00285         }
00286 
00287         global_font[global_font_num]= font;
00288         i= global_font_num;
00289         global_font_num++;
00290         return(i);
00291 }
00292 
00293 void BLF_enable(int fontid, int option)
00294 {
00295         FontBLF *font;
00296 
00297         font= BLF_get(fontid);
00298         if (font)
00299                 font->flags |= option;
00300 }
00301 
00302 void BLF_disable(int fontid, int option)
00303 {
00304         FontBLF *font;
00305 
00306         font= BLF_get(fontid);
00307         if (font)
00308                 font->flags &= ~option;
00309 }
00310 
00311 void BLF_enable_default(int option)
00312 {
00313         FontBLF *font;
00314 
00315         font= BLF_get(global_font_default);
00316         if (font)
00317                 font->flags |= option;
00318 }
00319 
00320 void BLF_disable_default(int option)
00321 {
00322         FontBLF *font;
00323 
00324         font= BLF_get(global_font_default);
00325         if (font)
00326                 font->flags &= ~option;
00327 }
00328 
00329 void BLF_aspect(int fontid, float x, float y, float z)
00330 {
00331         FontBLF *font;
00332 
00333         font= BLF_get(fontid);
00334         if (font) {
00335                 font->aspect[0]= x;
00336                 font->aspect[1]= y;
00337                 font->aspect[2]= z;
00338         }
00339 }
00340 
00341 void BLF_matrix(int fontid, double *m)
00342 {
00343         FontBLF *font;
00344         int i;
00345 
00346         font= BLF_get(fontid);
00347         if (font) {
00348                 for (i= 0; i < 16; i++)
00349                         font->m[i]= m[i];
00350         }
00351 }
00352 
00353 void BLF_position(int fontid, float x, float y, float z)
00354 {
00355         FontBLF *font;
00356         float remainder;
00357         float xa, ya, za;
00358 
00359         font= BLF_get(fontid);
00360         if (font) {
00361                 if (font->flags & BLF_ASPECT) {
00362                         xa= font->aspect[0];
00363                         ya= font->aspect[1];
00364                         za= font->aspect[2];
00365                 }
00366                 else {
00367                         xa= 1.0f;
00368                         ya= 1.0f;
00369                         za= 1.0f;
00370                 }
00371 
00372                 remainder= x - floor(x);
00373                 if (remainder > 0.4 && remainder < 0.6) {
00374                         if (remainder < 0.5)
00375                                 x -= 0.1 * xa;
00376                         else
00377                                 x += 0.1 * xa;
00378                 }
00379 
00380                 remainder= y - floor(y);
00381                 if (remainder > 0.4 && remainder < 0.6) {
00382                         if (remainder < 0.5)
00383                                 y -= 0.1 * ya;
00384                         else
00385                                 y += 0.1 * ya;
00386                 }
00387 
00388                 remainder= z - floor(z);
00389                 if (remainder > 0.4 && remainder < 0.6) {
00390                         if (remainder < 0.5)
00391                                 z -= 0.1 * za;
00392                         else
00393                                 z += 0.1 * za;
00394                 }
00395 
00396                 font->pos[0]= x;
00397                 font->pos[1]= y;
00398                 font->pos[2]= z;
00399         }
00400 }
00401 
00402 void BLF_size(int fontid, int size, int dpi)
00403 {
00404         FontBLF *font;
00405 
00406         font= BLF_get(fontid);
00407         if (font)
00408                 blf_font_size(font, size, dpi);
00409 }
00410 
00411 void BLF_blur(int fontid, int size)
00412 {
00413         FontBLF *font;
00414         
00415         font= BLF_get(fontid);
00416         if (font)
00417                 font->blur= size;
00418 }
00419 
00420 void BLF_draw_default(float x, float y, float z, const char *str, size_t len)
00421 {
00422         if (!str)
00423                 return;
00424 
00425         if (global_font_default == -1)
00426                 global_font_default= blf_search("default");
00427 
00428         if (global_font_default == -1) {
00429                 printf("Warning: Can't found default font!!\n");
00430                 return;
00431         }
00432 
00433         BLF_size(global_font_default, global_font_points, global_font_dpi);
00434         BLF_position(global_font_default, x, y, z);
00435         BLF_draw(global_font_default, str, len);
00436 }
00437 
00438 /* same as above but call 'BLF_draw_ascii' */
00439 void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len)
00440 {
00441         if (!str)
00442                 return;
00443 
00444         if (global_font_default == -1)
00445                 global_font_default= blf_search("default");
00446 
00447         if (global_font_default == -1) {
00448                 printf("Warning: Can't found default font!!\n");
00449                 return;
00450         }
00451 
00452         BLF_size(global_font_default, global_font_points, global_font_dpi);
00453         BLF_position(global_font_default, x, y, z);
00454         BLF_draw_ascii(global_font_default, str, len); /* XXX, use real length */
00455 }
00456 
00457 void BLF_rotation_default(float angle)
00458 {
00459         FontBLF *font;
00460 
00461         font= BLF_get(global_font_default);
00462         if (font)
00463                 font->angle= angle;
00464 }
00465 
00466 static void blf_draw__start(FontBLF *font)
00467 {
00468         /*
00469          * The pixmap alignment hack is handle
00470          * in BLF_position (old ui_rasterpos_safe).
00471          */
00472 
00473         glEnable(GL_BLEND);
00474         glEnable(GL_TEXTURE_2D);
00475         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00476 
00477         glPushMatrix();
00478 
00479         if (font->flags & BLF_MATRIX)
00480                 glMultMatrixd((GLdouble *)&font->m);
00481 
00482         glTranslatef(font->pos[0], font->pos[1], font->pos[2]);
00483 
00484         if (font->flags & BLF_ASPECT)
00485                 glScalef(font->aspect[0], font->aspect[1], font->aspect[2]);
00486 
00487         if (font->flags & BLF_ROTATION)
00488                 glRotatef(font->angle, 0.0f, 0.0f, 1.0f);
00489 }
00490 
00491 static void blf_draw__end(void)
00492 {
00493         glPopMatrix();
00494         glDisable(GL_BLEND);
00495         glDisable(GL_TEXTURE_2D);
00496 }
00497 
00498 void BLF_draw(int fontid, const char *str, size_t len)
00499 {
00500         FontBLF *font= BLF_get(fontid);
00501         if (font) {
00502                 blf_draw__start(font);
00503                 blf_font_draw(font, str, len);
00504                 blf_draw__end();
00505         }
00506 }
00507 
00508 void BLF_draw_ascii(int fontid, const char *str, size_t len)
00509 {
00510         FontBLF *font= BLF_get(fontid);
00511         if (font) {
00512                 blf_draw__start(font);
00513                 blf_font_draw_ascii(font, str, len);
00514                 blf_draw__end();
00515         }
00516 }
00517 
00518 void BLF_boundbox(int fontid, const char *str, rctf *box)
00519 {
00520         FontBLF *font;
00521 
00522         font= BLF_get(fontid);
00523         if (font)
00524                 blf_font_boundbox(font, str, box);
00525 }
00526 
00527 void BLF_width_and_height(int fontid, const char *str, float *width, float *height)
00528 {
00529         FontBLF *font;
00530 
00531         font= BLF_get(fontid);
00532         if (font)
00533                 blf_font_width_and_height(font, str, width, height);
00534 }
00535 
00536 float BLF_width(int fontid, const char *str)
00537 {
00538         FontBLF *font;
00539 
00540         font= BLF_get(fontid);
00541         if (font)
00542                 return(blf_font_width(font, str));
00543         return(0.0f);
00544 }
00545 
00546 float BLF_fixed_width(int fontid)
00547 {
00548         FontBLF *font;
00549 
00550         font= BLF_get(fontid);
00551         if (font)
00552                 return(blf_font_fixed_width(font));
00553         return(0.0f);
00554 }
00555 
00556 float BLF_width_default(const char *str)
00557 {
00558         float width;
00559 
00560         if (global_font_default == -1)
00561                 global_font_default= blf_search("default");
00562 
00563         if (global_font_default == -1) {
00564                 printf("Error: Can't found default font!!\n");
00565                 return(0.0f);
00566         }
00567 
00568         BLF_size(global_font_default, global_font_points, global_font_dpi);
00569         width= BLF_width(global_font_default, str);
00570         return(width);
00571 }
00572 
00573 float BLF_height(int fontid, const char *str)
00574 {
00575         FontBLF *font;
00576 
00577         font= BLF_get(fontid);
00578         if (font)
00579                 return(blf_font_height(font, str));
00580         return(0.0f);
00581 }
00582 
00583 float BLF_height_max(int fontid)
00584 {
00585         FontBLF *font;
00586 
00587         font= BLF_get(fontid);
00588         if (font) {
00589                 if(font->glyph_cache)
00590                         return(font->glyph_cache->max_glyph_height);
00591         }
00592         return(0.0f);
00593 }
00594 
00595 float BLF_width_max(int fontid)
00596 {
00597         FontBLF *font;
00598 
00599         font= BLF_get(fontid);
00600         if (font) {
00601                 if(font->glyph_cache)
00602                         return(font->glyph_cache->max_glyph_width);
00603         }
00604         return(0.0f);
00605 }
00606 
00607 float BLF_descender(int fontid)
00608 {
00609         FontBLF *font;
00610 
00611         font= BLF_get(fontid);
00612         if (font) {
00613                 if(font->glyph_cache)
00614                         return(font->glyph_cache->descender);
00615         }
00616         return(0.0f);
00617 }
00618 
00619 float BLF_ascender(int fontid)
00620 {
00621         FontBLF *font;
00622 
00623         font= BLF_get(fontid);
00624         if (font) {
00625                 if(font->glyph_cache)
00626                         return(font->glyph_cache->ascender);
00627         }
00628         return(0.0f);
00629 }
00630 
00631 float BLF_height_default(const char *str)
00632 {
00633         float height;
00634 
00635         if (global_font_default == -1)
00636                 global_font_default= blf_search("default");
00637 
00638         if (global_font_default == -1) {
00639                 printf("Error: Can't found default font!!\n");
00640                 return(0.0f);
00641         }
00642 
00643         BLF_size(global_font_default, global_font_points, global_font_dpi);
00644         height= BLF_height(global_font_default, str);
00645         return(height);
00646 }
00647 
00648 void BLF_rotation(int fontid, float angle)
00649 {
00650         FontBLF *font;
00651 
00652         font= BLF_get(fontid);
00653         if (font)
00654                 font->angle= angle;
00655 }
00656 
00657 void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax)
00658 {
00659         FontBLF *font;
00660 
00661         font= BLF_get(fontid);
00662         if (font) {
00663                 font->clip_rec.xmin= xmin;
00664                 font->clip_rec.ymin= ymin;
00665                 font->clip_rec.xmax= xmax;
00666                 font->clip_rec.ymax= ymax;
00667         }
00668 }
00669 
00670 void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax)
00671 {
00672         FontBLF *font;
00673 
00674         font= BLF_get(global_font_default);
00675         if (font) {
00676                 font->clip_rec.xmin= xmin;
00677                 font->clip_rec.ymin= ymin;
00678                 font->clip_rec.xmax= xmax;
00679                 font->clip_rec.ymax= ymax;
00680         }
00681 }
00682 
00683 void BLF_shadow(int fontid, int level, float r, float g, float b, float a)
00684 {
00685         FontBLF *font;
00686 
00687         font= BLF_get(fontid);
00688         if (font) {
00689                 font->shadow= level;
00690                 font->shadow_col[0]= r;
00691                 font->shadow_col[1]= g;
00692                 font->shadow_col[2]= b;
00693                 font->shadow_col[3]= a;
00694         }
00695 }
00696 
00697 void BLF_shadow_offset(int fontid, int x, int y)
00698 {
00699         FontBLF *font;
00700 
00701         font= BLF_get(fontid);
00702         if (font) {
00703                 font->shadow_x= x;
00704                 font->shadow_y= y;
00705         }
00706 }
00707 
00708 void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch)
00709 {
00710         FontBLF *font;
00711 
00712         font= BLF_get(fontid);
00713         if (font) {
00714                 font->b_fbuf= fbuf;
00715                 font->b_cbuf= cbuf;
00716                 font->bw= w;
00717                 font->bh= h;
00718                 font->bch= nch;
00719         }
00720 }
00721 
00722 void BLF_buffer_col(int fontid, float r, float g, float b, float a)
00723 {
00724         FontBLF *font;
00725 
00726         font= BLF_get(fontid);
00727         if (font) {
00728                 font->b_col[0]= r;
00729                 font->b_col[1]= g;
00730                 font->b_col[2]= b;
00731                 font->b_col[3]= a;
00732         }
00733 }
00734 
00735 void BLF_draw_buffer(int fontid, const char *str)
00736 {
00737         FontBLF *font;
00738 
00739         font= BLF_get(fontid);
00740         if (font)
00741                 blf_font_buffer(font, str);
00742 }