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:
authorCampbell Barton <ideasman42@gmail.com>2014-01-03 10:04:42 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-01-03 10:08:23 +0400
commit15bc30f4ee49c69f3ed6f92701a0f5cd52d306c5 (patch)
treefc77fe7096673256d90c512267adb58eb53c23de /source
parenta5cb2229abbc7d43f34dabea332afd33614fc0db (diff)
Text3d: store number of characters and utf8 length separately
EditFont's use of Curve.len was very confusing, in editmode it represented the number of characters, in object mode the number of bytes. add Curve.len_wchar and keep track of both. Also don't convert the editmode text into utf8 on every keystroke. Now this is done on exiting editmode or save - to match most other object types. This also fixes curves 'body_format' being reported with an invalid size.
Diffstat (limited to 'source')
-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");