Add blender internal font.
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33
34 #ifdef WITH_FREETYPE2
35
36 #include <ft2build.h>
37
38 #include FT_FREETYPE_H
39 #include FT_GLYPH_H
40
41 #endif /* WITH_FREETYPE2 */
42
43 #include "MEM_guardedalloc.h"
44
45 #include "DNA_listBase.h"
46 #include "DNA_vec_types.h"
47
48 #include "BKE_utildefines.h"
49
50 #include "BLI_blenlib.h"
51 #include "BLI_linklist.h"       /* linknode */
52 #include "BLI_string.h"
53
54 #include "BIF_gl.h"
55 #include "BIF_glutil.h"
56 #include "BLF_api.h"
57
58 #include "blf_internal_types.h"
59 #include "blf_internal.h"
60
61
62 /* Max number of font in memory.
63  * Take care that now every font have a glyph cache per size/dpi,
64  * so we don't need load the same font with different size, just
65  * load one and call BLF_size.
66  */
67 #define BLF_MAX_FONT 16
68
69 /* Font array. */
70 FontBLF *global_font[BLF_MAX_FONT];
71
72 /* Number of font. */
73 int global_font_num= 0;
74
75 /* Current font. */
76 int global_font_cur= 0;
77
78
79 int BLF_init(void)
80 {
81         int i;
82
83         for (i= 0; i < BLF_MAX_FONT; i++)
84                 global_font[i]= NULL;
85
86         return(blf_font_init());
87 }
88
89 void BLF_exit(void)
90 {
91         FontBLF *font;
92         int i;
93
94         for (i= 0; i < global_font_num; i++) {
95                 font= global_font[i];
96                 if(font && font->free)
97                         (*font->free)(font);
98         }
99
100         blf_font_exit();
101 }
102
103 int blf_search(char *name)
104 {
105         FontBLF *font;
106         int i;
107
108         for (i= 0; i < BLF_MAX_FONT; i++) {
109                 font= global_font[i];
110                 if (font && (!strcmp(font->name, name)))
111                         return(i);
112         }
113         return(-1);
114 }
115
116 int BLF_load(char *name)
117 {
118         FontBLF *font;
119         char *filename;
120         int i;
121
122         if (!name)
123                 return(-1);
124
125         /* check if we already load this font. */
126         i= blf_search(name);
127         if (i >= 0) {
128                 font= global_font[i];
129                 font->ref++;
130                 printf("Increment reference (%d): %s\n", font->ref, name);
131                 return(i);
132         }
133
134         if (global_font_num+1 >= BLF_MAX_FONT) {
135                 printf("Too many fonts!!!\n");
136                 return(-1);
137         }
138
139         filename= blf_dir_search(name);
140         if (!filename) {
141                 printf("Can't found font: %s\n", name);
142                 return(-1);
143         }
144
145 #ifdef WITH_FREETYPE2
146         font= blf_font_new(name, filename);
147         MEM_freeN(filename);
148
149         if (!font) {
150                 printf("Can't load font: %s\n", name);
151                 return(-1);
152         }
153
154         global_font[global_font_num]= font;
155         i= global_font_num;
156         global_font_num++;
157         return(i);
158 #endif /* WITH_FREETYPE2 */
159
160         return(-1);
161 }
162
163 int BLF_load_mem(char *name, unsigned char *mem, int mem_size)
164 {
165         FontBLF *font;
166         int i;
167
168         if (!name)
169                 return(-1);
170
171         i= blf_search(name);
172         if (i >= 0) {
173                 font= global_font[i];
174                 font->ref++;
175                 printf("Increment reference (%d): %s\n", font->ref, name);
176                 return(i);
177         }
178
179         if (global_font_num+1 >= BLF_MAX_FONT) {
180                 printf("Too many fonts!!!\n");
181                 return(-1);
182         }
183
184         font= blf_internal_new(name);
185         if (!font) {
186 #ifdef WITH_FREETYPE2
187                 if (!mem || !mem_size) {
188                         printf("Can't load font, %s from memory!!\n", name);
189                         return(-1);
190                 }
191
192                 font= blf_font_new_from_mem(name, mem, mem_size);
193 #endif /* WITH_FREETYPE2 */
194
195                 if (!font) {
196                         printf("Can't load font, %s from memory!!\n", name);
197                         return(-1);
198                 }
199         }
200
201         global_font[global_font_num]= font;
202         i= global_font_num;
203         global_font_num++;
204         return(i);
205 }
206
207 void BLF_set(int fontid)
208 {
209         if (fontid >= 0 && fontid < BLF_MAX_FONT)
210                 global_font_cur= fontid;
211 }
212
213 int BLF_get(void)
214 {
215         return(global_font_cur);
216 }
217
218 void BLF_enable(int option)
219 {
220         FontBLF *font;
221
222         font= global_font[global_font_cur];
223         if (font)
224                 font->flags |= option;
225 }
226
227 void BLF_disable(int option)
228 {
229         FontBLF *font;
230
231         font= global_font[global_font_cur];
232         if (font)
233                 font->flags &= ~option;
234 }
235
236 void BLF_aspect(float aspect)
237 {
238         FontBLF *font;
239
240         font= global_font[global_font_cur];
241         if (font)
242                 font->aspect= aspect;
243 }
244
245 void BLF_position(float x, float y, float z)
246 {
247         FontBLF *font;
248         float remainder;
249
250         font= global_font[global_font_cur];
251         if (font) {
252                 remainder= x - floor(x);
253                 if (remainder > 0.4 && remainder < 0.6) {
254                         if (remainder < 0.5)
255                                 x -= 0.1 * font->aspect;
256                         else
257                                 x += 0.1 * font->aspect;
258                 }
259
260                 remainder= y - floor(y);
261                 if (remainder > 0.4 && remainder < 0.6) {
262                         if (remainder < 0.5)
263                                 y -= 0.1 * font->aspect;
264                         else
265                                 y += 0.1 * font->aspect;
266                 }
267
268                 font->pos[0]= x;
269                 font->pos[1]= y;
270                 font->pos[2]= z;
271         }
272 }
273
274 void BLF_size(int size, int dpi)
275 {
276         FontBLF *font;
277
278         font= global_font[global_font_cur];
279         if (font && font->size_set)
280                 (*font->size_set)(font, size, dpi);
281 }
282
283 void BLF_draw(char *str)
284 {
285         FontBLF *font;
286
287         font= global_font[global_font_cur];
288         if (font && font->draw) {
289                 glEnable(GL_BLEND);
290                 glEnable(GL_TEXTURE_2D);
291                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
292
293                 glPushMatrix();
294                 glTranslatef(font->pos[0], font->pos[1], font->pos[2]);
295                 glScalef(font->aspect, font->aspect, 1.0);
296
297                 if (font->flags & BLF_ROTATION)
298                         glRotatef(font->angle, 0.0f, 0.0f, 1.0f);
299
300                 (*font->draw)(font, str);
301
302                 glPopMatrix();
303                 glDisable(GL_BLEND);
304                 glDisable(GL_TEXTURE_2D);
305         }
306 }
307
308 void BLF_boundbox(char *str, rctf *box)
309 {
310         FontBLF *font;
311
312         font= global_font[global_font_cur];
313         if (font && font->boundbox_get)
314                 (*font->boundbox_get)(font, str, box);
315 }
316
317 float BLF_width(char *str)
318 {
319         FontBLF *font;
320
321         font= global_font[global_font_cur];
322         if (font && font->width_get)
323                 return((*font->width_get)(font, str));
324         return(0.0f);
325 }
326
327 float BLF_height(char *str)
328 {
329         FontBLF *font;
330
331         font= global_font[global_font_cur];
332         if (font && font->height_get)
333                 return((*font->height_get)(font, str));
334         return(0.0f);
335 }
336
337 void BLF_rotation(float angle)
338 {
339         FontBLF *font;
340
341         font= global_font[global_font_cur];
342         if (font)
343                 font->angle= angle;
344 }
345
346 void BLF_clipping(float xmin, float ymin, float xmax, float ymax)
347 {
348         FontBLF *font;
349
350         font= global_font[global_font_cur];
351         if (font) {
352                 font->clip_rec.xmin= xmin;
353                 font->clip_rec.ymin= ymin;
354                 font->clip_rec.xmax= xmax;
355                 font->clip_rec.ymax= ymax;
356         }
357 }