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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_font.h7
-rw-r--r--source/blender/blenkernel/intern/curve.c6
-rw-r--r--source/blender/blenkernel/intern/font.c76
-rw-r--r--source/blender/blenloader/intern/versioning_260.c10
-rw-r--r--source/blender/blenloader/intern/writefile.c8
-rw-r--r--source/blender/editors/curve/editfont.c284
-rw-r--r--source/blender/makesdna/DNA_curve_types.h14
-rw-r--r--source/blender/makesrna/intern/rna_curve.c21
9 files changed, 219 insertions, 209 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index f397e6be2c9..e2f86c26626 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -42,7 +42,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 269
-#define BLENDER_SUBVERSION 7
+#define BLENDER_SUBVERSION 8
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
#define BLENDER_MINVERSION 262
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index 76fc7350d19..16cbcde0167 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -65,6 +65,11 @@ typedef struct EditFont {
struct CharInfo *textbufinfo;
float textcurs[4][2];
+
+ /* positional vars relative to the textbuf, textbufinfo (not utf8 bytes)
+ * a copy of these is kept in Curve, but use these in editmode */
+ int len, pos;
+ int selstart, selend;
} EditFont;
@@ -80,7 +85,7 @@ struct VFont *BKE_vfont_load(struct Main *bmain, const char *name);
bool BKE_vfont_to_curve(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode,
struct CharTrans **r_chartransdata);
-int BKE_vfont_select_get(struct Object *ob, int *start, int *end);
+int BKE_vfont_select_get(struct Object *ob, int *r_start, int *r_end);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 1c4560cd2b2..d1dde91feb6 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -190,7 +190,7 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type)
cu->vfont->id.us += 4;
cu->str = MEM_mallocN(12, "str");
BLI_strncpy(cu->str, "Text", 12);
- cu->len = cu->pos = 4;
+ cu->len = cu->len_wchar = cu->pos = 4;
cu->strinfo = MEM_callocN(12 * sizeof(CharInfo), "strinfo new");
cu->totbox = cu->actbox = 1;
cu->tb = MEM_callocN(MAXTEXTBOX * sizeof(TextBox), "textbox");
@@ -4041,7 +4041,7 @@ void BKE_curve_material_index_remove(Curve *cu, int index)
if (curvetype == OB_FONT) {
struct CharInfo *info = cu->strinfo;
int i;
- for (i = cu->len - 1; i >= 0; i--, info++) {
+ for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
if (info->mat_nr && info->mat_nr >= index) {
info->mat_nr--;
}
@@ -4068,7 +4068,7 @@ void BKE_curve_material_index_clear(Curve *cu)
if (curvetype == OB_FONT) {
struct CharInfo *info = cu->strinfo;
int i;
- for (i = cu->len - 1; i >= 0; i--, info++) {
+ for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
info->mat_nr = 0;
}
}
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 90362c7a3ad..222251f6e5e 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -457,25 +457,26 @@ static void buildchar(Main *bmain, Curve *cu, unsigned int character, CharInfo *
}
}
-int BKE_vfont_select_get(Object *ob, int *start, int *end)
+int BKE_vfont_select_get(Object *ob, int *r_start, int *r_end)
{
Curve *cu = ob->data;
+ EditFont *ef = cu->editfont;
- if (cu->editfont == NULL || ob->type != OB_FONT) return 0;
+ if ((ob->type != OB_FONT) || (ef == NULL)) return 0;
- BLI_assert(cu->selstart >= 0 && cu->selstart <= cu->len + 1);
- BLI_assert(cu->selend >= 0 && cu->selend <= cu->len + 1);
- BLI_assert(cu->pos >= 0 && cu->pos <= cu->len);
+ BLI_assert(ef->selstart >= 0 && ef->selstart <= ef->len + 1);
+ BLI_assert(ef->selend >= 0 && ef->selend <= ef->len + 1);
+ BLI_assert(ef->pos >= 0 && ef->pos <= ef->len);
- if (cu->selstart == 0) return 0;
- if (cu->selstart <= cu->selend) {
- *start = cu->selstart - 1;
- *end = cu->selend - 1;
+ if (ef->selstart == 0) return 0;
+ if (ef->selstart <= ef->selend) {
+ *r_start = ef->selstart - 1;
+ *r_end = ef->selend - 1;
return 1;
}
else {
- *start = cu->selend;
- *end = cu->selstart - 2;
+ *r_start = ef->selend;
+ *r_end = ef->selstart - 2;
return -1;
}
}
@@ -497,9 +498,10 @@ static float char_width(Curve *cu, VChar *che, CharInfo *info)
bool BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int mode,
struct CharTrans **r_chartransdata)
{
+ Curve *cu = ob->data;
+ EditFont *ef = cu->editfont;
VFont *vfont, *oldvfont;
VFontData *vfd = NULL;
- Curve *cu;
CharInfo *info = NULL, *custrinfo;
TextBox *tb;
VChar *che;
@@ -519,7 +521,6 @@ bool BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int mode,
BLI_assert(ob->type == OB_FONT);
/* Set font data */
- cu = (Curve *) ob->data;
vfont = cu->vfont;
if (cu->str == NULL) return ok;
@@ -533,20 +534,18 @@ bool BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int mode,
if (cu->ulheight == 0.0f)
cu->ulheight = 0.05f;
- if (cu->editfont) {
- slen = cu->len;
- mem = cu->editfont->textbuf;
- custrinfo = cu->editfont->textbufinfo;
+ if (ef) {
+ slen = ef->len;
+ mem = ef->textbuf;
+ custrinfo = ef->textbufinfo;
}
else {
- size_t utf8len;
-
- utf8len = BLI_strlen_utf8(cu->str);
+ slen = cu->len_wchar;
/* Create unicode string */
- mem = MEM_mallocN(((utf8len + 1) * sizeof(wchar_t)), "convertedmem");
+ mem = MEM_mallocN(((slen + 1) * sizeof(wchar_t)), "convertedmem");
- slen = BLI_strncpy_wchar_from_utf8(mem, cu->str, utf8len + 1);
+ BLI_strncpy_wchar_from_utf8(mem, cu->str, slen + 1);
if (cu->strinfo == NULL) { /* old file */
cu->strinfo = MEM_callocN((slen + 4) * sizeof(CharInfo), "strinfo compat");
@@ -945,10 +944,8 @@ makebreak:
}
if (mode == FO_CURSUP || mode == FO_CURSDOWN || mode == FO_PAGEUP || mode == FO_PAGEDOWN) {
- /* 2: curs up
- * 3: curs down */
- ct = chartransdata + cu->pos;
-
+ ct = &chartransdata[ef->pos];
+
if ((mode == FO_CURSUP || mode == FO_PAGEUP) && ct->linenr == 0) {
/* pass */
}
@@ -964,7 +961,7 @@ makebreak:
}
cnr = ct->charnr;
/* seek for char with lnr en cnr */
- cu->pos = 0;
+ ef->pos = 0;
ct = chartransdata;
for (i = 0; i < slen; i++) {
if (ct->linenr == lnr) {
@@ -975,21 +972,21 @@ makebreak:
else if (ct->linenr > lnr) {
break;
}
- cu->pos++;
+ ef->pos++;
ct++;
}
}
}
/* cursor first */
- if (cu->editfont) {
+ if (ef) {
float si, co;
- ct = chartransdata + cu->pos;
+ ct = &chartransdata[ef->pos];
si = sinf(ct->rot);
co = cosf(ct->rot);
- f = cu->editfont->textcurs[0];
+ f = ef->textcurs[0];
f[0] = cu->fsize * (-0.1f * co + ct->xof);
f[1] = cu->fsize * ( 0.1f * si + ct->yof);
@@ -1071,8 +1068,7 @@ makebreak:
mem[0] = ascii;
mem[1] = 0;
custrinfo[0] = *info;
- cu->pos = 1;
- cu->len = 1;
+ cu->len = cu->len_wchar = cu->pos = 1;
mul_v3_m4v3(ob->loc, ob->obmat, vecyo);
outta = 1;
cu->sepchar = 0;
@@ -1086,14 +1082,16 @@ makebreak:
finally:
- if (cu->editfont == NULL)
+ if (ef == NULL)
MEM_freeN(mem);
- if (r_chartransdata) {
- *r_chartransdata = chartransdata;
- }
- else {
- MEM_freeN(chartransdata);
+ if (chartransdata) {
+ if (ok && r_chartransdata) {
+ *r_chartransdata = chartransdata;
+ }
+ else {
+ MEM_freeN(chartransdata);
+ }
}
return ok;
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index d63b72bc4c1..d8e3e02b196 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -2645,4 +2645,14 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
+
+ if (!MAIN_VERSION_ATLEAST(main, 269, 8)) {
+ Curve *cu;
+
+ for (cu = main->curve.first; cu; cu = cu->id.next) {
+ if (cu->str) {
+ cu->len_wchar = BLI_strlen_utf8(cu->str);
+ }
+ }
+ }
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 9ffe4dae82a..beb8d584e41 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1664,12 +1664,8 @@ static void write_curves(WriteData *wd, ListBase *idbase)
if (cu->adt) write_animdata(wd, cu->adt);
if (cu->vfont) {
- /* TODO, sort out 'cu->len', in editmode its character, object mode its bytes */
- size_t len_bytes;
- size_t len_chars = BLI_strlen_utf8_ex(cu->str, &len_bytes);
-
- writedata(wd, DATA, len_bytes + 1, cu->str);
- writestruct(wd, DATA, "CharInfo", len_chars + 1, cu->strinfo);
+ writedata(wd, DATA, cu->len + 1, cu->str);
+ writestruct(wd, DATA, "CharInfo", cu->len_wchar + 1, cu->strinfo);
writestruct(wd, DATA, "TextBox", cu->totbox, cu->tb);
}
else {
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 6bb6b286047..3118dd69eb0 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -220,47 +220,24 @@ static char findaccent(char char1, unsigned int code)
else return char1;
}
-
-static 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 = BLI_wstrlen_utf8(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 */
- BLI_strncpy_wchar_as_utf8(cu->str, ef->textbuf, len + 1);
-
- BLI_assert(wcslen(ef->textbuf) == cu->len);
-}
-
static int insert_into_textbuf(Object *obedit, uintptr_t c)
{
Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
- if (cu->len < MAXTEXT - 1) {
- EditFont *ef = cu->editfont;
+ if (ef->len < MAXTEXT - 1) {
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;
- ef->textbufinfo[cu->pos].mat_nr = obedit->actcol;
+ for (x = ef->len; x > ef->pos; x--) ef->textbuf[x] = ef->textbuf[x - 1];
+ for (x = ef->len; x > ef->pos; x--) ef->textbufinfo[x] = ef->textbufinfo[x - 1];
+ ef->textbuf[ef->pos] = c;
+ ef->textbufinfo[ef->pos] = cu->curinfo;
+ ef->textbufinfo[ef->pos].kern = 0;
+ ef->textbufinfo[ef->pos].mat_nr = obedit->actcol;
- cu->pos++;
- cu->len++;
- ef->textbuf[cu->len] = '\0';
-
- update_string(cu);
+ ef->pos++;
+ ef->len++;
+ ef->textbuf[ef->len] = '\0';
return 1;
}
@@ -273,10 +250,10 @@ static void text_update_edited(bContext *C, Scene *scene, Object *obedit, int re
struct Main *bmain = CTX_data_main(C);
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
- cu->curinfo = ef->textbufinfo[cu->pos ? cu->pos - 1 : 0];
+ cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0];
if (obedit->totcol > 0) {
- obedit->actcol = ef->textbufinfo[cu->pos ? cu->pos - 1 : 0].mat_nr;
+ obedit->actcol = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0].mat_nr;
/* since this array is calloc'd, it can be 0 even though we try ensure
* (mat_nr > 0) almost everywhere */
@@ -285,13 +262,11 @@ static void text_update_edited(bContext *C, Scene *scene, Object *obedit, int re
}
}
- if (mode == FO_EDIT)
- update_string(cu);
-
BKE_vfont_to_curve(bmain, scene, obedit, mode, NULL);
if (recalc)
DAG_id_tag_update(obedit->data, 0);
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
}
@@ -381,17 +356,18 @@ static int paste_file(bContext *C, ReportList *reports, const char *filename)
fclose(fp);
strp[filelen] = 0;
- if (cu->len + filelen < MAXTEXT) {
+ if (ef->len + filelen < MAXTEXT) {
int tmplen;
wchar_t *mem = MEM_mallocN((sizeof(wchar_t) * filelen) + (4 * sizeof(wchar_t)), "temporary");
tmplen = BLI_strncpy_wchar_from_utf8(mem, strp, filelen + 1);
wcscat(ef->textbuf, mem);
MEM_freeN(mem);
- cu->len += tmplen;
- cu->pos = cu->len;
+ ef->len += tmplen;
}
MEM_freeN(strp);
+ ef->pos = ef->len;
+
text_update_edited(C, scene, obedit, 1, FO_EDIT);
return OPERATOR_FINISHED;
@@ -441,7 +417,7 @@ void FONT_OT_file_paste(wmOperatorType *ot)
/******************* text to object operator ********************/
-static void txt_add_object(bContext *C, TextLine *firstline, int totline, float offset[3])
+static void txt_add_object(bContext *C, TextLine *firstline, int totline, const float offset[3])
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -482,10 +458,10 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float
cu->strinfo = MEM_callocN((nchars + 4) * sizeof(CharInfo), "strinfo");
cu->len = 0;
+ cu->len_wchar = nchars - 1;
cu->pos = 0;
s = cu->str;
- *s = '\0';
for (tmp = firstline, a = 0; cu->len < MAXTEXT && a < totline; tmp = tmp->next, a++) {
size_t nbytes_line;
@@ -502,9 +478,11 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float
cu->len += nbytes_line;
}
- cu->pos = cu->len;
}
+ cu->pos = cu->len_wchar;
+ *s = '\0';
+
WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, obedit);
}
@@ -561,18 +539,18 @@ static int kill_selection(Object *obedit, int ins) /* 1 == new character */
if (direction) {
int size;
if (ins) offset = 1;
- if (cu->pos >= selstart) cu->pos = selstart + offset;
+ if (ef->pos >= selstart) ef->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));
+ size = (ef->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) + 1);
- cu->selstart = cu->selend = 0;
+ memmove(ef->textbufinfo + selstart, ef->textbufinfo + getfrom, ((ef->len - selstart) + offset) * sizeof(CharInfo));
+ ef->len -= ((selend - selstart) + 1);
+ ef->selstart = ef->selend = 0;
}
return(direction);
@@ -684,11 +662,12 @@ static int font_select_all_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
- if (cu->len) {
- cu->selstart = 1;
- cu->selend = cu->len;
- cu->pos = cu->len;
+ if (ef->len) {
+ ef->selstart = 1;
+ ef->selend = ef->len;
+ ef->pos = ef->len;
text_update_edited(C, scene, obedit, true, FO_SELCHANGE);
@@ -795,21 +774,21 @@ static int paste_selection(Object *obedit, ReportList *reports)
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) {
+ /* Verify that the copy buffer => [copy buffer len] + ef->len < MAXTEXT */
+ if (ef->len + len <= MAXTEXT) {
kill_selection(obedit, 0);
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));
+ int size = (ef->len * sizeof(wchar_t)) - (ef->pos * sizeof(wchar_t)) + sizeof(wchar_t);
+ memmove(ef->textbuf + ef->pos + len, ef->textbuf + ef->pos, size);
+ memcpy(ef->textbuf + ef->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));
+ memmove(ef->textbufinfo + ef->pos + len, ef->textbufinfo + ef->pos, (ef->len - ef->pos + 1) * sizeof(CharInfo));
+ memcpy(ef->textbufinfo + ef->pos, ef->copybufinfo, len * sizeof(CharInfo));
- cu->len += len;
- cu->pos += len;
+ ef->len += len;
+ ef->pos += len;
return 1;
}
@@ -873,76 +852,76 @@ static int move_cursor(bContext *C, int type, int select)
switch (type) {
case LINE_BEGIN:
- if ((select) && (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_CHINFO_WRAP) break;
- cu->pos--;
+ if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
+ while (ef->pos > 0) {
+ if (ef->textbuf[ef->pos - 1] == '\n') break;
+ if (ef->textbufinfo[ef->pos - 1].flag & CU_CHINFO_WRAP) break;
+ ef->pos--;
}
cursmove = FO_CURS;
break;
case LINE_END:
- if ((select) && (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_CHINFO_WRAP) break;
- cu->pos++;
+ if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
+ while (ef->pos < ef->len) {
+ if (ef->textbuf[ef->pos] == 0) break;
+ if (ef->textbuf[ef->pos] == '\n') break;
+ if (ef->textbufinfo[ef->pos].flag & CU_CHINFO_WRAP) break;
+ ef->pos++;
}
cursmove = FO_CURS;
break;
case PREV_WORD:
{
- int pos = cu->pos;
- if ((select) && (cu->selstart == 0)) cu->selstart = cu->selend = cu->pos + 1;
- BLI_str_cursor_step_wchar(ef->textbuf, cu->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
- cu->pos = pos;
+ int pos = ef->pos;
+ if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
+ BLI_str_cursor_step_wchar(ef->textbuf, ef->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
+ ef->pos = pos;
cursmove = FO_CURS;
break;
}
case NEXT_WORD:
{
- int pos = cu->pos;
- if ((select) && (cu->selstart == 0)) cu->selstart = cu->selend = cu->pos + 1;
- BLI_str_cursor_step_wchar(ef->textbuf, cu->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
- cu->pos = pos;
+ int pos = ef->pos;
+ if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
+ BLI_str_cursor_step_wchar(ef->textbuf, ef->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
+ ef->pos = pos;
cursmove = FO_CURS;
break;
}
case PREV_CHAR:
- if ((select) && (cu->selstart == 0)) cu->selstart = cu->selend = cu->pos + 1;
- cu->pos--;
+ if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
+ ef->pos--;
cursmove = FO_CURS;
break;
case NEXT_CHAR:
- if ((select) && (cu->selstart == 0)) cu->selstart = cu->selend = cu->pos + 1;
- cu->pos++;
+ if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
+ ef->pos++;
cursmove = FO_CURS;
break;
case PREV_LINE:
- if ((select) && (cu->selstart == 0)) cu->selstart = cu->selend = cu->pos + 1;
+ if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
cursmove = FO_CURSUP;
break;
case NEXT_LINE:
- if ((select) && (cu->selstart == 0)) cu->selstart = cu->selend = cu->pos + 1;
+ if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
cursmove = FO_CURSDOWN;
break;
case PREV_PAGE:
- if ((select) && (cu->selstart == 0)) cu->selstart = cu->selend = cu->pos + 1;
+ if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
cursmove = FO_PAGEUP;
break;
case NEXT_PAGE:
- if ((select) && (cu->selstart == 0)) cu->selstart = cu->selend = cu->pos + 1;
+ if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
cursmove = FO_PAGEDOWN;
break;
}
@@ -951,22 +930,21 @@ static int move_cursor(bContext *C, int type, int select)
return OPERATOR_CANCELLED;
if (select == 0) {
- if (cu->selstart) {
+ if (ef->selstart) {
struct Main *bmain = CTX_data_main(C);
- cu->selstart = cu->selend = 0;
- update_string(cu);
+ ef->selstart = ef->selend = 0;
BKE_vfont_to_curve(bmain, scene, obedit, FO_SELCHANGE, NULL);
}
}
- 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 (ef->pos > ef->len) ef->pos = ef->len;
+ else if (ef->pos >= MAXTEXT) ef->pos = MAXTEXT;
+ else if (ef->pos < 0) ef->pos = 0;
text_update_edited(C, scene, obedit, select, cursmove);
if (select)
- cu->selend = cu->pos;
+ ef->selend = ef->pos;
return OPERATOR_FINISHED;
}
@@ -1033,14 +1011,14 @@ static int change_spacing_exec(bContext *C, wmOperator *op)
EditFont *ef = cu->editfont;
int kern, delta = RNA_int_get(op->ptr, "delta");
- kern = ef->textbufinfo[cu->pos - 1].kern;
+ kern = ef->textbufinfo[ef->pos - 1].kern;
kern += delta;
CLAMP(kern, -20, 20);
- if (ef->textbufinfo[cu->pos - 1].kern == kern)
+ if (ef->textbufinfo[ef->pos - 1].kern == kern)
return OPERATOR_CANCELLED;
- ef->textbufinfo[cu->pos - 1].kern = kern;
+ ef->textbufinfo[ef->pos - 1].kern = kern;
text_update_edited(C, scene, obedit, 1, FO_EDIT);
@@ -1075,17 +1053,17 @@ static int change_character_exec(bContext *C, wmOperator *op)
EditFont *ef = cu->editfont;
int character, delta = RNA_int_get(op->ptr, "delta");
- if (cu->pos <= 0)
+ if (ef->pos <= 0)
return OPERATOR_CANCELLED;
- character = ef->textbuf[cu->pos - 1];
+ character = ef->textbuf[ef->pos - 1];
character += delta;
CLAMP(character, 0, 255);
- if (character == ef->textbuf[cu->pos - 1])
+ if (character == ef->textbuf[ef->pos - 1])
return OPERATOR_CANCELLED;
- ef->textbuf[cu->pos - 1] = character;
+ ef->textbuf[ef->pos - 1] = character;
text_update_edited(C, scene, obedit, 1, FO_EDIT);
@@ -1117,10 +1095,11 @@ static int line_break_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
+ EditFont *ef = cu->editfont;
insert_into_textbuf(obedit, '\n');
- cu->selstart = cu->selend = 0;
+ ef->selstart = ef->selend = 0;
text_update_edited(C, scene, obedit, 1, FO_EDIT);
@@ -1161,7 +1140,7 @@ static int delete_exec(bContext *C, wmOperator *op)
EditFont *ef = cu->editfont;
int x, selstart, selend, type = RNA_enum_get(op->ptr, "type");
- if (cu->len == 0)
+ if (ef->len == 0)
return OPERATOR_CANCELLED;
if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
@@ -1175,7 +1154,7 @@ static int delete_exec(bContext *C, wmOperator *op)
switch (type) {
case DEL_ALL:
- cu->len = cu->pos = 0;
+ ef->len = ef->pos = 0;
ef->textbuf[0] = 0;
break;
case DEL_SELECTION:
@@ -1183,27 +1162,27 @@ static int delete_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
break;
case DEL_PREV_CHAR:
- if (cu->pos <= 0)
+ if (ef->pos <= 0)
return OPERATOR_CANCELLED;
- for (x = cu->pos; x <= cu->len; x++)
+ for (x = ef->pos; x <= ef->len; x++)
ef->textbuf[x - 1] = ef->textbuf[x];
- for (x = cu->pos; x <= cu->len; x++)
+ for (x = ef->pos; x <= ef->len; x++)
ef->textbufinfo[x - 1] = ef->textbufinfo[x];
- cu->pos--;
- ef->textbuf[--cu->len] = '\0';
+ ef->pos--;
+ ef->textbuf[--ef->len] = '\0';
break;
case DEL_NEXT_CHAR:
- if (cu->pos >= cu->len)
+ if (ef->pos >= ef->len)
return OPERATOR_CANCELLED;
- for (x = cu->pos; x < cu->len; x++)
+ for (x = ef->pos; x < ef->len; x++)
ef->textbuf[x] = ef->textbuf[x + 1];
- for (x = cu->pos; x < cu->len; x++)
+ for (x = ef->pos; x < ef->len; x++)
ef->textbufinfo[x] = ef->textbufinfo[x + 1];
- ef->textbuf[--cu->len] = '\0';
+ ef->textbuf[--ef->len] = '\0';
break;
default:
return OPERATOR_CANCELLED;
@@ -1279,7 +1258,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return insert_text_exec(C, op);
if (RNA_struct_property_is_set(op->ptr, "accent")) {
- if (cu->len != 0 && cu->pos > 0)
+ if (ef->len != 0 && ef->pos > 0)
accentcode = 1;
return OPERATOR_FINISHED;
}
@@ -1293,7 +1272,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
if (event_type == BACKSPACEKEY) {
- if (alt && cu->len != 0 && cu->pos > 0)
+ if (alt && ef->len != 0 && ef->pos > 0)
accentcode = 1;
return OPERATOR_PASS_THROUGH;
}
@@ -1308,9 +1287,9 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (accentcode) {
- if (cu->pos > 0) {
- inserted_text[0] = findaccent(ef->textbuf[cu->pos - 1], ascii);
- ef->textbuf[cu->pos - 1] = inserted_text[0];
+ if (ef->pos > 0) {
+ inserted_text[0] = findaccent(ef->textbuf[ef->pos - 1], ascii);
+ ef->textbuf[ef->pos - 1] = inserted_text[0];
}
accentcode = 0;
}
@@ -1473,34 +1452,48 @@ void make_editText(Object *obedit)
}
/* Convert the original text to wchar_t */
- cu->len = BLI_strncpy_wchar_from_utf8(ef->textbuf, cu->str, MAXTEXT + 4); /* length is bogus */
+ BLI_assert(BLI_strncpy_wchar_from_utf8(ef->textbuf, cu->str, MAXTEXT + 4) == cu->len_wchar); /* length is bogus */
+ ef->len = cu->len_wchar;
- memcpy(ef->textbufinfo, cu->strinfo, (cu->len) * sizeof(CharInfo));
+ memcpy(ef->textbufinfo, cu->strinfo, ef->len * sizeof(CharInfo));
- if (cu->pos > cu->len) cu->pos = cu->len;
+ if (ef->pos > ef->len) ef->pos = ef->len;
- if (cu->pos)
- cu->curinfo = ef->textbufinfo[cu->pos - 1];
- else
- cu->curinfo = ef->textbufinfo[0];
+ cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0];
- /* Convert to UTF-8 */
- update_string(cu);
+ /* Other vars */
+ ef->pos = cu->pos;
+ ef->selstart = cu->selstart;
+ ef->selend = cu->selend;
}
void load_editText(Object *obedit)
{
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
-
- update_string(cu);
+
+ /* Free the old curve string */
+ MEM_freeN(cu->str);
+
+ /* Calculate the actual string length in UTF-8 variable characters */
+ cu->len_wchar = ef->len;
+ cu->len = BLI_wstrlen_utf8(ef->textbuf);
+
+ /* Alloc memory for UTF-8 variable char length string */
+ cu->str = MEM_mallocN(cu->len + sizeof(wchar_t), "str");
+
+ /* Copy the wchar to UTF-8 */
+ BLI_strncpy_wchar_as_utf8(cu->str, ef->textbuf, cu->len + 1);
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->strinfo = MEM_callocN((cu->len_wchar + 4) * sizeof(CharInfo), "texteditinfo");
+ memcpy(cu->strinfo, ef->textbufinfo, cu->len_wchar * sizeof(CharInfo));
- cu->len = strlen(cu->str);
+ /* Other vars */
+ cu->pos = ef->pos;
+ cu->selstart = ef->selstart;
+ cu->selend = ef->selend;
}
void free_editText(Object *obedit)
@@ -1763,15 +1756,14 @@ static void undoFont_to_editFont(void *strv, void *ecu, void *UNUSED(obdata))
EditFont *ef = cu->editfont;
char *str = strv;
- cu->pos = *((short *)str);
- cu->len = *((short *)(str + 2));
+ ef->pos = *((short *)str);
+ ef->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));
+ memcpy(ef->textbuf, str + 4, (ef->len + 1) * sizeof(wchar_t));
+ memcpy(ef->textbufinfo, str + 4 + (ef->len + 1) * sizeof(wchar_t), ef->len * sizeof(CharInfo));
- cu->selstart = cu->selend = 0;
-
- update_string(cu);
+ ef->selstart = ef->selend = 0;
+
}
static void *editFont_to_undoFont(void *ecu, void *UNUSED(obdata))
@@ -1784,11 +1776,11 @@ static void *editFont_to_undoFont(void *ecu, void *UNUSED(obdata))
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));
+ memcpy(str + 4, ef->textbuf, (ef->len + 1) * sizeof(wchar_t));
+ memcpy(str + 4 + (ef->len + 1) * sizeof(wchar_t), ef->textbufinfo, ef->len * sizeof(CharInfo));
- *((short *)str) = cu->pos;
- *((short *)(str + 2)) = cu->len;
+ *((short *)(str + 0)) = ef->pos;
+ *((short *)(str + 2)) = ef->len;
return str;
}
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 24035464259..ad6a3a77413 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -216,15 +216,25 @@ typedef struct Curve {
* - strlen(cu->str) object-mode (bytes).
* - BLI_strlen_utf8(cu->str) in edit-mode.
* This should be cleaned up and some point, see 'write_curves' - campbell */
- short len, lines, pos, spacemode;
+ short lines;
+ char spacemode, pad1;
float spacing, linedist, shear, fsize, wordspace, ulpos, ulheight;
float xof, yof;
float linewidth;
+ int pad3;
+ int len_wchar; /* number of characters (strinfo) */
+ int len; /* number of bytes (str - utf8) */
char *str;
struct SelBox *selboxes; /* runtime variable for drawing selections (editmode data) */
struct EditFont *editfont;
+ /* copy of EditFont vars (wchar_t aligned),
+ * warning! don't use in editmode (storage only) */
+ int pos;
+ int selstart, selend;
+ int pad2;
+
char family[24];
struct VFont *vfont;
struct VFont *vfontb;
@@ -237,8 +247,6 @@ typedef struct Curve {
int totbox, actbox;
struct TextBox *tb;
- int selstart, selend;
-
struct CharInfo *strinfo;
struct CharInfo curinfo;
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index da5b6676cb9..97c1725ff01 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -448,28 +448,29 @@ static void rna_Curve_body_get(PointerRNA *ptr, char *value)
static int rna_Curve_body_length(PointerRNA *ptr)
{
Curve *cu = (Curve *)ptr->id.data;
- return cu->editfont ? strlen(cu->str) : cu->len;
+ return cu->len;
}
-/* TODO - check UTF & python play nice */
+/* TODO, how to handle editmode? */
static void rna_Curve_body_set(PointerRNA *ptr, const char *value)
{
- int len = strlen(value);
+ size_t len_bytes;
+ size_t len_chars = BLI_strlen_utf8_ex(value, &len_bytes);
+
Curve *cu = (Curve *)ptr->id.data;
- cu->len = cu->pos = len;
+ cu->len = len_bytes;
+ cu->pos = len_chars;
if (cu->str)
MEM_freeN(cu->str);
if (cu->strinfo)
MEM_freeN(cu->strinfo);
- cu->str = MEM_callocN(len + sizeof(wchar_t), "str");
- /* don't know why this is +4, just duplicating load_editText() */
- cu->strinfo = MEM_callocN((len + 4) * sizeof(CharInfo), "strinfo");
+ cu->str = MEM_mallocN(len_bytes + sizeof(wchar_t), "str");
+ cu->strinfo = MEM_callocN((len_chars + 4) * sizeof(CharInfo), "strinfo");
- /*BLI_strncpy_wchar_as_utf8(cu->str, value, len + 1); *//* value is not wchar_t */
- BLI_strncpy(cu->str, value, len + 1);
+ BLI_strncpy(cu->str, value, len_bytes + 1);
}
static void rna_Nurb_update_cyclic_u(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -1021,7 +1022,7 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop = RNA_def_property(srna, "body_format", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "strinfo", "len");
+ RNA_def_property_collection_sdna(prop, NULL, "strinfo", "len_wchar");
RNA_def_property_struct_type(prop, "TextCharacterFormat");
RNA_def_property_ui_text(prop, "Character Info", "Stores the style of each character");