diff options
-rw-r--r-- | source/blender/blenkernel/BKE_blender.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_font.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/font.c | 76 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_260.c | 10 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 8 | ||||
-rw-r--r-- | source/blender/editors/curve/editfont.c | 284 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_curve_types.h | 14 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_curve.c | 21 |
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"); |