Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Ewering <blender@instinctive.de>2005-06-18 01:04:27 +0400
committerAlexander Ewering <blender@instinctive.de>2005-06-18 01:04:27 +0400
commit97df61a7e5391e302d1a5f9069cf0b388f85e0c8 (patch)
tree1c0004b1efa87ebf22ffe014d836033ac2f2ac30
parent9ee2a1ee095a1b9ce02b5ac30a50a4446f513ddc (diff)
Initial commit for new text object.
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 ===
-rw-r--r--source/blender/blenkernel/BKE_displist.h2
-rw-r--r--source/blender/blenkernel/BKE_font.h9
-rw-r--r--source/blender/blenkernel/intern/curve.c8
-rw-r--r--source/blender/blenkernel/intern/displist.c21
-rw-r--r--source/blender/blenkernel/intern/font.c305
-rw-r--r--source/blender/blenlib/intern/psfont.c14
-rw-r--r--source/blender/blenloader/intern/readfile.c20
-rw-r--r--source/blender/blenloader/intern/writefile.c2
-rw-r--r--source/blender/include/BIF_editfont.h5
-rw-r--r--source/blender/include/BIF_glutil.h3
-rw-r--r--source/blender/include/butspace.h8
-rw-r--r--source/blender/makesdna/DNA_curve_types.h47
-rw-r--r--source/blender/makesdna/DNA_vfont_types.h3
-rw-r--r--source/blender/src/buttons_editing.c157
-rw-r--r--source/blender/src/drawobject.c81
-rw-r--r--source/blender/src/editfont.c419
-rw-r--r--source/blender/src/editobject.c68
-rw-r--r--source/blender/src/editscreen.c4
-rw-r--r--source/blender/src/glutil.c2
-rw-r--r--source/blender/src/toets.c2
20 files changed, 1016 insertions, 164 deletions
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index 3193c8cbfec..ca08b5454a3 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -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);
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index 2f923315aaf..d99085f9ee9 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -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
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 83c51de76d1..c118a109b8f 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -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;
}
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 87aa3dc17b9..647ff535585 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -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)
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index fc1d45f9696..999b8315242 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -69,11 +69,15 @@
#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;
diff --git a/source/blender/blenlib/intern/psfont.c b/source/blender/blenlib/intern/psfont.c
index 74e8bef6e8a..f7fbf7e3d16 100644
--- a/source/blender/blenlib/intern/psfont.c
+++ b/source/blender/blenlib/intern/psfont.c
@@ -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);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 5f0d684695d..f82adec594b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 8ade6df7b4c..2b87df727ec 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -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 */
diff --git a/source/blender/include/BIF_editfont.h b/source/blender/include/BIF_editfont.h
index fe3604493f5..5842edc898e 100644
--- a/source/blender/include/BIF_editfont.h
+++ b/source/blender/include/BIF_editfont.h
@@ -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
diff --git a/source/blender/include/BIF_glutil.h b/source/blender/include/BIF_glutil.h
index d776a9003f9..ba7e008d58a 100644
--- a/source/blender/include/BIF_glutil.h
+++ b/source/blender/include/BIF_glutil.h
@@ -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);
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 7bbadba8847..8cc6ad4519d 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -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
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 0713f770dc4..4482d24ba06 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -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
diff --git a/source/blender/makesdna/DNA_vfont_types.h b/source/blender/makesdna/DNA_vfont_types.h
index 5f9e3f61446..df9279d6243 100644
--- a/source/blender/makesdna/DNA_vfont_types.h
+++ b/source/blender/makesdna/DNA_vfont_types.h
@@ -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
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 49fdf7fad67..0af92664773 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -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);
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index cb5f6d99384..058401c95a7 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -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);
diff --git a/source/blender/src/editfont.c b/source/blender/src/editfont.c
index eb1032b9e7d..25297176e14 100644
--- a/source/blender/src/editfont.c
+++ b/source/blender/src/editfont.c
@@ -30,6 +30,7 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
+#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
@@ -76,13 +77,15 @@
#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;
}
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index 8eb489a8ce5..edaaab474d3 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -173,6 +173,8 @@
/* --------------------------------- */
+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) {
diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c
index 20cada29b95..c11203343b1 100644
--- a/source/blender/src/editscreen.c
+++ b/source/blender/src/editscreen.c
@@ -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;
diff --git a/source/blender/src/glutil.c b/source/blender/src/glutil.c
index c1175806947..fcb32adc5b9 100644
--- a/source/blender/src/glutil.c
+++ b/source/blender/src/glutil.c
@@ -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);
diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c
index 552f846038f..5cc23d6914b 100644
--- a/source/blender/src/toets.c
+++ b/source/blender/src/toets.c
@@ -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());