~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/src/editfont.c

  • Committer: Bazaar Package Importer
  • Author(s): Kevin Roy
  • Date: 2011-02-08 22:20:54 UTC
  • mfrom: (1.4.2 upstream)
  • mto: (14.2.6 sid) (1.5.1)
  • mto: This revision was merged to the branch mainline in revision 27.
  • Revision ID: james.westby@ubuntu.com-20110208222054-kk0gwa4bu8h5lyq4
Tags: upstream-2.56.1-beta-svn34076
ImportĀ upstreamĀ versionĀ 2.56.1-beta-svn34076

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * $Id: editfont.c 19983 2009-04-29 19:13:32Z genscher $
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) 2001-2002 by NaN Holding BV.
21
 
 * All rights reserved.
22
 
 *
23
 
 * The Original Code is: all of this file.
24
 
 *
25
 
 * Contributor(s): none yet.
26
 
 *
27
 
 * ***** END GPL LICENSE BLOCK *****
28
 
 */
29
 
 
30
 
#include <stdlib.h>
31
 
#include <string.h>
32
 
#include <fcntl.h>
33
 
#include <wchar.h>
34
 
 
35
 
#ifdef HAVE_CONFIG_H
36
 
#include <config.h>
37
 
#endif
38
 
 
39
 
#ifndef WIN32 
40
 
#include <unistd.h>
41
 
#else
42
 
#include <io.h>
43
 
#endif
44
 
 
45
 
#include "MTC_matrixops.h"
46
 
 
47
 
#include "MEM_guardedalloc.h"
48
 
 
49
 
#include "BLI_blenlib.h"
50
 
#include "BLI_arithb.h"
51
 
 
52
 
#include "DNA_curve_types.h"
53
 
#include "DNA_object_types.h"
54
 
#include "DNA_vfont_types.h"
55
 
#include "DNA_scene_types.h"
56
 
#include "DNA_text_types.h"
57
 
#include "DNA_view3d_types.h"
58
 
#include "DNA_userdef_types.h"
59
 
 
60
 
#include "BKE_depsgraph.h"
61
 
#include "BKE_font.h"
62
 
#include "BKE_object.h"
63
 
#include "BKE_global.h"
64
 
#include "BKE_main.h"
65
 
#include "BKE_utildefines.h"
66
 
 
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"
72
 
 
73
 
#include "BDR_editobject.h"
74
 
 
75
 
#include "mydevice.h"
76
 
 
77
 
#include "blendef.h"
78
 
 
79
 
#define MAXTEXT 32766
80
 
 
81
 
/* -- prototypes --------*/
82
 
VFont *get_builtin_font(void);
83
 
 
84
 
int textediting=0;
85
 
 
86
 
extern struct SelBox *selboxes;         /* from blenkernel/font.c */
87
 
 
88
 
static char findaccent(char char1, unsigned int code)
89
 
{
90
 
        char new= 0;
91
 
        
92
 
        if(char1=='a') {
93
 
                if(code=='`') new= 224;
94
 
                else if(code==39) new= 225;
95
 
                else if(code=='^') new= 226;
96
 
                else if(code=='~') new= 227;
97
 
                else if(code=='"') new= 228;
98
 
                else if(code=='o') new= 229;
99
 
                else if(code=='e') new= 230;
100
 
                else if(code=='-') new= 170;
101
 
        }
102
 
        else if(char1=='c') {
103
 
                if(code==',') new= 231;
104
 
                if(code=='|') new= 162;
105
 
        }
106
 
        else if(char1=='e') {
107
 
                if(code=='`') new= 232;
108
 
                else if(code==39) new= 233;
109
 
                else if(code=='^') new= 234;
110
 
                else if(code=='"') new= 235;
111
 
        }
112
 
        else if(char1=='i') {
113
 
                if(code=='`') new= 236;
114
 
                else if(code==39) new= 237;
115
 
                else if(code=='^') new= 238;
116
 
                else if(code=='"') new= 239;
117
 
        }
118
 
        else if(char1=='n') {
119
 
                if(code=='~') new= 241;
120
 
        }
121
 
        else if(char1=='o') {
122
 
                if(code=='`') new= 242;
123
 
                else if(code==39) new= 243;
124
 
                else if(code=='^') new= 244;
125
 
                else if(code=='~') new= 245;
126
 
                else if(code=='"') new= 246;
127
 
                else if(code=='/') new= 248;
128
 
                else if(code=='-') new= 186;
129
 
                else if(code=='e') new= 143;
130
 
        }
131
 
        else if(char1=='s') {
132
 
                if(code=='s') new= 167;
133
 
        }
134
 
        else if(char1=='u') {
135
 
                if(code=='`') new= 249;
136
 
                else if(code==39) new= 250;
137
 
                else if(code=='^') new= 251;
138
 
                else if(code=='"') new= 252;
139
 
        }
140
 
        else if(char1=='y') {
141
 
                if(code==39) new= 253;
142
 
                else if(code=='"') new= 255;
143
 
        }
144
 
        else if(char1=='A') {
145
 
                if(code=='`') new= 192;
146
 
                else if(code==39) new= 193;
147
 
                else if(code=='^') new= 194;
148
 
                else if(code=='~') new= 195;
149
 
                else if(code=='"') new= 196;
150
 
                else if(code=='o') new= 197;
151
 
                else if(code=='e') new= 198;
152
 
        }
153
 
        else if(char1=='C') {
154
 
                if(code==',') new= 199;
155
 
        }
156
 
        else if(char1=='E') {
157
 
                if(code=='`') new= 200;
158
 
                else if(code==39) new= 201;
159
 
                else if(code=='^') new= 202;
160
 
                else if(code=='"') new= 203;
161
 
        }
162
 
        else if(char1=='I') {
163
 
                if(code=='`') new= 204;
164
 
                else if(code==39) new= 205;
165
 
                else if(code=='^') new= 206;
166
 
                else if(code=='"') new= 207;
167
 
        }
168
 
        else if(char1=='N') {
169
 
                if(code=='~') new= 209;
170
 
        }
171
 
        else if(char1=='O') {
172
 
                if(code=='`') new= 210;
173
 
                else if(code==39) new= 211;
174
 
                else if(code=='^') new= 212;
175
 
                else if(code=='~') new= 213;
176
 
                else if(code=='"') new= 214;
177
 
                else if(code=='/') new= 216;
178
 
                else if(code=='e') new= 141;
179
 
        }
180
 
        else if(char1=='U') {
181
 
                if(code=='`') new= 217;
182
 
                else if(code==39) new= 218;
183
 
                else if(code=='^') new= 219;
184
 
                else if(code=='"') new= 220;
185
 
        }
186
 
        else if(char1=='Y') {
187
 
                if(code==39) new= 221;
188
 
        }
189
 
        else if(char1=='1') {
190
 
                if(code=='4') new= 188;
191
 
                if(code=='2') new= 189;
192
 
        }
193
 
        else if(char1=='3') {
194
 
                if(code=='4') new= 190;
195
 
        }
196
 
        else if(char1==':') {
197
 
                if(code=='-') new= 247;
198
 
        }
199
 
        else if(char1=='-') {
200
 
                if(code==':') new= 247;
201
 
                if(code=='|') new= 135;
202
 
                if(code=='+') new= 177;
203
 
        }
204
 
        else if(char1=='|') {
205
 
                if(code=='-') new= 135;
206
 
                if(code=='=') new= 136;
207
 
        }
208
 
        else if(char1=='=') {
209
 
                if(code=='|') new= 136;
210
 
        }
211
 
        else if(char1=='+') {
212
 
                if(code=='-') new= 177;
213
 
        }
214
 
        
215
 
        if(new) return new;
216
 
        else return char1;
217
 
}
218
 
 
219
 
