Initial commit for new text object.
authorAlexander Ewering <blender@instinctive.de>
Fri, 17 Jun 2005 21:04:27 +0000 (21:04 +0000)
committerAlexander Ewering <blender@instinctive.de>
Fri, 17 Jun 2005 21:04:27 +0000 (21:04 +0000)
Important notes:

 - Full compatibility with old text objects not fully restored
   (word spacing will be 0.0, need to set it manually to 1.0), will
   either need version upgrade to 238 or a hack. Will check.

 - lorem.c (about to be committed) contains BF copyright notice, but as
   BF did not exist a few hundred years ago, probably best to remove it :)

 - If you notice any cross-platform issues (especially beloved windows),
   please report

 - A few tiny warnings left, I will fix those issues still.

The rest has been said already - so have fun testing. And please do!

=== Reminder:
=== Documentation at http://blender.instinctive.de/docs/textobject.txt ===

20 files changed:
source/blender/blenkernel/BKE_displist.h
source/blender/blenkernel/BKE_font.h
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/font.c
source/blender/blenlib/intern/psfont.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/include/BIF_editfont.h
source/blender/include/BIF_glutil.h
source/blender/include/butspace.h
source/blender/makesdna/DNA_curve_types.h
source/blender/makesdna/DNA_vfont_types.h
source/blender/src/buttons_editing.c
source/blender/src/drawobject.c
source/blender/src/editfont.c
source/blender/src/editobject.c
source/blender/src/editscreen.c
source/blender/src/glutil.c
source/blender/src/toets.c

index 3193c8cbfecfa362da95d91bdf5a928922ed8d2a..ca08b5454a3ed87c9a2038a093c4814ae6c619c5 100644 (file)
@@ -127,6 +127,8 @@ typedef struct DispList {
        float *verts, *nors;
        int *index;
        unsigned int *col1, *col2;
+       int charidx;
+       int pad;
 } DispList;
 
 extern void copy_displist(struct ListBase *lbn, struct ListBase *lb);
index 2f923315aafc32038d608983810c1ba46f981248..d99085f9ee9b7a297fca2ce3457235ec7a3f98f3 100644 (file)
@@ -39,13 +39,22 @@ struct Object;
 struct Curve;
 struct objfnt;
 
+typedef struct SelBox {
+       float x, y, w, h;
+} SelBox;
+
 void BKE_font_register_builtin(void *mem, int size);
 
 void free_vfont(struct VFont *sc); 
 struct VFont *load_vfont(char *name);
 
 struct chartrans *text_to_curve(struct Object *ob, int mode);
+int style_to_sel(void);
+int mat_to_sel(void);
 void font_duplilist(struct Object *par);
+struct SelBox *selboxes;
+int getselection(int *start, int *end);
+
 
 #endif
 
index 83c51de76d1c7cf4067dcf6c8194af71816a196c..c118a109b8fc605f106090b7bacfa31b5ee42d43 100644 (file)
@@ -145,8 +145,10 @@ void free_curve(Curve *cu)
        
        if(cu->mat) MEM_freeN(cu->mat);
        if(cu->str) MEM_freeN(cu->str);
+       if(cu->strinfo) MEM_freeN(cu->strinfo);
        if(cu->bb) MEM_freeN(cu->bb);
        if(cu->path) free_path(cu->path);
+       if(cu->tb) MEM_freeN(cu->tb);
 }
 
 Curve *add_curve(int type)
@@ -165,6 +167,7 @@ Curve *add_curve(int type)
        cu->pathlen= 100;
        cu->resolu= cu->resolv= 6;
        cu->width= 1.0;
+       cu->wordspace = 1.0;
        cu->spacing= cu->linedist= 1.0;
        cu->fsize= 1.0;
        cu->texflag= CU_AUTOSPACE;
@@ -189,6 +192,8 @@ Curve *copy_curve(Curve *cu)
        }
        
        cun->str= MEM_dupallocN(cu->str);
+       cun->strinfo= MEM_dupallocN(cu->strinfo);       
+       cun->tb= MEM_dupallocN(cu->tb);
        cun->bb= MEM_dupallocN(cu->bb);
        
        cun->key= copy_key(cu->key);
@@ -202,6 +207,9 @@ Curve *copy_curve(Curve *cu)
        if(cun->ipo) cun->ipo= copy_ipo(cun->ipo);
 
        id_us_plus((ID *)cun->vfont);
+       id_us_plus((ID *)cun->vfontb);  
+       id_us_plus((ID *)cun->vfonti);
+       id_us_plus((ID *)cun->vfontbi);
        
        return cun;
 }
index 87aa3dc17b9389f6700d8466816a95cb81c96d0f..647ff5355857c9859f4922f816072625a8724f74 100644 (file)
@@ -1272,6 +1272,7 @@ static void curve_to_displist(ListBase *nubase, ListBase *dispbase)
                                dl->parts= 1;
                                dl->nr= len;
                                dl->col= nu->mat_nr;
+                               dl->charidx= nu->charidx;
 
                                data= dl->verts;
 
@@ -1359,12 +1360,17 @@ void filldisplist(ListBase *dispbase, ListBase *to)
        EditFace *efa;
        DispList *dlnew=0, *dl;
        float *f1;
-       int colnr=0, cont=1, tot, a, *index;
+       int colnr=0, charidx=0, cont=1, tot, a, *index;
        long totvert;
        
        if(dispbase==0) return;
        if(dispbase->first==0) return;
 
