[Bf-blender-cvs] [3b024d6] master: Text3d: fix font family feature for unicode and correct tooltip

Campbell Barton noreply at git.blender.org
Sun Jan 5 15:37:47 CET 2014


Commit: 3b024d63fe50d8e69d2d76e009f032cad3f1a538
Author: Campbell Barton
Date:   Mon Jan 6 01:33:45 2014 +1100
https://developer.blender.org/rB3b024d63fe50d8e69d2d76e009f032cad3f1a538

Text3d: fix font family feature for unicode and correct tooltip

===================================================================

M	source/blender/blenkernel/BKE_font.h
M	source/blender/blenkernel/intern/anim.c
M	source/blender/blenkernel/intern/displist.c
M	source/blender/blenkernel/intern/font.c
M	source/blender/editors/curve/editfont.c
M	source/blender/editors/object/object_edit.c
M	source/blender/makesdna/DNA_curve_types.h
M	source/blender/makesrna/intern/rna_curve.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index 9c6a28d..1d52aa6 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 7ae7fb3..a84ce56 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 4282e86..da386e4 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 2a5f8cb..1d268b7 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 2263c69..1fbd3a0 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_e

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list