wchar_t *copybuf=NULL;
220
 
wchar_t *copybufinfo=NULL;
221
 
 
222
 
static wchar_t *textbuf=NULL;
223
 
static CharInfo *textbufinfo=NULL;
224
 
static wchar_t *oldstr=NULL;
225
 
static CharInfo *oldstrinfo=NULL;
226
 
 
227
 
void update_string(Curve *cu)
228
 
{
229
 
        int len;
230
 
 
231
 
        // Free the old curve string    
232
 
        MEM_freeN(cu->str);
233
 
 
234
 
        // Calculate the actual string length in UTF-8 variable characters
235
 
        len = wcsleninu8(textbuf);
236
 
 
237
 
        // Alloc memory for UTF-8 variable char length string
238
 
        cu->str = MEM_callocN(len + sizeof(wchar_t), "str");
239
 
 
240
 
        // Copy the wchar to UTF-8
241
 
        wcs2utf8s(cu->str, textbuf);
242
 
}
243
 
 
244
 
static int insert_into_textbuf(Curve *cu, uintptr_t c)
245
 
{
246
 
        if (cu->len<MAXTEXT-1) {
247
 
                int x;
248
 
 
249
 
                for(x= cu->len; x>cu->pos; x--) textbuf[x]= textbuf[x-1];
250
 
                for(x= cu->len; x>cu->pos; x--) textbufinfo[x]= textbufinfo[x-1];               
251
 
                textbuf[cu->pos]= c;
252
 
                textbufinfo[cu->pos] = cu->curinfo;
253
 
                textbufinfo[cu->pos].kern = 0;
254
 
                if (G.obedit->actcol>0)
255
 
                        textbufinfo[cu->pos].mat_nr = G.obedit->actcol;
256
 
                else
257
 
                        textbufinfo[cu->pos].mat_nr = 0;
258
 
                                        
259
 
                cu->pos++;
260
 
                cu->len++;
261
 
                textbuf[cu->len]='\0';
262
 
 
263
 
                update_string(cu);
264
 
 
265
 
                return 1;
266
 
        } else {
267
 
                return 0;
268
 
        }
269
 
}
270
 
 
271
 
void add_lorem(void)
272
 
{
273
 
        char *p, *p2;
274
 
        int i;
275
 
        Curve *cu=G.obedit->data;
276
 
        static char* lastlorem;
277
 
        
278
 
        if (lastlorem)
279
 
                p= lastlorem;
280
 
        else
281
 
                p= BIF_lorem;
282
 
        
283
 
        i= rand()/(RAND_MAX/6)+4;       
284
 
                
285
 
        for (p2=p; *p2 && i; p2++) {
286
 
                insert_into_textbuf(cu, *p2);
287
 
                if (*p2=='.') i--;
288
 
        }
289
 
        lastlorem = p2+1;
290
 
        if (strlen(lastlorem)<5) lastlorem = BIF_lorem;
291
 
        
292
 
        insert_into_textbuf(cu, '\n');
293
 
        insert_into_textbuf(cu, '\n');  
294
 
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
295
 
        allqueue(REDRAWVIEW3D, 0);      
296
 
}
297
 
 
298
 
void load_3dtext_fs(char *file) 
299
 
{
300
 
        FILE *fp;
301
 
        int filelen;
302
 
        char *strp;
303
 
        Curve *cu=G.obedit->data;
304
 
 
305
 
        fp= fopen(file, "r");
306
 
        if (!fp) return;
307
 
 
308
 
        fseek(fp, 0L, SEEK_END);
309
 
        filelen = ftell(fp);
310
 
        fseek(fp, 0L, SEEK_SET);        
311
 
 
312
 
        strp = MEM_callocN(filelen+4, "tempstr");       
313
 
 
314
 
        filelen = fread(strp, 1, filelen, fp);
315
 
        fclose(fp);
316
 
        strp[filelen]= 0;
317
 
        
318
 
        if(cu->len+filelen<MAXTEXT)
319
 
        {
320
 
                int tmplen;
321
 
                wchar_t *mem = MEM_callocN((sizeof(wchar_t)*filelen)+(4*sizeof(wchar_t)), "temporary");
322
 
                tmplen = utf8towchar(mem, strp);
323
 
                wcscat(textbuf, mem);
324
 
                MEM_freeN(mem);
325
 
                cu->len += tmplen;
326
 
                cu->pos= cu->len;
327
 
        }
328
 
        MEM_freeN(strp);
329
 
 
330
 
        update_string(cu);
331
 
 
332
 
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
333
 
        allqueue(REDRAWVIEW3D, 0);      
334
 
}
335
 
 
336
 
VFont *get_builtin_font(void)
337
 
{
338
 
        VFont *vf;
339
 
        
340
 
        for (vf= G.main->vfont.first; vf; vf= vf->id.next)
341
 
                if (BLI_streq(vf->name, "<builtin>"))
342
 
                        return vf;
343
 
        
344
 
        return load_vfont("<builtin>");
345
 
}
346
 
 
347
 
 
348
 
void txt_export_to_object(struct Text *text)
349
 