+       /* tijd= clock(); */
+       /* bit-wise and comes after == .... so this doesn't work...  */
+/*     if(G.f & G_PLAYANIM == 0) waitcursor(1); */
+       if( !(G.f & G_PLAYANIM) ) waitcursor(1);
+
        while(cont) {
                cont= 0;
                totvert=0;
@@ -1373,10 +1379,11 @@ void filldisplist(ListBase *dispbase, ListBase *to)
                while(dl) {
        
                        if(dl->type==DL_POLY) {
-                               if(colnr<dl->col) cont= 1;
-                               else if(colnr==dl->col) {
+                               if(charidx<dl->charidx) cont= 1;
+                               else if(charidx==dl->charidx) {
                        
                                        colnr= dl->col;
+                                       charidx= dl->charidx;
                
                                        /* make editverts and edges */
                                        f1= dl->verts;
@@ -1464,10 +1471,16 @@ void filldisplist(ListBase *dispbase, ListBase *to)
                }
                BLI_end_edgefill();
 
-               colnr++;
+               charidx++;
        }
        
        /* do not free polys, needed for wireframe display */
+       
+       /* same as above ... */
+/*     if(G.f & G_PLAYANIM == 0) waitcursor(0); */
+       if( !(G.f & G_PLAYANIM) ) waitcursor(0);
+       /* printf("time: %d\n",(clock()-tijd)/1000); */
+
 }
 
 static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
index fc1d45f9696fbd1a9d2a54e8813ab48af8710f64..999b83152427d648427100a363a5eeaacd43fc83 100644 (file)
 #include "BKE_curve.h"
 #include "BKE_displist.h"
 
+#define callocstructN(x,y,name) (x*)MEM_callocN((y)* sizeof(x),name)
+struct SelBox *selboxes= NULL;
 
 struct chartrans {
        float xof, yof;
        float rot;
        short linenr,charnr;
+       char dobreak;
 };
 
 void free_vfont(struct VFont *vf)
@@ -215,17 +219,40 @@ VFont *load_vfont(char *name)
        return vfont;
 }
 
-static void buildchar(Curve *cu, unsigned char ascii, float ofsx, float ofsy, float rot)
+static VFont *which_vfont(Curve *cu, CharInfo *info)
+{
+       switch(info->flag & CU_STYLE) {
+               case CU_BOLD:
+                       return(cu->vfontb);
+               case CU_ITALIC:
+                       return(cu->vfonti);
+               case (CU_BOLD|CU_ITALIC):
+                       return(cu->vfontbi);
+               default:
+                       return(cu->vfont);
+       }                       
+}
+
+static void buildchar(Curve *cu, unsigned char ascii, CharInfo *info, float ofsx, float ofsy, float rot, int charidx)
 {
        BezTriple *bezt1, *bezt2;
        Nurb *nu1, *nu2;
        float *fp, fsize, shear, x, si, co;
        VFontData *vfd;
-       int i;
+       int i, sel=0;
 
-       vfd= vfont_get_data(cu->vfont); 
+       vfd= vfont_get_data(which_vfont(cu, info));     
        if (!vfd) return;
-       
+
+       if (cu->selend < cu->selstart) {
+               if ((charidx >= (cu->selend)) && (charidx <= (cu->selstart-2)))
+                       sel= 1;
+       }
+       else {
+               if ((charidx >= (cu->selstart-1)) && (charidx <= (cu->selend-1)))
+                       sel= 1;
+       }
+
        /* make a copy at distance ofsx,ofsy with shear*/
        fsize= cu->fsize;
        shear= cu->shear;
@@ -244,6 +271,8 @@ static void buildchar(Curve *cu, unsigned char ascii, float ofsx, float ofsy, fl
                        nu2->bp = 0;
                        nu2->knotsu = nu2->knotsv = 0;
                        nu2->flag= CU_SMOOTH;
+                       nu2->charidx = charidx;
+                       if (info->mat_nr) nu2->mat_nr= info->mat_nr-1;
                        /* nu2->trim.first = 0; */
                        /* nu2->trim.last = 0; */
                        i = nu2->pntsu;
@@ -285,7 +314,7 @@ static void buildchar(Curve *cu, unsigned char ascii, float ofsx, float ofsy, fl
                                }
                        }
                        bezt2 = nu2->bezt;
-                       
+
                        for (i= nu2->pntsu; i > 0; i--) {
                                fp= bezt2->vec[0];
 
@@ -300,23 +329,52 @@ static void buildchar(Curve *cu, unsigned char ascii, float ofsx, float ofsy, fl
                        
                        BLI_addtail(&(cu->nurb), nu2);
                }
+               
                nu1 = nu1->next;
        }
 }
 
+int getselection(int *start, int *end)
+{
+       Curve *cu;
+       
+       if (G.obedit==NULL || G.obedit->type != OB_FONT) return 0;
+       
+       cu= G.obedit->data;
+
+       if (cu->selstart == 0) return 0;
+       if (cu->selstart <= cu->selend) {
+               *start = cu->selstart-1;
+               *end = cu->selend-1;
+               return 1;
+       }
+       else {
+               *start = cu->selend;
+               *end = cu->selstart-2;
+               return -1;
+       }
+}
 
 struct chartrans *text_to_curve(Object *ob, int mode) 
 {
-       VFont *vfont;
+       VFont *vfont, *oldvfont;
        VFontData *vfd;
        Curve *cu, *cucu;
        struct chartrans *chartransdata, *ct;
        float distfac, tabfac, ctime, dtime, tvec[4], vec[4], rotvec[3], minx, maxx, miny, maxy;
        float cmat[3][3], timeofs, si, co, sizefac;
-       float *f, maxlen=0, xof, yof, xtrax, linedist, *linedata, *linedata2;
-       int i, slen, oldflag;
+       float *f, maxlen=0, xof, yof, xtrax, linedist, *linedata, *linedata2, *linedata3;
+       int i, slen, oldflag, j;
        short cnr=0, lnr=0;
        char ascii, *mem;
+       int outta;
+       float vecyo[3];
+       CharInfo *info;
+       float wsfac;
+       TextBox *tb;
+       int curbox;
+       int selstart, selend;
+       SelBox *sb;
 
        /* renark: do calculations including the trailing '\0' of a string
           because the cursor can be at that location */
@@ -324,54 +382,101 @@ struct chartrans *text_to_curve(Object *ob, int mode)
        if(ob->type!=OB_FONT) return 0;
 
        cu= ob->data;
+       mem= cu->str;
+       slen = strlen(mem);     
 
-       vfont= cu->vfont;
-       if (vfont==0) return 0;
        if (cu->str==0) return 0;
-
-       vfd= vfont_get_data(vfont);
-       if (!vfd) return 0;
-       
-       /* count number of lines */
-       mem= cu->str;
-       slen = strlen(mem);
-       cu->lines= 1;
-       for (i= 0; i<=slen; i++, mem++) {
-               ascii = *mem;
-               if(ascii== '\n' || ascii== '\r') cu->lines++;
+       if (cu->strinfo==NULL) {        /* old file */
+               fprintf(stderr, "old file\n");
+               cu->strinfo = MEM_callocN((slen+1) * sizeof(CharInfo), "strinfo compat");
        }
 
        /* calc offset and rotation of each char */
        ct = chartransdata =
                (struct chartrans*)MEM_callocN((slen+1)* sizeof(struct chartrans),"buildtext");
-       linedata= MEM_mallocN(sizeof(float)*cu->lines,"buildtext2");
-       linedata2= MEM_mallocN(sizeof(float)*cu->lines,"buildtext2");
-       xof= cu->xof;
-       yof= cu->yof;
 
-       xtrax= 0.5f*cu->spacing-0.5f;
+       /* We assume the worst case: 1 character per line (is freed at end anyway) */
+
+       linedata= MEM_mallocN(sizeof(float)*(slen+2),"buildtext2");
+       linedata2= MEM_mallocN(sizeof(float)*(slen+2),"buildtext3");
+       linedata3= MEM_mallocN(sizeof(float)*(slen+2),"buildtext4");    
+       
        linedist= cu->linedist;
+       
+       xof= cu->xof + (cu->tb[0].x/cu->fsize);
+       yof= cu->yof + (cu->tb[0].y/cu->fsize);
+
+       xtrax= 0.5f*cu->spacing-0.5f;
+
+       oldvfont = NULL;
 
+       for (i=0; i<slen; i++) cu->strinfo[i].flag &= ~CU_WRAP;
+
+       if (selboxes) MEM_freeN(selboxes);
+       selboxes = NULL;
+       if (getselection(&selstart, &selend))
+               selboxes = MEM_callocN((selend-selstart+1)*sizeof(SelBox), "font selboxes");
+
+       tb = &(cu->tb[0]);
+       curbox= 0;
        for (i = 0 ; i<=slen ; i++) {
+       makebreak:
                ascii = cu->str[i];
-               if(ascii== '\n' || ascii== '\r' || ascii==0) {
+               info = &(cu->strinfo[i]);
+               vfont = which_vfont(cu, info);
+       if (vfont==0) return 0;
+       if (vfont != oldvfont) {
+               vfd= vfont_get_data(vfont);
+               oldvfont = vfont;
+       }
+       if (!vfd) return 0;     
+       if((tb->w != 0.0) && (ct->dobreak==0) && ((xof-(tb->x/cu->fsize)+vfd->width[ascii])*cu->fsize) > tb->w) {
+//                     fprintf(stderr, "linewidth exceeded: %c%c%c...\n", cu->str[i], cu->str[i+1], cu->str[i+2]);
+               for (j=i; j && (cu->str[j] != '\n') && (cu->str[j] != '\r') && (chartransdata[j].dobreak==0); j--) {
+                       if (cu->str[j]==' ') {
+                                       ct -= (i-(j-1));
+                                       cnr -= (i-(j-1));
+                                       i = j-1;
+                                       xof = ct->xof;
+                                       ct[1].dobreak = 1;
+                                       cu->strinfo[i+1].flag |= CU_WRAP;
+                                       goto makebreak;
+                       }
+                       if (chartransdata[j].dobreak) {
+//                             fprintf(stderr, "word too long: %c%c%c...\n", cu->str[j], cu->str[j+1], cu->str[j+2]);
+                               ct->dobreak= 1;
+                               cu->strinfo[i+1].flag |= CU_WRAP;
+                               ct -= 1;
+                               cnr -= 1;
+                               i--;
+                               xof = ct->xof;
+                               goto makebreak;
+                       }
+               }
+       }
+               if(ascii== '\n' || ascii== '\r' || ascii==0 || ct->dobreak) {
                        ct->xof= xof;
                        ct->yof= yof;
                        ct->linenr= lnr;
                        ct->charnr= cnr;
                        
-                       /* only empty lines are allowed smaller than 1 */
-//                     if( linedist<1.0) {
-//                             if(i<slen && (cu->str[i+1]=='\r' || cu->str[i+1]=='\n')) yof-= linedist;
-//                             else yof-= 1.0;
-//                     }
-//                     else
                        yof-= linedist;
                        
-                       maxlen= MAX2(maxlen, xof);
-                       linedata[lnr]= xof;
+                       maxlen= MAX2(maxlen, (xof-tb->x/cu->fsize));
+                       linedata[lnr]= xof-tb->x/cu->fsize;
                        linedata2[lnr]= cnr;
-                       xof= cu->xof;
+                       linedata3[lnr]= tb->w/cu->fsize;
+                       
+                       if ( (tb->h != 0.0) &&
+                            ((-(yof-(tb->y/cu->fsize))) > ((tb->h/cu->fsize)-(linedist*cu->fsize))) &&
+                            (cu->totbox > (curbox+1)) ) {
+                               maxlen= 0;
+                               tb++;
+                               curbox++;
+                               yof= cu->yof + tb->y/cu->fsize;
+                       }
+                       
+                       xof= cu->xof + (tb->x/cu->fsize);
                        lnr++;
                        cnr= 0;
                }
@@ -391,51 +496,45 @@ struct chartrans *text_to_curve(Object *ob, int mode)
                        ct->linenr= lnr;
                        ct->charnr= cnr++;
 
-                       xof += vfd->width[ascii] + xtrax;
+                       if (selboxes && (i>=selstart) && (i<=selend)) {
+                       sb = &(selboxes[i-selstart]);
+                       sb->y = yof*cu->fsize-linedist*cu->fsize*0.1;
+                       sb->h = linedist*cu->fsize;
+                       sb->w = xof*cu->fsize;
+               }
+       
+                       if (ascii==32) wsfac = cu->wordspace; else wsfac = 1.0;
+                       xof += (vfd->width[ascii]*wsfac*(1.0+(info->kern/20.0)) ) + xtrax;
+                       
+                       if (selboxes && (i>=selstart) && (i<=selend)) sb->w = (xof*cu->fsize) - sb->w;
                }
                ct++;
        }
+       
 
-       /* met alle fontsettings plekken letters berekenen */
-       if(cu->spacemode!=CU_LEFT/* && lnr>1*/) {
-               ct= chartransdata;
+       
+       cu->lines= 1;
+       ct= chartransdata;
+       for (i= 0; i<=slen; i++, mem++, ct++) {
+               ascii = *mem;
+               if(ascii== '\n' || ascii== '\r' || ct->dobreak) cu->lines++;
+       }       
 
-               if(cu->spacemode==CU_RIGHT) {
-                       for(i=0;i<lnr;i++) linedata[i]= -linedata[i];
-                       for (i=0; i<=slen; i++) {
-                               ct->xof+= linedata[ct->linenr];
-                               ct++;
-                       }
-               } else if(cu->spacemode==CU_MIDDLE) {
-                       for(i=0;i<lnr;i++) linedata[i]= -linedata[i]/2;
-                       for (i=0; i<=slen; i++) {
-                               ct->xof+= linedata[ct->linenr];
-                               ct++;
-                       }
-               } else if(cu->spacemode==CU_FLUSH) {
-                       for(i=0;i<lnr;i++)
-                               if(linedata2[i]>1)
-                                       linedata[i]= ((maxlen-linedata[i])/(linedata2[i]-1));
-                       for (i=0; i<=slen; i++) {
-                               ct->xof+= (ct->charnr*linedata[ct->linenr])-maxlen/2;
-                               ct++;
-                       }
-               }
-       }
+       // linedata is now: width of line
+       // linedata2 is now: number of characters
+       // linedata3 is now: maxlen of that line
 
-       /* old alignment here, to spot the differences */
-/*
        if(cu->spacemode!=CU_LEFT && lnr>1) {
                ct= chartransdata;
 
                if(cu->spacemode==CU_RIGHT) {
-                       for(i=0;i<lnr;i++) linedata[i]= maxlen-linedata[i];
+                       for(i=0;i<lnr;i++) linedata[i]= linedata3[i]-linedata[i];
                        for (i=0; i<=slen; i++) {
                                ct->xof+= linedata[ct->linenr];
                                ct++;
                        }
                } else if(cu->spacemode==CU_MIDDLE) {
-                       for(i=0;i<lnr;i++) linedata[i]= (maxlen-linedata[i])/2;
+                       for(i=0;i<lnr;i++) linedata[i]= (linedata3[i]-linedata[i])/2;
                        for (i=0; i<=slen; i++) {
                                ct->xof+= linedata[ct->linenr];
                                ct++;
@@ -443,14 +542,18 @@ struct chartrans *text_to_curve(Object *ob, int mode)
                } else if(cu->spacemode==CU_FLUSH) {
                        for(i=0;i<lnr;i++)
                                if(linedata2[i]>1)
-                                       linedata[i]= (maxlen-linedata[i])/(linedata2[i]-1);
+                                       linedata[i]= (linedata3[i]-linedata[i])/(linedata2[i]-1);
                        for (i=0; i<=slen; i++) {
-                               ct->xof+= ct->charnr*linedata[ct->linenr];
+                               for (j=i; (cu->str[j]) && (cu->str[j]!='\n') && 
+                                         (cu->str[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
+                               if ((cu->str[j]!='\r') && (cu->str[j]!='\n')) {
+                                       ct->xof+= ct->charnr*linedata[ct->linenr];
+                               }
                                ct++;
                        }
                }
        }
-*/     
+       
        /* TEXT ON CURVE */
        if(cu->textoncurve) {
                cucu= cu->textoncurve->data;
@@ -533,17 +636,29 @@ struct chartrans *text_to_curve(Object *ob, int mode)
                }
        }
 
+       if (selboxes) {
+               ct= chartransdata;
+               for (i=0; i<=selend; i++, ct++) {
+                       if (i>=selstart) {
+                               selboxes[i-selstart].x = ct->xof*cu->fsize;
+                       }
+               }
+       }
 
-       if(mode==FO_CURSUP || mode==FO_CURSDOWN) {
+       if(mode==FO_CURSUP || mode==FO_CURSDOWN || mode==FO_PAGEUP || mode==FO_PAGEDOWN) {
                /* 2: curs up
                   3: curs down */
                ct= chartransdata+cu->pos;
                
-               if(mode==FO_CURSUP && ct->linenr==0);
-               else if(mode==FO_CURSDOWN && ct->linenr==lnr);
+               if((mode==FO_CURSUP || mode==FO_PAGEUP) && ct->linenr==0);
+               else if((mode==FO_CURSDOWN || mode==FO_PAGEDOWN) && ct->linenr==lnr);
                else {
-                       if(mode==FO_CURSUP) lnr= ct->linenr-1;
-                       else lnr= ct->linenr+1;
+                       switch(mode) {
+                               case FO_CURSUP:         lnr= ct->linenr-1; break;
+                               case FO_CURSDOWN:       lnr= ct->linenr+1; break;
+                               case FO_PAGEUP:         lnr= ct->linenr-10; break;
+                               case FO_PAGEDOWN:       lnr= ct->linenr+10; break;
+                       }
                        cnr= ct->charnr;
                        /* seek for char with lnr en cnr */
                        cu->pos= 0;
@@ -582,21 +697,55 @@ struct chartrans *text_to_curve(Object *ob, int mode)
                
        }
 
+       if (mode == FO_SELCHANGE) {
+               MEM_freeN(chartransdata);
+               MEM_freeN(linedata);
+               MEM_freeN(linedata2);           
+               MEM_freeN(linedata3);
+               return NULL;
+       }
+
        if(mode==0) {
                /* make nurbdata */
                
                freeNurblist(&cu->nurb);
                
                ct= chartransdata;
-               for (i= 0; i<slen; i++) {
-                       ascii = cu->str[i];
-                       buildchar(cu, ascii, ct->xof, ct->yof, ct->rot);
-                       ct++;
+               if (cu->sepchar==0) {
+               for (i= 0; i<slen; i++) {
+                       ascii = cu->str[i];
+                       info = &(cu->strinfo[i]);
+                               buildchar(cu, ascii, info, ct->xof, ct->yof, ct->rot, i);
+                       ct++;
+               }
                }
+               else {
+               outta = 0;
+               for (i= 0; (i<slen) && (outta==0); i++) {
+                       ascii = cu->str[i];
+                       info = &(cu->strinfo[i]);
+                               if (cu->sepchar == (i+1)) {
+                                       cu->str[0] = ascii;
+                                       cu->str[1] = 0;
+                                       cu->strinfo[0]= *info;
+                                       cu->pos = 1;
+                                       cu->len = 1;
+                                       vecyo[0] = ct->xof;
+                                       vecyo[1] = ct->yof;
+                                       vecyo[2] = 0;
+                                       Mat4MulVecfl(ob->obmat, vecyo);
+                                       VECCOPY(ob->loc, vecyo);
+                                       outta = 1;
+                                       cu->sepchar = 0;
+                               }
+                       ct++;
+               }
+       }
        }
 
        MEM_freeN(linedata);
        MEM_freeN(linedata2);
+       MEM_freeN(linedata3);   
 
        if(mode==FO_DUPLI) {
                return chartransdata;
index 74e8bef6e8a68980801e1a2a933a97bdbf8708f6..f7fbf7e3d16c473c015a33e10842be51b3802541 100644 (file)
@@ -119,8 +119,8 @@ typedef struct pschar {
 #define NOTHEX         (100)
 #define MC1 52845
 #define MC2 22719
-#define MAXSUBRS 1000
-#define MAXCHARS 1000
+#define MAXSUBRS 4000
+#define MAXCHARS 4000
 #define MAXTRIES 30
 
 /* some local thingies */
@@ -215,7 +215,7 @@ static unsigned short int mr;
 static char *bindat;
 static int datbytes;
 static int firsted;
-static short chardata[2000];
+static short chardata[20000];
 static int nshorts;
 
 static int thecharwidth, thesidebearing;
@@ -763,10 +763,12 @@ static int decryptprogram(char *buf, int len)
 
        resetdecrypt(4330);
        for(i=0; i<len; i++) {
-               if(i<SKIP)
+               if(i<SKIP) {
                        mdecrypt(buf[i]);
-               else
+               }
+               else {
                        buf[i-SKIP] = mdecrypt(buf[i]);
+               }
        }
        return len-SKIP;
 }
@@ -1447,10 +1449,10 @@ static void spline_line(float x0, float y0, float x1, float y1)
 static void spline_curveto(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3)
 {
        applymat(mat,&x0,&y0);
+
        applymat(mat,&x1,&y1);
        applymat(mat,&x2,&y2);
        applymat(mat,&x3,&y3);
-
        if(sp_npnts == 0) {
                chardata[nshorts++] = SP_MOVETO;
                chardata[nshorts++] = floor(x0);
index 5f0d684695d3debb62b9d144d9e216f7f35356bf..f82adec594b7b08d9ae62b79435e038554181a88 100644 (file)
@@ -1888,6 +1888,9 @@ static void lib_link_curve(FileData *fd, Main *main)
                        cu->taperobj= newlibadr(fd, cu->id.lib, cu->taperobj);
                        cu->textoncurve= newlibadr(fd, cu->id.lib, cu->textoncurve);
                        cu->vfont= newlibadr_us(fd, cu->id.lib, cu->vfont);
+                       cu->vfontb= newlibadr_us(fd, cu->id.lib, cu->vfontb);                   
+                       cu->vfonti= newlibadr_us(fd, cu->id.lib, cu->vfonti);
+                       cu->vfontbi= newlibadr_us(fd, cu->id.lib, cu->vfontbi);
 
                        cu->ipo= newlibadr_us(fd, cu->id.lib, cu->ipo);
                        cu->key= newlibadr_us(fd, cu->id.lib, cu->key);
@@ -1920,6 +1923,7 @@ static void switch_endian_knots(Nurb *nu)
 static void direct_link_curve(FileData *fd, Curve *cu)
 {
        Nurb *nu;
+       TextBox *tb;
 
        cu->mat= newdataadr(fd, cu->mat);
        test_pointer_array(fd, (void **)&cu->mat);
@@ -1928,6 +1932,19 @@ static void direct_link_curve(FileData *fd, Curve *cu)
        if(cu->vfont==0) link_list(fd, &(cu->nurb));
        else {
                cu->nurb.first=cu->nurb.last= 0;
+               cu->strinfo= newdataadr(fd, cu->strinfo);               
+               cu->tb= newdataadr(fd, cu->tb);
+               tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "TextBoxread");
+               if (cu->tb) {
+                       memcpy(tb, cu->tb, cu->totbox*sizeof(TextBox));
+                       MEM_freeN(cu->tb);
+                       cu->tb= tb;                     
+               } else {
+                       cu->totbox = 1;
+                       cu->actbox = 1;
+                       cu->tb = tb;
+                       cu->tb[0].w = cu->linewidth;
+               }               
        }
 
        cu->bev.first=cu->bev.last= 0;
@@ -5018,6 +5035,9 @@ static void expand_curve(FileData *fd, Main *mainvar, Curve *cu)
                expand_doit(fd, mainvar, cu->mat[a]);
        }
        expand_doit(fd, mainvar, cu->vfont);
+       expand_doit(fd, mainvar, cu->vfontb);   
+       expand_doit(fd, mainvar, cu->vfonti);
+       expand_doit(fd, mainvar, cu->vfontbi);
        expand_doit(fd, mainvar, cu->key);
        expand_doit(fd, mainvar, cu->ipo);
        expand_doit(fd, mainvar, cu->bevobj);
index 8ade6df7b4cb49f2f09129a9bef0193548fae638..2b87df727ecaa7f1bbfa8909a9e6da1c78364041 100644 (file)
@@ -850,6 +850,8 @@ static void write_curves(WriteData *wd, ListBase *idbase)
 
                        if(cu->vfont) {
                                writedata(wd, DATA, cu->len+1, cu->str);
+                               writestruct(wd, DATA, "CharInfo", cu->len, cu->strinfo);
+                               writestruct(wd, DATA, "TextBox", cu->totbox, cu->tb);                           
                        }
                        else {
                                /* is also the order of reading */
index fe3604493f52a9bde2a46f2ade90b9b683c25b3c..5842edc898e6534cf220f273b5a330b9943b4ef0 100644 (file)
@@ -35,6 +35,8 @@
 
 struct Text;
 
+char *BIF_lorem;
+
 void do_textedit(unsigned short event, short val, char _ascii);
 void make_editText(void);
 void load_editText(void);
@@ -44,6 +46,9 @@ void paste_editText(void);
 void txt_export_to_object(struct Text *text);
 void txt_export_to_objects(struct Text *text);
 void undo_push_font(char *);
+void load_3dtext_fs(char *);
+void add_lorem(void);
+void text_makedisplist(struct Object *ob);
 
 /**
  * @attention The argument is discarded. It is there for
index d776a9003f981c16ae703b6108e47115a94bb381..ba7e008d58a435066e8d07928d8e302977f25e15 100644 (file)
@@ -193,6 +193,9 @@ void bglEnd(void);
 void bglVertex3fv(float *vec);
 void bglVertex2fv(float *vec);
 
+void set_inverted_drawing(int enable);
+
+
 /* own working polygon offset */
 void bglPolygonOffset(float dist);
 
index 7bbadba8847fa131da591b204e9fe53c9ca6bacb..8cc6ad4519d736d0e55833447f0c863ce6464b09 100644 (file)
@@ -317,7 +317,7 @@ enum {
 #define B_DOCENTRECURSOR       2017
 
        /* 32 values! */
-#define B_OBLAY                        2018
+#define B_OBLAY                        2019
 
 #define B_MESHBUTS             2100
 
@@ -397,6 +397,12 @@ enum {
 #define B_LOADFONT             2204
 #define B_TEXTONCURVE  2205
 #define B_PACKFONT             2206
+#define B_LOAD3DTEXT   2207
+#define B_LOREM                        2208
+#define B_FASTFONT             2209
+#define B_INSTB                        2210
+#define B_DELTB                        2211
+#define B_STYLETOSEL   2212
 
 /* *********************** */
 #define B_IKABUTS              2400
index 0713f770dc4f1e1e97030f89b560be9820b32af8..4482d24ba06b7d01b13470c57442b6bdc64c99b3 100644 (file)
@@ -40,6 +40,8 @@
 #include "DNA_vec_types.h"
 #include "DNA_ID.h"
 
+#define MAXTEXTBOX 256  /* used in readfile.c and editfont.c */
+
 struct BoundBox;
 struct Object;
 struct Ipo;
@@ -101,8 +103,21 @@ typedef struct Nurb {
        BPoint *bp;
        BezTriple *bezt;
        
+       int charidx;
+       int pad;
 } Nurb;
 
+typedef struct CharInfo {
+       short kern;
+       short mat_nr;
+       char flag;
+       char pad;
+       short pad2;
+} CharInfo;
+
+typedef struct TextBox {
+       float x, y, w, h;
+} TextBox;
 
 typedef struct Curve {
        ID id;
@@ -135,12 +150,26 @@ typedef struct Curve {
        
        /* font part */
        short len, lines, pos, spacemode;
-       float spacing, linedist, shear, fsize;
+       float spacing, linedist, shear, fsize, wordspace;
        float xof, yof;
-       
-       char *str, family[24];
+       float linewidth;
+
+       char *str;
+       char family[24];
        struct VFont *vfont;
+       struct VFont *vfontb;
+       struct VFont *vfonti;
+       struct VFont *vfontbi;
 
+       int sepchar;
+       
+       int totbox, actbox, pad;
+       struct TextBox *tb;     
+       
+       int selstart, selend;   
+       
+       struct CharInfo *strinfo;       
+       struct CharInfo curinfo;        
 } Curve;
 
 typedef struct IpoCurve {
@@ -177,6 +206,7 @@ typedef struct IpoCurve {
 #define CU_NOPUNOFLIP  64
 #define CU_STRETCH             128
 #define CU_OFFS_PATHDIST       256
+#define CU_FAST                        512 /* Font: no filling inside editmode */
 
 /* spacemode */
 #define CU_LEFT                        0
@@ -204,5 +234,16 @@ typedef struct IpoCurve {
 #define HD_VECT                2
 #define HD_ALIGN       3
 
+/* *************** CHARINFO **************** */
+
+/* flag */
+#define CU_STYLE               (1+2)
+#define CU_BOLD                        1
+#define CU_ITALIC              2
+#define CU_UNDERLINE   4
+#define CU_WRAP                        8       /* wordwrap occured here */
+
+
+
 #endif
 
index 5f9e3f614460b44f594c33f48396d45a84ebb903..df9279d6243bda8da7f7a5a180c47ef87cd06dfb 100644 (file)
@@ -55,6 +55,9 @@ typedef struct VFont {
 #define FO_CURSUP              2
 #define FO_CURSDOWN            3
 #define FO_DUPLI               4
+#define FO_PAGEUP              8
+#define FO_PAGEDOWN            9
+#define FO_SELCHANGE   10
 
 #endif
 
index 49fdf7fad67e82322552baad3ba1ba7f17037aac..0af926647733d1b91529937b2f24eff5f6d78066 100644 (file)
@@ -479,6 +479,13 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
                                        nu= nu->next;
                                }
                        }
+                       else if (G.obedit->type == OB_FONT) {
+                       if (mat_to_sel()) {
+                               text_to_curve(G.obedit, 0);
+                               text_makedisplist(G.obedit);
+                               allqueue(REDRAWVIEW3D, 0);
+                       }
+                       }
                        allqueue(REDRAWVIEW3D_Z, 0);
                        makeDispList(G.obedit);
                        BIF_undo_push("Assign material index");
@@ -840,9 +847,25 @@ static void load_buts_vfont(char *name)
                if(vf==0) return;
        }
        else id_us_plus((ID *)vf);
-
-       if(cu->vfont) cu->vfont->id.us--;
-       cu->vfont= vf;
+       
+       switch(cu->curinfo.flag & CU_STYLE) {
+               case CU_BOLD:
+                       if(cu->vfontb) cu->vfontb->id.us--;
+                       cu->vfontb= vf;
+                       break;
+               case CU_ITALIC:
+                       if(cu->vfonti) cu->vfonti->id.us--;             
+                       cu->vfonti= vf;
+                       break;                                          
+               case (CU_BOLD|CU_ITALIC):
+                       if(cu->vfontbi) cu->vfontbi->id.us--;
+                       cu->vfontbi= vf;
+                       break;
+               default:
+                       if(cu->vfont) cu->vfont->id.us--;
+                       cu->vfont= vf;
+                       break;                                          
+       }       
 
        text_to_curve(OBACT, 0);
        makeDispList(OBACT);
@@ -858,6 +881,7 @@ void do_fontbuts(unsigned short event)
        Object *ob;
        ScrArea *sa;
        char str[80];
+       int i;
 
        ob= OBACT;
 
@@ -867,6 +891,51 @@ void do_fontbuts(unsigned short event)
                makeDispList(ob);
                allqueue(REDRAWVIEW3D, 0);
                break;
+
+       case B_STYLETOSEL:
+               if (style_to_sel()) {
+                       text_to_curve(ob, 0);
+                       text_makedisplist(ob);
+                       allqueue(REDRAWVIEW3D, 0);
+               }
+               allqueue(REDRAWBUTSEDIT, 0);
+               break;
+               
+       case B_FASTFONT:
+               if (G.obedit) {
+                       cu= G.obedit->data;
+                       cu->flag ^= CU_FAST;
+                       error("Not in editmode!");
+               }
+               break;
+       case B_INSTB:
+               cu= ob->data;
+               if (cu->totbox < 256) {
+                       for (i = cu->totbox; i>cu->actbox; i--) cu->tb[i]= cu->tb[i-1];
+                       cu->tb[cu->actbox]= cu->tb[cu->actbox-1];
+                       cu->actbox++;
+                       cu->totbox++;
+                       allqueue(REDRAWBUTSEDIT, 0);
+                       allqueue(REDRAWVIEW3D, 0);
+                       text_to_curve(ob, 0);
+                       makeDispList(ob);
+               }
+               else {
+                       error("Do you really need that many text frames?");
+               }
+               break;
+       case B_DELTB:
+               cu= ob->data;
+               if (cu->totbox > 1) {
+                       for (i = cu->actbox-1; i < cu->totbox; i++) cu->tb[i]= cu->tb[i+1];
+                       cu->totbox--;
+                       cu->actbox--;
+                       allqueue(REDRAWBUTSEDIT, 0);
+                       allqueue(REDRAWVIEW3D, 0);
+                       text_to_curve(ob, 0);
+                       makeDispList(ob);                       
+               }
+               break;
        case B_TOUPPER:
                to_upper();
                break;
@@ -908,6 +977,19 @@ void do_fontbuts(unsigned short event)
                allqueue(REDRAWBUTSEDIT, 0);
                break;
 
+       case B_LOAD3DTEXT:
+               if (!G.obedit) { error("Only in editmode!"); return; }
+               if (G.obedit->type != OB_FONT) return;  
+               activate_fileselect(FILE_SPECIAL, "Open Text File", G.sce, load_3dtext_fs);
+               break;
+               
+       case B_LOREM:
+               if (!G.obedit) { error("Only in editmode!"); return; }
+               if (G.obedit->type != OB_FONT) return;  
+               add_lorem();
+               
+               break;          
+
        case B_SETFONT:
                if(ob) {
                        cu= ob->data;
@@ -915,8 +997,24 @@ void do_fontbuts(unsigned short event)
                        vf= give_vfontpointer(G.buts->texnr);
                        if(vf) {
                                id_us_plus((ID *)vf);
-                               cu->vfont->id.us--;
-                               cu->vfont= vf;
+                               switch(cu->curinfo.flag & CU_STYLE) {
+                                       case CU_BOLD:
+                                               cu->vfontb->id.us--;
+                                               cu->vfontb= vf;
+                                               break;
+                                       case CU_ITALIC:
+                                               cu->vfonti->id.us--;
+                                               cu->vfonti= vf;
+                                               break;                                          
+                                       case (CU_BOLD|CU_ITALIC):
+                                               cu->vfontbi->id.us--;
+                                               cu->vfontbi= vf;
+                                               break;
+                                       default:
+                                               cu->vfont->id.us--;
+                                               cu->vfont= vf;
+                                               break;                                          
+                               }
                                text_to_curve(ob, 0);
                                makeDispList(ob);
                                BIF_undo_push("Set vector font");
@@ -944,14 +1042,28 @@ static void editing_panel_font_type(Object *ob, Curve *cu)
        uiBlock *block;
        char *strp;
        static int packdummy = 0;
-       VFontData *vfd;
+       char str[32];
 
        block= uiNewBlock(&curarea->uiblocks, "editing_panel_font_type", UI_EMBOSS, UI_HELV, curarea->win);
-       if(uiNewPanel(curarea, block, "Font", "Editing", 640, 0, 318, 204)==0) return;
+       if(uiNewPanel(curarea, block, "Font", "Editing", 640, 0, 470, 204)==0) return;
+
+       switch(cu->curinfo.flag & CU_STYLE) {
+               case CU_BOLD:
+                       G.buts->texnr= give_vfontnr(cu->vfontb);
+                       break;
+               case CU_ITALIC:
+                       G.buts->texnr= give_vfontnr(cu->vfonti);
+                       break;                                          
+               case (CU_BOLD|CU_ITALIC):
+                       G.buts->texnr= give_vfontnr(cu->vfontbi);
+                       break;
+               default:
+                       G.buts->texnr= give_vfontnr(cu->vfont);
+                       break;                                          
+       }       
 
-       G.buts->texnr= give_vfontnr(cu->vfont);
        strp= give_vfontbutstr();
-       vfd= cu->vfont->data;
+//     vfd= cu->vfont->data;
 
        uiDefBut(block, BUT,B_LOADFONT, "Load", 480,188,68,20, 0, 0, 0, 0, 0, "Load a new font");
        uiDefButS(block, MENU, B_SETFONT, strp, 550,188,220,20, &G.buts->texnr, 0, 0, 0, 0, "Change font for object");
@@ -962,7 +1074,16 @@ static void editing_panel_font_type(Object *ob, Curve *cu)
                packdummy = 0;
        }
        uiDefIconButI(block, TOG|BIT|0, B_PACKFONT, ICON_PACKAGE,       772,188,20,20, &packdummy, 0, 0, 0, 0, "Pack/Unpack this font");
-       uiDefBut(block, LABEL, 0, vfd->name,  480, 165,314,20, 0, 0, 0, 0, 0, "Postscript name of the font");
+
+       /* This doesn't work anyway */
+//     uiDefBut(block, LABEL, 0, vfd->name,  480, 165,314,20, 0, 0, 0, 0, 0, "Postscript name of the font");
+
+       uiDefBut(block, BUT, B_LOAD3DTEXT, "Insert Text", 480, 165, 90, 20, 0, 0, 0, 0, 0, "Insert text file at cursor");
+       uiDefBut(block, BUT, B_LOREM, "Lorem", 575, 165, 70, 20, 0, 0, 0, 0, 0, "Insert a paragraph of Lorem Ipsum at cursor"); 
+       uiBlockBeginAlign(block);
+       uiDefButC(block, TOG|BIT|0,B_STYLETOSEL, "B",           752,165,20,20, &(cu->curinfo.flag), 0,0, 0, 0, "");
+       uiDefButC(block, TOG|BIT|1,B_STYLETOSEL, "i",           772,165,20,20, &(cu->curinfo.flag), 0, 0, 0, 0, "");    
+       uiBlockEndAlign(block);
 
        MEM_freeN(strp);
 
@@ -974,17 +1095,31 @@ static void editing_panel_font_type(Object *ob, Curve *cu)
        uiDefBut(block, BUT, B_TOUPPER, "ToUpper",              715,135,78,20, 0, 0, 0, 0, 0, "Toggle between upper and lower case in editmode");
        uiBlockEndAlign(block);
 
+       uiDefButS(block, TOG|BIT|9,B_FASTFONT, "Fast Edit",             715,105,78,20, &cu->flag, 0, 0, 0, 0, "Don't fill polygons while editing");     
+
        uiDefIDPoinBut(block, test_obpoin_but, B_TEXTONCURVE, "TextOnCurve:",   480,105,220,19, &cu->textoncurve, "Apply a deforming curve to the text");
        uiDefBut(block, TEX,REDRAWVIEW3D, "Ob Family:", 480,84,220,19, cu->family, 0.0, 20.0, 0, 0, "Blender uses font from selfmade objects");
 
        uiBlockBeginAlign(block);
        uiDefButF(block, NUM,B_MAKEFONT, "Size:",               480,56,155,20, &cu->fsize, 0.1,10.0, 10, 0, "Size of the text");
        uiDefButF(block, NUM,B_MAKEFONT, "Linedist:",   640,56,155,20, &cu->linedist, 0.0,10.0, 10, 0, "Distance between text lines");
+       uiDefButF(block, NUM,B_MAKEFONT, "Word spacing:",       795,56,155,20, &cu->wordspace, 0.0,10.0, 10, 0, "Distance factor between words");               
        uiDefButF(block, NUM,B_MAKEFONT, "Spacing:",    480,34,155,20, &cu->spacing, 0.0,10.0, 10, 0, "Spacing of individual characters");
        uiDefButF(block, NUM,B_MAKEFONT, "X offset:",   640,34,155,20, &cu->xof, -50.0,50.0, 10, 0, "Horizontal position from object centre");
        uiDefButF(block, NUM,B_MAKEFONT, "Shear:",              480,12,155,20, &cu->shear, -1.0,1.0, 10, 0, "Italic angle of the characters");
        uiDefButF(block, NUM,B_MAKEFONT, "Y offset:",   640,12,155,20, &cu->yof, -50.0,50.0, 10, 0, "Vertical position from object centre");
        uiBlockEndAlign(block);
+       
+       sprintf(str, "%d TextFrame: ", cu->totbox);
+       uiBlockBeginAlign(block);
+       uiDefButI(block, NUM, REDRAWVIEW3D, str, 805, 188, 145, 20, &cu->actbox, 1.0, cu->totbox, 0, 10, "Textbox to show settings for");
+       uiDefBut(block, BUT,B_INSTB, "Insert", 805, 168, 72, 20, 0, 0, 0, 0, 0, "Insert a new text frame after the current one");
+       uiDefBut(block, BUT,B_DELTB, "Delete", 877, 168, 73, 20, 0, 0, 0, 0, 0, "Delete current text frame and shift the others up");   
+       uiDefButF(block, NUM,B_MAKEFONT, "X:", 805, 148, 72, 20, &(cu->tb[cu->actbox-1].x), -50.0, 50.0, 10, 0, "Horizontal offset of text frame");
+       uiDefButF(block, NUM,B_MAKEFONT, "Y:", 877, 148, 73, 20, &(cu->tb[cu->actbox-1].y), -50.0, 50.0, 10, 0, "Horizontal offset of text frame");     
+       uiDefButF(block, NUM,B_MAKEFONT, "Width:", 805, 128, 145, 20, &(cu->tb[cu->actbox-1].w), 0.0, 50.0, 10, 0, "Horizontal offset of text frame");
+       uiDefButF(block, NUM,B_MAKEFONT, "Height:", 805, 108, 145, 20, &(cu->tb[cu->actbox-1].h), 0.0, 50.0, 10, 0, "Horizontal offset of text frame");         
+       uiBlockEndAlign(block);
 }
 
 
@@ -2299,7 +2434,7 @@ static void editing_panel_links(Object *ob)
        else poin= &( ((Curve *)ob->data)->texflag );
        uiDefButI(block, TOG|BIT|0, B_AUTOTEX, "AutoTexSpace",  143,15,140,19, poin, 0, 0, 0, 0, "Adjusts active object's texture space automatically when transforming object");
 
-       sprintf(str,"%d Mat:", ob->totcol);
+       sprintf(str,"%d Mat ", ob->totcol);
        if(ob->totcol) min= 1.0; else min= 0.0;
        ma= give_current_material(ob, ob->actcol);
 
index cb5f6d99384038f9371d52e17d48497cfd390b28..058401c95a7302dae7b3f2ba8973c78145a77af0 100644 (file)
@@ -76,6 +76,7 @@
 #include "BKE_DerivedMesh.h"
 #include "BKE_displist.h"
 #include "BKE_effect.h"
+#include "BKE_font.h"
 #include "BKE_global.h"
 #include "BKE_ipo.h"
 #include "BKE_lattice.h"
@@ -3408,6 +3409,11 @@ void draw_object(Base *base)
        static int warning_recursive= 0;
        int sel, drawtype, colindex= 0, ipoflag;
        short dt, dtx, zbufoff= 0;
+       Material *ma;
+       float vec1[3], vec2[3];
+       int i, selstart, selend;
+       SelBox *sb;
+       float selboxw;
 
        ob= base->object;
 
@@ -3592,8 +3598,79 @@ void draw_object(Base *base)
                cu= ob->data;
                if(ob==G.obedit) {
                        tekentextcurs();
-                       cpack(0xFFFF90);
-                       drawDispList(ob, OB_WIRE);
+
+                       if (cu->flag & CU_FAST) {
+                               cpack(0xFFFFFF);
+                               set_inverted_drawing(1);
+                               drawDispList(ob, OB_WIRE);
+                               set_inverted_drawing(0);
+                       }
+
+                       if (cu->linewidth != 0.0) {
+                               BIF_ThemeColor(TH_WIRE);
+                               VECCOPY(vec1, ob->orig);
+                               VECCOPY(vec2, ob->orig);
+                               vec1[0] += cu->linewidth;
+                               vec2[0] += cu->linewidth;
+                               vec1[1] += cu->linedist * cu->fsize;
+                               vec2[1] -= cu->lines * cu->linedist * cu->fsize;
+                       setlinestyle(3);
+                       glBegin(GL_LINE_STRIP); 
+                               glVertex2fv(vec1); 
+                               glVertex2fv(vec2); 
+                       glEnd();
+                       setlinestyle(0);
+               }
+               
+               setlinestyle(3);
+               for (i=0; i<cu->totbox; i++) {
+                       if (cu->tb[i].w != 0.0) {
+                               if (i == (cu->actbox-1))
+                                       BIF_ThemeColor(TH_ACTIVE);
+                               else
+                                       BIF_ThemeColor(TH_WIRE);
+                               VECCOPY(vec1, ob->orig);
+                               vec1[0] += cu->tb[i].x;
+                               vec1[1] += cu->tb[i].y + cu->linedist*cu->fsize;
+                               glBegin(GL_LINE_STRIP);
+                               glVertex2fv(vec1);
+                               vec1[0] += cu->tb[i].w;
+                               glVertex2fv(vec1);
+                               vec1[1] -= (cu->tb[i].h + cu->linedist*cu->fsize);
+                               glVertex2fv(vec1);
+                               vec1[0] -= cu->tb[i].w;
+                               glVertex2fv(vec1);
+                               vec1[1] += cu->tb[i].h + cu->linedist*cu->fsize;
+                               glVertex2fv(vec1);
+                               glEnd();
+                       }
+               }
+               setlinestyle(0);
+               
+
+               if (getselection(&selstart, &selend) && selboxes) {
+                       cpack(0xffffff);
+                       set_inverted_drawing(1);                
+                       for (i=0; i<(selend-selstart+1); i++) {
+                               sb = &(selboxes[i]);
+                               if (i<(selend-selstart)) {
+                                       if (selboxes[i+1].y == sb->y)
+                                               selboxw= selboxes[i+1].x - sb->x;
+                                       else
+                                               selboxw= sb->w;
+                               }
+                               else {
+                                       selboxw= sb->w;
+                               }
+                               glBegin(GL_QUADS);
+                               glVertex3f(sb->x, sb->y, 0.001);
+                               glVertex3f(sb->x+selboxw, sb->y, 0.001);                                
+                               glVertex3f(sb->x+selboxw, sb->y+sb->h, 0.001);
+                               glVertex3f(sb->x, sb->y+sb->h, 0.001);
+                               glEnd();
+                       }
+                       set_inverted_drawing(0);                        
+               }
                }
                else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob);
                else if(boundbox_clip(ob->obmat, cu->bb)) drawDispList(ob, dt);
index eb1032b9e7d5f28355583987314b6fb8f3e2bb72..25297176e14be68c8a59fc80f89a3d3c79a7beca 100644 (file)
@@ -30,6 +30,7 @@
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
  */
 
+#include <stdlib.h>
 #include <string.h>
 #include <fcntl.h>
 
 
 #include "blendef.h"
 
-#define MAXTEXT        1000
+#define MAXTEXT        50000
 
 /* -- prototypes --------*/
 VFont *get_builtin_font(void);
 
 int textediting=0;
 
+extern struct SelBox *selboxes;                /* from blenkernel/font.c */
+
 static char findaccent(char char1, char code)
 {
        char new= 0;
@@ -214,9 +217,13 @@ static char findaccent(char char1, char code)
        else return char1;
 }
 
+static char *copybuf=NULL;
+static char *copybufinfo=NULL;
 
 static char *textbuf=NULL;
+static CharInfo *textbufinfo=NULL;
 static char *oldstr=NULL;
+static CharInfo *oldstrinfo=NULL;
 
 static int insert_into_textbuf(Curve *cu, char c)
 {
@@ -224,7 +231,14 @@ static int insert_into_textbuf(Curve *cu, char c)
                int x;
 
                for(x= cu->len; x>cu->pos; x--) textbuf[x]= textbuf[x-1];
+               for(x= cu->len; x>cu->pos; x--) textbufinfo[x]= textbufinfo[x-1];               
                textbuf[cu->pos]= c;
+               textbufinfo[cu->pos] = cu->curinfo;
+               textbufinfo[cu->pos].kern = 0;
+               if (G.obedit->actcol>0)
+                       textbufinfo[cu->pos].mat_nr = G.obedit->actcol;
+               else
+                       textbufinfo[cu->pos].mat_nr = 0;
                                        
                cu->pos++;
                cu->len++;
@@ -236,6 +250,52 @@ static int insert_into_textbuf(Curve *cu, char c)
        }
 }
 
+void add_lorem(void)
+{
+       char *p, *p2;
+       int i;
+       Curve *cu=G.obedit->data;
+       static char* lastlorem;
+       
+       if (lastlorem)
+               p= lastlorem;
+       else
+               p= BIF_lorem;
+       
+       i= rand()/(RAND_MAX/6)+4;       
+               
+       for (p2=p; *p2 && i; p2++) {
+               insert_into_textbuf(cu, *p2);
+               if (*p2=='.') i--;
+       }
+       lastlorem = p2+1;
+       if (strlen(lastlorem)<5) lastlorem = BIF_lorem;
+       
+       insert_into_textbuf(cu, '\n');
+       insert_into_textbuf(cu, '\n');  
+       text_to_curve(G.obedit, 0);
+       text_makedisplist(G.obedit);
+       allqueue(REDRAWVIEW3D, 0);      
+}
+
+void load_3dtext_fs(char *file) 
+{
+       FILE *fp;
+       int c;
+
+       fp= fopen(file, "r");
+       if (!fp) return;
+       
+       while (!feof(fp)) {
+               c = fgetc(fp);
+               if (c!=EOF) insert_into_textbuf(OBACT->data, c);
+       }
+       fclose(fp);
+
+       text_to_curve(G.obedit, 0);
+       text_makedisplist(G.obedit);
+       allqueue(REDRAWVIEW3D, 0);      
+}
 
 VFont *get_builtin_font(void)
 {
@@ -294,8 +354,10 @@ void txt_export_to_object(struct Text *text)
        }
 
        if(cu->str) MEM_freeN(cu->str);
+       if(cu->strinfo) MEM_freeN(cu->strinfo); 
 
        cu->str= MEM_mallocN(nchars+4, "str");
+       cu->strinfo= MEM_callocN((nchars+4)*sizeof(CharInfo), "strinfo");
        
        tmp= text->lines.first;
        strcpy(cu->str, tmp->line);
@@ -371,8 +433,10 @@ void txt_export_to_objects(struct Text *text)
                nchars = strlen(curline->line) + 1;
        
                if(cu->str) MEM_freeN(cu->str);
+               if(cu->strinfo) MEM_freeN(cu->strinfo);         
        
                cu->str= MEM_mallocN(nchars+4, "str");
+               cu->strinfo= MEM_callocN((nchars+4)*sizeof(CharInfo), "strinfo");
                
                strcpy(cu->str, curline->line);
                cu->len= strlen(curline->line);
@@ -389,7 +453,7 @@ void txt_export_to_objects(struct Text *text)
 }
 
 
-static void text_makedisplist(Object *ob)
+void text_makedisplist(Object *ob)
 {
        Base *base;
        // free displists of other users...
@@ -399,12 +463,123 @@ static void text_makedisplist(Object *ob)
        makeDispList(ob);
 }
 
+static short next_word(Curve *cu)
+{
+       short s;
+       for (s=cu->pos; (cu->str[s]) && (cu->str[s]!=' ') && (cu->str[s]!='\n') &&
+                       (cu->str[s]!=1) && (cu->str[s]!='\r'); s++);
+       if (cu->str[s]) return(s+1); else return(s);
+}
+
+static short prev_word(Curve *cu)
+{
+       short s;
+       
+       if (cu->pos==0) return(0);
+       for (s=cu->pos-2; (cu->str[s]) && (cu->str[s]!=' ') && (cu->str[s]!='\n') &&
+                       (cu->str[s]!=1) && (cu->str[s]!='\r'); s--);
+       if (cu->str[s]) return(s+1); else return(s);
+}
+
+
+
+static int killselection(int ins)      /* 1 == new character */
+{
+       int selend, selstart, direction;
+       Curve *cu= G.obedit->data;
+       int offset = 0;
+       int getfrom;
+
+       direction = getselection(&selstart, &selend);
+       if (direction) {
+               if (ins) offset = 1;
+               if (cu->pos >= selstart) cu->pos = selstart+offset;
+               if ((direction == -1) && ins) {
+                       selstart++;
+                       selend++;
+               }
+               getfrom = selend+offset;
+               if (ins==0) getfrom++;
+               memmove(textbuf+selstart, textbuf+getfrom, (cu->len-selstart)+offset);
+               memmove(textbufinfo+selstart, textbufinfo+getfrom, ((cu->len-selstart)+offset)*sizeof(CharInfo));
+               cu->len -= (selend-selstart)+offset;
+               cu->selstart = cu->selend = 0;
+       }
+       return(direction);
+}
+
+static void copyselection(void)
+{
+       int selstart, selend;
+       
+       if (getselection(&selstart, &selend)) {
+               memcpy(copybuf, textbuf+selstart, (selend-selstart)+1);
+               copybuf[(selend-selstart)+1]=0;
+               memcpy(copybufinfo, textbufinfo+selstart, ((selend-selstart)+1)*sizeof(CharInfo));      
+       }
+}
+
+static void pasteselection(void)
+{
+       Curve *cu= G.obedit->data;
+       int len= strlen(copybuf);
+       
+       if (len) {
+               memmove(textbuf+cu->pos+len, textbuf+cu->pos, cu->len-cu->pos+1);
+               memcpy(textbuf+cu->pos, copybuf, len);
+               
+               memmove(textbufinfo+cu->pos+len, textbufinfo+cu->pos, (cu->len-cu->pos+1)*sizeof(CharInfo));
+               memcpy(textbufinfo+cu->pos, copybufinfo, len*sizeof(CharInfo)); 
+               
+               cu->len += len;
+               cu->pos += len;
+       }
+}
+
+int style_to_sel(void) {
+       int selstart, selend;
+       int i;
+       Curve *cu;
+       
+       if (G.obedit && (G.obedit->type == OB_FONT)) {
+               cu= G.obedit->data;
+               
+               if (getselection(&selstart, &selend)) {
+                       for (i=selstart; i<=selend; i++) {
+                               textbufinfo[i].flag &= ~CU_STYLE;
+                               textbufinfo[i].flag |= (cu->curinfo.flag & CU_STYLE);
+                       }
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+int mat_to_sel(void) {
+       int selstart, selend;
+       int i;
+       Curve *cu;
+       
+       if (G.obedit && (G.obedit->type == OB_FONT)) {
+               cu= G.obedit->data;
+               
+               if (getselection(&selstart, &selend)) {
+                       for (i=selstart; i<=selend; i++) {
+                               textbufinfo[i].mat_nr = G.obedit->actcol;
+                       }
+                       return 1;
+               }
+       }
+       return 0;
+}
+
 void do_textedit(unsigned short event, short val, char _ascii)
 {
        Curve *cu;
        static int accentcode= 0;
        int x, doit=0, cursmove=0;
        int ascii = _ascii;
+       short kern;
 
        cu= G.obedit->data;
 
@@ -474,6 +649,8 @@ void do_textedit(unsigned short event, short val, char _ascii)
                                }
                        }
                        
+                       killselection(1);
+                       
                        doit= 1;
                }
        }
@@ -481,45 +658,81 @@ void do_textedit(unsigned short event, short val, char _ascii)
                cursmove= 0;
                
                switch(event) {
+               case ENDKEY:
+                       if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;         
+                       while(cu->pos<cu->len) {
+                               if( textbuf[cu->pos]==0) break;
+                               if( textbuf[cu->pos]=='\n') break;
+                               if( textbufinfo[cu->pos].flag & CU_WRAP ) break;
+                               cu->pos++;
+                       }
+                       cursmove=FO_CURS;
+                       break;
+
+               case HOMEKEY:
+                       if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+                       while(cu->pos>0) {
+                               if( textbuf[cu->pos-1]=='\n') break;
+                               if( textbufinfo[cu->pos-1].flag & CU_WRAP ) break;                              
+                               cu->pos--;
+                       }               
+                       cursmove=FO_CURS;
+                       break;
+                       
                case RETKEY:
-                       insert_into_textbuf(cu, '\n');
+                       if(G.qual & LR_CTRLKEY) {
+                               insert_into_textbuf(cu, 1);
+                               if (textbuf[cu->pos]!='\n') insert_into_textbuf(cu, '\n');                              
+                       }
+                       else {
+                               insert_into_textbuf(cu, '\n');
+                       }
+                       cu->selstart = cu->selend = 0;
                        doit= 1;
                        break;
 
                case RIGHTARROWKEY:     
-                       if(G.qual & LR_SHIFTKEY) {
-                               while(cu->pos<cu->len) {
-                                       if( textbuf[cu->pos]==0) break;
-                                       if( textbuf[cu->pos]=='\n') break;
-                                       cu->pos++;
-                               }
-                       }
+                       if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+                       if (G.qual & LR_CTRLKEY) {
+                               cu->pos= next_word(cu);
+                               cursmove= FO_CURS;                              
+                       } 
+                       else if (G.qual & LR_ALTKEY) {
+                               kern = textbufinfo[cu->pos-1].kern;
+                               kern += 1;
+                               if (kern>10) kern = 10;
+                               textbufinfo[cu->pos-1].kern = kern;
+                               doit = 1;
+                       }
                        else {
                                cu->pos++;
+                               cursmove= FO_CURS;                              
                        }
-                       cursmove= FO_CURS;
+
                        break;
                        
                case LEFTARROWKEY:
-                       
-                       if(G.qual & LR_SHIFTKEY) {
-                               while(cu->pos>0) {
-                                       if( textbuf[cu->pos-1]=='\n') break;
-                                       cu->pos--;
-                               }
-                       }
+                       if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+                       if (G.qual & LR_CTRLKEY) {
+                               cu->pos= prev_word(cu);
+                               cursmove= FO_CURS;
+                       } 
+                       else if (G.qual & LR_ALTKEY) {
+                               kern = textbufinfo[cu->pos-1].kern;
+                               kern -= 1;
+                               if (kern<-10) kern = -10;
+                               textbufinfo[cu->pos-1].kern = kern;
+                               doit = 1;
+                       }
                        else {
                                cu->pos--;
+                               cursmove=FO_CURS;
                        }
-                       cursmove=FO_CURS;
                        break;
 
                case UPARROWKEY:
-                       if(G.qual & LR_SHIFTKEY) {
-                               cu->pos= 0;
-                               cursmove= FO_CURS;
-                       }
-                       else if(G.qual & LR_ALTKEY) {
+                       if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+                       if(G.qual & LR_ALTKEY) {
                                if (cu->pos && textbuf[cu->pos - 1] < 255) {
                                        textbuf[cu->pos - 1]++;
                                        doit= 1;
@@ -528,12 +741,14 @@ void do_textedit(unsigned short event, short val, char _ascii)
                        else cursmove=FO_CURSUP;
                        break;
                        
+               case PAGEUPKEY:
+                       if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+                       cursmove=FO_PAGEUP;
+                       break;
+                       
                case DOWNARROWKEY:
-                       if(G.qual & LR_SHIFTKEY) {
-                               cu->pos= cu->len;
-                               cursmove= FO_CURS;
-                       }
-                       else if(G.qual & LR_ALTKEY) {
+                       if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+                       if(G.qual & LR_ALTKEY) {
                                if (cu->pos && textbuf[cu->pos - 1] > 1) {
                                        textbuf[cu->pos - 1]--;
                                        doit= 1;
@@ -541,45 +756,107 @@ void do_textedit(unsigned short event, short val, char _ascii)
                        }
                        else cursmove= FO_CURSDOWN;
                        break;
+
+               case PAGEDOWNKEY:
+                       if ((G.qual & LR_SHIFTKEY) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+                       cursmove=FO_PAGEDOWN;
+                       break;
                        
                case BACKSPACEKEY:
                        if(cu->len!=0) {
                                if(G.qual & LR_ALTKEY) {
                                        if(cu->pos>0) accentcode= 1;
                                }
-                               else if(G.qual & LR_SHIFTKEY) {
-                                       cu->pos= 0;
-                                       textbuf[0]= 0;
-                                       cu->len= 0;
-                               }
-                               else if(cu->pos>0) {
-                                       for(x=cu->pos;x<=cu->len;x++) textbuf[x-1]= textbuf[x];
-                                       cu->pos--;
-                                       textbuf[--cu->len]='\0';
+                               else {
+                                       if (killselection(0)==0) {
+                                               if (cu->pos>0) {
+                                                       for(x=cu->pos;x<=cu->len;x++) textbuf[x-1]= textbuf[x];
+                                                       for(x=cu->pos;x<=cu->len;x++) textbufinfo[x-1]= textbufinfo[x];                                 
+                                                       cu->pos--;
+                                                       textbuf[--cu->len]='\0';
+                                                       doit=1;
+                                               }
+                                       } else doit=1;
                                }
                        }
-                       doit= 1;
                        break;
 
                case DELKEY:
                        if(cu->len!=0) {
-                               if(cu->pos<cu->len) {
-                                       for(x=cu->pos;x<cu->len;x++) textbuf[x]= textbuf[x+1];
-                                       textbuf[--cu->len]='\0';
-                               }
+                               if (killselection(0)==0) {
+                                       if(cu->pos<cu->len) {                                   
+                                               for(x=cu->pos;x<cu->len;x++) textbuf[x]= textbuf[x+1];
+                                               for(x=cu->pos;x<cu->len;x++) textbufinfo[x]= textbufinfo[x+1];                                  
+                                               textbuf[--cu->len]='\0';
+                                               doit=1;
+                                       }
+                               } else doit=1;
                        }
-                       doit= 1;
                        break;
-               }
+               
+               case IKEY:
+                       if (G.qual & LR_CTRLKEY) {
+                               cu->curinfo.flag ^= CU_ITALIC;
+                               if (style_to_sel()) doit= 1;                            
+                               allqueue(REDRAWBUTSEDIT, 0);
+                       }
+                       break;
+
+               case BKEY:
+                       if (G.qual & LR_CTRLKEY) {
+                               cu->curinfo.flag ^= CU_BOLD;
+                               if (style_to_sel()) doit= 1;
+                               allqueue(REDRAWBUTSEDIT, 0);
+                       }
+                       break;                  
+                       
+               case XKEY:
+                       if (G.qual & LR_CTRLKEY) {
+                               copyselection();
+                               killselection(0);
+                               doit= 1;
+                       }
+                       break;
+                       
+               case CKEY:
+                       if (G.qual & LR_CTRLKEY) {
+                               copyselection();
+                       }
+                       break;                          
+                       
+               case VKEY:
+                       if (G.qual & LR_CTRLKEY) {
+                               pasteselection();
+                               doit= 1;
+                       }
+                       break;                                                  
+               
+               }
                        
                if(cursmove) {
+                       if ((G.qual & LR_SHIFTKEY)==0) {
+                               if (cu->selstart) {
+                                       cu->selstart = cu->selend = 0;
+                                       text_to_curve(G.obedit, FO_SELCHANGE);
+                                       allqueue(REDRAWVIEW3D, 0);
+                               }
+                       }
                        if(cu->pos>cu->len) cu->pos= cu->len;
                        else if(cu->pos>=MAXTEXT) cu->pos= MAXTEXT;
                        else if(cu->pos<0) cu->pos= 0;
                }
        }
        if(doit || cursmove) {
+               if (cu->pos) cu->curinfo = textbufinfo[cu->pos-1];
+               if (G.obedit->totcol>0) {
+                       G.obedit->actcol = textbufinfo[cu->pos-1].mat_nr;
+               }
+               allqueue(REDRAWBUTSEDIT, 0);
                text_to_curve(G.obedit, cursmove);
+               if (cursmove && (G.qual & LR_SHIFTKEY)) {
+                       cu->selend = cu->pos;
+                       text_to_curve(G.obedit, FO_SELCHANGE);
+               }
                if(cursmove==0) {
                        text_makedisplist(G.obedit);
                }                       
@@ -648,11 +925,18 @@ void make_editText(void)
 
        cu= G.obedit->data;
        if(textbuf==NULL) textbuf= MEM_mallocN(MAXTEXT+4, "texteditbuf");
+       if(textbufinfo==NULL) textbufinfo= MEM_callocN((MAXTEXT+4)*sizeof(CharInfo), "texteditbufinfo");
+       if(copybuf==NULL) copybuf= MEM_callocN(MAXTEXT+4, "texteditcopybuf");
+       if(copybufinfo==NULL) copybufinfo= MEM_callocN((MAXTEXT+4)*sizeof(CharInfo), "texteditcopybufinfo");    
        BLI_strncpy(textbuf, cu->str, MAXTEXT);
+       cu->len= strlen(textbuf);
+       
+       memcpy(textbufinfo, cu->strinfo, (cu->len)*sizeof(CharInfo));
        oldstr= cu->str;
+       oldstrinfo= cu->strinfo;
        cu->str= textbuf;
+       cu->strinfo= textbufinfo;
 
-       cu->len= strlen(textbuf);
        if(cu->pos>cu->len) cu->pos= cu->len;
        
        text_to_curve(G.obedit, 0);
@@ -671,15 +955,32 @@ void load_editText(void)
 
        MEM_freeN(oldstr);
        oldstr= NULL;
+       MEM_freeN(oldstrinfo);
+       oldstrinfo= NULL;
        
        cu->str= MEM_mallocN(cu->len+4, "textedit");
        strcpy(cu->str, textbuf);
+       cu->strinfo= MEM_callocN((cu->len+4)*sizeof(CharInfo), "texteditinfo");
+       memcpy(cu->strinfo, textbufinfo, (cu->len)*sizeof(CharInfo));
+
+       cu->len= strlen(cu->str);
        
        /* this memory system is weak... */
        MEM_freeN(textbuf);
+       MEM_freeN(textbufinfo);
        textbuf= NULL;
+       textbufinfo= NULL;
+       
+       if (selboxes) {
+               MEM_freeN(selboxes);
+               selboxes= NULL;
+       }
+       
+       MEM_freeN(copybuf);
+       MEM_freeN(copybufinfo);
+       copybuf= NULL;
+       copybufinfo= NULL;      
        
-       cu->len= strlen(cu->str);
        textediting= 0;
        
        text_makedisplist(G.obedit);
@@ -709,7 +1010,8 @@ void remake_editText(void)
 void free_editText(void)
 {
        if(oldstr) MEM_freeN(oldstr);
-       textbuf= oldstr= NULL;
+       if(oldstrinfo) MEM_freeN(oldstrinfo);
+       textbuf= textbufinfo= oldstr= oldstrinfo= NULL;
        textediting= 0;
 }
 
@@ -723,18 +1025,22 @@ void add_primitiveFont(int dummy_argument)
        
        add_object_draw(OB_FONT);
        base_init_from_view3d(BASACT, G.vd);
-       G.obedit= BASACT->object;
-       where_is_object(G.obedit);
        
-       cu= G.obedit->data;
+       where_is_object(BASACT->object);
        
-       cu->vfont= get_builtin_font();
-       cu->vfont->id.us++;
+       cu= BASACT->object->data;
+       
+       cu->vfont= cu->vfontb= cu->vfonti= cu->vfontbi= get_builtin_font();
+       cu->vfont->id.us+=4;
        cu->str= MEM_mallocN(12, "str");
        strcpy(cu->str, "Text");
        cu->pos= 4;
+       cu->strinfo= MEM_callocN(12*sizeof(CharInfo), "strinfo");
+       cu->totbox= cu->actbox= 1;
+       cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "textbox");
+       cu->tb[0].w = cu->tb[0].h = 0.0;
        
-       make_editText();
+       enter_editmode();
 
        allqueue(REDRAWALL, 0);
 }
@@ -792,6 +1098,8 @@ static void undoFont_to_editFont(void *strv)
        strncpy(textbuf, str+2, MAXTEXT);
        cu->pos= *((short *)str);
        cu->len= strlen(textbuf);
+       memcpy(textbufinfo, str+2+cu->len+1, cu->len*sizeof(CharInfo));
+       cu->selstart = cu->selend = 0;
        text_to_curve(G.obedit, 0);
        text_makedisplist(G.obedit);
        
@@ -803,10 +1111,11 @@ static void *editFont_to_undoFont(void)
        Curve *cu= G.obedit->data;
        char *str;
        
-       str= MEM_callocN(MAXTEXT+4, "string undo");
+       str= MEM_callocN(MAXTEXT+4+(MAXTEXT+4)*sizeof(CharInfo), "string undo");
        
        strncpy(str+2, textbuf, MAXTEXT);
        *((short *)str)= cu->pos;
+       memcpy(str+2+cu->len+1, textbufinfo, cu->len*sizeof(CharInfo));
        
        return str;
 }
index 8eb489a8ce550002618b536769a8af84e6564a6c..edaaab474d3398fec8e552a6d4cf8dbf4f4968f0 100644 (file)
 
 /* --------------------------------- */
 
+Base *dupfontbase;
+
 void add_object_draw(int type) /* for toolbox or menus, only non-editmode stuff */
 {
        Object *ob;
@@ -1363,6 +1365,7 @@ void enter_editmode(void)
        Mesh *me;
        int ok= 0;
        bArmature *arm;
+       Curve *cu;
        
        if(G.scene->id.lib) return;
        base= BASACT;
@@ -1418,6 +1421,20 @@ void enter_editmode(void)
                allqueue(REDRAWVIEW3D, 0);
        }
        else if(ob->type==OB_FONT) {
+               cu= ob->data;
+               if ((cu->flag & CU_FAST)==0) { 
+                       base->flag |= SELECT;
+                       ob->flag |= SELECT;
+                       G.qual |= LR_ALTKEY;    /* patch to make sure we get a linked duplicate */
+                       adduplicate(1);
+                       G.qual &= ~LR_ALTKEY;
+                       dupfontbase = BASACT;
+                       BASACT->flag &= ~SELECT;
+                       BASACT->object->flag &= ~SELECT;
+                       set_active_base(base);
+                       base->flag |= SELECT;
+                       base->object->flag |= SELECT;
+               }
                G.obedit= ob;
                ok= 1;
                make_editText();
@@ -1463,7 +1480,7 @@ void make_displists_by_parent(Object *ob) {
 
 void exit_editmode(int freedata)       /* freedata==0 at render, 1= freedata, 2= do undo buffer too */
 {
-       Base *base;
+       Base *base, *oldbase;
        Object *ob;
        Curve *cu;
 
@@ -1553,6 +1570,22 @@ void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do un
                make_displists_by_parent(ob);
        }
 
+       if ((ob->type == OB_FONT) && (freedata)) {
+               cu= ob->data;
+               if ((cu->flag & CU_FAST)==0) {
+                       oldbase = BASACT;
+                       BASACT->flag &= ~SELECT;
+                       BASACT->object->flag &= ~SELECT;
+                       set_active_base(dupfontbase);
+                       BASACT->flag |= SELECT;
+                       BASACT->object->flag |= SELECT;
+                       delete_obj(1);
+                       oldbase->flag |= SELECT;
+                       oldbase->object->flag |= SELECT;
+                       set_active_base(oldbase);
+               }
+       }
+
        if(freedata) {
                setcursor_space(SPACE_VIEW3D, CURSOR_STD);
        
@@ -1890,6 +1923,31 @@ void movetolayer(void)
        BIF_undo_push("Move to layer");
 }
 
+void split_font()
+{
+       Object *ob = OBACT;
+       Base *oldbase = BASACT;
+       Curve *cu= ob->data;
+       char *p= cu->str;
+       int slen= strlen(p);
+       int i;
+
+       for (i = 0; i<=slen; p++, i++) {
+               adduplicate(1);
+               cu= OBACT->data;
+               cu->sepchar = i+1;
+               text_to_curve(OBACT, 0);        // pass 1: only one letter, adapt position
+               text_to_curve(OBACT, 0);        // pass 2: remake
+               freedisplist(&OBACT->disp);
+               makeDispList(OBACT);
+               
+               OBACT->flag &= ~SELECT;
+               BASACT->flag &= ~SELECT;
+               oldbase->flag |= SELECT;
+               oldbase->object->flag |= SELECT;
+               set_active_base(oldbase);               
+       }
+}
 
 void special_editmenu(void)
 {
@@ -2007,6 +2065,14 @@ void special_editmenu(void)
 
                                allqueue(REDRAWVIEW3D, 0);
                        }
+                       else if (OBACT->type == OB_FONT) {
+                               nr= pupmenu("Split %t|Characters%x1");
+                               if (nr > 0) {
+                                       switch(nr) {
+                                               case 1: split_font();
+                                       }
+                               }
+                       }                       
                }
        }
        else if(G.obedit->type==OB_MESH) {
index 20cada29b95e7b667820d613495189b84f504987..c11203343b1cb4fd97f267fb73accd9758bff12b 100644 (file)
@@ -133,6 +133,8 @@ static void drawscredge_area(ScrArea *sa);
 
 /**********************************************************************/
 
+extern int textediting;
+
 static void screen_set_cursor(bScreen *sc) 
 {
        if (sc->winakt>3) {
@@ -1286,7 +1288,7 @@ void screenmain(void)
                        }
                }
                else if(ELEM(event, LEFTARROWKEY, RIGHTARROWKEY)) {
-                       if(val && (G.qual & LR_CTRLKEY)) {
+                       if(textediting==0 && val && (G.qual & LR_CTRLKEY)) {
                                bScreen *sc= (event==LEFTARROWKEY)?G.curscreen->id.prev:G.curscreen->id.next;
                                if(is_allowed_to_change_screen(sc)) setscreen(sc);
                                g_activearea= NULL;
index c1175806947410bbfa8b1dd942f4cff14bf457c7..fcb32adc5b9808df6006d763a6e182382a4c926c 100644 (file)
@@ -52,7 +52,7 @@
        
 #define glToggle(mode, onoff)  (((onoff)?glEnable:glDisable)(mode))
 
-static void set_inverted_drawing(int enable) 
+void set_inverted_drawing(int enable) 
 {
        glLogicOp(enable?GL_INVERT:GL_COPY);
 
index 552f846038fe0b99c33d5e29202f64ad97573b90..5cc23d6914b7963ebf1d2237d7ce552036555243 100644 (file)
@@ -983,7 +983,7 @@ int blenderqread(unsigned short event, short val)
                break;
                
        case XKEY:
-               if(textspace==0) {
+               if(textspace==0 && textediting==0) {
                        if(G.qual==LR_CTRLKEY) {
                                if(okee("Erase all")) {
                                        strcpy(G.sce, BLI_gethome());