|
Blender
V2.59
|
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 }