{
350
 
        ID *id;
351
 
        Curve *cu;
352
 
        struct TextLine *tmp;
353
 
        int nchars = 0;
354
 
//      char sdir[FILE_MAXDIR];
355
 
//      char sfile[FILE_MAXFILE];
356
 
 
357
 
        if(!text || !text->lines.first) return;
358
 
 
359
 
        id = (ID *)text;
360
 
 
361
 
        if (G.obedit && G.obedit->type==OB_FONT) return;
362
 
        check_editmode(OB_FONT);
363
 
        
364
 
        add_object(OB_FONT);
365
 
 
366
 
        base_init_from_view3d(BASACT, G.vd);
367
 
        G.obedit= BASACT->object;
368
 
        where_is_object(G.obedit);
369
 
 
370
 
        cu= G.obedit->data;
371
 
 
372
 
/*      
373
 
//              renames object, careful with long filenames.
374
 
 
375
 
        if (text->name) {
376
 
        //ID *find_id(char *type, char *name)   
377
 
                BLI_split_dirfile(text->name, sdir, sfile);
378
 
//              rename_id((ID *)G.obedit, sfile);
379
 
                rename_id((ID *)cu, sfile);
380
 
                id->us++;
381
 
        }
382
 
*/      
383
 
        cu->vfont= get_builtin_font();
384
 
        cu->vfont->id.us++;
385
 
 
386
 
        tmp= text->lines.first;
387
 
        while(cu->len<MAXTEXT && tmp) {
388
 
                nchars += strlen(tmp->line) + 1;
389
 
                tmp = tmp->next;
390
 
        }
391
 
 
392
 
        if(cu->str) MEM_freeN(cu->str);
393
 
        if(cu->strinfo) MEM_freeN(cu->strinfo); 
394
 
 
395
 
        cu->str= MEM_mallocN(nchars+4, "str");
396
 
        cu->strinfo= MEM_callocN((nchars+4)*sizeof(CharInfo), "strinfo");
397
 
        cu->totbox= cu->actbox= 1;
398
 
        cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "textbox");
399
 
        cu->tb[0].w = cu->tb[0].h = 0.0;
400
 
        
401
 
        tmp= text->lines.first;
402
 
        strcpy(cu->str, tmp->line);
403
 
        cu->len= strlen(tmp->line);
404
 
        cu->pos= cu->len;
405
 
 
406
 
        tmp= tmp->next;
407
 
 
408
 
        while(cu->len<MAXTEXT && tmp) {
409
 
                strcat(cu->str, "\n");
410
 
                strcat(cu->str, tmp->line);
411
 
                cu->len+= strlen(tmp->line) + 1;
412
 
                cu->pos= cu->len;
413
 
                tmp= tmp->next;
414
 
        }
415
 
 
416
 
        make_editText();
417
 
        exit_editmode(EM_FREEDATA|EM_WAITCURSOR);
418
 
 
419
 
        allqueue(REDRAWVIEW3D, 0);
420
 
}
421
 
 
422
 
 
423
 
void txt_export_to_objects(struct Text *text)
424
 
{
425
 
        ID *id;
426
 
        Curve *cu;
427
 
        struct TextLine *curline;
428
 
        int nchars;
429
 
        int linenum = 0;
430
 
        float offset[3] = {0.0,0.0,0.0};
431
 
 
432
 
        if(!text || !text->lines.first) return;
433
 
 
434
 
        id = (ID *)text;
435
 
 
436
 
        if (G.obedit && G.obedit->type==OB_FONT) return;
437
 
        check_editmode(OB_FONT);
438
 
 
439
 
        curline = text->lines.first;
440
 
        while(curline){ 
441
 
                /*skip lines with no text, but still make space for them*/
442
 
                if(curline->line[0] == '\0'){
443
 
                        linenum++;
444
 
                        curline = curline->next;
445
 
                        continue;
446
 
                }
447
 
                        
448
 
                nchars = 0;     
449
 
                add_object(OB_FONT);
450
 
        
451
 
                base_init_from_view3d(BASACT, G.vd);
452
 
                G.obedit= BASACT->object;
453
 
                where_is_object(G.obedit);      
454
 
                
455
 
                /* Do the translation */
456
 
                offset[0] = 0;
457
 
                offset[1] = -linenum;
458
 
                offset[2] = 0;
459
 
        
460
 
                Mat4Mul3Vecfl(G.vd->viewinv,offset);
461
 
                
462
 
                G.obedit->loc[0] += offset[0];
463
 
                G.obedit->loc[1] += offset[1];
464
 
                G.obedit->loc[2] += offset[2];
465
 
                /* End Translation */
466
 
                                        
467
 
                cu= G.obedit->data;
468
 
                
469
 
                cu->vfont= get_builtin_font();
470
 
                cu->vfont->id.us++;
471
 
        
472
 
                nchars = strlen(curline->line) + 1;
473
 
        
474
 
                if(cu->str) MEM_freeN(cu->str);
475
 
                if(cu->strinfo) MEM_freeN(cu->strinfo);         
476
 
        
477
 
                cu->str= MEM_mallocN(nchars+4, "str");
478
 
                cu->strinfo= MEM_callocN((nchars+4)*sizeof(CharInfo), "strinfo");
479
 
                cu->totbox= cu->actbox= 1;
480
 
                cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "textbox");
481
 
                cu->tb[0].w = cu->tb[0].h = 0.0;
482
 
                
483
 
                strcpy(cu->str, curline->line);
484
 
                cu->len= strlen(curline->line);
485
 
                cu->pos= cu->len;
486
 
 
487
 
                make_editText();
488
 
                exit_editmode(EM_FREEDATA|EM_WAITCURSOR);
489
 
 
490
 
                linenum++;
491
 
                curline = curline->next;
492
 
        }
493
 
        BIF_undo_push("Add Text as Objects");
494
 
        allqueue(REDRAWVIEW3D, 0);
495
 
}
496
 
 
497
 
static short next_word(Curve *cu)
498
 
{
499
 
        short s;
500
 
        for (s=cu->pos; (cu->str[s]) && (cu->str[s]!=' ') && (cu->str[s]!='\n') &&
501
 
                        (cu->str[s]!=1) && (cu->str[s]!='\r'); s++);
502
 
        if (cu->str[s]) return(s+1); else return(s);
503
 
}
504
 
 
505
 
static short prev_word(Curve *cu)
506
 
{
507
 
        short s;
508
 
        
509
 
        if (cu->pos==0) return(0);
510
 
        for (s=cu->pos-2; (cu->str[s]) && (cu->str[s]!=' ') && (cu->str[s]!='\n') &&
511
 
                        (cu->str[s]!=1) && (cu->str[s]!='\r'); s--);
512
 
        if (cu->str[s]) return(s+1); else return(s);
513
 
}
514
 
 
515
 
 
516
 
 
517
 
