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