diff options
-rw-r--r-- | source/blender/blenkernel/BKE_font.h | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 74 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/font.c | 53 | ||||
-rw-r--r-- | source/blender/editors/curve/editfont.c | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_curve_types.h | 6 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_curve.c | 6 |
8 files changed, 112 insertions, 52 deletions
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h index 9c6a28d674f..1d52aa6edcc 100644 --- a/source/blender/blenkernel/BKE_font.h +++ b/source/blender/blenkernel/BKE_font.h @@ -83,11 +83,17 @@ void BKE_vfont_free(struct VFont *sc); struct VFont *BKE_vfont_builtin_get(void); struct VFont *BKE_vfont_load(struct Main *bmain, const char *name); -bool BKE_vfont_to_curve_nubase(struct Main *bmain, struct Scene *scene, struct Object *ob, - struct ListBase *nubase, int mode, struct CharTrans **r_chartransdata); - -bool BKE_vfont_to_curve(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode, - struct CharTrans **r_chartransdata); +bool BKE_vfont_to_curve_nubase_ex(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode, + struct ListBase *r_nubase, + const wchar_t **r_text, int *r_text_len, bool *r_text_free, + struct CharTrans **r_chartransdata); +bool BKE_vfont_to_curve_nubase(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode, + struct ListBase *r_nubase); + +bool BKE_vfont_to_curve_ex(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode, + const wchar_t **r_text, int *r_text_len, bool *r_text_free, + struct CharTrans **r_chartransdata); +bool BKE_vfont_to_curve(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode); int BKE_vfont_select_get(struct Object *ob, int *r_start, int *r_end); 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); } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 4282e860c4e..da386e41ded 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1375,7 +1375,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba ob->curve_cache->path = NULL; if (ob->type == OB_FONT) { - BKE_vfont_to_curve_nubase(G.main, scene, ob, &nubase, FO_EDIT, NULL); + BKE_vfont_to_curve_nubase(G.main, scene, ob, FO_EDIT, &nubase); } else { BKE_nurbList_duplicate(&nubase, BKE_curve_nurbs_get(cu)); diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 2a5f8cb8041..1d268b7d7ce 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -495,8 +495,10 @@ static float char_width(Curve *cu, VChar *che, CharInfo *info) } } -bool BKE_vfont_to_curve_nubase(Main *bmain, Scene *scene, Object *ob, ListBase *nubase, - int mode, struct CharTrans **r_chartransdata) +bool BKE_vfont_to_curve_nubase_ex(Main *bmain, Scene *scene, Object *ob, int mode, + ListBase *r_nubase, + const wchar_t **r_text, int *r_text_len, bool *r_text_free, + struct CharTrans **r_chartransdata) { Curve *cu = ob->data; EditFont *ef = cu->editfont; @@ -1020,7 +1022,7 @@ makebreak: if (mode == FO_EDIT) { /* make nurbdata */ - BKE_nurbList_free(nubase); + BKE_nurbList_free(r_nubase); ct = chartransdata; for (i = 0; i < slen; i++) { @@ -1037,7 +1039,7 @@ makebreak: } /* We do not want to see any character for \n or \r */ if (cha != '\n' && cha != '\r') - buildchar(bmain, cu, nubase, cha, info, ct->xof, ct->yof, ct->rot, i); + buildchar(bmain, cu, r_nubase, cha, info, ct->xof, ct->yof, ct->rot, i); if ((info->flag & CU_CHINFO_UNDERLINE) && (cu->textoncurve == NULL) && (cha != '\n') && (cha != '\r')) { float ulwidth, uloverlap = 0.0f; @@ -1054,7 +1056,7 @@ makebreak: twidth = char_width(cu, che, info); ulwidth = cu->fsize * ((twidth * (1.0f + (info->kern / 40.0f))) + uloverlap); - build_underline(cu, nubase, + build_underline(cu, r_nubase, ct->xof * cu->fsize, ct->yof * cu->fsize + (cu->ulpos - 0.05f) * cu->fsize, ct->xof * cu->fsize + ulwidth, ct->yof * cu->fsize + (cu->ulpos - 0.05f) * cu->fsize - cu->ulheight * cu->fsize, @@ -1068,8 +1070,18 @@ makebreak: finally: - if (ef == NULL) - MEM_freeN((void *)mem); + { + if (r_text) { + *r_text = mem; + *r_text_len = slen; + *r_text_free = (ef == NULL); + } + else { + if (ef == NULL) { + MEM_freeN((void *)mem); + } + } + } if (chartransdata) { if (ok && r_chartransdata) { @@ -1083,12 +1095,33 @@ finally: return ok; } -bool BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int mode, - struct CharTrans **r_chartransdata) + +bool BKE_vfont_to_curve_nubase(Main *bmain, Scene *scene, Object *ob, int mode, + ListBase *r_nubase) +{ + BLI_assert(ob->type == OB_FONT); + + return BKE_vfont_to_curve_nubase_ex(bmain, scene, ob, mode, + r_nubase, + NULL, NULL, NULL, NULL); +} + +bool BKE_vfont_to_curve_ex(Main *bmain, Scene *scene, Object *ob, int mode, + const wchar_t **r_text, int *r_text_len, bool *r_text_free, + struct CharTrans **r_chartransdata) { Curve *cu = (Curve *) ob->data; BLI_assert(ob->type == OB_FONT); - return BKE_vfont_to_curve_nubase(bmain, scene, ob, &cu->nurb, mode, r_chartransdata); + return BKE_vfont_to_curve_nubase_ex(bmain, scene, ob, mode, + &cu->nurb, + r_text, r_text_len, r_text_free, r_chartransdata); +} + + +bool BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int mode) +{ + return BKE_vfont_to_curve_ex(bmain, scene, ob, mode, + NULL, NULL, NULL, NULL); } diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 2263c69b712..1fbd3a0f9f5 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -264,7 +264,7 @@ static void text_update_edited(bContext *C, Scene *scene, Object *obedit, const } } - BKE_vfont_to_curve(bmain, scene, obedit, mode, NULL); + BKE_vfont_to_curve(bmain, scene, obedit, mode); if (recalc) DAG_id_tag_update(obedit->data, 0); @@ -1037,7 +1037,7 @@ static int move_cursor(bContext *C, int type, int select) if (ef->selstart) { struct Main *bmain = CTX_data_main(C); ef->selstart = ef->selend = 0; - BKE_vfont_to_curve(bmain, scene, obedit, FO_SELCHANGE, NULL); + BKE_vfont_to_curve(bmain, scene, obedit, FO_SELCHANGE); } } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 82b6f15dc38..f7fb2a29cdb 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -930,9 +930,6 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) if (cu1->vfontbi) cu1->vfontbi->id.us--; cu1->vfontbi = cu->vfontbi; id_us_plus((ID *)cu1->vfontbi); - - BKE_vfont_to_curve(bmain, scene, base->object, FO_EDIT, NULL); /* needed? */ - BLI_strncpy(cu1->family, cu->family, sizeof(cu1->family)); diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 2cc56d49ff8..adcc4af41e0 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -212,10 +212,6 @@ typedef struct Curve { void *lastsel; /* font part */ - /* WARNING: cu->len is... - * - 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 lines; char spacemode, pad1; float spacing, linedist, shear, fsize, wordspace, ulpos, ulheight; @@ -235,7 +231,7 @@ typedef struct Curve { int selstart, selend; int pad2; - char family[24]; + char family[64]; struct VFont *vfont; struct VFont *vfontb; struct VFont *vfonti; diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index bb124600686..8aacfe470ea 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -1009,9 +1009,9 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna) prop = RNA_def_property(srna, "family", PROP_STRING, PROP_NONE); RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); RNA_def_property_ui_text(prop, "Object Font", - "Use Blender Objects as font characters (give font objects a common name " - "followed by the character they represent, eg. family_a, family_b, etc, " - "and turn on Verts Duplication)"); + "Use Objects as font characters (give font objects a common name " + "followed by the character they represent, eg. 'family_a', 'family_b', etc, " + "and set this to 'family_', turn on Vertex Duplication)"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop = RNA_def_property(srna, "body", PROP_STRING, PROP_NONE); |