static int killselection(int ins)       /* 1 == new character */
518
 
{
519
 
        int selend, selstart, direction;
520
 
        Curve *cu= G.obedit->data;
521
 
        int offset = 0;
522
 
        int getfrom;
523
 
 
524
 
        direction = getselection(&selstart, &selend);
525
 
        if (direction) {
526
 
                int size;
527
 
                if (ins) offset = 1;
528
 
                if (cu->pos >= selstart) cu->pos = selstart+offset;
529
 
                if ((direction == -1) && ins) {
530
 
                        selstart++;
531
 
                        selend++;
532
 
                }
533
 
                getfrom = selend+offset;
534
 
                if (ins==0) getfrom++;
535
 
                size = (cu->len * sizeof(wchar_t)) - (selstart * sizeof(wchar_t)) + (offset*sizeof(wchar_t));
536
 
                memmove(textbuf+selstart, textbuf+getfrom, size);
537
 
                memmove(textbufinfo+selstart, textbufinfo+getfrom, ((cu->len-selstart)+offset)*sizeof(CharInfo));
538
 
                cu->len -= (selend-selstart)+offset;
539
 
                cu->selstart = cu->selend = 0;
540
 
        }
541
 
        return(direction);
542
 
}
543
 
 
544
 
static void copyselection(void)
545
 
{
546
 
        int selstart, selend;
547
 
        
548
 
        if (getselection(&selstart, &selend)) {
549
 
                memcpy(copybuf, textbuf+selstart, ((selend-selstart)+1)*sizeof(wchar_t));
550
 
                copybuf[(selend-selstart)+1]=0;
551
 
                memcpy(copybufinfo, textbufinfo+selstart, ((selend-selstart)+1)*sizeof(CharInfo));      
552
 
        }
553
 
}
554
 
 
555
 
static void pasteselection(void)
556
 
{
557
 
        Curve *cu= G.obedit->data;
558
 
 
559
 
        int len= wcslen(copybuf);
560
 
 
561
 
        // Verify that the copy buffer => [copy buffer len] + cu->len < MAXTEXT
562
 
        if(cu->len + len <= MAXTEXT)
563
 
        {
564
 
                if (len) {      
565
 
                        int size = (cu->len * sizeof(wchar_t)) - (cu->pos*sizeof(wchar_t)) + sizeof(wchar_t);
566
 
                        memmove(textbuf+cu->pos+len, textbuf+cu->pos, size);
567
 
                        memcpy(textbuf+cu->pos, copybuf, len * sizeof(wchar_t));
568
 
                
569
 
                        memmove(textbufinfo+cu->pos+len, textbufinfo+cu->pos, (cu->len-cu->pos+1)*sizeof(CharInfo));
570
 
                        memcpy(textbufinfo+cu->pos, copybufinfo, len*sizeof(CharInfo)); 
571
 
                
572
 
                        cu->len += len;
573
 
                        cu->pos += len;
574
 
                }
575
 
        }
576
 
        else
577
 
        {
578
 
                error("Text too long");
579
 
        }
580
 
}
581
 
 
582
 
int style_to_sel(int style, int toggle) 
583
 
{
584
 
        int selstart, selend;
585
 
        int i;
586
 
        Curve *cu;
587
 
        
588
 
        if (G.obedit && (G.obedit->type == OB_FONT)) {
589
 
                cu= G.obedit->data;
590
 
                
591
 
                if (getselection(&selstart, &selend)) {
592
 
                        for (i=selstart; i<=selend; i++) {
593
 
                                if (toggle==0) {
594
 
                                        textbufinfo[i].flag &= ~style;
595
 
                                } else {
596
 
                                        textbufinfo[i].flag |= style;
597
 
                                }
598
 
                        }
599
 
                        return 1;
600
 
                }
601
 
        }
602
 
        return 0;
603
 
}
604
 
 
605
 
int mat_to_sel(void) {
606
 
        int selstart, selend;
607
 
        int i;
608
 
        Curve *cu;
609
 
        
610
 
        if (G.obedit && (G.obedit->type == OB_FONT)) {
611
 
                cu= G.obedit->data;
612
 
                
613
 
                if (getselection(&selstart, &selend)) {
614
 
                        for (i=selstart; i<=selend; i++) {
615
 
                                textbufinfo[i].mat_nr = G.obedit->actcol;
616
 
                        }
617
 
                        return 1;
618
 
                }
619
 
        }
620
 
        return 0;
621
 
}
622
 
 
623
 
void do_textedit(unsigned short event, short val, uintptr_t _ascii)
624
 
