forked from bartvdbraak/blender
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 ===
This commit is contained in:
parent
9ee2a1ee09
commit
97df61a7e5
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
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++;
|
||||
slen = strlen(mem);
|
||||
|
||||
if (cu->str==0) return 0;
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
linedist= cu->linedist;
|
||||
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
struct VFont *vfont;
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 RETKEY:
|
||||
insert_into_textbuf(cu, '\n');
|
||||
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++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
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 LEFTARROWKEY:
|
||||
|
||||
if(G.qual & LR_SHIFTKEY) {
|
||||
while(cu->pos>0) {
|
||||
if( textbuf[cu->pos-1]=='\n') break;
|
||||
cu->pos--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cu->pos--;
|
||||
}
|
||||
cursmove=FO_CURS;
|
||||
break;
|
||||
|
||||
case UPARROWKEY:
|
||||
if(G.qual & LR_SHIFTKEY) {
|
||||
cu->pos= 0;
|
||||
cursmove= FO_CURS;
|
||||
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:
|
||||
if(G.qual & LR_CTRLKEY) {
|
||||
insert_into_textbuf(cu, 1);
|
||||
if (textbuf[cu->pos]!='\n') insert_into_textbuf(cu, '\n');
|
||||
}
|
||||
else if(G.qual & LR_ALTKEY) {
|
||||
else {
|
||||
insert_into_textbuf(cu, '\n');
|
||||
}
|
||||
cu->selstart = cu->selend = 0;
|
||||
doit= 1;
|
||||
break;
|
||||
|
||||
case RIGHTARROWKEY:
|
||||
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;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case LEFTARROWKEY:
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
case UPARROWKEY:
|
||||
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);
|
||||
oldstr= cu->str;
|
||||
cu->str= textbuf;
|
||||
|
||||
cu->len= strlen(textbuf);
|
||||
|
||||
memcpy(textbufinfo, cu->strinfo, (cu->len)*sizeof(CharInfo));
|
||||
oldstr= cu->str;
|
||||
oldstrinfo= cu->strinfo;
|
||||
cu->str= textbuf;
|
||||
cu->strinfo= textbufinfo;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user