fix a small bug , and update language-packs
[blender-staging.git] / source / blender / blenfont / intern / blf.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file blender/blenfont/intern/blf.c
30  *  \ingroup blf
31  */
32
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #ifdef INTERNATIONAL
39 #include <libintl.h>
40 #endif
41
42 #include <math.h>
43
44 #include <ft2build.h>
45
46 #include FT_FREETYPE_H
47 #include FT_GLYPH_H
48
49 #include "MEM_guardedalloc.h"
50
51 #include "DNA_listBase.h"
52 #include "DNA_vec_types.h"
53
54 #include "BIF_gl.h"
55 #include "BLF_api.h"
56
57 #include "blf_internal_types.h"
58 #include "blf_internal.h"
59
60
61 /* Max number of font in memory.
62  * Take care that now every font have a glyph cache per size/dpi,
63  * so we don't need load the same font with different size, just
64  * load one and call BLF_size.
65  */
66 #define BLF_MAX_FONT 16
67
68 /* Font array. */
69 static FontBLF *global_font[BLF_MAX_FONT];
70
71 /* Number of font. */
72 static int global_font_num= 0;
73
74 /* Default size and dpi, for BLF_draw_default. */
75 static int global_font_default= -1;
76 static int global_font_points= 11;
77 static int global_font_dpi= 72;
78
79 // XXX, should these be made into global_font_'s too?
80 int blf_mono_font= -1;
81 int blf_mono_font_render= -1;
82
83 static FontBLF *BLF_get(int fontid)
84 {
85         if (fontid >= 0 && fontid < BLF_MAX_FONT)
86                 return(global_font[fontid]);
87         return(NULL);
88 }
89
90 int BLF_init(int points, int dpi)
91 {
92         int i;
93
94         for (i= 0; i < BLF_MAX_FONT; i++)
95                 global_font[i]= NULL;
96
97         global_font_points= points;
98         global_font_dpi= dpi;
99         return(blf_font_init());
100 }
101
102 void BLF_exit(void)
103 {
104         FontBLF *font;
105         int i;
106
107         for (i= 0; i < global_font_num; i++) {
108                 font= global_font[i];
109                 if (font)
110                         blf_font_free(font);
111         }
112
113         blf_font_exit();
114 }
115
116 void BLF_cache_clear(void)
117 {
118         FontBLF *font;
119         int i;
120
121         for (i= 0; i < global_font_num; i++) {
122                 font= global_font[i];
123                 if (font)
124                         blf_glyph_cache_clear(font);
125         }
126 }
127
128 static int blf_search(const char *name)
129 {
130         FontBLF *font;
131         int i;
132
133         for (i= 0; i < BLF_MAX_FONT; i++) {
134                 font= global_font[i];
135                 if (font && (!strcmp(font->name, name)))
136                         return(i);
137         }
138         return(-1);
139 }
140
141 int BLF_load(const char *name)
142 {
143         FontBLF *font;
144         char *filename;
145         int i;
146
147         if (!name)
148                 return(-1);
149
150         /* check if we already load this font. */
151         i= blf_search(name);
152         if (i >= 0) {
153                 /*font= global_font[i];*/ /*UNUSED*/
154                 return(i);
155         }
156
157         if (global_font_num+1 >= BLF_MAX_FONT) {
158                 printf("Too many fonts!!!\n");
159                 return(-1);
160         }
161
162         filename= blf_dir_search(name);
163         if (!filename) {
164                 printf("Can't find font: %s\n", name);
165                 return(-1);
166         }
167
168         font= blf_font_new(name, filename);
169         MEM_freeN(filename);
170
171         if (!font) {
172                 printf("Can't load font: %s\n", name);
173                 return(-1);
174         }
175
176         global_font[global_font_num]= font;
177         i= global_font_num;
178         global_font_num++;
179         return(i);
180 }
181
182 int BLF_load_unique(const char *name)
183 {
184         FontBLF *font;
185         char *filename;
186         int i;
187
188         if (!name)
189                 return(-1);
190
191         /* Don't search in the cache!! make a new
192          * object font, this is for keep fonts threads safe.
193          */
194         if (global_font_num+1 >= BLF_MAX_FONT) {
195                 printf("Too many fonts!!!\n");
196                 return(-1);
197         }
198
199         filename= blf_dir_search(name);
200         if (!filename) {
201                 printf("Can't find font: %s\n", name);
202                 return(-1);
203         }
204
205         font= blf_font_new(name, filename);
206         MEM_freeN(filename);
207
208         if (!font) {
209                 printf("Can't load font: %s\n", name);
210                 return(-1);
211         }
212
213         global_font[global_font_num]= font;
214         i= global_font_num;
215         global_font_num++;
216         return(i);
217 }
218
219 void BLF_metrics_attach(int fontid, unsigned char *mem, int mem_size)
220 {
221         FontBLF *font;
222
223         font= BLF_get(fontid);
224         if (font)
225                 blf_font_attach_from_mem(font, mem, mem_size);
226 }
227
228 int BLF_load_mem(const char *name, unsigned char *mem, int mem_size)
229 {
230         FontBLF *font;
231         int i;
232
233         if (!name)
234                 return(-1);
235
236         i= blf_search(name);
237         if (i >= 0) {
238                 /*font= global_font[i];*/ /*UNUSED*/
239                 return(i);
240         }
241
242         if (global_font_num+1 >= BLF_MAX_FONT) {
243                 printf("Too many fonts!!!\n");
244                 return(-1);
245         }
246
247         if (!mem || !mem_size) {
248                 printf("Can't load font: %s from memory!!\n", name);
249                 return(-1);
250         }
251
252         font= blf_font_new_from_mem(name, mem, mem_size);
253         if (!font) {
254                 printf("Can't load font: %s from memory!!\n", name);
255                 return(-1);
256         }
257
258         global_font[global_font_num]= font;
259         i= global_font_num;
260         global_font_num++;
261         return(i);
262 }
263
264 int BLF_load_mem_unique(const char *name, unsigned char *mem, int mem_size)
265 {
266         FontBLF *font;
267         int i;
268
269         if (!name)
270                 return(-1);
271
272         /*
273          * Don't search in the cache, make a new object font!
274          * this is to keep the font thread safe.
275          */
276         if (global_font_num+1 >= BLF_MAX_FONT) {
277                 printf("Too many fonts!!!\n");
278                 return(-1);
279         }
280
281         if (!mem || !mem_size) {
282                 printf("Can't load font: %s from memory!!\n", name);
283                 return(-1);
284         }
285
286         font= blf_font_new_from_mem(name, mem, mem_size);
287         if (!font) {
288                 printf("Can't load font: %s from memory!!\n", name);
289                 return(-1);
290         }
291
292         global_font[global_font_num]= font;
293         i= global_font_num;
294         global_font_num++;
295         return(i);
296 }
297
298 void BLF_enable(int fontid, int option)
299 {
300         FontBLF *font;
301
302         font= BLF_get(fontid);
303         if (font)
304                 font->flags |= option;
305 }
306
307 const char* BLF_gettext(const char *msgid)
308 {
309 #ifdef INTERNATIONAL
310         if( msgid!=NULL && strlen(msgid)>0 )
311                 return gettext( msgid );
312         return "";
313 #else
314         return msgid;
315 #endif
316 }
317
318 void BLF_disable(int fontid, int option)
319 {
320         FontBLF *font;
321
322         font= BLF_get(fontid);
323         if (font)
324                 font->flags &= ~option;
325 }
326
327 void BLF_enable_default(int option)
328 {
329         FontBLF *font;
330
331         font= BLF_get(global_font_default);
332         if (font)
333                 font->flags |= option;
334 }
335
336 void BLF_disable_default(int option)
337 {
338         FontBLF *font;
339
340         font= BLF_get(global_font_default);
341         if (font)
342                 font->flags &= ~option;
343 }
344
345 void BLF_aspect(int fontid, float x, float y, float z)
346 {
347         FontBLF *font;
348
349         font= BLF_get(fontid);
350         if (font) {
351                 font->aspect[0]= x;
352                 font->aspect[1]= y;
353                 font->aspect[2]= z;
354         }
355 }
356
357 void BLF_matrix(int fontid, double *m)
358 {
359         FontBLF *font;
360         int i;
361
362         font= BLF_get(fontid);
363         if (font) {
364                 for (i= 0; i < 16; i++)
365                         font->m[i]= m[i];
366         }
367 }
368
369 void BLF_position(int fontid, float x, float y, float z)
370 {
371         FontBLF *font;
372         float remainder;
373         float xa, ya, za;
374
375         font= BLF_get(fontid);
376         if (font) {
377                 if (font->flags & BLF_ASPECT) {
378                         xa= font->aspect[0];
379                         ya= font->aspect[1];
380                         za= font->aspect[2];
381                 }
382                 else {
383                         xa= 1.0f;
384                         ya= 1.0f;
385                         za= 1.0f;
386                 }
387
388                 remainder= x - floor(x);
389                 if (remainder > 0.4 && remainder < 0.6) {
390                         if (remainder < 0.5)
391                                 x -= 0.1 * xa;
392                         else
393                                 x += 0.1 * xa;
394                 }
395
396                 remainder= y - floor(y);
397                 if (remainder > 0.4 && remainder < 0.6) {
398                         if (remainder < 0.5)
399                                 y -= 0.1 * ya;
400                         else
401                                 y += 0.1 * ya;
402                 }
403
404                 remainder= z - floor(z);
405                 if (remainder > 0.4 && remainder < 0.6) {
406                         if (remainder < 0.5)
407                                 z -= 0.1 * za;
408                         else
409                                 z += 0.1 * za;
410                 }
411
412                 font->pos[0]= x;
413                 font->pos[1]= y;
414                 font->pos[2]= z;
415         }
416 }
417
418 void BLF_size(int fontid, int size, int dpi)
419 {
420         FontBLF *font;
421
422         font= BLF_get(fontid);
423         if (font)
424                 blf_font_size(font, size, dpi);
425 }
426
427 void BLF_blur(int fontid, int size)
428 {
429         FontBLF *font;
430         
431         font= BLF_get(fontid);
432         if (font)
433                 font->blur= size;
434 }
435
436 void BLF_draw_default(float x, float y, float z, const char *str, size_t len)
437 {
438         if (!str)
439                 return;
440
441         if (global_font_default == -1)
442                 global_font_default= blf_search("default");
443
444         if (global_font_default == -1) {
445                 printf("Warning: Can't found default font!!\n");
446                 return;
447         }
448
449         BLF_size(global_font_default, global_font_points, global_font_dpi);
450         BLF_position(global_font_default, x, y, z);
451         BLF_draw(global_font_default, str, len);
452 }
453
454 /* same as above but call 'BLF_draw_ascii' */
455 void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len)
456 {
457         if (!str)
458                 return;
459
460         if (global_font_default == -1)
461                 global_font_default= blf_search("default");
462
463         if (global_font_default == -1) {
464                 printf("Warning: Can't found default font!!\n");
465                 return;
466         }
467
468         BLF_size(global_font_default, global_font_points, global_font_dpi);
469         BLF_position(global_font_default, x, y, z);
470         BLF_draw_ascii(global_font_default, str, len); /* XXX, use real length */
471 }
472
473 void BLF_rotation_default(float angle)
474 {
475         FontBLF *font;
476
477         font= BLF_get(global_font_default);
478         if (font)
479                 font->angle= angle;
480 }
481
482 static void blf_draw__start(FontBLF *font)
483 {
484         /*
485          * The pixmap alignment hack is handle
486          * in BLF_position (old ui_rasterpos_safe).
487          */
488
489         glEnable(GL_BLEND);
490         glEnable(GL_TEXTURE_2D);
491         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
492
493         glPushMatrix();
494
495         if (font->flags & BLF_MATRIX)
496                 glMultMatrixd((GLdouble *)&font->m);
497
498         glTranslatef(font->pos[0], font->pos[1], font->pos[2]);
499
500         if (font->flags & BLF_ASPECT)
501                 glScalef(font->aspect[0], font->aspect[1], font->aspect[2]);
502
503         if (font->flags & BLF_ROTATION)
504                 glRotatef(font->angle, 0.0f, 0.0f, 1.0f);
505 }
506
507 static void blf_draw__end(void)
508 {
509         glPopMatrix();
510         glDisable(GL_BLEND);
511         glDisable(GL_TEXTURE_2D);
512 }
513
514 void BLF_draw(int fontid, const char *str, size_t len)
515 {
516         FontBLF *font= BLF_get(fontid);
517         if (font) {
518                 blf_draw__start(font);
519                 blf_font_draw(font, str, len);
520                 blf_draw__end();
521         }
522 }
523
524 void BLF_draw_ascii(int fontid, const char *str, size_t len)
525 {
526         FontBLF *font= BLF_get(fontid);
527         if (font) {
528                 blf_draw__start(font);
529                 blf_font_draw_ascii(font, str, len);
530                 blf_draw__end();
531         }
532 }
533
534 void BLF_boundbox(int fontid, const char *str, rctf *box)
535 {
536         FontBLF *font;
537
538         font= BLF_get(fontid);
539         if (font)
540                 blf_font_boundbox(font, str, box);
541 }
542
543 void BLF_width_and_height(int fontid, const char *str, float *width, float *height)
544 {
545         FontBLF *font;
546
547         font= BLF_get(fontid);
548         if (font)
549                 blf_font_width_and_height(font, str, width, height);
550 }
551
552 float BLF_width(int fontid, const char *str)
553 {
554         FontBLF *font;
555
556         font= BLF_get(fontid);
557         if (font)
558                 return(blf_font_width(font, str));
559         return(0.0f);
560 }
561
562 float BLF_fixed_width(int fontid)
563 {
564         FontBLF *font;
565
566         font= BLF_get(fontid);
567         if (font)
568                 return(blf_font_fixed_width(font));
569         return(0.0f);
570 }
571
572 float BLF_width_default(const char *str)
573 {
574         float width;
575
576         if (global_font_default == -1)
577                 global_font_default= blf_search("default");
578
579         if (global_font_default == -1) {
580                 printf("Error: Can't found default font!!\n");
581                 return(0.0f);
582         }
583
584         BLF_size(global_font_default, global_font_points, global_font_dpi);
585         width= BLF_width(global_font_default, str);
586         return(width);
587 }
588
589 float BLF_height(int fontid, const char *str)
590 {
591         FontBLF *font;
592
593         font= BLF_get(fontid);
594         if (font)
595                 return(blf_font_height(font, str));
596         return(0.0f);
597 }
598
599 float BLF_height_max(int fontid)
600 {
601         FontBLF *font;
602
603         font= BLF_get(fontid);
604         if (font) {
605                 if(font->glyph_cache)
606                         return(font->glyph_cache->max_glyph_height);
607         }
608         return(0.0f);
609 }
610
611 float BLF_width_max(int fontid)
612 {
613         FontBLF *font;
614
615         font= BLF_get(fontid);
616         if (font) {
617                 if(font->glyph_cache)
618                         return(font->glyph_cache->max_glyph_width);
619         }
620         return(0.0f);
621 }
622
623 float BLF_descender(int fontid)
624 {
625         FontBLF *font;
626
627         font= BLF_get(fontid);
628         if (font) {
629                 if(font->glyph_cache)
630                         return(font->glyph_cache->descender);
631         }
632         return(0.0f);
633 }
634
635 float BLF_ascender(int fontid)
636 {
637         FontBLF *font;
638
639         font= BLF_get(fontid);
640         if (font) {
641                 if(font->glyph_cache)
642                         return(font->glyph_cache->ascender);
643         }
644         return(0.0f);
645 }
646
647 float BLF_height_default(const char *str)
648 {
649         float height;
650
651         if (global_font_default == -1)
652                 global_font_default= blf_search("default");
653
654         if (global_font_default == -1) {
655                 printf("Error: Can't found default font!!\n");
656                 return(0.0f);
657         }
658
659         BLF_size(global_font_default, global_font_points, global_font_dpi);
660         height= BLF_height(global_font_default, str);
661         return(height);
662 }
663
664 void BLF_rotation(int fontid, float angle)
665 {
666         FontBLF *font;
667
668         font= BLF_get(fontid);
669         if (font)
670                 font->angle= angle;
671 }
672
673 void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax)
674 {
675         FontBLF *font;
676
677         font= BLF_get(fontid);
678         if (font) {
679                 font->clip_rec.xmin= xmin;
680                 font->clip_rec.ymin= ymin;
681                 font->clip_rec.xmax= xmax;
682                 font->clip_rec.ymax= ymax;
683         }
684 }
685
686 void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax)
687 {
688         FontBLF *font;
689
690         font= BLF_get(global_font_default);
691         if (font) {
692                 font->clip_rec.xmin= xmin;
693                 font->clip_rec.ymin= ymin;
694                 font->clip_rec.xmax= xmax;
695                 font->clip_rec.ymax= ymax;
696         }
697 }
698
699 void BLF_shadow(int fontid, int level, float r, float g, float b, float a)
700 {
701         FontBLF *font;
702
703         font= BLF_get(fontid);
704         if (font) {
705                 font->shadow= level;
706                 font->shadow_col[0]= r;
707                 font->shadow_col[1]= g;
708                 font->shadow_col[2]= b;
709                 font->shadow_col[3]= a;
710         }
711 }
712
713 void BLF_shadow_offset(int fontid, int x, int y)
714 {
715         FontBLF *font;
716
717         font= BLF_get(fontid);
718         if (font) {
719                 font->shadow_x= x;
720                 font->shadow_y= y;
721         }
722 }
723
724 void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch)
725 {
726         FontBLF *font;
727
728         font= BLF_get(fontid);
729         if (font) {
730                 font->b_fbuf= fbuf;
731                 font->b_cbuf= cbuf;
732                 font->bw= w;
733                 font->bh= h;
734                 font->bch= nch;
735         }
736 }
737
738 void BLF_buffer_col(int fontid, float r, float g, float b, float a)
739 {
740         FontBLF *font;
741
742         font= BLF_get(fontid);
743         if (font) {
744                 font->b_col[0]= r;
745                 font->b_col[1]= g;
746                 font->b_col[2]= b;
747                 font->b_col[3]= a;
748         }
749 }
750
751 void BLF_draw_buffer(int fontid, const char *str)
752 {
753         FontBLF *font;
754
755         font= BLF_get(fontid);
756         if (font)
757                 blf_font_buffer(font, str);
758 }