Modified interface texture font support, which should work nicely with the freshly...
[blender.git] / source / blender / ftfont / intern / FTF_TTFont.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * Copyright (C) 2002 Blender Foundation. All Rights Reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL/BL DUAL LICENSE BLOCK *****
29  */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <locale.h>
35 #include "libintl.h"
36 #include "BLI_blenlib.h"
37
38 #include "../FTF_Settings.h"
39
40 #include "FTF_TTFont.h"
41
42 #ifdef __APPLE__
43 #include "BKE_utildefines.h"
44 #endif
45
46 #define DOMAIN_NAME "blender"
47
48 #define SYSTEM_ENCODING_DEFAULT "UTF-8"
49 #define FONT_SIZE_DEFAULT 12
50 //#define FONT_PATH_DEFAULT ".bfont.ttf"
51
52 #define FTF_MAX_STR_SIZE 512
53
54
55 int utf8towchar(wchar_t *w, char *c)
56 {
57   int len=0;
58   if(w==NULL || c==NULL) return(0);
59   //printf("%s\n",c);
60   while(*c)
61   {
62     //Converts Unicode to wchar:
63
64     if(*c & 0x80)
65     {
66       if(*c & 0x40)
67       {
68         if(*c & 0x20)
69         {
70           if(*c & 0x10)
71           {
72             *w=(c[0] & 0x0f)<<18 | (c[1]&0x1f)<<12 | (c[2]&0x3f)<<6 | (c[3]&0x7f);
73             c++;
74           }
75           else
76             *w=(c[0] & 0x1f)<<12 | (c[1]&0x3f)<<6 | (c[2]&0x7f);
77           c++;
78         }
79         else
80           *w=(c[0] &0x3f)<<6 | c[1]&0x7f;
81         c++;
82       }
83       else
84         *w=(c[0] & 0x7f);
85     }
86     else
87       *w=(c[0] & 0x7f);
88
89     c++;
90     w++;
91     len++;
92   }
93   return len;
94 }
95
96
97 FTF_TTFont::FTF_TTFont(void)
98 {       
99 #ifdef __APPLE__
100         char *bundlepath;
101 #endif
102
103         font=NULL;
104         fontm= fonts= fontl= NULL;
105         font_size=FONT_SIZE_DEFAULT;
106         mode = FTF_PIXMAPFONT;
107         fsize = 1.0;
108         strcpy(encoding_name, SYSTEM_ENCODING_DEFAULT);
109
110         //set messagepath directory
111
112 #ifndef LOCALEDIR
113 #define LOCALEDIR "/usr/share/locale"
114 #endif
115
116         strcpy(messagepath, ".blender/locale");
117
118         if (BLI_exist(messagepath) == NULL) {   // locale not in current dir
119                 BLI_make_file_string("/", messagepath, BLI_gethome(), ".blender/locale");
120                 
121                 if(BLI_exist(messagepath) == NULL) {    // locale not in home dir
122
123 #ifdef WIN32 
124                         BLI_make_file_string("/", messagepath, BLI_gethome(), "/locale");
125                         if(BLI_exist(messagepath) == NULL) {
126 #endif
127 #ifdef __APPLE__
128                         /* message catalogs are stored inside the application bundle */
129                         bundlepath = BLI_getbundle();
130                         strcpy(messagepath, bundlepath);
131                         strcat(messagepath, "/Contents/Resources/locale");
132                         if(BLI_exist(messagepath) == NULL) { // locale not in bundle (now that's odd..)
133 #endif
134                                 strcpy(messagepath, LOCALEDIR);
135
136                                 if(BLI_exist(messagepath) == NULL) {    // locale not in LOCALEDIR
137                                         strcpy(messagepath, "message");         // old compatibility as last
138                                 }
139 #ifdef WIN32
140                         }
141 #endif
142 #ifdef __APPLE__
143                         }
144 #endif
145                 }
146         }
147 }
148
149
150 FTF_TTFont::~FTF_TTFont(void)
151 {
152         if (fonts) delete fonts;
153         if (fontm) delete fontm;
154         if (fontl) delete fontl;
155 }
156
157 void FTF_TTFont::SetFontSize(char size)
158 {
159                 if(size=='s') font=fonts;
160                 else if(size=='l') font=fontl;
161                 else font=fontm;
162 }
163
164 int FTF_TTFont::SetFont(const unsigned char* str, int datasize, int fontsize)
165 {
166         int err = 0;
167         bool success = 0;
168
169         if (fonts) delete fonts;
170         if (fontm) delete fontm;
171         if (fontl) delete fontl;
172         fonts= NULL;
173         fontm= NULL;
174         fontl= NULL;
175
176         if(mode == FTF_PIXMAPFONT) {
177
178                 if(datasize) font = new FTGLPixmapFont(str, datasize);
179                 else font = new FTGLPixmapFont( (char *)str);
180
181                 err = font->Error();
182
183                 if(err) {
184                         printf("Failed to open font %s\n", str);
185                         return 0;
186                 } else {
187                         
188                         fontm= font;
189
190                         if(datasize) fonts = new FTGLPixmapFont(str, datasize);
191                         else fonts = new FTGLPixmapFont((char *)str);
192                         if(datasize) fontl = new FTGLPixmapFont(str, datasize);
193                         else fontl = new FTGLPixmapFont((char *)str);
194                         
195                         success = fonts->FaceSize(fontsize-2<8?8:fontsize-2);
196                         success = fontm->FaceSize(fontsize-1<8?8:fontsize-1);
197                         success = fontl->FaceSize(fontsize);
198                         if(!success) return 0;
199
200                         success = fonts->CharMap(ft_encoding_unicode);
201                         success = fontm->CharMap(ft_encoding_unicode);
202                         success = fontl->CharMap(ft_encoding_unicode);
203                         if(!success) return 0;
204
205                         return 1;
206                 }
207
208         } else if(mode == FTF_TEXTUREFONT) {
209
210                 if(datasize) font = new FTGLTextureFont(str, datasize);
211                 else font = new FTGLTextureFont( (char *)str);
212
213                 err = font->Error();
214
215                 if(err) {
216                         printf("Failed to open font %s\n", str);
217                         return 0;
218                 } else {
219                         
220                         fontm= font;
221
222                         if(datasize) fonts = new FTGLTextureFont(str, datasize);
223                         else fonts = new FTGLTextureFont((char *)str);
224                         if(datasize) fontl = new FTGLTextureFont(str, datasize);
225                         else fontl = new FTGLTextureFont((char *)str);
226                         
227                         success = fonts->FaceSize(fontsize-2<8?8:fontsize-2);
228                         success = fontm->FaceSize(fontsize-1<8?8:fontsize-1);
229                         success = fontl->FaceSize(fontsize);
230 //                      success = fonts->FaceSize(fontsize/2);
231 //                      success = fontm->FaceSize(fontsize);
232 //                      success = fontl->FaceSize(fontsize*2);
233                         if(!success) return 0;
234
235                         success = fonts->CharMap(ft_encoding_unicode);
236                         success = fontm->CharMap(ft_encoding_unicode);
237                         success = fontl->CharMap(ft_encoding_unicode);
238                         if(!success) return 0;
239
240                         return 1;
241                 }
242         }
243 }
244
245 void FTF_TTFont::SetLanguage(char* str)
246 {
247
248 #if defined (_WIN32) || defined(__APPLE__)
249         char envstr[12];
250
251         sprintf(envstr, "LANG=%s", str);
252         envstr[strlen(envstr)]='\0';
253 #ifdef _WIN32
254         gettext_putenv(envstr);
255 #else
256         putenv(envstr);
257 #endif
258 #else
259         char *locreturn = setlocale(LC_ALL, str);
260         if (locreturn == NULL) {
261                 printf("could not change language to %s\n", str);
262         }
263         
264         setlocale(LC_NUMERIC, "C");
265 #endif
266
267
268         bindtextdomain(DOMAIN_NAME, messagepath);
269 //      bind_textdomain_codeset(DOMAIN_NAME, encoding_name);
270         textdomain(DOMAIN_NAME);
271
272         strcpy(language, str);
273 }
274
275
276 void FTF_TTFont::SetEncoding(char* str)
277 {
278         strcpy(encoding_name, str);
279 //      bind_textdomain_codeset(DOMAIN_NAME, encoding_name);
280 }
281
282
283 void FTF_TTFont::SetSize(int size)
284 {
285         fonts->FaceSize(size-2<8?8:size-2);
286         fontm->FaceSize(size-1<8?8:size-1);
287         fontl->FaceSize(size);
288
289         font_size = size;
290 }
291
292 int FTF_TTFont::GetSize(void)
293 {
294         return font_size;
295 }
296
297 /*
298 int FTF_TTFont::Ascender(void)
299 {
300         return (int)font->Ascender();
301 }
302
303 int FTF_TTFont::Descender(void)
304 {
305         return (int)font->Descender();
306 }
307
308 */
309 int FTF_TTFont::TransConvString(char* str, char* ustr, unsigned int flag)
310 {
311         return 0;
312 }
313
314
315 float FTF_TTFont::DrawString(char* str, unsigned int flag)
316 {
317         float color[4];
318         wchar_t wstr[FTF_MAX_STR_SIZE-1]={'\0'};
319         int len=0;
320   
321         if (FTF_USE_GETTEXT & flag) 
322                 len=utf8towchar(wstr,gettext(str));
323         else 
324                 len=utf8towchar(wstr,str);
325
326         glGetFloatv(GL_CURRENT_COLOR, color);
327         
328         if(mode == FTF_PIXMAPFONT) {
329
330                 glPixelTransferf(GL_RED_SCALE, color[0]);
331                 glPixelTransferf(GL_GREEN_SCALE, color[1]);
332                 glPixelTransferf(GL_BLUE_SCALE, color[2]);
333
334                 font->Render(wstr);
335                 
336                 glPixelTransferf(GL_RED_SCALE, 1.0);
337                 glPixelTransferf(GL_GREEN_SCALE, 1.0);
338                 glPixelTransferf(GL_BLUE_SCALE, 1.0);
339
340         } else if(mode == FTF_TEXTUREFONT) {
341
342                 glEnable(GL_BLEND);
343                 glEnable(GL_TEXTURE_2D);
344                 
345                 glPushMatrix();
346                 glTranslatef(pen_x, pen_y, 0.0);
347                 glScalef(fsize, fsize, 1.0);
348
349                 font->Render(wstr);
350                 glPopMatrix();
351   
352                 glDisable(GL_BLEND);
353                 glDisable(GL_TEXTURE_2D);
354         }
355
356         return font->Advance(wstr);
357 }
358
359
360 float FTF_TTFont::GetStringWidth(char* str, unsigned int flag)
361 {
362         wchar_t wstr[FTF_MAX_STR_SIZE-1]={'\0'};
363         int len=0;
364
365         if (FTF_USE_GETTEXT & flag) 
366                 len=utf8towchar(wstr,gettext(str));
367         else 
368                 len=utf8towchar(wstr,str);
369
370         if(mode == FTF_PIXMAPFONT) {
371                 return font->Advance(wstr);
372         } else if(mode == FTF_TEXTUREFONT) {
373                 return font->Advance(wstr);// * fsize;
374         }
375 }
376
377
378 void FTF_TTFont::GetBoundingBox(char* str, float *llx, float *lly, float *llz, float *urx, float *ury, float *urz, unsigned int flag)
379 {
380         wchar_t wstr[FTF_MAX_STR_SIZE-1]={'\0'};
381         int len=0;
382   
383         if (FTF_USE_GETTEXT & flag) 
384                 len=utf8towchar(wstr,gettext(str));
385         else 
386                 len=utf8towchar(wstr,str);
387
388         font->BBox(wstr, *llx, *lly, *llz, *urx, *ury, *urz);
389 }
390
391
392 void FTF_TTFont::SetPosition(float x, float y)
393 {
394         pen_x = x;
395         pen_y = y;
396 }
397
398
399 void FTF_TTFont::SetMode(int m)
400 {
401         mode = m;
402 }
403
404
405 void FTF_TTFont::SetScale(float size)
406 {
407         fsize = size;
408 }
409
410