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
path: root/source
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2009-01-23 17:43:25 +0300
committerTon Roosendaal <ton@blender.org>2009-01-23 17:43:25 +0300
commit66437a62a73966de8ccb673473ba69d6c1ed66a3 (patch)
tree6b200663643b67dea804e8b9805abf128a010493 /source
parentf4133b730c93f6db985b6751d18b72ea7f429c34 (diff)
2.5
Font object + editing back. Was quite some work due to a myriad of globals all over! Works nicely 100% local now. To enable a single textedit operator, I've added a new keymap entry KM_TEXTEDIT, which gives all keyboard events to the handler. Also had to add a new keymap-add function to force a keymap handler in beginning of region handlers. In future this can be used to prioritize handlers. Also: split off the arrow keys (frame change) to a separate region level handler. Can be set with default flag in regiontype->keymapflag ED_KEYMAP_FRAMES
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_curve.h1
-rw-r--r--source/blender/blenkernel/BKE_font.h22
-rw-r--r--source/blender/blenkernel/BKE_global.h2
-rw-r--r--source/blender/blenkernel/intern/anim.c2
-rw-r--r--source/blender/blenkernel/intern/curve.c33
-rw-r--r--source/blender/blenkernel/intern/displist.c2
-rw-r--r--source/blender/blenkernel/intern/font.c221
-rw-r--r--source/blender/blenloader/intern/readfile.c2
-rw-r--r--source/blender/editors/curve/curve_intern.h42
-rw-r--r--source/blender/editors/curve/curve_ops.c82
-rw-r--r--source/blender/editors/curve/editfont.c1312
-rw-r--r--source/blender/editors/curve/lorem.c513
-rw-r--r--source/blender/editors/include/ED_curve.h9
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/mesh/editmesh.c2
-rw-r--r--source/blender/editors/object/object_edit.c11
-rw-r--r--source/blender/editors/screen/area.c4
-rw-r--r--source/blender/editors/screen/screen_ops.c18
-rw-r--r--source/blender/editors/space_action/space_action.c4
-rw-r--r--source/blender/editors/space_api/spacetypes.c3
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c4
-rw-r--r--source/blender/editors/space_image/space_image.c3
-rw-r--r--source/blender/editors/space_ipo/space_ipo.c4
-rw-r--r--source/blender/editors/space_nla/space_nla.c2
-rw-r--r--source/blender/editors/space_node/space_node.c4
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c4
-rw-r--r--source/blender/editors/space_sound/space_sound.c2
-rw-r--r--source/blender/editors/space_time/space_time.c2
-rw-r--r--source/blender/editors/space_view3d/drawobject.c22
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c11
-rw-r--r--source/blender/makesdna/DNA_curve_types.h6
-rw-r--r--source/blender/windowmanager/WM_api.h2
-rw-r--r--source/blender/windowmanager/WM_types.h3
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c25
-rw-r--r--source/blender/windowmanager/wm_event_types.h7
35 files changed, 2223 insertions, 164 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 7065948ea0b..b17f4a76198 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -49,6 +49,7 @@ struct BevList;
void unlink_curve( struct Curve *cu);
void free_curve( struct Curve *cu);
+void BKE_free_editfont(struct Curve *cu);
struct Curve *add_curve(char *name, int type);
struct Curve *copy_curve( struct Curve *cu);
void make_local_curve( struct Curve *cu);
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index 3445e5b1ce2..d328ccd57f4 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -43,6 +43,7 @@ struct Object;
struct Curve;
struct objfnt;
struct TmpFont;
+struct CharInfo;
struct chartrans {
float xof, yof;
@@ -55,20 +56,31 @@ typedef struct SelBox {
float x, y, w, h;
} SelBox;
-extern struct SelBox *selboxes;
+typedef struct EditFont {
+ wchar_t *copybuf;
+ wchar_t *copybufinfo;
+
+ wchar_t *textbuf;
+ struct CharInfo *textbufinfo;
+ wchar_t *oldstr;
+ struct CharInfo *oldstrinfo;
+
+ float textcurs[4][2];
+
+} EditFont;
+
void BKE_font_register_builtin(void *mem, int size);
void free_vfont(struct VFont *sc);
void free_ttfont(void);
+struct VFont *get_builtin_font(void);
struct VFont *load_vfont(char *name);
struct TmpFont *vfont_find_tmpfont(struct VFont *vfont);
-struct chartrans *text_to_curve(struct Scene *scene, struct Object *ob, int mode);
-int style_to_sel(int style, int toggle);
-int mat_to_sel(void);
+struct chartrans *BKE_text_to_curve(struct Scene *scene, struct Object *ob, int mode);
-int getselection(struct Object *ob, int *start, int *end);
+int BKE_font_getselection(struct Object *ob, int *start, int *end);
void chtoutf8(unsigned long c, char *o);
void wcs2utf8s(char *dst, wchar_t *src);
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 4bd9435708d..07ade7cb208 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -76,8 +76,6 @@ typedef struct Global {
/* Used for BMesh transformations */
struct BME_Glob *editBMesh;
- float textcurs[4][2];
-
/* Frank's variables */
int save_over;
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index e9d0fc7c95a..8c71a1d807e 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -991,7 +991,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int level, i
/* in par the family name is stored, use this to find the other objects */
- chartransdata= text_to_curve(scene, par, FO_DUPLI);
+ chartransdata= BKE_text_to_curve(scene, par, FO_DUPLI);
if(chartransdata==0) return;
memset(obar, 0, 256*sizeof(void *));
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 91189fc7d3a..2e0347870cc 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -56,6 +56,7 @@
#include "BKE_anim.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
+#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_key.h"
#include "BKE_library.h"
@@ -86,14 +87,32 @@ void unlink_curve(Curve *cu)
cu->key= 0;
}
+/* frees editcurve entirely */
+void BKE_free_editfont(Curve *cu)
+{
+ if(cu->editfont) {
+ EditFont *ef= cu->editfont;
+
+ if(ef->oldstr) MEM_freeN(ef->oldstr);
+ if(ef->oldstrinfo) MEM_freeN(ef->oldstrinfo);
+ if(ef->textbuf) MEM_freeN(ef->textbuf);
+ if(ef->textbufinfo) MEM_freeN(ef->textbufinfo);
+ if(ef->copybuf) MEM_freeN(ef->copybuf);
+ if(ef->copybufinfo) MEM_freeN(ef->copybufinfo);
+
+ MEM_freeN(ef);
+ cu->editfont= NULL;
+ }
+}
-/* niet curve zelf vrijgeven */
+/* don't free curve itself */
void free_curve(Curve *cu)
{
freeNurblist(&cu->nurb);
BLI_freelistN(&cu->bev);
freedisplist(&cu->disp);
+ BKE_free_editfont(cu);
if(cu->editnurb) {
freeNurblist(cu->editnurb);
@@ -131,6 +150,18 @@ Curve *add_curve(char *name, int type)
cu->bb= unit_boundbox();
+ if(type==OB_FONT) {
+ 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;
+ }
+
return cu;
}
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 952c49ea12a..645f468d250 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1477,7 +1477,7 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
if(cu->path) free_path(cu->path);
cu->path= NULL;
- if(ob->type==OB_FONT) text_to_curve(scene, ob, 0);
+ if(ob->type==OB_FONT) BKE_text_to_curve(scene, ob, 0);
if(!forOrco) curve_calc_modifiers_pre(scene, ob, 0, &originalVerts, &deformedVerts, &numVerts);
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 80670bf1228..8f8a8fba983 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -65,10 +65,6 @@
#include "BKE_curve.h"
#include "BKE_displist.h"
-#define callocstructN(x,y,name) (x*)MEM_callocN((y)* sizeof(x),name)
-
-struct SelBox *selboxes= NULL;
-
static ListBase ttfdata= {NULL, NULL};
/* UTF-8 <-> wchar transformations */
@@ -454,6 +450,17 @@ static VFont *which_vfont(Curve *cu, CharInfo *info)
}
}
+VFont *get_builtin_font(void)
+{
+ VFont *vf;
+
+ for (vf= G.main->vfont.first; vf; vf= vf->id.next)
+ if (BLI_streq(vf->name, "<builtin>"))
+ return vf;
+
+ return load_vfont("<builtin>");
+}
+
static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, int charidx, short mat_nr)
{
Nurb *nu2;
@@ -622,11 +629,11 @@ static void buildchar(Curve *cu, unsigned long character, CharInfo *info, float
}
}
-int getselection(Object *ob, int *start, int *end)
+int BKE_font_getselection(Object *ob, int *start, int *end)
{
Curve *cu= ob->data;
- if (cu->editstr==NULL || ob->type != OB_FONT) return 0;
+ if (cu->editfont==NULL || ob->type != OB_FONT) return 0;
if (cu->selstart == 0) return 0;
if (cu->selstart <= cu->selend) {
@@ -641,30 +648,23 @@ int getselection(Object *ob, int *start, int *end)
}
}
-struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
+struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
{
VFont *vfont, *oldvfont;
VFontData *vfd= NULL;
- Curve *cu, *cucu;
- struct chartrans *chartransdata=NULL, *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, *linedata3, *linedata4;
- int i, slen, oldflag, j;
- short cnr=0, lnr=0, wsnr= 0;
- wchar_t *mem, *tmp, ascii;
- int outta;
- float vecyo[3], curofs;
- CharInfo *info;
- float wsfac;
- float ulwidth, uloverlap;
+ Curve *cu;
+ CharInfo *info, *custrinfo;
TextBox *tb;
- int curbox;
- int selstart, selend;
- SelBox *sb= NULL; /* to please gcc */
VChar *che;
+ struct chartrans *chartransdata=NULL, *ct;
+ float *f, xof, yof, xtrax, linedist, *linedata, *linedata2, *linedata3, *linedata4;
float twidth;
+ int i, slen, j;
+ int curbox;
+ int selstart, selend;
int utf8len;
+ short cnr=0, lnr=0, wsnr= 0;
+ wchar_t *mem, *tmp, ascii;
/* renark: do calculations including the trailing '\0' of a string
because the cursor can be at that location */
@@ -674,7 +674,7 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
// Set font data
cu= (Curve *) ob->data;
vfont= cu->vfont;
-
+
if(cu->str == NULL) return 0;
if(vfont == NULL) return 0;
@@ -687,19 +687,23 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
// Count the wchar_t string length
slen = wcslen(mem);
- if (cu->ulheight == 0.0) cu->ulheight = 0.05;
- if (cu->strinfo==NULL) { /* old file */
+ if (cu->ulheight == 0.0)
+ cu->ulheight = 0.05;
+
+ if (cu->strinfo==NULL) /* old file */
cu->strinfo = MEM_callocN((slen+1) * sizeof(CharInfo), "strinfo compat");
- }
- if (cu->tb==NULL) {
+
+ custrinfo= cu->strinfo;
+ if (cu->editfont)
+ custrinfo= cu->editfont->textbufinfo;
+
+ if (cu->tb==NULL)
cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "TextBox compat");
- }
vfd= vfont_get_data(vfont);
/* The VFont Data can not be found */
- if(!vfd)
- {
+ if(!vfd) {
if(mem)
MEM_freeN(mem);
return 0;
@@ -725,12 +729,12 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
oldvfont = NULL;
- for (i=0; i<slen; i++) cu->strinfo[i].flag &= ~CU_WRAP;
+ for (i=0; i<slen; i++) custrinfo[i].flag &= ~CU_WRAP;
- if (selboxes) MEM_freeN(selboxes);
- selboxes = NULL;
- if (getselection(ob, &selstart, &selend))
- selboxes = MEM_callocN((selend-selstart+1)*sizeof(SelBox), "font selboxes");
+ if (cu->selboxes) MEM_freeN(cu->selboxes);
+ cu->selboxes = NULL;
+ if (BKE_font_getselection(ob, &selstart, &selend))
+ cu->selboxes = MEM_callocN((selend-selstart+1)*sizeof(SelBox), "font selboxes");
tb = &(cu->tb[0]);
curbox= 0;
@@ -739,14 +743,13 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
// Characters in the list
che = vfd->characters.first;
ascii = mem[i];
- info = &(cu->strinfo[i]);
+ info = &(custrinfo[i]);
vfont = which_vfont(cu, info);
if(vfont==NULL) break;
// Find the character
- while(che)
- {
+ while(che) {
if(che->index == ascii)
break;
che = che->next;
@@ -755,15 +758,13 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
#ifdef WITH_FREETYPE2
// The character wasn't in the current curve base so load it
// But if the font is <builtin> then do not try loading since whole font is in the memory already
- if(che == NULL && strcmp(vfont->name, "<builtin>"))
- {
+ if(che == NULL && strcmp(vfont->name, "<builtin>")) {
BLI_vfontchar_from_freetypefont(vfont, ascii);
}
// Try getting the character again from the list
che = vfd->characters.first;
- while(che)
- {
+ while(che) {
if(che->index == ascii)
break;
che = che->next;
@@ -771,8 +772,7 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
#endif
/* No VFont found */
- if (vfont==0)
- {
+ if (vfont==0) {
if(mem)
MEM_freeN(mem);
MEM_freeN(chartransdata);
@@ -785,8 +785,7 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
}
/* VFont Data for VFont couldn't be found */
- if (!vfd)
- {
+ if (!vfd) {
if(mem)
MEM_freeN(mem);
MEM_freeN(chartransdata);
@@ -795,13 +794,9 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
// The character wasn't found, propably ascii = 0, then the width shall be 0 as well
if(!che)
- {
twidth = 0;
- }
else
- {
twidth = che->width;
- }
// Calculate positions
if((tb->w != 0.0) && (ct->dobreak==0) && ((xof-(tb->x/cu->fsize)+twidth)*cu->fsize) > tb->w) {
@@ -815,13 +810,13 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
i = j-1;
xof = ct->xof;
ct[1].dobreak = 1;
- cu->strinfo[i+1].flag |= CU_WRAP;
+ custrinfo[i+1].flag |= CU_WRAP;
goto makebreak;
}
if (chartransdata[j].dobreak) {
// fprintf(stderr, "word too long: %c%c%c...\n", mem[j], mem[j+1], mem[j+2]);
ct->dobreak= 1;
- cu->strinfo[i+1].flag |= CU_WRAP;
+ custrinfo[i+1].flag |= CU_WRAP;
ct -= 1;
cnr -= 1;
i--;
@@ -831,6 +826,8 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
}
}
if(ascii== '\n' || ascii== '\r' || ascii==0 || ct->dobreak) {
+ float maxlen;
+
ct->xof= xof;
ct->yof= yof;
ct->linenr= lnr;
@@ -864,6 +861,8 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
wsnr= 0;
}
else if(ascii==9) { /* TAB */
+ float tabfac;
+
ct->xof= xof;
ct->yof= yof;
ct->linenr= lnr;
@@ -874,13 +873,16 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
xof= cu->xof+tabfac;
}
else {
+ SelBox *sb= NULL;
+ float wsfac;
+
ct->xof= xof;
ct->yof= yof;
ct->linenr= lnr;
ct->charnr= cnr++;
- if (selboxes && (i>=selstart) && (i<=selend)) {
- sb = &(selboxes[i-selstart]);
+ if (cu->selboxes && (i>=selstart) && (i<=selend)) {
+ sb = &(cu->selboxes[i-selstart]);
sb->y = yof*cu->fsize-linedist*cu->fsize*0.1;
sb->h = linedist*cu->fsize;
sb->w = xof*cu->fsize;
@@ -889,25 +891,23 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
if (ascii==32) {
wsfac = cu->wordspace;
wsnr++;
- } else wsfac = 1.0;
+ }
+ else wsfac = 1.0;
+
// Set the width of the character
if(!che)
- {
twidth = 0;
- }
- else
- {
+ else
twidth = che->width;
- }
+
xof += (twidth*wsfac*(1.0+(info->kern/40.0)) ) + xtrax;
- if (selboxes && (i>=selstart) && (i<=selend)) sb->w = (xof*cu->fsize) - sb->w;
+ if (sb)
+ sb->w = (xof*cu->fsize) - sb->w;
}
ct++;
}
-
-
cu->lines= 1;
ct= chartransdata;
tmp = mem;
@@ -949,9 +949,9 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
// }
ct++;
}
- } else if((cu->spacemode==CU_JUSTIFY) &&
- (cu->tb[0].w != 0.0)) {
- curofs= 0;
+ }
+ else if((cu->spacemode==CU_JUSTIFY) && (cu->tb[0].w != 0.0)) {
+ float curofs= 0.0f;
for (i=0; i<=slen; i++) {
for (j=i; (mem[j]) && (mem[j]!='\n') &&
(mem[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
@@ -968,14 +968,17 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
/* TEXT ON CURVE */
if(cu->textoncurve) {
- cucu= cu->textoncurve->data;
+ Curve *cucu= cu->textoncurve->data;
+ int oldflag= cucu->flag;
- oldflag= cucu->flag;
cucu->flag |= (CU_PATH+CU_FOLLOW);
if(cucu->path==NULL) makeDispListCurveTypes(scene, cu->textoncurve, 0);
if(cucu->path) {
- float imat[4][4], imat3[3][3];
+ float distfac, imat[4][4], imat3[3][3], cmat[3][3];
+ float minx, maxx, miny, maxy;
+ float timeofs, sizefac;
+
Mat4Invert(imat, ob->obmat);
Mat3CpyMat4(imat3, imat);
@@ -1020,27 +1023,24 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
ct= chartransdata;
for (i=0; i<=slen; i++, ct++) {
+ float ctime, dtime, vec[4], tvec[4], rotvec[3];
+ float si, co;
/* rotate around center character */
ascii = mem[i];
// Find the character
che = vfd->characters.first;
- while(che)
- {
+ while(che) {
if(che->index == ascii)
break;
che = che->next;
}
if(che)
- {
twidth = che->width;
- }
else
- {
twidth = 0;
- }
dtime= distfac*0.35f*twidth; /* why not 0.5? */
dtime= distfac*0.5f*twidth; /* why not 0.5? */
@@ -1070,12 +1070,12 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
}
}
- if (selboxes) {
+ if (cu->selboxes) {
ct= chartransdata;
for (i=0; i<=selend; i++, ct++) {
if (i>=selstart) {
- selboxes[i-selstart].x = ct->xof*cu->fsize;
- selboxes[i-selstart].y = ct->yof*cu->fsize;
+ cu->selboxes[i-selstart].x = ct->xof*cu->fsize;
+ cu->selboxes[i-selstart].y = ct->yof*cu->fsize;
}
}
}
@@ -1111,12 +1111,14 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
}
/* cursor first */
- if(cu->editstr) {
+ if(cu->editfont) {
+ float si, co;
+
ct= chartransdata+cu->pos;
si= (float)sin(ct->rot);
co= (float)cos(ct->rot);
- f= G.textcurs[0];
+ f= cu->editfont->textcurs[0];
f[0]= cu->fsize*(-0.1f*co + ct->xof);
f[1]= cu->fsize*(0.1f*si + ct->yof);
@@ -1146,57 +1148,62 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
if(mode==0) {
/* make nurbdata */
unsigned long cha;
-
+
freeNurblist(&cu->nurb);
ct= chartransdata;
if (cu->sepchar==0) {
- for (i= 0; i<slen; i++) {
- cha = (unsigned long) mem[i];
- info = &(cu->strinfo[i]);
- if (info->mat_nr > (ob->totcol)) {
- /* printf("Error: Illegal material index (%d) in text object, setting to 0\n", info->mat_nr); */
- info->mat_nr = 0;
- }
+ for (i= 0; i<slen; i++) {
+ cha = (unsigned long) mem[i];
+ info = &(custrinfo[i]);
+
+ if (info->mat_nr > (ob->totcol)) {
+ /* printf("Error: Illegal material index (%d) in text object, setting to 0\n", info->mat_nr); */
+ info->mat_nr = 0;
+ }
+
// We do not want to see any character for \n or \r
if(cha != '\n' && cha != '\r')
buildchar(cu, cha, info, ct->xof, ct->yof, ct->rot, i);
+
if ((info->flag & CU_UNDERLINE) && (cu->textoncurve == NULL) && (cha != '\n') && (cha != '\r')) {
- uloverlap = 0;
+ float ulwidth, uloverlap= 0.0f;
+
if ( (i<(slen-1)) && (mem[i+1] != '\n') && (mem[i+1] != '\r') &&
- ((mem[i+1] != ' ') || (cu->strinfo[i+1].flag & CU_UNDERLINE)) && ((cu->strinfo[i+1].flag & CU_WRAP)==0)
- ) {
+ ((mem[i+1] != ' ') || (custrinfo[i+1].flag & CU_UNDERLINE)) && ((custrinfo[i+1].flag & CU_WRAP)==0)
+ ) {
uloverlap = xtrax + 0.1;
}
// Find the character, the characters has to be in the memory already
// since character checking has been done earlier already.
che = vfd->characters.first;
- while(che)
- {
+ while(che) {
if(che->index == cha)
break;
che = che->next;
}
-
+
if(!che) twidth =0; else twidth=che->width;
ulwidth = cu->fsize * ((twidth* (1.0+(info->kern/40.0)))+uloverlap);
build_underline(cu, ct->xof*cu->fsize, ct->yof*cu->fsize + (cu->ulpos-0.05)*cu->fsize,
- ct->xof*cu->fsize + ulwidth,
- ct->yof*cu->fsize + (cu->ulpos-0.05)*cu->fsize - cu->ulheight*cu->fsize,
- i, info->mat_nr);
+ ct->xof*cu->fsize + ulwidth,
+ ct->yof*cu->fsize + (cu->ulpos-0.05)*cu->fsize - cu->ulheight*cu->fsize,
+ i, info->mat_nr);
}
- ct++;
- }
+ ct++;
+ }
}
else {
- outta = 0;
- for (i= 0; (i<slen) && (outta==0); i++) {
- ascii = mem[i];
- info = &(cu->strinfo[i]);
+ int outta = 0;
+ for (i= 0; (i<slen) && (outta==0); i++) {
+ ascii = mem[i];
+ info = &(custrinfo[i]);
if (cu->sepchar == (i+1)) {
+ float vecyo[3];
+
mem[0] = ascii;
mem[1] = 0;
- cu->strinfo[0]= *info;
+ custrinfo[0]= *info;
cu->pos = 1;
cu->len = 1;
vecyo[0] = ct->xof;
@@ -1207,10 +1214,10 @@ struct chartrans *text_to_curve(Scene *scene, Object *ob, int mode)
outta = 1;
cu->sepchar = 0;
}
- ct++;
+ ct++;
+ }
}
}
- }
if(mode==FO_DUPLI) {
MEM_freeN(mem);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 0d1eba2048b..256ef7cb8aa 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2658,7 +2658,7 @@ static void direct_link_curve(FileData *fd, Curve *cu)
cu->editnurb= NULL;
cu->lastselbp= NULL;
cu->path= NULL;
- cu->editstr= NULL;
+ cu->editfont= NULL;
nu= cu->nurb.first;
while(nu) {
diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h
new file mode 100644
index 00000000000..a77300f29f5
--- /dev/null
+++ b/source/blender/editors/curve/curve_intern.h
@@ -0,0 +1,42 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef ED_CURVE_INTERN_H
+#define ED_CURVE_INTERN_H
+
+/* internal exports only */
+struct wmOperatorType;
+
+/* lorem.c */
+char *ED_lorem;
+
+/* editfont.c */
+void FONT_OT_textedit(struct wmOperatorType *ot);
+
+#endif /* ED_UTIL_INTERN_H */
+
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
new file mode 100644
index 00000000000..ee7260606a5
--- /dev/null
+++ b/source/blender/editors/curve/curve_ops.c
@@ -0,0 +1,82 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_object.h"
+
+#include "curve_intern.h"
+
+
+/* ************************** registration **********************************/
+
+
+void ED_operatortypes_curve(void)
+{
+ WM_operatortype_append(FONT_OT_textedit);
+}
+
+void ED_keymap_curve(wmWindowManager *wm)
+{
+ ListBase *keymap= WM_keymap_listbase(wm, "Font", 0, 0);
+
+ /* only set in editmode font, by space_view3d listener */
+ WM_keymap_add_item(keymap, "FONT_OT_textedit", KM_TEXTINPUT, KM_ANY, KM_ANY, 0);
+
+ /* only set in editmode curve, by space_view3d listener */
+// keymap= WM_keymap_listbase(wm, "Curve", 0, 0);
+
+// WM_keymap_add_item(keymap, "OBJECT_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
+
+}
+
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
new file mode 100644
index 00000000000..f5a51a258a8
--- /dev/null
+++ b/source/blender/editors/curve/editfont.c
@@ -0,0 +1,1312 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <wchar.h>
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "DNA_curve_types.h"
+#include "DNA_object_types.h"
+#include "DNA_vfont_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_text_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
+
+#include "BKE_context.h"
+#include "BKE_curve.h"
+#include "BKE_depsgraph.h"
+#include "BKE_font.h"
+#include "BKE_object.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_utildefines.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_curve.h"
+#include "ED_object.h"
+#include "ED_util.h"
+
+#include "curve_intern.h"
+
+/* XXX */
+static void BIF_undo_push() {}
+static void error() {}
+static int okee() {return 0;}
+/* XXX */
+
+
+#define MAXTEXT 32766
+
+int textediting=0;
+
+static char findaccent(char char1, unsigned int code)
+{
+ char new= 0;
+
+ if(char1=='a') {
+ if(code=='`') new= 224;
+ else if(code==39) new= 225;
+ else if(code=='^') new= 226;
+ else if(code=='~') new= 227;
+ else if(code=='"') new= 228;
+ else if(code=='o') new= 229;
+ else if(code=='e') new= 230;
+ else if(code=='-') new= 170;
+ }
+ else if(char1=='c') {
+ if(code==',') new= 231;
+ if(code=='|') new= 162;
+ }
+ else if(char1=='e') {
+ if(code=='`') new= 232;
+ else if(code==39) new= 233;
+ else if(code=='^') new= 234;
+ else if(code=='"') new= 235;
+ }
+ else if(char1=='i') {
+ if(code=='`') new= 236;
+ else if(code==39) new= 237;
+ else if(code=='^') new= 238;
+ else if(code=='"') new= 239;
+ }
+ else if(char1=='n') {
+ if(code=='~') new= 241;
+ }
+ else if(char1=='o') {
+ if(code=='`') new= 242;
+ else if(code==39) new= 243;
+ else if(code=='^') new= 244;
+ else if(code=='~') new= 245;
+ else if(code=='"') new= 246;
+ else if(code=='/') new= 248;
+ else if(code=='-') new= 186;
+ else if(code=='e') new= 143;
+ }
+ else if(char1=='s') {
+ if(code=='s') new= 167;
+ }
+ else if(char1=='u') {
+ if(code=='`') new= 249;
+ else if(code==39) new= 250;
+ else if(code=='^') new= 251;
+ else if(code=='"') new= 252;
+ }
+ else if(char1=='y') {
+ if(code==39) new= 253;
+ else if(code=='"') new= 255;
+ }
+ else if(char1=='A') {
+ if(code=='`') new= 192;
+ else if(code==39) new= 193;
+ else if(code=='^') new= 194;
+ else if(code=='~') new= 195;
+ else if(code=='"') new= 196;
+ else if(code=='o') new= 197;
+ else if(code=='e') new= 198;
+ }
+ else if(char1=='C') {
+ if(code==',') new= 199;
+ }
+ else if(char1=='E') {
+ if(code=='`') new= 200;
+ else if(code==39) new= 201;
+ else if(code=='^') new= 202;
+ else if(code=='"') new= 203;
+ }
+ else if(char1=='I') {
+ if(code=='`') new= 204;
+ else if(code==39) new= 205;
+ else if(code=='^') new= 206;
+ else if(code=='"') new= 207;
+ }
+ else if(char1=='N') {
+ if(code=='~') new= 209;
+ }
+ else if(char1=='O') {
+ if(code=='`') new= 210;
+ else if(code==39) new= 211;
+ else if(code=='^') new= 212;
+ else if(code=='~') new= 213;
+ else if(code=='"') new= 214;
+ else if(code=='/') new= 216;
+ else if(code=='e') new= 141;
+ }
+ else if(char1=='U') {
+ if(code=='`') new= 217;
+ else if(code==39) new= 218;
+ else if(code=='^') new= 219;
+ else if(code=='"') new= 220;
+ }
+ else if(char1=='Y') {
+ if(code==39) new= 221;
+ }
+ else if(char1=='1') {
+ if(code=='4') new= 188;
+ if(code=='2') new= 189;
+ }
+ else if(char1=='3') {
+ if(code=='4') new= 190;
+ }
+ else if(char1==':') {
+ if(code=='-') new= 247;
+ }
+ else if(char1=='-') {
+ if(code==':') new= 247;
+ if(code=='|') new= 135;
+ if(code=='+') new= 177;
+ }
+ else if(char1=='|') {
+ if(code=='-') new= 135;
+ if(code=='=') new= 136;
+ }
+ else if(char1=='=') {
+ if(code=='|') new= 136;
+ }
+ else if(char1=='+') {
+ if(code=='-') new= 177;
+ }
+
+ if(new) return new;
+ else return char1;
+}
+
+
+void update_string(Curve *cu)
+{
+ EditFont *ef= cu->editfont;
+ int len;
+
+ // Free the old curve string
+ MEM_freeN(cu->str);
+
+ // Calculate the actual string length in UTF-8 variable characters
+ len = wcsleninu8(ef->textbuf);
+
+ // Alloc memory for UTF-8 variable char length string
+ cu->str = MEM_callocN(len + sizeof(wchar_t), "str");
+
+ // Copy the wchar to UTF-8
+ wcs2utf8s(cu->str, ef->textbuf);
+}
+
+static int insert_into_textbuf(Object *obedit, unsigned long c)
+{
+ Curve *cu= obedit->data;
+
+ if (cu->len<MAXTEXT-1) {
+ EditFont *ef= cu->editfont;
+ int x;
+
+ for(x= cu->len; x>cu->pos; x--) ef->textbuf[x]= ef->textbuf[x-1];
+ for(x= cu->len; x>cu->pos; x--) ef->textbufinfo[x]= ef->textbufinfo[x-1];
+ ef->textbuf[cu->pos]= c;
+ ef->textbufinfo[cu->pos] = cu->curinfo;
+ ef->textbufinfo[cu->pos].kern = 0;
+ if (obedit->actcol>0)
+ ef->textbufinfo[cu->pos].mat_nr = obedit->actcol;
+ else
+ ef->textbufinfo[cu->pos].mat_nr = 0;
+
+ cu->pos++;
+ cu->len++;
+ ef->textbuf[cu->len]='\0';
+
+ update_string(cu);
+
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void add_lorem(Scene *scene)
+{
+ Object *obedit= scene->obedit;
+ char *p, *p2;
+ int i;
+ static char *lastlorem;
+
+ if (lastlorem)
+ p= lastlorem;
+ else
+ p= ED_lorem;
+
+ i= rand()/(RAND_MAX/6)+4;
+
+ for (p2=p; *p2 && i; p2++) {
+ insert_into_textbuf(obedit, *p2);
+ if (*p2=='.') i--;
+ }
+ lastlorem = p2+1;
+ if (strlen(lastlorem)<5) lastlorem = ED_lorem;
+
+ insert_into_textbuf(obedit, '\n');
+ insert_into_textbuf(obedit, '\n');
+ DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+
+}
+
+void load_3dtext_fs(Scene *scene, char *file)
+{
+ Curve *cu= scene->obedit->data;
+ EditFont *ef= cu->editfont;
+ FILE *fp;
+ int filelen;
+ char *strp;
+
+ fp= fopen(file, "r");
+ if (!fp) return;
+
+ fseek(fp, 0L, SEEK_END);
+ filelen = ftell(fp);
+ fseek(fp, 0L, SEEK_SET);
+
+ strp = MEM_callocN(filelen+4, "tempstr");
+
+ filelen = fread(strp, 1, filelen, fp);
+ fclose(fp);
+ strp[filelen]= 0;
+
+ if(cu->len+filelen<MAXTEXT)
+ {
+ int tmplen;
+ wchar_t *mem = MEM_callocN((sizeof(wchar_t)*filelen)+(4*sizeof(wchar_t)), "temporary");
+ tmplen = utf8towchar(mem, strp);
+ wcscat(ef->textbuf, mem);
+ MEM_freeN(mem);
+ cu->len += tmplen;
+ cu->pos= cu->len;
+ }
+ MEM_freeN(strp);
+
+ update_string(cu);
+
+ DAG_object_flush_update(scene, scene->obedit, OB_RECALC_DATA);
+}
+
+
+void txt_export_to_object(Scene *scene, struct Text *text)
+{
+ Object *obedit= scene->obedit; // XXX
+ ID *id;
+ Curve *cu;
+ struct TextLine *tmp;
+ int nchars = 0;
+// char sdir[FILE_MAXDIR];
+// char sfile[FILE_MAXFILE];
+
+ if(!text || !text->lines.first) return;
+
+ id = (ID *)text;
+
+ if (obedit && obedit->type==OB_FONT) return;
+// XXX check_editmode(OB_FONT);
+
+ add_object(scene, OB_FONT);
+
+ ED_object_base_init_from_view(NULL, BASACT); // XXX
+ obedit= BASACT->object;
+ where_is_object(scene, obedit);
+
+ cu= obedit->data;
+
+/*
+// renames object, careful with long filenames.
+
+ if (text->name) {
+ //ID *find_id(char *type, char *name)
+ BLI_split_dirfile(text->name, sdir, sfile);
+// rename_id((ID *)obedit, sfile);
+ rename_id((ID *)cu, sfile);
+ id->us++;
+ }
+*/
+ cu->vfont= get_builtin_font();
+ cu->vfont->id.us++;
+
+ tmp= text->lines.first;
+ while(cu->len<MAXTEXT && tmp) {
+ nchars += strlen(tmp->line) + 1;
+ tmp = tmp->next;
+ }
+
+ 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");
+ cu->totbox= cu->actbox= 1;
+ cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "textbox");
+ cu->tb[0].w = cu->tb[0].h = 0.0;
+
+ tmp= text->lines.first;
+ strcpy(cu->str, tmp->line);
+ cu->len= strlen(tmp->line);
+ cu->pos= cu->len;
+
+ tmp= tmp->next;
+
+ while(cu->len<MAXTEXT && tmp) {
+ strcat(cu->str, "\n");
+ strcat(cu->str, tmp->line);
+ cu->len+= strlen(tmp->line) + 1;
+ cu->pos= cu->len;
+ tmp= tmp->next;
+ }
+
+ make_editText(obedit);
+ ED_object_exit_editmode(NULL, EM_FREEDATA|EM_WAITCURSOR); // XXX
+
+}
+
+
+void txt_export_to_objects(struct Text *text)
+{
+ Scene *scene= NULL; // XXX
+ Object *obedit= NULL; // XXX
+ RegionView3D *rv3d= NULL; // XXX
+ ID *id;
+ Curve *cu;
+ struct TextLine *curline;
+ int nchars;
+ int linenum = 0;
+ float offset[3] = {0.0,0.0,0.0};
+
+ if(!text || !text->lines.first) return;
+
+ id = (ID *)text;
+
+ if (obedit && obedit->type==OB_FONT) return;
+// XXX check_editmode(OB_FONT);
+
+ curline = text->lines.first;
+ while(curline){
+ /*skip lines with no text, but still make space for them*/
+ if(curline->line[0] == '\0'){
+ linenum++;
+ curline = curline->next;
+ continue;
+ }
+
+ nchars = 0;
+ add_object(scene, OB_FONT);
+
+ ED_object_base_init_from_view(NULL, BASACT); // XXX
+ obedit= BASACT->object;
+ where_is_object(scene, obedit);
+
+ /* Do the translation */
+ offset[0] = 0;
+ offset[1] = -linenum;
+ offset[2] = 0;
+
+ Mat4Mul3Vecfl(rv3d->viewinv, offset);
+
+ obedit->loc[0] += offset[0];
+ obedit->loc[1] += offset[1];
+ obedit->loc[2] += offset[2];
+ /* End Translation */
+
+ cu= obedit->data;
+
+ cu->vfont= get_builtin_font();
+ cu->vfont->id.us++;
+
+ 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");
+ cu->totbox= cu->actbox= 1;
+ cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "textbox");
+ cu->tb[0].w = cu->tb[0].h = 0.0;
+
+ strcpy(cu->str, curline->line);
+ cu->len= strlen(curline->line);
+ cu->pos= cu->len;
+
+ make_editText(obedit);
+ ED_object_exit_editmode(NULL, EM_FREEDATA|EM_WAITCURSOR); // XXX
+
+ linenum++;
+ curline = curline->next;
+ }
+ BIF_undo_push("Add Text as Objects");
+}
+
+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(Object *obedit, int ins) /* 1 == new character */
+{
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+ int selend, selstart, direction;
+ int offset = 0;
+ int getfrom;
+
+ direction = BKE_font_getselection(obedit, &selstart, &selend);
+ if (direction) {
+ int size;
+ 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++;
+ size = (cu->len * sizeof(wchar_t)) - (selstart * sizeof(wchar_t)) + (offset*sizeof(wchar_t));
+ memmove(ef->textbuf+selstart, ef->textbuf+getfrom, size);
+ memmove(ef->textbufinfo+selstart, ef->textbufinfo+getfrom, ((cu->len-selstart)+offset)*sizeof(CharInfo));
+ cu->len -= (selend-selstart)+offset;
+ cu->selstart = cu->selend = 0;
+ }
+ return(direction);
+}
+
+static void copyselection(Object *obedit)
+{
+ int selstart, selend;
+
+ if (BKE_font_getselection(obedit, &selstart, &selend)) {
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+
+ memcpy(ef->copybuf, ef->textbuf+selstart, ((selend-selstart)+1)*sizeof(wchar_t));
+ ef->copybuf[(selend-selstart)+1]=0;
+ memcpy(ef->copybufinfo, ef->textbufinfo+selstart, ((selend-selstart)+1)*sizeof(CharInfo));
+ }
+}
+
+static void pasteselection(Object *obedit)
+{
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+
+ int len= wcslen(ef->copybuf);
+
+ // Verify that the copy buffer => [copy buffer len] + cu->len < MAXTEXT
+ if(cu->len + len <= MAXTEXT)
+ {
+ if (len) {
+ int size = (cu->len * sizeof(wchar_t)) - (cu->pos*sizeof(wchar_t)) + sizeof(wchar_t);
+ memmove(ef->textbuf+cu->pos+len, ef->textbuf+cu->pos, size);
+ memcpy(ef->textbuf+cu->pos, ef->copybuf, len * sizeof(wchar_t));
+
+ memmove(ef->textbufinfo+cu->pos+len, ef->textbufinfo+cu->pos, (cu->len-cu->pos+1)*sizeof(CharInfo));
+ memcpy(ef->textbufinfo+cu->pos, ef->copybufinfo, len*sizeof(CharInfo));
+
+ cu->len += len;
+ cu->pos += len;
+ }
+ }
+ else
+ {
+ error("Text too long");
+ }
+}
+
+int style_to_sel(Object *obedit, int style, int toggle)
+{
+ int selstart, selend;
+ int i;
+
+ if (obedit && (obedit->type == OB_FONT)) {
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+
+ if (BKE_font_getselection(obedit, &selstart, &selend)) {
+ for (i=selstart; i<=selend; i++) {
+ if (toggle==0) {
+ ef->textbufinfo[i].flag &= ~style;
+ } else {
+ ef->textbufinfo[i].flag |= style;
+ }
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int mat_to_sel(Object *obedit)
+{
+ int selstart, selend;
+ int i;
+
+ if (obedit && (obedit->type == OB_FONT)) {
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+
+ if (BKE_font_getselection(obedit, &selstart, &selend)) {
+ for (i=selstart; i<=selend; i++) {
+ ef->textbufinfo[i].mat_nr = obedit->actcol;
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int do_textedit(bContext *C, wmOperator *op, wmEvent *evt)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+ static int accentcode= 0;
+ int x, doit=0, cursmove=0;
+ unsigned long ascii = evt->ascii;
+ int alt= evt->alt, shift= evt->shift, ctrl= evt->ctrl;
+ int event= evt->type, val= evt->val;
+ short kern;
+
+ /* tab should exit editmode, but we allow it to be typed using modifier keys */
+ if(event==TABKEY) {
+ if(alt==ctrl==shift==0)
+ return OPERATOR_PASS_THROUGH;
+ else
+ ascii= 9;
+ }
+ if(event==BACKSPACEKEY)
+ ascii= 0;
+
+ if(val && ascii) {
+
+ /* handle case like TAB (==9) */
+ if( (ascii > 31 && ascii < 254 && ascii != 127) || (ascii==13) || (ascii==10) || (ascii==8)) {
+
+ if(accentcode) {
+ if(cu->pos>0) ef->textbuf[cu->pos-1]= findaccent(ef->textbuf[cu->pos-1], ascii);
+ accentcode= 0;
+ }
+ else if(cu->len<MAXTEXT-1) {
+ if(alt ) {
+
+ /* might become obsolete, apple has default values for this, other OS's too? */
+
+ if(ascii=='t') ascii= 137;
+ else if(ascii=='c') ascii= 169;
+ else if(ascii=='f') ascii= 164;
+ else if(ascii=='g') ascii= 176;
+ else if(ascii=='l') ascii= 163;
+ else if(ascii=='r') ascii= 174;
+ else if(ascii=='s') ascii= 223;
+ else if(ascii=='v') ascii= 1001;
+ else if(ascii=='y') ascii= 165;
+ else if(ascii=='.') ascii= 138;
+ else if(ascii=='1') ascii= 185;
+ else if(ascii=='2') ascii= 178;
+ else if(ascii=='3') ascii= 179;
+ else if(ascii=='%') ascii= 139;
+ else if(ascii=='?') ascii= 191;
+ else if(ascii=='!') ascii= 161;
+ else if(ascii=='x') ascii= 215;
+ else if(ascii=='>') ascii= 187;
+ else if(ascii=='<') ascii= 171;
+ }
+ if(ascii==1001) {
+ int file, filelen;
+ char *strp;
+
+/* this should be solved by clipboard support */
+#ifdef __WIN32_DISABLED
+ file= open("C:\\windows\\temp\\cutbuf", O_BINARY|O_RDONLY);
+#else
+ file= open("/tmp/.cutbuffer", O_BINARY|O_RDONLY);
+#endif
+ if(file>0) {
+
+ filelen = BLI_filesize(file);
+
+ strp= MEM_mallocN(filelen+4, "tempstr");
+ read(file, strp, filelen);
+ close(file);
+ strp[filelen]= 0;
+
+ if(cu->len+filelen<MAXTEXT) {
+ int tmplen;
+ wchar_t *mem = MEM_callocN((sizeof(wchar_t)*filelen)+(4*sizeof(wchar_t)), "temporary");
+ tmplen = utf8towchar(mem, strp);
+ wcscat(ef->textbuf, mem);
+ MEM_freeN(mem);
+ cu->len += tmplen;
+ cu->pos= cu->len;
+ }
+ MEM_freeN(strp);
+ }
+ }
+ else {
+ insert_into_textbuf(obedit, ascii);
+ }
+ }
+
+ killselection(obedit, 1);
+
+ doit= 1;
+ }
+ else
+ {
+ insert_into_textbuf(obedit, ascii);
+ doit = 1;
+ }
+ }
+ else if(val) {
+ cursmove= 0;
+
+ switch(event) {
+ case ENDKEY:
+ if ((shift) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+ while(cu->pos<cu->len) {
+ if( ef->textbuf[cu->pos]==0) break;
+ if( ef->textbuf[cu->pos]=='\n') break;
+ if( ef->textbufinfo[cu->pos].flag & CU_WRAP ) break;
+ cu->pos++;
+ }
+ cursmove=FO_CURS;
+ break;
+
+ case HOMEKEY:
+ if ((shift) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+ while(cu->pos>0) {
+ if( ef->textbuf[cu->pos-1]=='\n') break;
+ if( ef->textbufinfo[cu->pos-1].flag & CU_WRAP ) break;
+ cu->pos--;
+ }
+ cursmove=FO_CURS;
+ break;
+
+ case RETKEY:
+ if(ctrl) {
+ insert_into_textbuf(obedit, 1);
+ if (ef->textbuf[cu->pos]!='\n') insert_into_textbuf(obedit, '\n');
+ }
+ else {
+ insert_into_textbuf(obedit, '\n');
+ }
+ cu->selstart = cu->selend = 0;
+ doit= 1;
+ break;
+
+ case RIGHTARROWKEY:
+ if ((shift) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+ if (ctrl) {
+ cu->pos= next_word(cu);
+ cursmove= FO_CURS;
+ }
+ else if (alt) {
+ kern = ef->textbufinfo[cu->pos-1].kern;
+ kern += 1;
+ if (kern>20) kern = 20;
+ ef->textbufinfo[cu->pos-1].kern = kern;
+ doit = 1;
+ }
+ else {
+ cu->pos++;
+ cursmove= FO_CURS;
+ }
+
+ break;
+
+ case LEFTARROWKEY:
+ if ((shift) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+ if (ctrl) {
+ cu->pos= prev_word(cu);
+ cursmove= FO_CURS;
+ }
+ else if (alt) {
+ kern = ef->textbufinfo[cu->pos-1].kern;
+ kern -= 1;
+ if (kern<-20) kern = -20;
+ ef->textbufinfo[cu->pos-1].kern = kern;
+ doit = 1;
+ }
+ else {
+ cu->pos--;
+ cursmove=FO_CURS;
+ }
+ break;
+
+ case UPARROWKEY:
+ if ((shift) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+ if(alt) {
+ if (cu->pos && ef->textbuf[cu->pos - 1] < 255) {
+ ef->textbuf[cu->pos - 1]++;
+ doit= 1;
+ }
+ }
+ else cursmove=FO_CURSUP;
+ break;
+
+ case PAGEUPKEY:
+ if ((shift) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+ cursmove=FO_PAGEUP;
+ break;
+
+ case DOWNARROWKEY:
+ if ((shift) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+ if(alt) {
+ if (cu->pos && ef->textbuf[cu->pos - 1] > 1) {
+ ef->textbuf[cu->pos - 1]--;
+ doit= 1;
+ }
+ }
+ else cursmove= FO_CURSDOWN;
+ break;
+
+ case PAGEDOWNKEY:
+ if ((shift) && (cu->selstart==0)) cu->selstart = cu->selend = cu->pos+1;
+ cursmove=FO_PAGEDOWN;
+ break;
+
+ case BACKSPACEKEY:
+ if(cu->len!=0) {
+ if(alt) {
+ if(cu->pos>0) accentcode= 1;
+ }
+ else if (ctrl) {
+ cu->len = cu->pos = 0;
+ ef->textbuf[0]= 0;
+ doit= 1;
+ }
+ else {
+ if (killselection(obedit, 0)==0) {
+ if (cu->pos>0) {
+ for(x=cu->pos;x<=cu->len;x++) ef->textbuf[x-1]= ef->textbuf[x];
+ for(x=cu->pos;x<=cu->len;x++) ef->textbufinfo[x-1]= ef->textbufinfo[x];
+ cu->pos--;
+ ef->textbuf[--cu->len]='\0';
+ doit=1;
+ }
+ } else doit=1;
+ }
+ }
+ break;
+
+ case DELKEY:
+ if(cu->len!=0) {
+ if (killselection(obedit, 0)==0) {
+ if(cu->pos<cu->len) {
+ for(x=cu->pos;x<cu->len;x++) ef->textbuf[x]= ef->textbuf[x+1];
+ for(x=cu->pos;x<cu->len;x++) ef->textbufinfo[x]= ef->textbufinfo[x+1];
+ ef->textbuf[--cu->len]='\0';
+ doit=1;
+ }
+ } else doit=1;
+ }
+ break;
+
+ case IKEY:
+ if (ctrl) {
+ cu->curinfo.flag ^= CU_ITALIC;
+ if (style_to_sel(obedit, CU_ITALIC, cu->curinfo.flag & CU_ITALIC)) doit= 1;
+ }
+ break;
+
+ case BKEY:
+ if (ctrl) {
+ cu->curinfo.flag ^= CU_BOLD;
+ if (style_to_sel(obedit, CU_BOLD, cu->curinfo.flag & CU_BOLD)) doit= 1;
+ }
+ break;
+
+ case UKEY:
+ if (ctrl) {
+ cu->curinfo.flag ^= CU_UNDERLINE;
+ if (style_to_sel(obedit, CU_UNDERLINE, cu->curinfo.flag & CU_UNDERLINE)) doit= 1;
+ }
+ break;
+
+ case XKEY:
+ if (ctrl) {
+ copyselection(obedit);
+ killselection(obedit, 0);
+ doit= 1;
+ }
+ break;
+
+ case CKEY:
+ if (ctrl) {
+ copyselection(obedit);
+ }
+ break;
+
+ case VKEY:
+ if (ctrl) {
+ pasteselection(obedit);
+ doit= 1;
+ }
+ break;
+ default:
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ if(cursmove) {
+ if ((shift)==0) {
+ if (cu->selstart) {
+ cu->selstart = cu->selend = 0;
+ update_string(cu);
+ BKE_text_to_curve(scene, obedit, FO_SELCHANGE);
+ }
+ }
+ 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 = ef->textbufinfo[cu->pos-1];
+ } else cu->curinfo = ef->textbufinfo[0];
+
+ if (obedit->totcol>0) {
+ obedit->actcol = ef->textbufinfo[cu->pos-1].mat_nr;
+ }
+ update_string(cu);
+ BKE_text_to_curve(scene, obedit, cursmove);
+ if (cursmove && (shift)) {
+ cu->selend = cu->pos;
+ DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ }
+ if(cursmove==0) {
+ DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ }
+
+ BIF_undo_push("Textedit");
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, NULL); // XXX better note
+
+ }
+ return OPERATOR_FINISHED;
+}
+
+static int font_editmode(bContext *C)
+{
+ Object *obedit= CTX_data_edit_object(C);
+ if(obedit && obedit->type==OB_FONT)
+ return 1;
+ return 0;
+}
+
+void FONT_OT_textedit(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name= "Edit Text";
+ ot->idname= "FONT_OT_textedit";
+
+ /* api callbacks */
+ ot->invoke= do_textedit;
+
+ ot->poll= font_editmode;
+}
+
+
+void paste_unicodeText(Scene *scene, char *filename)
+{
+ Object *obedit= scene->obedit; // XXX
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+ int filelen, doit= 0;
+ char *strp;
+ FILE *fp = NULL;
+
+ fp= fopen(filename, "r");
+
+ if(fp) {
+
+ fseek( fp, 0L, SEEK_END );
+ filelen = ftell( fp );
+ fseek( fp, 0L, SEEK_SET );
+
+ strp= MEM_mallocN(filelen+4, "tempstr");
+ //fread() instead of read(),
+ //because windows read() converts text to DOS \r\n linebreaks
+ //causing double linebreaks in the 3d text
+ filelen = fread(strp, 1, filelen, fp);
+ fclose(fp);
+ strp[filelen]= 0;
+
+
+ if(cu->len+filelen<MAXTEXT)
+ {
+ int tmplen;
+ wchar_t *mem = MEM_callocN((sizeof(wchar_t)*filelen)+(4*sizeof(wchar_t)), "temporary");
+ tmplen = utf8towchar(mem, strp);
+// mem =utf8s2wc(strp);
+ wcscat(ef->textbuf, mem);
+ MEM_freeN(mem);
+ cu->len += tmplen;
+ cu->pos= cu->len;
+ }
+ MEM_freeN(strp);
+ doit = 1;
+ }
+ if(doit) {
+ update_string(cu);
+ BKE_text_to_curve(scene, obedit, 0);
+ DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ BIF_undo_push("Paste text");
+ }
+}
+
+void paste_editText(Scene *scene)
+{
+ Object *obedit= scene->obedit; // XXX
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+ int filelen, doit= 0;
+ char *strp;
+ FILE *fp = NULL;
+
+#ifdef WIN32
+ fp= fopen("C:\\windows\\temp\\cutbuf.txt", "r");
+
+// The following is more likely to work on all Win32 installations.
+// suggested by Douglas Toltzman. Needs windows include files...
+/*
+ char tempFileName[MAX_PATH];
+ DWORD pathlen;
+ static const char cutbufname[]="cutbuf.txt";
+
+ if ((pathlen=GetTempPath(sizeof(tempFileName),tempFileName)) > 0 &&
+ pathlen + sizeof(cutbufname) <= sizeof(tempFileName))
+ {
+ strcat(tempFileName,cutbufname);
+ file= open(tempFileName, O_BINARY|O_RDONLY);
+ }
+*/
+#else
+ fp= fopen("/tmp/.cutbuffer", "r");
+#endif
+
+ if(fp) {
+
+ fseek(fp, 0L, SEEK_END);
+ filelen = ftell( fp );
+ fseek(fp, 0L, SEEK_SET);
+
+ strp= MEM_mallocN(filelen+4, "tempstr");
+ // fread() instead of read(),
+ // because windows read() converts text to DOS \r\n linebreaks
+ // causing double linebreaks in the 3d text
+ filelen = fread(strp, 1, filelen, fp);
+ fclose(fp);
+ strp[filelen]= 0;
+
+ if(cu->len+filelen<MAXTEXT) {
+ int tmplen;
+ wchar_t *mem = MEM_callocN((sizeof(wchar_t) * filelen) + (4 * sizeof(wchar_t)), "temporary");
+ tmplen = utf8towchar(mem, strp);
+ wcscat(ef->textbuf, mem);
+ MEM_freeN(mem);
+ cu->len += tmplen;
+ cu->pos= cu->len;
+ }
+ MEM_freeN(strp);
+ doit = 1;
+ }
+ if(doit) {
+ update_string(cu);
+ BKE_text_to_curve(scene, obedit, 0);
+ DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ BIF_undo_push("Paste text");
+ }
+}
+
+void make_editText(Object *obedit)
+{
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+
+ if(ef==NULL) {
+ ef= cu->editfont= MEM_callocN(sizeof(EditFont), "editfont");
+
+ ef->textbuf= MEM_callocN((MAXTEXT+4)*sizeof(wchar_t), "texteditbuf");
+ ef->textbufinfo= MEM_callocN((MAXTEXT+4)*sizeof(CharInfo), "texteditbufinfo");
+ ef->copybuf= MEM_callocN((MAXTEXT+4)*sizeof(wchar_t), "texteditcopybuf");
+ ef->copybufinfo= MEM_callocN((MAXTEXT+4)*sizeof(CharInfo), "texteditcopybufinfo");
+ ef->oldstr= MEM_callocN((MAXTEXT+4)*sizeof(wchar_t), "oldstrbuf");
+ ef->oldstrinfo= MEM_callocN((MAXTEXT+4)*sizeof(wchar_t), "oldstrbuf");
+ }
+
+ // Convert the original text to wchar_t
+ utf8towchar(ef->textbuf, cu->str);
+ wcscpy(ef->oldstr, ef->textbuf);
+
+ cu->len= wcslen(ef->textbuf);
+
+ memcpy(ef->textbufinfo, cu->strinfo, (cu->len)*sizeof(CharInfo));
+ memcpy(ef->oldstrinfo, cu->strinfo, (cu->len)*sizeof(CharInfo));
+
+ if(cu->pos>cu->len) cu->pos= cu->len;
+
+ if (cu->pos) {
+ cu->curinfo = ef->textbufinfo[cu->pos-1];
+ } else cu->curinfo = ef->textbufinfo[0];
+
+ // Convert to UTF-8
+ update_string(cu);
+
+ textediting= 1;
+ BIF_undo_push("Original");
+}
+
+
+void load_editText(Object *obedit)
+{
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+
+ MEM_freeN(ef->oldstr);
+ ef->oldstr= NULL;
+ MEM_freeN(ef->oldstrinfo);
+ ef->oldstrinfo= NULL;
+
+ update_string(cu);
+
+ if(cu->strinfo)
+ MEM_freeN(cu->strinfo);
+ cu->strinfo= MEM_callocN((cu->len+4)*sizeof(CharInfo), "texteditinfo");
+ memcpy(cu->strinfo, ef->textbufinfo, (cu->len)*sizeof(CharInfo));
+
+ cu->len= strlen(cu->str);
+
+ /* this memory system is weak... */
+
+ if (cu->selboxes) {
+ MEM_freeN(cu->selboxes);
+ cu->selboxes= NULL;
+ }
+
+ textediting= 0;
+
+}
+
+void remake_editText(Object *obedit)
+{
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+
+ if(okee("Reload original text")==0) return;
+
+ // Copy the oldstr to textbuf temporary global variable
+ wcscpy(ef->textbuf, ef->oldstr);
+ memcpy(ef->textbufinfo, ef->oldstrinfo, (cu->len)*sizeof(CharInfo));
+
+ // Set the object length and position
+ cu= obedit->data;
+ cu->len= wcslen(ef->textbuf);
+ if(cu->pos>cu->len) cu->pos= cu->len;
+
+ update_string(cu);
+
+ BIF_undo_push("Reload");
+}
+
+
+void free_editText(Object *obedit)
+{
+ BKE_free_editfont((Curve *)obedit->data);
+
+ textediting= 0;
+}
+
+
+void add_primitiveFont(int dummy_argument)
+{
+ Scene *scene= NULL; // XXX
+ Object *obedit= scene->obedit;
+ Curve *cu;
+
+ if (obedit && obedit->type==OB_FONT) return;
+// XXX check_editmode(OB_FONT);
+
+// XXX add_object_draw(OB_FONT);
+ ED_object_base_init_from_view(NULL, BASACT); // XXX
+
+ where_is_object(scene, BASACT->object);
+
+ 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;
+
+// if (U.flag & USER_ADD_EDITMODE)
+// enter_editmode(EM_WAITCURSOR);
+
+}
+
+void to_upper(Scene *scene)
+{
+ Object *obedit= scene->obedit; // XXX
+ Curve *cu= obedit->data;
+ EditFont *ef= cu->editfont;
+ int len, ok;
+ wchar_t *str;
+
+ if(obedit==0) {
+ return;
+ }
+
+ ok= 0;
+ cu= obedit->data;
+
+ len= wcslen(ef->textbuf);
+ str= ef->textbuf;
+ while(len) {
+ if( *str>=97 && *str<=122) {
+ ok= 1;
+ *str-= 32;
+ }
+ len--;
+ str++;
+ }
+
+ if(ok==0) {
+ len= wcslen(ef->textbuf);
+ str= ef->textbuf;
+ while(len) {
+ if( *str>=65 && *str<=90) {
+ *str+= 32;
+ }
+ len--;
+ str++;
+ }
+ }
+ DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ BIF_undo_push("To upper");
+
+ update_string(cu);
+}
+
+
+/* **************** undo for font object ************** */
+
+static void undoFont_to_editFont(void *strv, void *ecu)
+{
+ Curve *cu= (Curve *)ecu;
+ EditFont *ef= cu->editfont;
+ char *str= strv;
+
+ cu->pos= *((short *)str);
+ cu->len= *((short *)(str+2));
+
+ memcpy(ef->textbuf, str+4, (cu->len+1)*sizeof(wchar_t));
+ memcpy(ef->textbufinfo, str+4 + (cu->len+1)*sizeof(wchar_t), cu->len*sizeof(CharInfo));
+
+ cu->selstart = cu->selend = 0;
+
+ update_string(cu);
+
+}
+
+static void *editFont_to_undoFont(void *ecu)
+{
+ Curve *cu= (Curve *)ecu;
+ EditFont *ef= cu->editfont;
+ char *str;
+
+ // The undo buffer includes [MAXTEXT+6]=actual string and [MAXTEXT+4]*sizeof(CharInfo)=charinfo
+ str= MEM_callocN((MAXTEXT+6)*sizeof(wchar_t) + (MAXTEXT+4)*sizeof(CharInfo), "string undo");
+
+ // Copy the string and string information
+ memcpy(str+4, ef->textbuf, (cu->len+1)*sizeof(wchar_t));
+ memcpy(str+4 + (cu->len+1)*sizeof(wchar_t), ef->textbufinfo, cu->len*sizeof(CharInfo));
+
+ *((short *)str)= cu->pos;
+ *((short *)(str+2))= cu->len;
+
+ return str;
+}
+
+static void free_undoFont(void *strv)
+{
+ MEM_freeN(strv);
+}
+
+static void *get_undoFont(bContext *C)
+{
+ Object *obedit= CTX_data_edit_object(C);
+ if(obedit && obedit->type==OB_FONT) {
+ return obedit->data;
+ }
+ return NULL;
+}
+
+/* and this is all the undo system needs to know */
+void undo_push_font(bContext *C, char *name)
+{
+ undo_editmode_push(C, name, get_undoFont, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL);
+}
+
+
+
+/***/
diff --git a/source/blender/editors/curve/lorem.c b/source/blender/editors/curve/lorem.c
new file mode 100644
index 00000000000..e552f99d0e8
--- /dev/null
+++ b/source/blender/editors/curve/lorem.c
@@ -0,0 +1,513 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "curve_intern.h"
+
+char *ED_lorem =
+"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. "
+"Aliquam tristique interdum sem. "
+"Nullam pretium, tortor non euismod varius, nulla odio sodales nulla, at bibendum lorem metus sed nulla. "
+"Vestibulum in lectus at pede blandit viverra. "
+"Fusce scelerisque ipsum nec enim. "
+"Fusce euismod nunc id enim. "
+"In venenatis cursus arcu. "
+"Aenean quis dui. "
+"Maecenas laoreet. "
+"Nulla tempor, arcu pulvinar pretium suscipit, tortor wisi dapibus libero, id ornare felis ipsum suscipit purus. "
+"Maecenas ipsum. "
+"Morbi cursus. "
+"Vestibulum diam purus, commodo et, convallis eu, posuere at, ligula. "
+"Nulla aliquam aliquet lorem. "
+"Nunc et mauris hendrerit est bibendum suscipit. "
+"Donec pellentesque libero eu nisl. "
+"Pellentesque eget libero. "
+"Donec tempus ipsum sed quam. "
+"Sed blandit nunc quis enim. "
+"Quisque lectus diam, adipiscing hendrerit, placerat non, pulvinar id, felis. "
+"In congue magna sit amet urna. "
+"Nunc non augue sed nisl dictum laoreet. "
+"Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. "
+"In venenatis dapibus massa. "
+"Nulla hendrerit sapien et quam. "
+"Nunc ac magna lobortis tellus tincidunt posuere. "
+"Cras augue mauris, mattis lobortis, fermentum at, semper ac, tellus. "
+"Cras vitae ligula sit amet sem posuere iaculis. "
+"Aliquam condimentum eleifend felis. "
+"Ut sit amet sapien. "
+"Suspendisse potenti. "
+"Mauris urna. "
+"Ut eu enim eu ante porta vestibulum. "
+"Aenean scelerisque est ac felis. "
+"Suspendisse auctor. "
+"Nunc pellentesque. "
+"Morbi laoreet ante et nibh. "
+"Donec feugiat arcu eget enim. "
+"Morbi vehicula tortor ac ipsum. "
+"Quisque lacus arcu, elementum ac, faucibus vel, posuere id, est. "
+"Proin commodo gravida sem. "
+"Vivamus tincidunt vehicula libero. "
+"Phasellus wisi. "
+"Maecenas pretium tellus eu sapien. "
+"Nunc sit amet nunc. "
+"In hac habitasse platea dictumst. "
+"Aenean dictum neque sed tortor. "
+"Donec et erat. "
+"Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed justo turpis, scelerisque ut, mattis sit amet, ornare rutrum, massa. "
+"Vestibulum bibendum enim sit amet velit. "
+"Vivamus tellus ipsum, luctus ut, consectetuer vitae, dignissim non, ligula. "
+"Phasellus lacinia wisi at est. "
+"Donec elit wisi, commodo non, placerat in, convallis id, elit. "
+"Nunc dolor dolor, vestibulum id, bibendum vitae, lacinia id, erat. "
+"Cras sit amet eros. "
+"Suspendisse suscipit lobortis lectus. "
+"Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. "
+"Cras orci. "
+"Praesent massa urna, lobortis semper, auctor a, pretium vitae, tellus. "
+"Curabitur at purus. "
+"Morbi tortor quam, imperdiet venenatis, egestas a, cursus eu, est. "
+"Nunc interdum lectus sit amet libero. "
+"Quisque dignissim placerat ligula. "
+"Nunc porttitor posuere arcu. "
+"Mauris faucibus quam at massa. "
+"Vivamus sodales aliquet mauris. "
+"In id ante. "
+"Pellentesque varius ipsum in arcu. "
+"Fusce mauris lacus, tristique ac, lobortis quis, lobortis luctus, pede. "
+"Sed wisi. "
+"Vestibulum mattis. "
+"Maecenas hendrerit sem nec purus. "
+"Proin id quam. "
+"Cras nec mauris. "
+"Integer orci. "
+"Nullam dui sem, molestie sed, egestas quis, cursus in, magna. "
+"Mauris neque lacus, consectetuer nec, sagittis eu, porttitor eget, dui. "
+"Fusce consectetuer. "
+"Donec nec tellus quis leo lobortis ullamcorper. "
+"Etiam metus urna, aliquet pretium, ultrices eu, cursus ut, turpis. "
+"Morbi bibendum vehicula lectus. "
+"Sed non ante vitae arcu pellentesque tempor. "
+"Fusce sed ligula in sem tempor imperdiet. "
+"Aliquam vel est. "
+"Phasellus sollicitudin sollicitudin nibh. "
+"Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. "
+"Sed vel leo nec eros blandit imperdiet. "
+"Nulla facilisi. "
+"Suspendisse lobortis, dui ut fringilla hendrerit, justo purus ullamcorper ligula, ultricies ultrices dolor enim in libero. "
+"Sed elementum, pede eget porta convallis, dui nulla dignissim pede, eget vehicula odio ante at sem. "
+"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "
+"Sed ullamcorper tincidunt ipsum. "
+"Fusce risus nibh, accumsan sit amet, tempus eget, tristique ac, neque. "
+"Sed quis lorem ut tortor facilisis fermentum. "
+"Fusce pulvinar quam sit amet ipsum. "
+"Morbi ac elit quis tellus malesuada blandit. "
+"Maecenas suscipit sollicitudin sem. "
+"Nam sed eros vel lacus lobortis congue. "
+"Proin interdum nunc lobortis orci. "
+"Donec egestas enim eu odio. "
+"Vestibulum id metus. "
+"Pellentesque auctor, sem varius luctus tempus, libero magna cursus neque, et porttitor diam diam quis purus. "
+"Vestibulum sit amet dolor. "
+"Nulla in magna. "
+"Cras id diam at lectus faucibus placerat. "
+"Nunc porta posuere sapien. "
+"Etiam scelerisque. "
+"Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. "
+"Aliquam pellentesque mi sed tortor. "
+"Maecenas eleifend diam non urna. "
+"Donec luctus pharetra tellus. "
+"Proin ac ipsum eget libero bibendum volutpat. "
+"Cras id tellus. "
+"Nulla non risus. "
+"In dolor. "
+"Fusce scelerisque quam in massa ultrices porta. "
+"Morbi ut dolor eu massa egestas condimentum. "
+"Mauris vulputate. "
+"In hac habitasse platea dictumst. "
+"Suspendisse potenti. "
+"Mauris vehicula leo in tortor. "
+"Mauris vel erat a urna laoreet semper. "
+"Pellentesque ut metus ac tellus commodo eleifend. "
+"Suspendisse quis urna. "
+"Curabitur lacinia dignissim dui. "
+"Nam nec ante. "
+"In id enim. "
+"Aenean mattis enim. "
+"In ut neque porttitor risus hendrerit tincidunt. "
+"Suspendisse potenti. "
+"Ut vestibulum lectus vitae tortor. "
+"Duis velit. "
+"Nulla facilisi. "
+"Integer sit amet urna. "
+"Cras varius tortor in pede. "
+"Sed facilisis. "
+"Praesent lacinia libero nec nibh. "
+"Donec aliquam risus non nisl. "
+"Nam a nunc et felis tempor feugiat. "
+"Nunc metus. "
+"Vestibulum euismod, metus in semper laoreet, urna ipsum pharetra lorem, sed ultricies magna lorem sit amet wisi. "
+"Sed wisi. "
+"Nullam facilisis elit sed nisl. "
+"Phasellus mattis leo nec massa. "
+"Aenean malesuada. "
+"Cras wisi erat, lobortis nec, cursus eget, lobortis at, libero. "
+"In massa nisl, rutrum non, cursus nec, faucibus sed, lacus. "
+"Pellentesque malesuada. "
+"Cras euismod, neque ac suscipit tempus, velit lorem luctus elit, dapibus rhoncus wisi est ut sem. "
+"Proin vulputate enim in eros elementum accumsan. "
+"Ut lorem nisl, hendrerit et, interdum nec, lacinia in, dolor. "
+"Duis nec quam. "
+"Praesent velit felis, posuere id, luctus quis, laoreet ut, ipsum. "
+"Praesent eget arcu. "
+"Mauris massa felis, ornare non, ultrices id, tristique in, elit. "
+"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "
+"Phasellus vulputate, mi ac bibendum facilisis, libero enim suscipit leo, non nonummy pede diam eget nibh. "
+"Sed tempus. "
+"Aenean interdum suscipit dui. "
+"Aliquam erat volutpat. "
+"Ut malesuada. "
+"Nam commodo, nulla ut fringilla rutrum, orci elit viverra diam, vitae mollis odio odio et purus. "
+"Aliquam erat volutpat. "
+"Sed aliquet lobortis ipsum. "
+"In ut est. "
+"Etiam condimentum. "
+"Vestibulum pellentesque tortor pulvinar lacus. "
+"Aenean orci. "
+"Suspendisse lacus nulla, nonummy a, dictum vitae, egestas quis, eros. "
+"Donec auctor gravida nisl. "
+"Cras ac est rutrum augue pulvinar ornare. "
+"Phasellus mauris nibh, vulputate in, rhoncus imperdiet, dapibus eget, lacus. "
+"Nam nunc mauris, suscipit at, ultricies a, facilisis at, tellus. "
+"Nam accumsan mollis libero. "
+"Vivamus condimentum mattis est. "
+"Donec lacus. "
+"Nullam ac sapien id massa lobortis molestie. "
+"Pellentesque elementum. "
+"Proin ut purus. "
+"Integer et sapien quis turpis commodo mollis. "
+"Nulla consequat. "
+"Proin a wisi ut tellus blandit elementum. "
+"Aliquam nulla lorem, bibendum ac, malesuada vel, elementum et, metus. "
+"Phasellus egestas nibh et ligula. "
+"Vivamus diam odio, lacinia quis, malesuada quis, sollicitudin ut, eros. "
+"Phasellus aliquet lorem ac ipsum. "
+"Sed cursus tellus ac orci. "
+"Phasellus at nulla. "
+"Donec porta sodales ante. "
+"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "
+"Sed id lectus at massa ullamcorper tristique. "
+"Suspendisse porttitor lacus. "
+"In hac habitasse platea dictumst. "
+"Nunc non turpis. "
+"Sed sagittis. "
+"Morbi laoreet scelerisque dui. "
+"Nam arcu tellus, tempor vitae, vestibulum et, imperdiet ut, velit. "
+"In sit amet augue a arcu volutpat suscipit. "
+"Donec dictum ultrices lectus. "
+"Phasellus a purus et orci dictum lacinia. "
+"Ut leo. "
+"Cras semper, lorem sit amet tincidunt congue, justo eros varius pede, in bibendum turpis lectus non eros. "
+"Phasellus quam. "
+"Suspendisse mattis sollicitudin magna. "
+"Aenean facilisis diam vel nisl nonummy condimentum. "
+"Suspendisse vel dolor. "
+"Vestibulum nonummy. "
+"Mauris imperdiet semper ante. "
+"Maecenas vulputate eros. "
+"Vestibulum ac dolor. "
+"Fusce risus metus, aliquet eget, facilisis et, feugiat vel, orci. "
+"Ut at nunc id ante sodales vulputate. "
+"Duis tristique mattis ante. "
+"Vestibulum neque mauris, laoreet id, congue interdum, aliquet ut, diam. "
+"Nulla volutpat blandit magna. "
+"Donec accumsan congue diam. "
+"Etiam vel dui eget nisl tempor varius. "
+"Cras dictum massa sed enim. "
+"Cras urna tortor, fringilla ac, ullamcorper in, euismod vel, arcu. "
+"Morbi posuere luctus augue. "
+"Aliquam dui dui, adipiscing in, lobortis eu, luctus eu, nulla. "
+"Cras velit pede, ullamcorper sit amet, feugiat in, auctor vitae, ante. "
+"Suspendisse dictum fringilla mauris. "
+"In a nibh. "
+"Donec ac ligula. "
+"In quam. "
+"Praesent vitae urna ultricies sem aliquam placerat. "
+"Aliquam erat volutpat. "
+"Nam est. "
+"Donec faucibus sodales metus. "
+"Ut congue. "
+"Donec arcu tellus, pharetra ac, vulputate ac, mollis sed, lectus. "
+"Nulla facilisi. "
+"Nullam volutpat nunc et felis. "
+"Sed pede odio, tincidunt in, volutpat malesuada, feugiat gravida, nulla. "
+"Nulla aliquam pede vitae arcu. "
+"Proin velit elit, nonummy sit amet, elementum vitae, varius vitae, dolor. "
+"Donec rutrum ipsum eu mi. "
+"Aliquam et sem. "
+"In adipiscing rhoncus velit. "
+"Nam viverra scelerisque arcu. "
+"Aliquam sem. "
+"Sed tincidunt nulla quis massa. "
+"Mauris faucibus tempus nunc. "
+"Phasellus condimentum. "
+"Curabitur aliquet iaculis sapien. "
+"Nunc rhoncus, odio vitae bibendum dignissim, tellus libero commodo ipsum, ut sollicitudin nisl nisl vel justo. "
+"Nulla facilisi. "
+"Praesent blandit enim ut justo. "
+"Proin elementum, elit eget accumsan pulvinar, orci quam auctor neque, sed convallis diam purus vel felis. "
+"Sed orci leo, eleifend vel, blandit non, semper eu, purus. "
+"Proin bibendum, libero ac consectetuer commodo, eros sapien blandit nisl, eu eleifend nibh nibh vel lectus. "
+"Vivamus placerat. "
+"Integer odio dolor, pharetra non, sodales id, viverra eget, diam. "
+"Nunc mauris magna, egestas quis, feugiat id, fermentum viverra, mi. "
+"Aenean suscipit nisl non nunc. "
+"Proin quis lectus ac tellus nonummy commodo. "
+"Nunc eget diam ac elit vestibulum auctor. "
+"Etiam vulputate, odio sed lacinia consequat, justo mi vulputate purus, sit amet euismod libero metus sed tortor. "
+"Maecenas ac elit sed lorem vulputate gravida. "
+"Proin lectus eros, ullamcorper id, volutpat quis, condimentum tincidunt, sapien. "
+"Sed et massa eget lorem aliquet tempus. "
+"Duis porttitor nisl non risus. "
+"Nam id quam. "
+"Nullam est. "
+"Proin orci diam, posuere et, pharetra commodo, dictum vel, enim. "
+"Proin eget erat. "
+"Donec nisl. "
+"Maecenas auctor velit ut pede. "
+"Nunc vitae lectus nec libero tincidunt hendrerit. "
+"Quisque varius, erat ultrices ultrices euismod, purus lacus dictum eros, at condimentum enim dui nec magna. "
+"Morbi diam. "
+"Phasellus sed est. "
+"Phasellus nec libero in arcu fringilla sollicitudin. "
+"In rutrum nisl at arcu. "
+"Nulla facilisi. "
+"Mauris dignissim. "
+"Etiam est mauris, pharetra sed, viverra et, tincidunt sed, neque. "
+"Ut at lectus id nibh luctus ornare. "
+"Mauris varius porttitor risus. "
+"Ut vulputate aliquet risus. "
+"Vestibulum luctus neque sit amet nunc. "
+"Duis fermentum nibh. "
+"Pellentesque dapibus. "
+"Proin eros libero, aliquam non, condimentum a, sodales ut, turpis. "
+"Integer accumsan mi sed lorem. "
+"Vestibulum pellentesque sodales nisl. "
+"Nulla eu justo quis dui pretium rhoncus. "
+"Praesent viverra commodo mi. "
+"Maecenas dolor libero, viverra a, elementum vitae, aliquet vitae, dui. "
+"Mauris convallis lectus et mi. "
+"Mauris sagittis. "
+"Sed arcu. "
+"Pellentesque auctor. "
+"Donec pellentesque purus non tellus. "
+"Ut leo wisi, ultrices sit amet, ultrices eu, gravida ac, libero. "
+"Mauris fermentum dapibus diam. "
+"Integer quis lacus dapibus odio pellentesque varius. "
+"Fusce pede quam, vehicula ut, pulvinar et, tincidunt sed, felis. "
+"Curabitur eros enim, vulputate sed, aliquam ac, euismod ac, erat. "
+"Ut dignissim, lacus a interdum iaculis, enim orci posuere nunc, nec ultricies lectus risus in odio. "
+"Etiam et massa id dui commodo vehicula. "
+"Nunc blandit tortor quis dui. "
+"Quisque nisl. "
+"Sed venenatis blandit ligula. "
+"Fusce viverra imperdiet magna. "
+"Donec eget nunc quis est pharetra lobortis. "
+"Vestibulum quis lectus. "
+"Mauris vel orci lobortis nunc fermentum bibendum. "
+"Pellentesque eget leo. "
+"Morbi vel urna sit amet erat fermentum facilisis. "
+"Sed vulputate, libero et sollicitudin congue, wisi lectus sodales dolor, eget molestie magna orci vel tellus. "
+"Sed tempor ante et enim. "
+"Mauris elit. "
+"Curabitur ullamcorper vehicula massa. "
+"Sed viverra. "
+"Duis nulla. "
+"Nam bibendum. "
+"Nam tortor lorem, ullamcorper vitae, dictum sed, posuere eu, justo. "
+"Aliquam adipiscing arcu vitae turpis. "
+"Donec malesuada posuere libero. "
+"Ut sed tellus. "
+"Fusce sed nunc eget nisl dapibus malesuada. "
+"Suspendisse potenti. "
+"Integer tristique libero et metus. "
+"Vivamus posuere. "
+"Maecenas non sem non quam fermentum blandit. "
+"Duis risus tellus, rutrum vitae, imperdiet nec, malesuada nec, ipsum. "
+"Nunc quam dolor, luctus eget, placerat non, rhoncus at, tellus. "
+"Duis pede lectus, mattis adipiscing, tempor ut, porta at, mi. "
+"Pellentesque risus nulla, sodales sed, interdum id, nonummy vitae, ligula. "
+"Morbi pulvinar pede ut massa. "
+"Nunc risus mauris, tincidunt et, faucibus eu, suscipit vel, orci. "
+"In faucibus felis in arcu. "
+"Nulla sit amet elit. "
+"Nulla erat sapien, sagittis eget, dignissim eget, viverra eu, felis. "
+"Nam ac ipsum. "
+"Suspendisse vulputate turpis vel sem lacinia ullamcorper. "
+"Mauris ornare ipsum sed ligula. "
+"Duis facilisis neque quis orci. "
+"Nullam et erat et orci lacinia pellentesque. "
+"Donec ac ipsum. "
+"Duis molestie ipsum ac arcu. "
+"Aenean congue accumsan ante. "
+"Integer bibendum, leo ut ornare aliquam, nunc erat condimentum arcu, ut pulvinar mi augue et nulla. "
+"Quisque lacinia aliquet wisi. "
+"Vivamus nec dui. "
+"Etiam wisi leo, euismod vitae, vulputate a, dictum vitae, quam. "
+"Quisque quis tortor. "
+"Etiam interdum. "
+"In massa erat, porttitor sed, tincidunt vel, vehicula fringilla, augue. "
+"Nulla vel urna. "
+"In libero mi, pretium sed, mattis tempus, sagittis sed, massa. "
+"Suspendisse quam wisi, fermentum quis, sagittis at, consequat eget, odio. "
+"Nullam imperdiet, purus quis aliquam cursus, turpis odio egestas justo, placerat gravida turpis wisi vel tortor. "
+"Nunc ultricies porta purus. "
+"Proin elementum erat ac orci. "
+"Ut vel magna nec mi feugiat tincidunt. "
+"Ut ligula. "
+"Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec et magna in diam porta nonummy. "
+"Maecenas ut sem in turpis fermentum viverra. "
+"Suspendisse at orci. "
+"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "
+"Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque rutrum eleifend justo. "
+"Nullam vitae pede. "
+"Donec condimentum nibh et odio. "
+"Sed et metus. "
+"Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. "
+"Nam tempus. "
+"Sed ac wisi. "
+"In hac habitasse platea dictumst. "
+"Sed sed wisi. "
+"Ut facilisis tellus non ligula. "
+"Integer metus. "
+"In lacinia dui. "
+"Curabitur ornare. "
+"Mauris vel urna. "
+"Nam consectetuer dignissim urna. "
+"Nunc elementum porttitor erat. "
+"Sed blandit, risus non commodo nonummy, ligula erat fermentum nibh, eu facilisis ante neque sed sem. "
+"Etiam scelerisque justo eget wisi. "
+"Nunc dignissim. "
+"Proin pulvinar quam non lectus. "
+"Proin ut turpis quis augue pellentesque dictum. "
+"Fusce et lorem. "
+"Aliquam urna lacus, blandit sed, vestibulum sit amet, placerat et, dolor. "
+"Curabitur auctor erat nec lorem. "
+"Phasellus urna wisi, lacinia ut, molestie tincidunt, condimentum id, odio. "
+"Curabitur convallis ullamcorper justo. "
+"Donec vestibulum est ac quam. "
+"Nullam vitae elit eu massa varius vulputate. "
+"Nulla facilisi. "
+"Suspendisse potenti. "
+"Praesent non libero. "
+"Nullam tristique massa id magna viverra commodo. "
+"Vestibulum libero tortor, luctus ac, viverra congue, consectetuer vel, libero. "
+"Aenean arcu augue, luctus id, laoreet pulvinar, dictum sed, lectus. "
+"Donec vestibulum volutpat dolor. "
+"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. "
+"Pellentesque augue turpis, laoreet nec, malesuada at, nonummy vitae, nibh. "
+"Etiam orci sapien, congue in, porttitor sit amet, rutrum vel, nibh. "
+"Integer eu lorem. "
+"Mauris pretium leo et elit. "
+"In nonummy ultricies sapien. "
+"Mauris varius. "
+"Mauris sed libero. "
+"Curabitur ullamcorper elit eu purus. "
+"Vestibulum velit pede, semper sit amet, lobortis vitae, tincidunt vel, dui. "
+"Nulla neque ante, sagittis eu, vestibulum et, lacinia a, libero. "
+"Morbi sit amet wisi. "
+"Pellentesque non felis quis arcu bibendum ornare. "
+"Aenean enim metus, commodo eu, hendrerit nonummy, euismod ut, quam. "
+"Nulla eleifend nisl quis dolor. "
+"Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. "
+"Maecenas pellentesque massa in erat molestie molestie. "
+"Mauris dignissim dapibus libero. "
+"Sed sed risus id neque dictum ornare. "
+"Sed eu ligula at felis sodales accumsan. "
+"Sed interdum, urna non pharetra hendrerit, quam mi ornare libero, id fringilla tortor orci non velit. "
+"Aliquam nec risus. "
+"Donec at nunc vitae tellus molestie vestibulum. "
+"Pellentesque vel justo. "
+"Duis ligula libero, vulputate quis, adipiscing bibendum, feugiat vitae, velit. "
+"Vivamus et arcu. "
+"Fusce eget quam. "
+"Ut ante. "
+"Suspendisse feugiat metus non ipsum. "
+"Nulla tempus leo ut mi. "
+"Curabitur vitae nisl. "
+"Vivamus elementum. "
+"Etiam a orci. "
+"Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus urna quam, tincidunt at, ultrices vel, feugiat eget, nulla. "
+"Maecenas lacus magna, nonummy eu, iaculis sed, consectetuer quis, enim. "
+"Praesent a eros. "
+"Aliquam nonummy dignissim neque. "
+"Nulla enim. "
+"Praesent molestie, orci quis tristique volutpat, lacus metus luctus sapien, et facilisis eros neque id sapien. "
+"Nunc condimentum dolor vel orci. "
+"Integer wisi diam, porttitor sit amet, feugiat in, dapibus in, lectus. "
+"Aliquam erat volutpat. "
+"Quisque mollis turpis vitae tortor. "
+"Mauris turpis mi, pretium ut, ultrices sed, porta in, justo. "
+"Suspendisse posuere. "
+"Quisque ultricies lacus vitae enim. "
+"Donec lacus. "
+"Suspendisse potenti. "
+"Donec molestie, magna sed euismod dictum, magna magna interdum diam, vitae sagittis leo lorem ac neque. "
+"Cras metus. "
+"Quisque nunc. "
+"Duis consectetuer. "
+"Vestibulum gravida sollicitudin urna. "
+"Integer volutpat, massa quis ultrices pulvinar, eros purus dignissim nunc, eget rhoncus enim lectus quis tortor. "
+"Integer lacinia quam quis erat convallis mattis. "
+"Suspendisse iaculis posuere velit. "
+"Etiam tellus enim, aliquet nec, laoreet a, molestie non, velit. "
+"Quisque lacus velit, eleifend imperdiet, fringilla id, dapibus scelerisque, lectus. "
+"Nulla quis lorem. "
+"Nulla malesuada neque et dui. "
+"Phasellus malesuada ultricies odio. "
+"Phasellus vitae ligula. "
+"Pellentesque feugiat arcu at erat. "
+"Vivamus ut eros ut lorem pulvinar iaculis. "
+"Proin lobortis ipsum id nunc. "
+"Curabitur vel massa. "
+"Suspendisse nulla ipsum, malesuada vel, posuere eget, mollis at, risus. "
+"Vestibulum sed diam id est dapibus ultrices. "
+"Proin tempus, eros a scelerisque vestibulum, ipsum arcu aliquam mi, ut feugiat libero odio in nisl. "
+"Quisque et massa a mauris luctus congue. "
+"Ut id eros. "
+"Fusce ante eros, pharetra non, molestie tristique, bibendum sit amet, wisi. "
+"Phasellus rutrum, dolor et semper elementum, eros ante malesuada massa, sed sollicitudin lectus velit et massa. "
+"In auctor. "
+"Aliquam erat volutpat. "
+"Etiam risus leo, vulputate suscipit, sollicitudin et, sodales eget, nisl. "
+"Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lobortis, libero ac laoreet mollis, ligula leo porta wisi, ut euismod felis ligula id elit. "
+"Vivamus malesuada nulla eu enim. "
+"Donec accumsan faucibus orci. "
+"Nulla lacinia ante. "
+"Praesent at nibh. "
+"Mauris porta dignissim wisi. "
+"Ut lacinia tortor nec nunc. "
+"Phasellus et augue. "
+"Integer rhoncus, libero a pellentesque rhoncus, tortor sapien lobortis pede, eget condimentum sapien risus vitae elit. "
+"Suspendisse sed turpis ut dolor placerat dignissim. "
+"Quisque quis leo. "
+"Cras ultrices. "
+"Maecenas hendrerit auctor tortor. "
+"Etiam sit amet arcu. ";
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index 0a53dc86c2f..b725ad46124 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -35,6 +35,10 @@ struct bContext;
struct Base;
struct View3D;
+/* curve_ops.c */
+void ED_operatortypes_curve(void);
+void ED_keymap_curve(struct wmWindowManager *wm);
+
/* editcurve.c */
void undo_push_curve (struct bContext *C, char *name);
ListBase *curve_get_editcurve(struct Object *ob);
@@ -46,6 +50,11 @@ void free_editNurb (struct Object *obedit);
void mouse_nurb(struct bContext *C, short mval[2], int extend);
+/* editfont.h */
+void make_editText (struct Object *obedit);
+void load_editText (struct Object *obedit);
+void remake_editText (struct Object *obedit);
+void free_editText (struct Object *obedit);
#endif /* ED_CURVE_H */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 1f5f83c852b..5c3e0272677 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -115,6 +115,7 @@ int ED_operator_uvedit(struct bContext *C);
#define ED_KEYMAP_VIEW2D 2
#define ED_KEYMAP_MARKERS 4
#define ED_KEYMAP_ANIMATION 8
+#define ED_KEYMAP_FRAMES 16
#endif /* ED_SCREEN_H */
diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c
index bc5b8a5853d..adb45db40f2 100644
--- a/source/blender/editors/mesh/editmesh.c
+++ b/source/blender/editors/mesh/editmesh.c
@@ -2073,7 +2073,7 @@ static void undoMesh_to_editMesh(void *umv, void *emv)
static void *getEditMesh(bContext *C)
{
Object *obedit= CTX_data_edit_object(C);
- if(obedit) {
+ if(obedit && obedit->type==OB_MESH) {
Mesh *me= obedit->data;
return me->edit_mesh;
}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 5803a80d12b..69655a202af 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -2816,8 +2816,8 @@ void OBJECT_OT_set_center(wmOperatorType *ot)
void ED_object_exit_editmode(bContext *C, int flag)
{
Scene *scene= CTX_data_scene(C);
- Object *ob;
Object *obedit= CTX_data_edit_object(C);
+ Object *ob;
int freedata = flag & EM_FREEDATA;
if(obedit==NULL) return;
@@ -2852,7 +2852,8 @@ void ED_object_exit_editmode(bContext *C, int flag)
if(freedata) free_editNurb(obedit);
}
else if(obedit->type==OB_FONT && freedata) {
-// load_editText();
+ load_editText(obedit);
+ if(freedata) free_editText(obedit);
}
else if(obedit->type==OB_LATTICE) {
load_editLatt(obedit);
@@ -2945,8 +2946,8 @@ void ED_object_enter_editmode(bContext *C, int flag)
}
else if(ob->type==OB_FONT) {
scene->obedit= ob; // XXX for context
-// ok= 1;
-// XXX make_editText();
+ ok= 1;
+ make_editText(ob);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_TEXT, scene);
}
else if(ob->type==OB_MBALL) {
@@ -4348,7 +4349,7 @@ void copy_attr(Scene *scene, View3D *v3d, short event)
cu1->vfontbi= cu->vfontbi;
id_us_plus((ID *)cu1->vfontbi);
- text_to_curve(scene, base->object, 0); /* needed? */
+ BKE_text_to_curve(scene, base->object, 0); /* needed? */
strcpy(cu1->family, cu->family);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 3f1d82b1936..d104efef73d 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -556,6 +556,10 @@ static void ed_default_handlers(wmWindowManager *wm, ListBase *handlers, int fla
ListBase *keymap= WM_keymap_listbase(wm, "Animation", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
+ if(flag & ED_KEYMAP_FRAMES) {
+ ListBase *keymap= WM_keymap_listbase(wm, "Frames", 0, 0);
+ WM_event_add_keymap_handler(handlers, keymap);
+ }
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 98012119c50..60768d10e9d 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -1700,6 +1700,9 @@ void ED_keymap_screen(wmWindowManager *wm)
{
ListBase *keymap= WM_keymap_listbase(wm, "Screen", 0, 0);
+ /* standard timers */
+ WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", TIMER0, KM_ANY, KM_ANY, 0);
+
WM_keymap_verify_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_area_move", LEFTMOUSE, KM_PRESS, 0, 0);
@@ -1716,13 +1719,6 @@ void ED_keymap_screen(wmWindowManager *wm)
WM_keymap_add_item(keymap, "SCREEN_OT_region_split", SKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_region_foursplit", SKEY, KM_PRESS, KM_CTRL|KM_ALT|KM_SHIFT, 0);
- /*frame offsets*/
- WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", TIMER0, KM_ANY, KM_ANY, 0);
- RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 10);
- RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", -10);
- RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", -1);
- RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
-
WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", F3KEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_last", F4KEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_region_flip", F5KEY, KM_PRESS, 0, 0);
@@ -1736,5 +1732,13 @@ void ED_keymap_screen(wmWindowManager *wm)
/* screen level global keymaps */
// err...
ED_marker_keymap(wm);
+
+ /* frame offsets */
+ keymap= WM_keymap_listbase(wm, "Frames", 0, 0);
+ RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 10);
+ RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", -10);
+ RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", -1);
+ RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
+
}
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 5c7519774bf..72053c01e12 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -404,7 +404,7 @@ void ED_spacetype_action(void)
art->init= action_main_area_init;
art->draw= action_main_area_draw;
art->listener= action_main_area_listener;
- art->keymapflag= ED_KEYMAP_VIEW2D/*|ED_KEYMAP_MARKERS*/|ED_KEYMAP_ANIMATION;
+ art->keymapflag= ED_KEYMAP_VIEW2D/*|ED_KEYMAP_MARKERS*/|ED_KEYMAP_ANIMATION|ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
@@ -412,7 +412,7 @@ void ED_spacetype_action(void)
art= MEM_callocN(sizeof(ARegionType), "spacetype action region");
art->regionid = RGN_TYPE_HEADER;
art->minsizey= HEADERY;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
art->init= action_header_area_init;
art->draw= action_header_area_draw;
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index b7fc3b3a5f8..829c530481f 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -40,6 +40,7 @@
#include "BIF_gl.h"
#include "ED_anim_api.h"
+#include "ED_curve.h"
#include "ED_mesh.h"
#include "ED_object.h"
#include "ED_sculpt.h"
@@ -79,6 +80,7 @@ void ED_spacetypes_init(void)
ED_operatortypes_mesh();
ED_operatortypes_sculpt();
ED_operatortypes_uvedit();
+ ED_operatortypes_curve();
ui_view2d_operatortypes();
spacetypes = BKE_spacetypes_list();
@@ -101,6 +103,7 @@ void ED_spacetypes_keymap(wmWindowManager *wm)
ED_keymap_object(wm);
ED_keymap_mesh(wm);
ED_keymap_uvedit(wm);
+ ED_keymap_curve(wm);
UI_view2d_keymap(wm);
spacetypes = BKE_spacetypes_list();
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 1b6e134ca96..f2134af7424 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -266,7 +266,7 @@ void ED_spacetype_buttons(void)
art->init= buttons_main_area_init;
art->draw= buttons_main_area_draw;
art->listener= buttons_area_listener;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
@@ -274,7 +274,7 @@ void ED_spacetype_buttons(void)
art= MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
art->regionid = RGN_TYPE_HEADER;
art->minsizey= HEADERY;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
art->init= buttons_header_area_init;
art->draw= buttons_header_area_draw;
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index feeb09e0f00..b21c9aaab2a 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -439,6 +439,7 @@ void ED_spacetype_image(void)
/* regions: main window */
art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
art->regionid = RGN_TYPE_WINDOW;
+ art->keymapflag= ED_KEYMAP_FRAMES;
art->init= image_main_area_init;
art->draw= image_main_area_draw;
art->listener= image_main_area_listener;
@@ -450,7 +451,7 @@ void ED_spacetype_image(void)
art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
art->regionid = RGN_TYPE_HEADER;
art->minsizey= HEADERY;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
art->init= image_header_area_init;
art->draw= image_header_area_draw;
diff --git a/source/blender/editors/space_ipo/space_ipo.c b/source/blender/editors/space_ipo/space_ipo.c
index 1c7dadcb296..38d0468bc37 100644
--- a/source/blender/editors/space_ipo/space_ipo.c
+++ b/source/blender/editors/space_ipo/space_ipo.c
@@ -317,7 +317,7 @@ void ED_spacetype_ipo(void)
art= MEM_callocN(sizeof(ARegionType), "spacetype ipo region");
art->regionid = RGN_TYPE_HEADER;
art->minsizey= HEADERY;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
art->init= ipo_header_area_init;
art->draw= ipo_header_area_draw;
@@ -328,7 +328,7 @@ void ED_spacetype_ipo(void)
art= MEM_callocN(sizeof(ARegionType), "spacetype ipo region");
art->regionid = RGN_TYPE_CHANNELS;
art->minsizex= 200;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
art->init= ipo_channel_area_init;
art->draw= ipo_channel_area_draw;
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index 1be1908b681..6e1a97dea34 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -265,7 +265,7 @@ void ED_spacetype_nla(void)
art->init= nla_main_area_init;
art->draw= nla_main_area_draw;
art->listener= nla_main_area_listener;
- art->keymapflag= ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 16ac87fc899..f50a3640385 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -313,7 +313,7 @@ void ED_spacetype_node(void)
art= MEM_callocN(sizeof(ARegionType), "spacetype node region");
art->regionid = RGN_TYPE_HEADER;
art->minsizey= HEADERY;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
art->init= node_header_area_init;
art->draw= node_header_area_draw;
@@ -324,7 +324,7 @@ void ED_spacetype_node(void)
art= MEM_callocN(sizeof(ARegionType), "spacetype node region");
art->regionid = RGN_TYPE_CHANNELS;
art->minsizex= 100;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
art->init= node_channel_area_init;
art->draw= node_channel_area_draw;
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 09e00c28414..76273f24441 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -222,7 +222,7 @@ void ED_spacetype_sequencer(void)
art->init= sequencer_main_area_init;
art->draw= drawseqspace;
art->listener= sequencer_main_area_listener;
- art->keymapflag= ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
@@ -230,7 +230,7 @@ void ED_spacetype_sequencer(void)
art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region");
art->regionid = RGN_TYPE_HEADER;
art->minsizey= HEADERY;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
art->init= sequencer_header_area_init;
art->draw= sequencer_header_area_draw;
diff --git a/source/blender/editors/space_sound/space_sound.c b/source/blender/editors/space_sound/space_sound.c
index 1b275e51e32..f8ef2b21ae7 100644
--- a/source/blender/editors/space_sound/space_sound.c
+++ b/source/blender/editors/space_sound/space_sound.c
@@ -238,7 +238,7 @@ void ED_spacetype_sound(void)
art->init= sound_main_area_init;
art->draw= sound_main_area_draw;
art->listener= sound_main_area_listener;
- art->keymapflag= ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index 1d95f982f93..94ab1064eec 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -309,7 +309,7 @@ void ED_spacetype_time(void)
/* regions: main window */
art= MEM_callocN(sizeof(ARegionType), "spacetype time region");
art->regionid = RGN_TYPE_WINDOW;
- art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS|ED_KEYMAP_ANIMATION;
+ art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS|ED_KEYMAP_ANIMATION|ED_KEYMAP_FRAMES;
art->init= time_main_area_init;
art->draw= time_main_area_draw;
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index ad9de1453f5..fee766ee3ff 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -4053,16 +4053,16 @@ static void curve_draw_speed(Scene *scene, Object *ob)
}
-static void tekentextcurs(void)
+static void draw_textcurs(float textcurs[][2])
{
cpack(0);
set_inverted_drawing(1);
glBegin(GL_QUADS);
- glVertex2fv(G.textcurs[0]);
- glVertex2fv(G.textcurs[1]);
- glVertex2fv(G.textcurs[2]);
- glVertex2fv(G.textcurs[3]);
+ glVertex2fv(textcurs[0]);
+ glVertex2fv(textcurs[1]);
+ glVertex2fv(textcurs[2]);
+ glVertex2fv(textcurs[3]);
glEnd();
set_inverted_drawing(0);
}
@@ -4932,8 +4932,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
case OB_FONT:
cu= ob->data;
if (cu->disp.first==NULL) makeDispListCurveTypes(scene, ob, 0);
- if(cu->editstr) {
- tekentextcurs();
+ if(cu->editfont) {
+ draw_textcurs(cu->editfont->textcurs);
if (cu->flag & CU_FAST) {
cpack(0xFFFFFF);
@@ -4987,17 +4987,17 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
setlinestyle(0);
- if (getselection(ob, &selstart, &selend) && selboxes) {
+ if (BKE_font_getselection(ob, &selstart, &selend) && cu->selboxes) {
float selboxw;
cpack(0xffffff);
set_inverted_drawing(1);
for (i=0; i<(selend-selstart+1); i++) {
- SelBox *sb = &(selboxes[i]);
+ SelBox *sb = &(cu->selboxes[i]);
if (i<(selend-selstart)) {
- if (selboxes[i+1].y == sb->y)
- selboxw= selboxes[i+1].x - sb->x;
+ if (cu->selboxes[i+1].y == sb->y)
+ selboxw= cu->selboxes[i+1].x - sb->x;
else
selboxw= sb->w;
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index d0a8e96f332..9ce9f8a244d 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -244,12 +244,18 @@ static void view3d_modal_keymaps(wmWindowManager *wm, ARegion *ar, int stype)
else
WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0);
if(stype==NS_EDITMODE_MESH)
WM_event_add_keymap_handler(&ar->handlers, keymap);
else
WM_event_remove_keymap_handler(&ar->handlers, keymap);
+
+ /* editfont keymap swallows all... */
+ keymap= WM_keymap_listbase(wm, "Font", 0, 0);
+ if(stype==NS_EDITMODE_TEXT)
+ WM_event_add_keymap_handler_priority(&ar->handlers, keymap, 10);
+ else
+ WM_event_remove_keymap_handler(&ar->handlers, keymap);
}
@@ -458,6 +464,7 @@ void ED_spacetype_view3d(void)
/* regions: main window */
art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region");
art->regionid = RGN_TYPE_WINDOW;
+ art->keymapflag= ED_KEYMAP_FRAMES;
art->draw= view3d_main_area_draw;
art->init= view3d_main_area_init;
art->free= view3d_main_area_free;
@@ -470,7 +477,7 @@ void ED_spacetype_view3d(void)
art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region");
art->regionid = RGN_TYPE_HEADER;
art->minsizey= HEADERY;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
art->listener= view3d_header_area_listener;
art->init= view3d_header_area_init;
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index bde65329371..992b8907ba7 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -46,6 +46,8 @@ struct Key;
struct Material;
struct VFont;
struct AnimData;
+struct SelBox;
+struct EditFont;
/* These two Lines with # tell makesdna this struct can be excluded. */
#
@@ -180,7 +182,9 @@ typedef struct Curve {
float linewidth;
char *str;
- char *editstr;
+ struct SelBox *selboxes;
+ struct EditFont *editfont;
+
char family[24];
struct VFont *vfont;
struct VFont *vfontb;
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 7921ad8c608..010a0108459 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -88,6 +88,8 @@ char *WM_key_event_operator_string(const struct bContext *C, const char *opname
struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap);
/* boundbox, optional subwindow boundbox for offset */
struct wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBase *keymap, rcti *bb, rcti *swinbb);
+ /* priority not implemented, it adds in begin */
+struct wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, ListBase *keymap, int priority);
void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 7ad61f1a3de..d2906f6512b 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -97,6 +97,9 @@ typedef struct wmEvent {
#define KM_ALT2 64
#define KM_OSKEY2 128
+/* type: defined in wm_event_types.c */
+#define KM_TEXTINPUT -2
+
/* val */
#define KM_ANY -1
#define KM_RELEASE 0
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 6c0339f87b2..0746322e336 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -493,9 +493,12 @@ static int wm_userdef_event_map(int kmitype)
static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
{
int kmitype= wm_userdef_event_map(kmi->type);
-
+
/* the matching rules */
- if(winevent->type!=kmitype) return 0;
+ if(kmitype==KM_TEXTINPUT)
+ if(ISKEYBOARD(winevent->type)) return 1;
+ if(kmitype!=KM_ANY)
+ if(winevent->type!=kmitype) return 0;
if(kmi->val!=KM_ANY)
if(winevent->val!=kmi->val) return 0;
@@ -877,6 +880,20 @@ wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap
return handler;
}
+/* priorities not implemented yet, for time being just insert in begin of list */
+wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, ListBase *keymap, int priority)
+{
+ wmEventHandler *handler;
+
+ WM_event_remove_keymap_handler(handlers, keymap);
+
+ handler= MEM_callocN(sizeof(wmEventHandler), "event keymap handler");
+ BLI_addhead(handlers, handler);
+ handler->keymap= keymap;
+
+ return handler;
+}
+
wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBase *keymap, rcti *bblocal, rcti *bbwin)
{
wmEventHandler *handler= WM_event_add_keymap_handler(handlers, keymap);
@@ -1115,6 +1132,10 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata)
event.ascii= kd->ascii;
event.val= (type==GHOST_kEventKeyDown); /* XXX eventmatch uses defines, bad code... */
+ /* exclude arrow keys, esc, etc from text input */
+ if(type==GHOST_kEventKeyUp || (event.ascii<32 && event.ascii>14))
+ event.ascii= '\0';
+
/* modifiers */
if (event.type==LEFTSHIFTKEY || event.type==RIGHTSHIFTKEY) {
event.shift= evt->shift= event.val;
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index 41c451755fc..a3bf0ca728f 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -78,7 +78,6 @@
#define TIMERJOBS 0x0114 /* timer event, internal use */
/* standard keyboard */
-
#define AKEY 'a'
#define BKEY 'b'
#define CKEY 'c'
@@ -166,12 +165,10 @@
#define PADSLASHKEY 161
#define PADASTERKEY 160
-
#define PADMINUS 162
#define PADENTER 163
#define PADPLUSKEY 164
-
#define F1KEY 300
#define F2KEY 301
#define F3KEY 302
@@ -196,6 +193,10 @@
#define COMMANDKEY 172
#define GRLESSKEY 173
+/* for event checks */
+#define ISKEYBOARD(event) (event >='a' && event <=255)
+
+
/* **************** BLENDER QUEUE EVENTS ********************* */
#define CHANGED 0x4000