diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-01-05 18:33:45 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-01-05 18:37:19 +0400 |
commit | 3b024d63fe50d8e69d2d76e009f032cad3f1a538 (patch) | |
tree | c96e952a539c783b3e91457f5c673bb98c9832bc /source/blender/blenkernel/intern/anim.c | |
parent | 38bbd9c778d6733f21732df1f51dd2dc5236fa44 (diff) |
Text3d: fix font family feature for unicode and correct tooltip
Diffstat (limited to 'source/blender/blenkernel/intern/anim.c')
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 7ae7fb3a9a0..a84ce5677b0 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1586,36 +1586,50 @@ static void new_particle_duplilist(EvaluationContext *eval_ctx, } } -static Object *find_family_object(Object **obar, char *family, char ch) +static Object *find_family_object(const char *family, size_t family_len, unsigned int ch, GHash *family_gh) { + Object **ob_pt; Object *ob; - int flen; - - if (obar[(int)ch]) return obar[(int)ch]; - - flen = strlen(family); - - ob = G.main->object.first; - while (ob) { - if (ob->id.name[flen + 2] == ch) { - if (strncmp(ob->id.name + 2, family, flen) == 0) break; + void *ch_key = SET_UINT_IN_POINTER(ch); + + if ((ob_pt = (Object **)BLI_ghash_lookup_p(family_gh, ch_key))) { + ob = *ob_pt; + } + else { + char ch_utf8[7]; + size_t ch_utf8_len; + + ch_utf8_len = BLI_str_utf8_from_unicode(ch, ch_utf8); + ch_utf8[ch_utf8_len] = '\0'; + ch_utf8_len += 1; /* compare with null terminator */ + + for (ob = G.main->object.first; ob; ob = ob->id.next) { + if (STREQLEN(ob->id.name + 2 + family_len, ch_utf8, ch_utf8_len)) { + if (STREQLEN(ob->id.name + 2, family, family_len)) { + break; + } + } } - ob = ob->id.next; + + /* inserted value can be NULL, just to save searches in future */ + BLI_ghash_insert(family_gh, ch_key, ob); } - - obar[(int)ch] = ob; - + return ob; } static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { - Object *ob, *obar[256] = {NULL}; + GHash *family_gh; + Object *ob; Curve *cu; struct CharTrans *ct, *chartransdata = NULL; float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof; - int slen, a; + int text_len, a; + size_t family_len; + const wchar_t *text = NULL; + bool text_free = false; /* simple preventing of too deep nested groups */ if (level > MAX_DUPLI_RECUR) return; @@ -1624,20 +1638,28 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int persiste /* in par the family name is stored, use this to find the other objects */ - BKE_vfont_to_curve(G.main, scene, par, FO_DUPLI, &chartransdata); - if (chartransdata == NULL) return; + BKE_vfont_to_curve_ex(G.main, scene, par, FO_DUPLI, + &text, &text_len, &text_free, &chartransdata); + + if (text == NULL || chartransdata == NULL) { + return; + } cu = par->data; - slen = strlen(cu->str); fsize = cu->fsize; xof = cu->xof; yof = cu->yof; ct = chartransdata; - for (a = 0; a < slen; a++, ct++) { + /* cache result */ + family_len = strlen(cu->family); + family_gh = BLI_ghash_int_new_ex(__func__, 256); + + /* advance matching BLI_strncpy_wchar_from_utf8 */ + for (a = 0; a < text_len; a++, ct++) { - ob = find_family_object(obar, cu->family, cu->str[a]); + ob = find_family_object(cu->family, family_len, text[a], family_gh); if (ob) { vec[0] = fsize * (ct->xof - xof); vec[1] = fsize * (ct->yof - yof); @@ -1651,7 +1673,13 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int persiste new_dupli_object(lb, ob, obmat, par->lay, persistent_id, level, a, OB_DUPLIVERTS, flag); } } - + + if (text_free) { + MEM_freeN((void *)text); + } + + BLI_ghash_free(family_gh, NULL, NULL); + MEM_freeN(chartransdata); } |