{
625
 
        Curve *cu;
626
 
        static int accentcode= 0;
627
 
        int x, doit=0, cursmove=0;
628
 
        uintptr_t ascii = _ascii;
629
 
        short kern;
630
 
 
631
 
        cu= G.obedit->data;
632
 
 
633
 
        if(ascii) {
634
 
        
635
 
                /* handle case like TAB (TAB==9) */
636
 
                if( (ascii > 31 && ascii < 254 && ascii != 127) || (ascii==13) || (ascii==10) || (ascii==8)) {
637
 
        
638
 
                        if(accentcode) {
639
 
                                if(cu->pos>0) textbuf[cu->pos-1]= findaccent(textbuf[cu->pos-1], ascii);
640
 
                                accentcode= 0;
641
 
                        }
642
 
                        else if(cu->len<MAXTEXT-1) {
643
 
                                if(G.qual & LR_ALTKEY ) {
644
 
                                
645
 
                                        /* might become obsolete, apple has default values for this, other OS's too? */
646
 
                                
647
 
                                        if(ascii=='t') ascii= 137;
648
 
                                        else if(ascii=='c') ascii= 169;
649
 
                                        else if(ascii=='f') ascii= 164;
650
 
                                        else if(ascii=='g') ascii= 176;
651
 
                                        else if(ascii=='l') ascii= 163;
652
 
                                        else if(ascii=='r') ascii= 174;
653
 
                                        else if(ascii=='s') ascii= 223;
654
 
                                        else if(ascii=='v') ascii= 1001;
655
 
                                        else if(ascii=='y') ascii= 165;
656
 
                                        else if(ascii=='.') ascii= 138;
657
 
                                        else if(ascii=='1') ascii= 185;
658
 
                                        else if(ascii=='2') ascii= 178;
659
 
                                        else if(ascii=='3') ascii= 179;
660
 
                                        else if(ascii=='%') ascii= 139;
661
 
                                        else if(ascii=='?') ascii= 191;
662
 
                                        else if(ascii=='!') ascii= 161;
663
 
                                        else if(ascii=='x') ascii= 215;
664
 
                                        else if(ascii=='>') ascii= 187;
665
 
                                        else if(ascii=='<') ascii= 171;
666
 
                                }
667
 
                                if(ascii==1001) {
668
 
                                        int file, filelen;
669
 
                                        char *strp;
670
 
                                        
671
 
/* this should be solved by clipboard support */
672
 
#ifdef __WIN32_DISABLED 
673
 
                                        file= open("C:\\windows\\temp\\cutbuf", O_BINARY|O_RDONLY);
674
 
#else
675
 
                                        file= open("/tmp/.cutbuffer", O_BINARY|O_RDONLY);
676
 
#endif
677
 
                                        if(file>0) {
678
 
                                        
679
 
                                                filelen = BLI_filesize(file);
680
 
                                        
681
 
                                                strp= MEM_mallocN(filelen+4, "tempstr");
682
 
                                                read(file, strp, filelen);
683
 
                                                close(file);
684
 
                                                strp[filelen]= 0;
685
 
 
686
 
                                                if(cu->len+filelen<MAXTEXT) {
687
 
                                                        int tmplen;
688
 
                                                        wchar_t *mem = MEM_callocN((sizeof(wchar_t)*filelen)+(4*sizeof(wchar_t)), "temporary");
689
 
                                                        tmplen = utf8towchar(mem, strp);
690
 
                                                        wcscat(textbuf, mem);
691
 
                                                        MEM_freeN(mem);
692
 
                                                        cu->len += tmplen;
693
 
                                                        cu->pos= cu->len;
694
 
                                                }
695
 
                                                MEM_freeN(strp);
696
 
                                        }
697
 
                                }
698
 
                                else {
699
 
                                        insert_into_textbuf(cu, ascii);
700
 
                                }
701
 
                        }
702
 
                        
703
 
                        killselection(1);
704
 
                        
705
 
                        doit= 1;
706
 
                }
707
 
                else
708
 
                {
709
 
                        insert_into_textbuf(cu, ascii);
710
 
                        doit = 1;
711
 
                }
712
 
        }
713
 
        else if(val) {
714
 
                cursmove= 0;
715
 
                
716
 
                switch(event) {
717
 
                case ENDKEY:
718
 
                        if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;         
719
 
                        while(cu->pos<cu->len) {
720
 
                                if( textbuf[cu->pos]==0) break;
721
 
                                if( textbuf[cu->pos]=='\n') break;
722
 
                                if( textbufinfo[cu->pos].flag & CU_WRAP ) break;
723
 
                                cu->pos++;
724
 
                        }
725
 
                        cursmove=FO_CURS;
726
 
                        break;
727
 
 
728
 
                case HOMEKEY:
729
 
                        if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
730
 
                        while(cu->pos>0) {
731
 
                                if( textbuf[cu->pos-1]=='\n') break;
732
 
                                if( textbufinfo[cu->pos-1].flag & CU_WRAP ) break;                              
733
 
                                cu->pos--;
734
 
                        }               
735
 
                        cursmove=FO_CURS;
736
 
                        break;
737
 
                        
738
 
                case RETKEY:
739
 
                        if(G.qual & LR_CTRLKEY) {
740
 
                                insert_into_textbuf(cu, 1);
741
 
                                if (textbuf[cu->pos]!='\n') insert_into_textbuf(cu, '\n');                              
742
 
                        }
743
 
                        else {
744
 
                                insert_into_textbuf(cu, '\n');
745
 
                        }
746
 
                        cu->selstart = cu->selend = 0;
747
 
                        doit= 1;
748
 
                        break;
749
 
 
750
 
                case RIGHTARROWKEY:     
751
 
                        if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
752
 
                        if (G.qual & LR_CTRLKEY) {
753
 
                                cu->pos= next_word(cu);
754
 
                                cursmove= FO_CURS;                              
755
 
                        } 
756
 
                        else if (G.qual & LR_ALTKEY) {
757
 
                                kern = textbufinfo[cu->pos-1].kern;
758
 
                                kern += 1;
759
 
                                if (kern>20) kern = 20;
760
 
                                textbufinfo[cu->pos-1].kern = kern;
761
 
                                doit = 1;
762
 
                        }
763
 
                        else {
764
 
                                cu->pos++;
765
 
                                cursmove= FO_CURS;                              
766
 
                        }
767
 
 
768
 
                        break;
769
 
                        
770
 
                case LEFTARROWKEY:
771
 
                        if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
772
 
                        if (G.qual & LR_CTRLKEY) {
773
 
                                cu->pos= prev_word(cu);
774
 
                                cursmove= FO_CURS;
775
 
                        } 
776
 
                        else if (G.qual & LR_ALTKEY) {
777
 
                                kern = textbufinfo[cu->pos-1].kern;
778
 
                                kern -= 1;
779
 
                                if (kern<-20) kern = -20;
780
 
                                textbufinfo[cu->pos-1].kern = kern;
781
 
                                doit = 1;
782
 
                        }
783
 
                        else {
784
 
                                cu->pos--;
785
 
                                cursmove=FO_CURS;
786
 
                        }
787
 
                        break;
788
 
 
789
 
                case UPARROWKEY:
790
 
                        if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
791
 
                        if(G.qual & LR_ALTKEY) {
792
 
                                if (cu->pos && textbuf[cu->pos - 1] < 255) {
793
 
                                        textbuf[cu->pos - 1]++;
794
 
                                        doit= 1;
795
 
                                }
796
 
                        }
797
 
                        else cursmove=FO_CURSUP;
798
 
                        break;
799
 
                        
800
 
                case PAGEUPKEY:
801
 
                        if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
802
 
                        cursmove=FO_PAGEUP;
803
 
                        break;
804
 
                        
805
 
                case DOWNARROWKEY:
806
 
                        if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
807
 
                        if(G.qual & LR_ALTKEY) {
808
 
                                if (cu->pos && textbuf[cu->pos - 1] > 1) {
809
 
                                        textbuf[cu->pos - 1]--;
810
 
                                        doit= 1;
811
 
                                }
812
 
                        }
813
 
                        else cursmove= FO_CURSDOWN;
814
 
                        break;
815
 
 
816
 
                case PAGEDOWNKEY:
817
 
                        if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
818
 
                        cursmove=FO_PAGEDOWN;
819
 
                        break;
820
 
                        
821
 
                case BACKSPACEKEY:
822
 
                        if(cu->len!=0) {
823
 
                                if(G.qual & LR_ALTKEY) {
824
 
                                        if(cu->pos>0) accentcode= 1;
825
 
                                }
826
 
                                else if (G.qual & LR_CTRLKEY) {
827
 
                                        cu->len = cu->pos = 0;
828
 
                                        textbuf[0]= 0;
829
 
                                        doit= 1;
830
 
                                }
831
 
                                else {
832
 
                                        if (killselection(0)==0) {
833
 
                                                if (cu->pos>0) {
834
 
                                                        for(x=cu->pos;x<=cu->len;x++) textbuf[x-1]= textbuf[x];
835
 
                                                        for(x=cu->pos;x<=cu->len;x++) textbufinfo[x-1]= textbufinfo[x];                                 
836
 
                                                        cu->pos--;
837
 
                                                        textbuf[--cu->len]='\0';
838
 
                                                        doit=1;
839
 
                                                }
840
 
                                        } else doit=1;
841
 
                                }
842
 
                        }
843
 
                        break;
844
 
 
845
 
                case DELKEY:
846
 
                        if(cu->len!=0) {
847
 
                                if (killselection(0)==0) {
848
 
                                        if(cu->pos<cu->len) {                                   
849
 
                                                for(x=cu->pos;x<cu->len;x++) textbuf[x]= textbuf[x+1];
850
 
                                                for(x=cu->pos;x<cu->len;x++) textbufinfo[x]= textbufinfo[x+1];                                  
851
 
                                                textbuf[--cu->len]='\0';
852
 
                                                doit=1;
853
 
                                        }
854
 
                                } else doit=1;
855
 
                        }
856
 
                        break;
857
 
                
858
 
                case IKEY:
859
 
                        if (G.qual & LR_CTRLKEY) {
860
 
                                cu->curinfo.flag ^= CU_ITALIC;
861
 
                                if (style_to_sel(CU_ITALIC, cu->curinfo.flag & CU_ITALIC)) doit= 1;                             
862
 
                                allqueue(REDRAWBUTSEDIT, 0);
863
 
                        }
864
 
                        break;
865
 
 
866
 
                case BKEY:
867
 
                        if (G.qual & LR_CTRLKEY) {
868
 
                                cu->curinfo.flag ^= CU_BOLD;
869
 
                                if (style_to_sel(CU_BOLD, cu->curinfo.flag & CU_BOLD)) doit= 1;
870
 
                                allqueue(REDRAWBUTSEDIT, 0);
871
 
                        }
872
 
                        break;                  
873
 
                        
874
 
                case UKEY:
875
 
                        if (G.qual & LR_CTRLKEY) {
876
 
                                cu->curinfo.flag ^= CU_UNDERLINE;
877
 
                                if (style_to_sel(CU_UNDERLINE, cu->curinfo.flag & CU_UNDERLINE)) doit= 1;
878
 
                                allqueue(REDRAWBUTSEDIT, 0);
879
 
                        }
880
 
                        break;
881
 
                        
882
 
                case XKEY:
883
 
                        if (G.qual & LR_CTRLKEY) {
884
 
                                copyselection();
885
 
                                killselection(0);
886
 
                                doit= 1;
887
 
                        }
888
 
                        break;
889
 
                        
890
 
                case CKEY:
891
 
                        if (G.qual & LR_CTRLKEY) {
892
 
                                copyselection();
893
 
                        }
894
 
                        break;                          
895
 
                        
896
 
                case VKEY:
897
 
                        if (G.qual & LR_CTRLKEY) {
898
 
                                pasteselection();
899
 
                                doit= 1;
900
 
                        }
901
 
                        break;
902
 
                
903
 
                }
904
 
                        
905
 
                if(cursmove) {
906
 
                        if ((G.qual & LR_SHIFTKEY)==0) {
907
 
                                if (cu->selstart) {
908
 
                                        cu->selstart = cu->selend = 0;
909
 
                                        update_string(cu);
910
 
                                        text_to_curve(G.obedit, FO_SELCHANGE);
911
 
                                        allqueue(REDRAWVIEW3D, 0);
912
 
                                }
913
 
                        }
914
 
                        if(cu->pos>cu->len) cu->pos= cu->len;
915
 
                        else if(cu->pos>=MAXTEXT) cu->pos= MAXTEXT;
916
 
                        else if(cu->pos<0) cu->pos= 0;
917
 
                }
918
 
        }
919
 
        if(doit || cursmove) {
920
 
        
921
 
                if (cu->pos) {
922
 
                        cu->curinfo = textbufinfo[cu->pos-1];
923
 
                } else cu->curinfo = textbufinfo[0];
924
 
                
925
 
                if (G.obedit->totcol>0) {
926
 
                        G.obedit->actcol = textbufinfo[cu->pos-1].mat_nr;
927
 
                }
928
 
                allqueue(REDRAWBUTSEDIT, 0);
929
 
                update_string(cu);
930
 
                text_to_curve(G.obedit, cursmove);
931
 
                if (cursmove && (G.qual & LR_SHIFTKEY)) {
932
 
                        cu->selend = cu->pos;
933
 
                        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
934
 
                }
935
 
                if(cursmove==0) {
936
 
                        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
937
 
                }                       
938
 
 
939
 
                BIF_undo_push("Textedit");
940
 
                allqueue(REDRAWVIEW3D, 0);
941
 
        }
942
 
}
943
 
 
944
 
