Initial revision
[blender.git] / source / blender / src / editfont.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <string.h>
34
35 #include <fcntl.h>
36 #ifndef WIN32 
37 #include <unistd.h>
38 #else
39 #include <io.h>
40 #endif
41
42 #include "MEM_guardedalloc.h"
43
44 #include "BLI_blenlib.h"
45 #include "BLI_editVert.h"
46
47 #include "DNA_curve_types.h"
48 #include "DNA_object_types.h"
49 #include "DNA_vfont_types.h"
50 #include "DNA_scene_types.h"
51
52 #include "BKE_displist.h"
53 #include "BKE_font.h"
54 #include "BKE_object.h"
55 #include "BKE_global.h"
56 #include "BKE_main.h"
57
58 #include "BIF_editfont.h"
59 #include "BIF_toolbox.h"
60 #include "BIF_space.h"
61 #include "BIF_mywindow.h"
62
63 #include "BDR_editobject.h"
64
65 #include "mydevice.h"
66
67 #include "blendef.h"
68
69 #define MAXTEXT 1000
70
71 int textediting=0;
72
73 static char findaccent(char char1, char code)
74 {
75         char new= 0;
76         
77         if(char1=='a') {
78                 if(code=='`') new= 224;
79                 else if(code==39) new= 225;
80                 else if(code=='^') new= 226;
81                 else if(code=='~') new= 227;
82                 else if(code=='"') new= 228;
83                 else if(code=='o') new= 229;
84                 else if(code=='e') new= 230;
85                 else if(code=='-') new= 170;
86         }
87         else if(char1=='c') {
88                 if(code==',') new= 231;
89                 if(code=='|') new= 162;
90         }
91         else if(char1=='e') {
92                 if(code=='`') new= 232;
93                 else if(code==39) new= 233;
94                 else if(code=='^') new= 234;
95                 else if(code=='"') new= 235;
96         }
97         else if(char1=='i') {
98                 if(code=='`') new= 236;
99                 else if(code==39) new= 237;
100                 else if(code=='^') new= 238;
101                 else if(code=='"') new= 239;
102         }
103         else if(char1=='n') {
104                 if(code=='~') new= 241;
105         }
106         else if(char1=='o') {
107                 if(code=='`') new= 242;
108                 else if(code==39) new= 243;
109                 else if(code=='^') new= 244;
110                 else if(code=='~') new= 245;
111                 else if(code=='"') new= 246;
112                 else if(code=='/') new= 248;
113                 else if(code=='-') new= 186;
114                 else if(code=='e') new= 143;
115         }
116         else if(char1=='s') {
117                 if(code=='s') new= 167;
118         }
119         else if(char1=='u') {
120                 if(code=='`') new= 249;
121                 else if(code==39) new= 250;
122                 else if(code=='^') new= 251;
123                 else if(code=='"') new= 252;
124         }
125         else if(char1=='y') {
126                 if(code==39) new= 253;
127                 else if(code=='"') new= 255;
128         }
129         else if(char1=='A') {
130                 if(code=='`') new= 192;
131                 else if(code==39) new= 193;
132                 else if(code=='^') new= 194;
133                 else if(code=='~') new= 195;
134                 else if(code=='"') new= 196;
135                 else if(code=='o') new= 197;
136                 else if(code=='e') new= 198;
137         }
138         else if(char1=='C') {
139                 if(code==',') new= 199;
140         }
141         else if(char1=='E') {
142                 if(code=='`') new= 200;
143                 else if(code==39) new= 201;
144                 else if(code=='^') new= 202;
145                 else if(code=='"') new= 203;
146         }
147         else if(char1=='I') {
148                 if(code=='`') new= 204;
149                 else if(code==39) new= 205;
150                 else if(code=='^') new= 206;
151                 else if(code=='"') new= 207;
152         }
153         else if(char1=='N') {
154                 if(code=='~') new= 209;
155         }
156         else if(char1=='O') {
157                 if(code=='`') new= 210;
158                 else if(code==39) new= 211;
159                 else if(code=='^') new= 212;
160                 else if(code=='~') new= 213;
161                 else if(code=='"') new= 214;
162                 else if(code=='/') new= 216;
163                 else if(code=='e') new= 141;
164         }
165         else if(char1=='U') {
166                 if(code=='`') new= 217;
167                 else if(code==39) new= 218;
168                 else if(code=='^') new= 219;
169                 else if(code=='"') new= 220;
170         }
171         else if(char1=='Y') {
172                 if(code==39) new= 221;
173         }
174         else if(char1=='1') {
175                 if(code=='4') new= 188;
176                 if(code=='2') new= 189;
177         }
178         else if(char1=='3') {
179                 if(code=='4') new= 190;
180         }
181         else if(char1==':') {
182                 if(code=='-') new= 247;
183         }
184         else if(char1=='-') {
185                 if(code==':') new= 247;
186                 if(code=='|') new= 135;
187                 if(code=='+') new= 177;
188         }
189         else if(char1=='|') {
190                 if(code=='-') new= 135;
191                 if(code=='=') new= 136;
192         }
193         else if(char1=='=') {
194                 if(code=='|') new= 136;
195         }
196         else if(char1=='+') {
197                 if(code=='-') new= 177;
198         }
199         
200         if(new) return new;
201         else return char1;
202 }
203
204 static char *textbuf=0;
205 static char *oldstr;
206
207 static int insert_into_textbuf(Curve *cu, char c)
208 {
209         if (cu->len<MAXTEXT-1) {
210                 int x;
211
212                 for(x= cu->len; x>cu->pos; x--) textbuf[x]= textbuf[x-1];
213                 textbuf[cu->pos]= c;
214                                         
215                 cu->pos++;
216                 cu->len++;
217                 textbuf[cu->len]='\0';
218
219                 return 1;
220         } else {
221                 return 0;
222         }
223 }
224
225 void do_textedit(unsigned short event, short val, char ascii)
226 {
227         Curve *cu;
228         static int accentcode= 0;
229         int x, doit=0, cursmove=0;
230
231         cu= G.obedit->data;
232
233         if(ascii) {
234         
235                 /* o.a. afvangen van TAB (TAB==9) */
236                 if( (ascii > 31 && ascii < 200 && ascii != 127) || (ascii==13) || (ascii==10) || (ascii==8)) {
237         
238                         if(accentcode) {
239                                 if(cu->pos>0) textbuf[cu->pos-1]= findaccent(textbuf[cu->pos-1], ascii);
240                                 accentcode= 0;
241                         }
242                         else if(cu->len<MAXTEXT-1) {
243                                 if(G.qual & LR_ALTKEY ) {
244                                         if(ascii=='t') ascii= 137;
245                                         else if(ascii=='c') ascii= 169;
246                                         else if(ascii=='f') ascii= 164;
247                                         else if(ascii=='g') ascii= 176;
248                                         else if(ascii=='l') ascii= 163;
249                                         else if(ascii=='r') ascii= 174;
250                                         else if(ascii=='s') ascii= 223;
251                                         else if(ascii=='v') ascii= 1001;
252                                         else if(ascii=='y') ascii= 165;
253                                         else if(ascii=='.') ascii= 138;
254                                         else if(ascii=='1') ascii= 185;
255                                         else if(ascii=='2') ascii= 178;
256                                         else if(ascii=='3') ascii= 179;
257                                         else if(ascii=='%') ascii= 139;
258                                         else if(ascii=='?') ascii= 191;
259                                         else if(ascii=='!') ascii= 161;
260                                         else if(ascii=='x') ascii= 215;
261                                         else if(ascii=='>') ascii= 187;
262                                         else if(ascii=='<') ascii= 171;
263                                 }
264                                 
265                                 if(ascii==1001) {
266                                         int file, filelen;
267                                         char *strp;
268                                         
269 /* this should be solved by clipboard support */
270 #ifdef __WIN32_DISABLED 
271                                         file= open("C:\\windows\\temp\\cutbuf", O_BINARY|O_RDONLY);
272 #else
273                                         file= open("/tmp/.cutbuffer", O_BINARY|O_RDONLY);
274 #endif
275                                         if(file>0) {
276                                         
277                                                 filelen = BLI_filesize(file);
278                                         
279                                                 strp= MEM_mallocN(filelen+1, "tempstr");
280                                                 read(file, strp, filelen);
281                                                 close(file);
282                                                 strp[filelen]= 0;
283                                                 if(cu->len+filelen<MAXTEXT) {
284                                                         strcat( textbuf, strp);
285                                                         cu->len= strlen(textbuf);
286                                                         cu->pos= cu->len;
287                                                 }
288                                                 MEM_freeN(strp);
289                                         }
290                                 }
291                                 else {
292                                         insert_into_textbuf(cu, ascii);
293                                 }
294                         }
295                         
296                         doit= 1;
297                 }
298         }
299         else if(val) {
300                 cursmove= 0;
301                 
302                 switch(event) {
303                 case RETKEY:
304                         insert_into_textbuf(cu, '\n');
305                         doit= 1;
306                         break;
307
308                 case RIGHTARROWKEY:     
309                         if(G.qual & LR_SHIFTKEY) {
310                                 while(cu->pos<cu->len) {
311                                         if( textbuf[cu->pos]==0) break;
312                                         if( textbuf[cu->pos]=='\n') break;
313                                         cu->pos++;
314                                 }
315                         }
316                         else {
317                                 cu->pos++;
318                         }
319                         cursmove= FO_CURS;
320                         break;
321                         
322                 case LEFTARROWKEY:
323                         
324                         if(G.qual & LR_SHIFTKEY) {
325                                 while(cu->pos>0) {
326                                         if( textbuf[cu->pos-1]=='\n') break;
327                                         cu->pos--;
328                                 }
329                         }
330                         else {
331                                 cu->pos--;
332                         }
333                         cursmove=FO_CURS;
334                         break;
335
336                 case UPARROWKEY:
337                         if(G.qual & LR_SHIFTKEY) {
338                                 cu->pos= 0;
339                                 cursmove= FO_CURS;
340                         }
341                         else if(G.qual & LR_ALTKEY) {
342                                 if (cu->pos && textbuf[cu->pos - 1] < 255) {
343                                         textbuf[cu->pos - 1]++;
344                                         doit= 1;
345                                 }
346                         }
347                         else cursmove=FO_CURSUP;
348                         break;
349                         
350                 case DOWNARROWKEY:
351                         if(G.qual & LR_SHIFTKEY) {
352                                 cu->pos= cu->len;
353                                 cursmove= FO_CURS;
354                         }
355                         else if(G.qual & LR_ALTKEY) {
356                                 if (cu->pos && textbuf[cu->pos - 1] > 1) {
357                                         textbuf[cu->pos - 1]--;
358                                         doit= 1;
359                                 }
360                         }
361                         else cursmove= FO_CURSDOWN;
362                         break;
363                         
364                 case BACKSPACEKEY:
365                         if(cu->len!=0) {
366                                 if(G.qual & LR_ALTKEY) {
367                                         if(cu->pos>0) accentcode= 1;
368                                 }
369                                 else if(G.qual & LR_SHIFTKEY) {
370                                         cu->pos= 0;
371                                         textbuf[0]= 0;
372                                         cu->len= 0;
373                                 }
374                                 else if(cu->pos>0) {
375                                         for(x=cu->pos;x<=cu->len;x++) textbuf[x-1]= textbuf[x];
376                                         cu->pos--;
377                                         textbuf[--cu->len]='\0';
378                                 }
379                         }
380                         doit= 1;
381                         break;
382                 }
383                         
384                 if(cursmove) {
385                         if(cu->pos>cu->len) cu->pos= cu->len;
386                         else if(cu->pos>=MAXTEXT) cu->pos= MAXTEXT;
387                         else if(cu->pos<0) cu->pos= 0;
388                 }
389         }
390         if(doit || cursmove) {
391                 text_to_curve(G.obedit, cursmove);
392                 if(cursmove==0) makeDispList(G.obedit);
393                 allqueue(REDRAWVIEW3D, 0);
394         }
395 }
396
397 void make_editText(void)
398 {
399         Curve *cu;
400
401         cu= G.obedit->data;
402         if(textbuf==0) textbuf= MEM_mallocN(MAXTEXT, "texteditbuf");
403         BLI_strncpy(textbuf, cu->str, MAXTEXT);
404         oldstr= cu->str;
405         cu->str= textbuf;
406
407         cu->len= strlen(textbuf);
408         if(cu->pos>cu->len) cu->pos= cu->len;
409         
410         text_to_curve(G.obedit, 0);
411         makeDispList(G.obedit);
412         
413         textediting= 1;
414 }
415
416 void load_editText(void)
417 {
418         Curve *cu;
419         
420         cu= G.obedit->data;
421
422         MEM_freeN(oldstr);
423         oldstr= 0;
424         
425         cu->str= MEM_mallocN(cu->len+1, "tekstedit");
426         strcpy(cu->str, textbuf);
427         
428         /* this memory system is weak... */
429         MEM_freeN(textbuf);
430         textbuf= 0;
431         
432         cu->len= strlen(cu->str);
433         textediting= 0;
434 }
435
436 void remake_editText(void)
437 {
438         Curve *cu;
439                 
440         if(okee("Reload Original text")==0) return;
441         
442         BLI_strncpy(textbuf, oldstr, MAXTEXT);
443         cu= G.obedit->data;
444         cu->len= strlen(textbuf);
445         if(cu->pos>cu->len) cu->pos= cu->len;
446         
447         text_to_curve(G.obedit, 0);
448         makeDispList(G.obedit);
449         
450         allqueue(REDRAWVIEW3D, 0);
451 }
452
453 void free_editText(void)
454 {
455         if(oldstr) MEM_freeN(oldstr);
456         textbuf= oldstr= 0;
457         textediting= 0;
458 }
459
460 static VFont *get_builtin_font(void)
461 {
462         VFont *vf;
463         
464         for (vf= G.main->vfont.first; vf; vf= vf->id.next)
465                 if (BLI_streq(vf->name, "<builtin>"))
466                         return vf;
467         
468         return load_vfont("<builtin>");
469 }
470
471 void add_primitiveFont(int dummy_argument)
472 {
473         Curve *cu;
474
475         if (G.obedit && G.obedit->type==OB_FONT) return;
476         check_editmode(OB_FONT);
477         
478         add_object(OB_FONT);
479         base_init_from_view3d(BASACT, G.vd);
480         G.obedit= BASACT->object;
481         where_is_object(G.obedit);
482         
483         cu= G.obedit->data;
484         
485         cu->vfont= get_builtin_font();
486         cu->vfont->id.us++;
487         cu->str= MEM_mallocN(12, "str");
488         strcpy(cu->str, "Text");
489         cu->pos= 4;
490         
491         make_editText();
492         allqueue(REDRAWVIEW3D, 0);
493 }
494
495 void to_upper(void)
496 {
497         Curve *cu;
498         int len, ok;
499         char *str;
500         
501         if(G.obedit==0) {
502                 return;
503         }
504         
505         ok= 0;
506         cu= G.obedit->data;
507         
508         len= strlen(cu->str);
509         str= cu->str;
510         while(len) {
511                 if( *str>=97 && *str<=122) {
512                         ok= 1;
513                         *str-= 32;
514                 }
515                 len--;
516                 str++;
517         }
518         
519         if(ok==0) {
520                 len= strlen(cu->str);
521                 str= cu->str;
522                 while(len) {
523                         if( *str>=65 && *str<=90) {
524                                 *str+= 32;
525                         }
526                         len--;
527                         str++;
528                 }
529         }
530         text_to_curve(G.obedit, 0);
531         makeDispList(G.obedit);
532
533         allqueue(REDRAWVIEW3D, 0);
534
535 }
536
537