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:
authorCampbell Barton <ideasman42@gmail.com>2014-01-05 18:33:45 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-01-05 18:37:19 +0400
commit3b024d63fe50d8e69d2d76e009f032cad3f1a538 (patch)
treec96e952a539c783b3e91457f5c673bb98c9832bc /source/blender/blenkernel/intern/anim.c
parent38bbd9c778d6733f21732df1f51dd2dc5236fa44 (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.c74
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);
}