void paste_unicodeText(char *filename)
945
 
{
946
 
        Curve *cu= G.obedit->data;
947
 
        int filelen, doit= 0;
948
 
        char *strp;
949
 
        FILE *fp = NULL;
950
 
 
951
 
        fp= fopen(filename, "r");
952
 
 
953
 
        if(fp) {
954
 
 
955
 
                fseek( fp, 0L, SEEK_END );
956
 
                filelen = ftell( fp );
957
 
                fseek( fp, 0L, SEEK_SET );
958
 
                        
959
 
                strp= MEM_mallocN(filelen+4, "tempstr");
960
 
                //fread() instead of read(),
961
 
                //because windows read() converts text to DOS \r\n linebreaks
962
 
                //causing double linebreaks in the 3d text
963
 
                filelen = fread(strp, 1, filelen, fp);
964
 
                fclose(fp);
965
 
                strp[filelen]= 0;
966
 
 
967
 
 
968
 
                if(cu->len+filelen<MAXTEXT) 
969
 
                {
970
 
                        int tmplen;
971
 
                        wchar_t *mem = MEM_callocN((sizeof(wchar_t)*filelen)+(4*sizeof(wchar_t)), "temporary");
972
 
                        tmplen = utf8towchar(mem, strp);
973
 
//                      mem =utf8s2wc(strp);
974
 
                        wcscat(textbuf, mem);
975
 
                        MEM_freeN(mem);
976
 
                        cu->len += tmplen;
977
 
                        cu->pos= cu->len;
978
 
                }
979
 
                MEM_freeN(strp);
980
 
                doit = 1;
981
 
        }
982
 
        if(doit) {
983
 
                update_string(cu);
984
 
                text_to_curve(G.obedit, 0);
985
 
                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
986
 
                allqueue(REDRAWVIEW3D, 0);
987
 
                BIF_undo_push("Paste text");
988
 
        }
989
 
}
990
 
 
991
 
