4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
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.
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.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): none yet.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
46 #include "MTC_matrixops.h"
48 #include "MEM_guardedalloc.h"
50 #include "BLI_blenlib.h"
51 #include "BLI_arithb.h"
53 #include "DNA_curve_types.h"
54 #include "DNA_object_types.h"
55 #include "DNA_vfont_types.h"
56 #include "DNA_scene_types.h"
57 #include "DNA_text_types.h"
58 #include "DNA_view3d_types.h"
60 #include "BKE_displist.h"
62 #include "BKE_object.h"
63 #include "BKE_global.h"
65 #include "BKE_utildefines.h"
67 #include "BIF_editfont.h"
68 #include "BIF_editmode_undo.h"
69 #include "BIF_toolbox.h"
70 #include "BIF_space.h"
71 #include "BIF_mywindow.h"
73 #include "BDR_editobject.h"
83 static char findaccent(char char1, char code)
88 if(code=='`') new= 224;
89 else if(code==39) new= 225;
90 else if(code=='^') new= 226;
91 else if(code=='~') new= 227;
92 else if(code=='"') new= 228;
93 else if(code=='o') new= 229;
94 else if(code=='e') new= 230;
95 else if(code=='-') new= 170;
98 if(code==',') new= 231;
99 if(code=='|') new= 162;
101 else if(char1=='e') {
102 if(code=='`') new= 232;
103 else if(code==39) new= 233;
104 else if(code=='^') new= 234;
105 else if(code=='"') new= 235;
107 else if(char1=='i') {
108 if(code=='`') new= 236;
109 else if(code==39) new= 237;
110 else if(code=='^') new= 238;
111 else if(code=='"') new= 239;
113 else if(char1=='n') {
114 if(code=='~') new= 241;
116 else if(char1=='o') {
117 if(code=='`') new= 242;
118 else if(code==39) new= 243;
119 else if(code=='^') new= 244;
120 else if(code=='~') new= 245;
121 else if(code=='"') new= 246;
122 else if(code=='/') new= 248;
123 else if(code=='-') new= 186;
124 else if(code=='e') new= 143;
126 else if(char1=='s') {
127 if(code=='s') new= 167;
129 else if(char1=='u') {
130 if(code=='`') new= 249;
131 else if(code==39) new= 250;
132 else if(code=='^') new= 251;
133 else if(code=='"') new= 252;
135 else if(char1=='y') {
136 if(code==39) new= 253;
137 else if(code=='"') new= 255;
139 else if(char1=='A') {
140 if(code=='`') new= 192;
141 else if(code==39) new= 193;
142 else if(code=='^') new= 194;
143 else if(code=='~') new= 195;
144 else if(code=='"') new= 196;
145 else if(code=='o') new= 197;
146 else if(code=='e') new= 198;
148 else if(char1=='C') {
149 if(code==',') new= 199;
151 else if(char1=='E') {
152 if(code=='`') new= 200;
153 else if(code==39) new= 201;
154 else if(code=='^') new= 202;
155 else if(code=='"') new= 203;
157 else if(char1=='I') {
158 if(code=='`') new= 204;
159 else if(code==39) new= 205;
160 else if(code=='^') new= 206;
161 else if(code=='"') new= 207;
163 else if(char1=='N') {
164 if(code=='~') new= 209;
166 else if(char1=='O') {
167 if(code=='`') new= 210;
168 else if(code==39) new= 211;
169 else if(code=='^') new= 212;
170 else if(code=='~') new= 213;
171 else if(code=='"') new= 214;
172 else if(code=='/') new= 216;
173 else if(code=='e') new= 141;
175 else if(char1=='U') {
176 if(code=='`') new= 217;
177 else if(code==39) new= 218;
178 else if(code=='^') new= 219;
179 else if(code=='"') new= 220;
181 else if(char1=='Y') {
182 if(code==39) new= 221;
184 else if(char1=='1') {
185 if(code=='4') new= 188;
186 if(code=='2') new= 189;
188 else if(char1=='3') {
189 if(code=='4') new= 190;
191 else if(char1==':') {
192 if(code=='-') new= 247;
194 else if(char1=='-') {
195 if(code==':') new= 247;
196 if(code=='|') new= 135;
197 if(code=='+') new= 177;
199 else if(char1=='|') {
200 if(code=='-') new= 135;
201 if(code=='=') new= 136;
203 else if(char1=='=') {
204 if(code=='|') new= 136;
206 else if(char1=='+') {
207 if(code=='-') new= 177;
215 static char *textbuf=NULL;
216 static char *oldstr=NULL;
218 static int insert_into_textbuf(Curve *cu, char c)
220 if (cu->len<MAXTEXT-1) {
223 for(x= cu->len; x>cu->pos; x--) textbuf[x]= textbuf[x-1];
228 textbuf[cu->len]='\0';
237 VFont *get_builtin_font(void)
241 for (vf= G.main->vfont.first; vf; vf= vf->id.next)
242 if (BLI_streq(vf->name, "<builtin>"))
245 return load_vfont("<builtin>");
249 void txt_export_to_object(struct Text *text)
253 struct TextLine *tmp;
255 // char sdir[FILE_MAXDIR];
256 // char sfile[FILE_MAXFILE];
262 if (G.obedit && G.obedit->type==OB_FONT) return;
263 check_editmode(OB_FONT);
267 base_init_from_view3d(BASACT, G.vd);
268 G.obedit= BASACT->object;
269 where_is_object(G.obedit);
274 // renames object, careful with long filenames.
277 //ID *find_id(char *type, char *name)
278 BLI_split_dirfile(text->name, sdir, sfile);
279 // rename_id((ID *)G.obedit, sfile);
280 rename_id((ID *)cu, sfile);
284 cu->vfont= get_builtin_font();
287 tmp= text->lines.first;
288 while(cu->len<MAXTEXT && tmp) {
289 nchars += strlen(tmp->line) + 1;
293 if(cu->str) MEM_freeN(cu->str);
295 cu->str= MEM_mallocN(nchars+4, "str");
297 tmp= text->lines.first;
298 strcpy(cu->str, tmp->line);
299 cu->len= strlen(tmp->line);
304 while(cu->len<MAXTEXT && tmp) {
305 strcat(cu->str, "\n");
306 strcat(cu->str, tmp->line);
307 cu->len+= strlen(tmp->line) + 1;
315 allqueue(REDRAWVIEW3D, 0);
319 void txt_export_to_objects(struct Text *text)
323 struct TextLine *curline;
326 float offset[3] = {0.0,0.0,0.0};
332 if (G.obedit && G.obedit->type==OB_FONT) return;
333 check_editmode(OB_FONT);
335 curline = text->lines.first;
337 /*skip lines with no text, but still make space for them*/
338 if(curline->line[0] == '\0'){
340 curline = curline->next;
347 base_init_from_view3d(BASACT, G.vd);
348 G.obedit= BASACT->object;
349 where_is_object(G.obedit);
351 /* Do the translation */
353 offset[1] = -linenum;
356 Mat4Mul3Vecfl(G.vd->viewinv,offset);
358 G.obedit->loc[0] += offset[0];
359 G.obedit->loc[1] += offset[1];
360 G.obedit->loc[2] += offset[2];
361 /* End Translation */
365 cu->vfont= get_builtin_font();
368 nchars = strlen(curline->line) + 1;
370 if(cu->str) MEM_freeN(cu->str);
372 cu->str= MEM_mallocN(nchars+4, "str");
374 strcpy(cu->str, curline->line);
375 cu->len= strlen(curline->line);
382 curline = curline->next;
384 BIF_undo_push("Add Text as Objects");
385 allqueue(REDRAWVIEW3D, 0);
389 void do_textedit(unsigned short event, short val, char _ascii)
392 static int accentcode= 0;
393 int x, doit=0, cursmove=0;
400 /* handle case like TAB (TAB==9) */
401 if( (ascii > 31 && ascii < 254 && ascii != 127) || (ascii==13) || (ascii==10) || (ascii==8)) {
404 if(cu->pos>0) textbuf[cu->pos-1]= findaccent(textbuf[cu->pos-1], ascii);
407 else if(cu->len<MAXTEXT-1) {
408 if(G.qual & LR_ALTKEY ) {
410 /* might become obsolete, apple has default values for this, other OS's too? */
412 if(ascii=='t') ascii= 137;
413 else if(ascii=='c') ascii= 169;
414 else if(ascii=='f') ascii= 164;
415 else if(ascii=='g') ascii= 176;
416 else if(ascii=='l') ascii= 163;
417 else if(ascii=='r') ascii= 174;
418 else if(ascii=='s') ascii= 223;
419 else if(ascii=='v') ascii= 1001;
420 else if(ascii=='y') ascii= 165;
421 else if(ascii=='.') ascii= 138;
422 else if(ascii=='1') ascii= 185;
423 else if(ascii=='2') ascii= 178;
424 else if(ascii=='3') ascii= 179;
425 else if(ascii=='%') ascii= 139;
426 else if(ascii=='?') ascii= 191;
427 else if(ascii=='!') ascii= 161;
428 else if(ascii=='x') ascii= 215;
429 else if(ascii=='>') ascii= 187;
430 else if(ascii=='<') ascii= 171;
437 /* this should be solved by clipboard support */
438 #ifdef __WIN32_DISABLED
439 file= open("C:\\windows\\temp\\cutbuf", O_BINARY|O_RDONLY);
441 file= open("/tmp/.cutbuffer", O_BINARY|O_RDONLY);
445 filelen = BLI_filesize(file);
447 strp= MEM_mallocN(filelen+4, "tempstr");
448 read(file, strp, filelen);
451 if(cu->len+filelen<MAXTEXT) {
452 strcat( textbuf, strp);
453 cu->len= strlen(textbuf);
460 insert_into_textbuf(cu, ascii);
472 insert_into_textbuf(cu, '\n');
477 if(G.qual & LR_SHIFTKEY) {
478 while(cu->pos<cu->len) {
479 if( textbuf[cu->pos]==0) break;
480 if( textbuf[cu->pos]=='\n') break;
492 if(G.qual & LR_SHIFTKEY) {
494 if( textbuf[cu->pos-1]=='\n') break;
505 if(G.qual & LR_SHIFTKEY) {
509 else if(G.qual & LR_ALTKEY) {
510 if (cu->pos && textbuf[cu->pos - 1] < 255) {
511 textbuf[cu->pos - 1]++;
515 else cursmove=FO_CURSUP;
519 if(G.qual & LR_SHIFTKEY) {
523 else if(G.qual & LR_ALTKEY) {
524 if (cu->pos && textbuf[cu->pos - 1] > 1) {
525 textbuf[cu->pos - 1]--;
529 else cursmove= FO_CURSDOWN;
534 if(G.qual & LR_ALTKEY) {
535 if(cu->pos>0) accentcode= 1;
537 else if(G.qual & LR_SHIFTKEY) {
543 for(x=cu->pos;x<=cu->len;x++) textbuf[x-1]= textbuf[x];
545 textbuf[--cu->len]='\0';
553 if(cu->pos<cu->len) {
554 for(x=cu->pos;x<cu->len;x++) textbuf[x]= textbuf[x+1];
555 textbuf[--cu->len]='\0';
563 if(cu->pos>cu->len) cu->pos= cu->len;
564 else if(cu->pos>=MAXTEXT) cu->pos= MAXTEXT;
565 else if(cu->pos<0) cu->pos= 0;
568 if(doit || cursmove) {
569 text_to_curve(G.obedit, cursmove);
570 if(cursmove==0) makeDispList(G.obedit);
571 BIF_undo_push("Textedit");
572 allqueue(REDRAWVIEW3D, 0);
577 void paste_editText(void)
580 int file, filelen, doit= 0;
585 file= open("C:\\windows\\temp\\cutbuf.txt", O_BINARY|O_RDONLY);
587 // The following is more likely to work on all Win32 installations.
588 // suggested by Douglas Toltzman. Needs windows include files...
590 char tempFileName[MAX_PATH];
592 static const char cutbufname[]="cutbuf.txt";
594 if ((pathlen=GetTempPath(sizeof(tempFileName),tempFileName)) > 0 &&
595 pathlen + sizeof(cutbufname) <= sizeof(tempFileName))
597 strcat(tempFileName,cutbufname);
598 file= open(tempFileName, O_BINARY|O_RDONLY);
602 file= open("/tmp/.cutbuffer", O_BINARY|O_RDONLY);
607 filelen = BLI_filesize(file);
609 strp= MEM_mallocN(filelen+4, "tempstr");
610 read(file, strp, filelen);
613 if(cu->len+filelen<MAXTEXT) {
614 strcat( textbuf, strp);
615 cu->len= strlen(textbuf);
622 text_to_curve(G.obedit, 0);
623 makeDispList(G.obedit);
624 allqueue(REDRAWVIEW3D, 0);
625 BIF_undo_push("Paste text");
630 void make_editText(void)
635 if(textbuf==NULL) textbuf= MEM_mallocN(MAXTEXT+4, "texteditbuf");
636 BLI_strncpy(textbuf, cu->str, MAXTEXT);
640 cu->len= strlen(textbuf);
641 if(cu->pos>cu->len) cu->pos= cu->len;
643 text_to_curve(G.obedit, 0);
644 makeDispList(G.obedit);
647 BIF_undo_push("Original");
651 void load_editText(void)
660 cu->str= MEM_mallocN(cu->len+4, "tekstedit");
661 strcpy(cu->str, textbuf);
663 /* this memory system is weak... */
667 cu->len= strlen(cu->str);
672 void remake_editText(void)
676 if(okee("Reload original text")==0) return;
678 BLI_strncpy(textbuf, oldstr, MAXTEXT);
680 cu->len= strlen(textbuf);
681 if(cu->pos>cu->len) cu->pos= cu->len;
683 text_to_curve(G.obedit, 0);
684 makeDispList(G.obedit);
686 allqueue(REDRAWVIEW3D, 0);
687 BIF_undo_push("Reload");
691 void free_editText(void)
693 if(oldstr) MEM_freeN(oldstr);
694 textbuf= oldstr= NULL;
699 void add_primitiveFont(int dummy_argument)
703 if (G.obedit && G.obedit->type==OB_FONT) return;
704 check_editmode(OB_FONT);
706 add_object_draw(OB_FONT);
707 base_init_from_view3d(BASACT, G.vd);
708 G.obedit= BASACT->object;
709 where_is_object(G.obedit);
713 cu->vfont= get_builtin_font();
715 cu->str= MEM_mallocN(12, "str");
716 strcpy(cu->str, "Text");
721 allqueue(REDRAWALL, 0);
737 len= strlen(cu->str);
740 if( *str>=97 && *str<=122) {
749 len= strlen(cu->str);
752 if( *str>=65 && *str<=90) {
759 text_to_curve(G.obedit, 0);
760 makeDispList(G.obedit);
762 allqueue(REDRAWVIEW3D, 0);
763 BIF_undo_push("To upper");
767 /* **************** undo for font object ************** */
769 static void undoFont_to_editFont(void *strv)
771 Curve *cu= G.obedit->data;
774 strncpy(textbuf, str+2, MAXTEXT);
775 cu->pos= *((short *)str);
776 cu->len= strlen(textbuf);
777 text_to_curve(G.obedit, 0);
778 makeDispList(G.obedit);
780 allqueue(REDRAWVIEW3D, 0);
783 static void *editFont_to_undoFont(void)
785 Curve *cu= G.obedit->data;
788 str= MEM_callocN(MAXTEXT+4, "string undo");
790 strncpy(str+2, textbuf, MAXTEXT);
791 *((short *)str)= cu->pos;
796 static void free_undoFont(void *strv)
801 /* and this is all the undo system needs to know */
802 void undo_push_font(char *name)
804 undo_editmode_push(name, free_undoFont, undoFont_to_editFont, editFont_to_undoFont);