43c85b78977094bf678a27a094880b3b02abd048
[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 || !mem || !mem_size)
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 #ifdef WITH_FREETYPE2
185         font= blf_font_new_from_mem(name, mem, mem_size);
186         if (!font) {
187                 printf("Can't load font, %s from memory!!\n", name);
188                 return(-1);
189         }
190
191         global_font[global_font_num]= font;
192         i= global_font_num;
193         global_font_num++;
194         return(i);
195 #endif /* WITH_FREETYPE2 */
196         return(-1);
197 }
198
199 void BLF_set(int fontid)
200 {
201         if (fontid >= 0 && fontid < BLF_MAX_FONT)
202                 global_font_cur= fontid;
203 }
204
205 void BLF_enable(int option)
206 {
207         FontBLF *font;
208
209         font= global_font[global_font_cur];
210         if (font)
211                 font->flags |= option;
212 }
213
214 void BLF_disable(int option)
215 {
216         FontBLF *font;
217
218         font= global_font[global_font_cur];
219         if (font)
220                 font->flags &= ~option;
221 }
222
223 void BLF_aspect(float aspect)
224 {
225         FontBLF *font;
226
227         font= global_font[global_font_cur];
228         if (font)
229                 font->aspect= aspect;
230 }
231
232 void BLF_position(float x, float y, float z)
233 {
234         FontBLF *font;
235         float remainder;
236
237         font= global_font[global_font_cur];
238         if (font) {
239                 remainder= x - floor(x);
240                 if (remainder > 0.4 && remainder < 0.6) {
241                         if (remainder < 0.5)
242                                 x -= 0.1 * font->aspect;
243                         else
244                                 x += 0.1 * font->aspect;
245                 }
246
247                 remainder= y - floor(y);
248                 if (remainder > 0.4 && remainder < 0.6) {
249                         if (remainder < 0.5)
250                                 y -= 0.1 * font->aspect;
251                         else
252                                 y += 0.1 * font->aspect;
253                 }
254
255                 font->pos[0]= x;
256                 font->pos[1]= y;
257                 font->pos[2]= z;
258         }
259 }
260
261 void BLF_size(int size, int dpi)
262 {
263         FontBLF *font;
264
265         font= global_font[global_font_cur];
266         if (font && font->size_set)
267                 (*font->size_set)(font, size, dpi);
268 }
269
270 void BLF_draw(char *str)
271 {
272         FontBLF *font;
273
274         font= global_font[global_font_cur];
275         if (font && font->draw && font->glyph_cache) {
276                 glEnable(GL_BLEND);
277                 glEnable(GL_TEXTURE_2D);
278                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
279
280                 glPushMatrix();
281                 glTranslatef(font->pos[0], font->pos[1], font->pos[2]);
282                 glScalef(font->aspect, font->aspect, 1.0);
283
284                 if (font->flags & BLF_ROTATION)
285                         glRotatef(font->angle, 0.0f, 0.0f, 1.0f);
286
287                 (*font->draw)(font, str);
288
289                 glPopMatrix();
290                 glDisable(GL_BLEND);
291                 glDisable(GL_TEXTURE_2D);
292         }
293 }
294
295 void BLF_boundbox(char *str, rctf *box)
296 {
297         FontBLF *font;
298
299         font= global_font[global_font_cur];
300         if (font && font->boundbox_get && font->glyph_cache)
301                 (*font->boundbox_get)(font, str, box);
302 }
303
304 float BLF_width(char *str)
305 {
306         FontBLF *font;
307
308         font= global_font[global_font_cur];
309         if (font && font->width_get && font->glyph_cache)
310                 return((*font->width_get)(font, str));
311         return(0.0f);
312 }
313
314 float BLF_height(char *str)
315 {
316         FontBLF *font;
317
318         font= global_font[global_font_cur];
319         if (font && font->height_get && font->glyph_cache)
320                 return((*font->height_get)(font, str));
321         return(0.0f);
322 }
323
324 void BLF_rotation(float angle)
325 {
326         FontBLF *font;
327
328         font= global_font[global_font_cur];
329         if (font)
330                 font->angle= angle;
331 }
332
333 void BLF_clipping(float xmin, float ymin, float xmax, float ymax)
334 {
335         FontBLF *font;
336
337         font= global_font[global_font_cur];
338         if (font) {
339                 font->clip_rec.xmin= xmin;
340                 font->clip_rec.ymin= ymin;
341                 font->clip_rec.xmax= xmax;
342                 font->clip_rec.ymax= ymax;
343         }
344 }