void paste_editText(void)
992
 
{
993
 
        Curve *cu= G.obedit->data;
994
 
        int filelen, doit= 0;
995
 
        char *strp;
996
 
        FILE *fp = NULL;
997
 
 
998
 
#ifdef WIN32
999
 
        fp= fopen("C:\\windows\\temp\\cutbuf.txt", "r");
1000
 
 
1001
 
//      The following is more likely to work on all Win32 installations.
1002
 
//      suggested by Douglas Toltzman. Needs windows include files...
1003
 
/*
1004
 
        char tempFileName[MAX_PATH];
1005
 
        DWORD pathlen;
1006
 
        static const char cutbufname[]="cutbuf.txt";
1007
 
 
1008
 
        if ((pathlen=GetTempPath(sizeof(tempFileName),tempFileName)) > 0 &&
1009
 
                pathlen + sizeof(cutbufname) <= sizeof(tempFileName))
1010
 
        {
1011
 
                strcat(tempFileName,cutbufname);
1012
 
                file= open(tempFileName, O_BINARY|O_RDONLY);
1013
 
        }
1014
 
*/
1015
 
#else
1016
 
        fp= fopen("/tmp/.cutbuffer", "r");
1017
 
#endif
1018
 
 
1019
 
        if(fp) {
1020
 
                
1021
 
                fseek(fp, 0L, SEEK_END);                
1022
 
                filelen = ftell( fp );
1023
 
                fseek(fp, 0L, SEEK_SET);
1024
 
                                
1025
 
                strp= MEM_mallocN(filelen+4, "tempstr");
1026
 
                // fread() instead of read(),
1027
 
                // because windows read() converts text to DOS \r\n linebreaks
1028
 
                // causing double linebreaks in the 3d text
1029
 
                filelen = fread(strp, 1, filelen, fp);
1030
 
                fclose(fp);
1031
 
                strp[filelen]= 0;
1032
 
                
1033
 
                if(cu->len+filelen<MAXTEXT) {
1034
 
                        int tmplen;
1035
 
                        wchar_t *mem = MEM_callocN((sizeof(wchar_t) * filelen) + (4 * sizeof(wchar_t)), "temporary");
1036
 
                        tmplen = utf8towchar(mem, strp);
1037
 
                        wcscat(textbuf, mem);
1038
 
                        MEM_freeN(mem);
1039
 
                        cu->len += tmplen;
1040
 
                        cu->pos= cu->len;
1041
 
                }
1042
 
                MEM_freeN(strp);
1043
 
                doit = 1;
1044
 
        }
1045
 
        if(doit) {
1046
 
                update_string(cu);
1047
 
                text_to_curve(G.obedit, 0);
1048
 
                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1049
 
                allqueue(REDRAWVIEW3D, 0);
1050
 
                BIF_undo_push("Paste text");
1051
 
        }
1052
 
}
1053
 
 
1054
 
 
1055
 
void make_editText(void)
1056
 
{
1057
 
        Curve *cu;
1058
 
        cu= G.obedit->data;
1059
 
        
1060
 
        if(textbuf==NULL) textbuf= MEM_callocN((MAXTEXT+4)*sizeof(wchar_t), "texteditbuf");
1061
 
        if(textbufinfo==NULL) textbufinfo= MEM_callocN((MAXTEXT+4)*sizeof(CharInfo), "texteditbufinfo");
1062
 
        if(copybuf==NULL) copybuf= MEM_callocN((MAXTEXT+4)*sizeof(wchar_t), "texteditcopybuf");
1063
 
        if(copybufinfo==NULL) copybufinfo= MEM_callocN((MAXTEXT+4)*sizeof(CharInfo), "texteditcopybufinfo");    
1064
 
        if(oldstr==NULL) oldstr= MEM_callocN((MAXTEXT+4)*sizeof(wchar_t), "oldstrbuf");
1065
 
        
1066
 
        // Convert the original text to wchar_t
1067
 
        utf8towchar(textbuf, cu->str);
1068
 
        wcscpy(oldstr, textbuf);
1069
 
                
1070
 
        cu->len= wcslen(textbuf);
1071
 
        
1072
 
        memcpy(textbufinfo, cu->strinfo, (cu->len)*sizeof(CharInfo));
1073
 
        
1074
 
        oldstrinfo= cu->strinfo;
1075
 
        cu->strinfo= textbufinfo;
1076
 
 
1077
 
        if(cu->pos>cu->len) cu->pos= cu->len;
1078
 
 
1079
 
        if (cu->pos) {
1080
 
                cu->curinfo = textbufinfo[cu->pos-1];
1081
 
        } else cu->curinfo = textbufinfo[0];
1082
 
        
1083
 
        // Convert to UTF-8
1084
 
        update_string(cu);
1085
 
        
1086
 
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1087
 
        
1088
 
        textediting= 1;
1089
 
        BIF_undo_push("Original");
1090
 
}
1091
 
 
1092
 
 
1093
 
void load_editText(void)
1094
 
{
1095
 
        Curve *cu;
1096
 
        
1097
 
        cu= G.obedit->data;
1098
 
 
1099
 
        MEM_freeN(oldstr);
1100
 
        oldstr= NULL;
1101
 
        MEM_freeN(oldstrinfo);
1102
 
        oldstrinfo= NULL;
1103
 
        
1104
 
        update_string(cu);
1105
 
        
1106
 
        cu->strinfo= MEM_callocN((cu->len+4)*sizeof(CharInfo), "texteditinfo");
1107
 
        memcpy(cu->strinfo, textbufinfo, (cu->len)*sizeof(CharInfo));
1108
 
 
1109
 
        cu->len= strlen(cu->str);
1110
 
        
1111
 
        /* this memory system is weak... */
1112
 
        MEM_freeN(textbuf);
1113
 
        MEM_freeN(textbufinfo);
1114
 
        textbuf= NULL;
1115
 
        textbufinfo= NULL;
1116
 
        
1117
 
        if (selboxes) {
1118
 
                MEM_freeN(selboxes);
1119
 
                selboxes= NULL;
1120
 
        }
1121
 
        
1122
 
        textediting= 0;
1123
 
        
1124
 
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1125
 
 
1126
 
}
1127
 
 
1128
 
 
1129
 
void remake_editText(void)
1130
 
{
1131
 
        Curve *cu;
1132
 
                
1133
 
        if(okee("Reload original text")==0) return;
1134
 
        
1135
 
        // Copy the oldstr to textbuf temporary global variable
1136
 
        wcscpy(textbuf, oldstr);
1137
 
 
1138
 
        // Set the object length and position   
1139
 
        cu= G.obedit->data;
1140
 
        cu->len= wcslen(textbuf);
1141
 
        if(cu->pos>cu->len) cu->pos= cu->len;
1142
 
 
1143
 
        update_string(cu);
1144
 
        
1145
 
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);     
1146
 
        allqueue(REDRAWVIEW3D, 0);
1147
 
        
1148
 
        BIF_undo_push("Reload");
1149
 
}
1150
 
 
1151
 
 
1152
 
void free_editText(void)
1153
 
{
1154
 
        if(oldstr) MEM_freeN(oldstr);
1155
 
        if(oldstrinfo) MEM_freeN(oldstrinfo);
1156
 
        if(textbuf) MEM_freeN(textbuf);
1157
 
        textbuf = oldstr = NULL;
1158
 
        textbufinfo = oldstrinfo = NULL;
1159
 
        textediting= 0;
1160
 
}
1161
 
 
1162
 
 
1163
 
void add_primitiveFont(int dummy_argument)
1164
 
{
1165
 
        Curve *cu;
1166
 
 
1167
 
        if (G.obedit && G.obedit->type==OB_FONT) return;
1168
 
        check_editmode(OB_FONT);
1169
 
        
1170
 
        add_object_draw(OB_FONT);
1171
 
        base_init_from_view3d(BASACT, G.vd);
1172
 
        
1173
 
        where_is_object(BASACT->object);
1174
 
        
1175
 
        cu= BASACT->object->data;
1176
 
        
1177
 
        cu->vfont= cu->vfontb= cu->vfonti= cu->vfontbi= get_builtin_font();
1178
 
        cu->vfont->id.us+=4;
1179
 
        cu->str= MEM_mallocN(12, "str");
1180
 
        strcpy(cu->str, "Text");
1181
 
        cu->pos= 4;
1182
 
        cu->strinfo= MEM_callocN(12*sizeof(CharInfo), "strinfo");
1183
 
        cu->totbox= cu->actbox= 1;
1184
 
        cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "textbox");
1185
 
        cu->tb[0].w = cu->tb[0].h = 0.0;
1186
 
        
1187
 
        if (U.flag & USER_ADD_EDITMODE) 
1188
 
                enter_editmode(EM_WAITCURSOR);
1189
 
 
1190
 
        allqueue(REDRAWALL, 0);
1191
 
}
1192
 
 
1193
 
void to_upper(void)
1194
 
{
1195
 
        Curve *cu;
1196
 
        int len, ok;
1197
 
        wchar_t *str;
1198
 
        
1199
 
        if(G.obedit==0) {
1200
 
                return;
1201
 
        }
1202
 
        
1203
 
        ok= 0;
1204
 
        cu= G.obedit->data;
1205
 
        
1206
 
        len= wcslen(textbuf);
1207
 
        str= textbuf;
1208
 
        while(len) {
1209
 
                if( *str>=97 && *str<=122) {
1210
 
                        ok= 1;
1211
 
                        *str-= 32;
1212
 
                }
1213
 
                len--;
1214
 
                str++;
1215
 
        }
1216
 
        
1217
 
        if(ok==0) {
1218
 
                len= wcslen(textbuf);
1219
 
                str= textbuf;
1220
 
                while(len) {
1221
 
                        if( *str>=65 && *str<=90) {
1222
 
                                *str+= 32;
1223
 
                        }
1224
 
                        len--;
1225
 
                        str++;
1226
 
                }
1227
 
        }
1228
 
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1229
 
        allqueue(REDRAWVIEW3D, 0);
1230
 
        BIF_undo_push("To upper");
1231
 
 
1232
 
        update_string(cu);
1233
 
}
1234
 
 
1235
 
 
1236
 
/* **************** undo for font object ************** */
1237
 
 
1238
 
static void undoFont_to_editFont(void *strv)
1239
 
{
1240
 
        Curve *cu= G.obedit->data;
1241
 
        char *str= strv;
1242
 
 
1243
 
        cu->pos= *((short *)str);
1244
 
        cu->len= *((short *)(str+2));
1245
 
 
1246
 
        memcpy(textbuf, str+4, (cu->len+1)*sizeof(wchar_t));
1247
 
        memcpy(textbufinfo, str+4 + (cu->len+1)*sizeof(wchar_t), cu->len*sizeof(CharInfo));
1248
 
        
1249
 
        cu->selstart = cu->selend = 0;
1250
 
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1251
 
        
1252
 
        update_string(cu);
1253
 
        
1254
 
        allqueue(REDRAWVIEW3D, 0);
1255
 
}
1256
 
 
1257
 
static void *editFont_to_undoFont(void)
1258
 
{
1259
 
        Curve *cu= G.obedit->data;
1260
 
        char *str;
1261
 
        
1262
 
        // The undo buffer includes [MAXTEXT+6]=actual string and [MAXTEXT+4]*sizeof(CharInfo)=charinfo
1263
 
        str= MEM_callocN((MAXTEXT+6)*sizeof(wchar_t) + (MAXTEXT+4)*sizeof(CharInfo), "string undo");
1264
 
 
1265
 
        // Copy the string and string information
1266
 
        memcpy(str+4, textbuf, (cu->len+1)*sizeof(wchar_t));
1267
 
        memcpy(str+4 + (cu->len+1)*sizeof(wchar_t), textbufinfo, cu->len*sizeof(CharInfo));
1268
 
 
1269
 
        *((short *)str)= cu->pos;
1270
 
        *((short *)(str+2))= cu->len;   
1271
 
        
1272
 
        return str;
1273
 
}
1274
 
 
1275
 
static void free_undoFont(void *strv)
1276
 
{
1277
 
        MEM_freeN(strv);
1278
 
}
1279
 
 
1280
 
/* and this is all the undo system needs to know */
1281
 
void undo_push_font(char *name)
1282
 
{
1283
 
        undo_editmode_push(name, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL);
1284
 
}
1285
 
 
1286
 
 
1287
 
 
1288
 
/***/