Text3d: fix font family feature for unicode and correct tooltip

This commit is contained in:
2014-01-06 01:33:45 +11:00
parent 38bbd9c778
commit 3b024d63fe
8 changed files with 112 additions and 52 deletions

View File

@@ -83,11 +83,17 @@ void BKE_vfont_free(struct VFont *sc);
struct VFont *BKE_vfont_builtin_get(void); struct VFont *BKE_vfont_builtin_get(void);
struct VFont *BKE_vfont_load(struct Main *bmain, const char *name); 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, bool BKE_vfont_to_curve_nubase_ex(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode,
struct ListBase *nubase, int mode, struct CharTrans **r_chartransdata); 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(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode, bool BKE_vfont_to_curve_ex(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode,
struct CharTrans **r_chartransdata); 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); int BKE_vfont_select_get(struct Object *ob, int *r_start, int *r_end);

View File

@@ -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; Object *ob;
int flen; void *ch_key = SET_UINT_IN_POINTER(ch);
if (obar[(int)ch]) return obar[(int)ch]; if ((ob_pt = (Object **)BLI_ghash_lookup_p(family_gh, ch_key))) {
ob = *ob_pt;
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;
}
ob = ob->id.next;
} }
else {
obar[(int)ch] = ob; 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;
}
}
}
/* inserted value can be NULL, just to save searches in future */
BLI_ghash_insert(family_gh, ch_key, ob);
}
return ob; return ob;
} }
static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int persistent_id[MAX_DUPLI_RECUR], int level, short flag) 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; Curve *cu;
struct CharTrans *ct, *chartransdata = NULL; struct CharTrans *ct, *chartransdata = NULL;
float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof; 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 */ /* simple preventing of too deep nested groups */
if (level > MAX_DUPLI_RECUR) return; 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 */ /* 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); BKE_vfont_to_curve_ex(G.main, scene, par, FO_DUPLI,
if (chartransdata == NULL) return; &text, &text_len, &text_free, &chartransdata);
if (text == NULL || chartransdata == NULL) {
return;
}
cu = par->data; cu = par->data;
slen = strlen(cu->str);
fsize = cu->fsize; fsize = cu->fsize;
xof = cu->xof; xof = cu->xof;
yof = cu->yof; yof = cu->yof;
ct = chartransdata; 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) { if (ob) {
vec[0] = fsize * (ct->xof - xof); vec[0] = fsize * (ct->xof - xof);
vec[1] = fsize * (ct->yof - yof); 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); 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); MEM_freeN(chartransdata);
} }

View File

@@ -1375,7 +1375,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
ob->curve_cache->path = NULL; ob->curve_cache->path = NULL;
if (ob->type == OB_FONT) { 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 { else {
BKE_nurbList_duplicate(&nubase, BKE_curve_nurbs_get(cu)); BKE_nurbList_duplicate(&nubase, BKE_curve_nurbs_get(cu));

View File

@@ -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, bool BKE_vfont_to_curve_nubase_ex(Main *bmain, Scene *scene, Object *ob, int mode,
int mode, struct CharTrans **r_chartransdata) ListBase *r_nubase,
const wchar_t **r_text, int *r_text_len, bool *r_text_free,
struct CharTrans **r_chartransdata)
{ {
Curve *cu = ob->data; Curve *cu = ob->data;
EditFont *ef = cu->editfont; EditFont *ef = cu->editfont;
@@ -1020,7 +1022,7 @@ makebreak:
if (mode == FO_EDIT) { if (mode == FO_EDIT) {
/* make nurbdata */ /* make nurbdata */
BKE_nurbList_free(nubase); BKE_nurbList_free(r_nubase);
ct = chartransdata; ct = chartransdata;
for (i = 0; i < slen; i++) { for (i = 0; i < slen; i++) {
@@ -1037,7 +1039,7 @@ makebreak:
} }
/* We do not want to see any character for \n or \r */ /* We do not want to see any character for \n or \r */
if (cha != '\n' && cha != '\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')) { if ((info->flag & CU_CHINFO_UNDERLINE) && (cu->textoncurve == NULL) && (cha != '\n') && (cha != '\r')) {
float ulwidth, uloverlap = 0.0f; float ulwidth, uloverlap = 0.0f;
@@ -1054,7 +1056,7 @@ makebreak:
twidth = char_width(cu, che, info); twidth = char_width(cu, che, info);
ulwidth = cu->fsize * ((twidth * (1.0f + (info->kern / 40.0f))) + uloverlap); 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, ct->yof * cu->fsize + (cu->ulpos - 0.05f) * cu->fsize,
ct->xof * cu->fsize + ulwidth, ct->xof * cu->fsize + ulwidth,
ct->yof * cu->fsize + (cu->ulpos - 0.05f) * cu->fsize - cu->ulheight * cu->fsize, ct->yof * cu->fsize + (cu->ulpos - 0.05f) * cu->fsize - cu->ulheight * cu->fsize,
@@ -1068,8 +1070,18 @@ makebreak:
finally: 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 (chartransdata) {
if (ok && r_chartransdata) { if (ok && r_chartransdata) {
@@ -1083,12 +1095,33 @@ finally:
return ok; 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; Curve *cu = (Curve *) ob->data;
BLI_assert(ob->type == OB_FONT); 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);
} }

View File

@@ -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) if (recalc)
DAG_id_tag_update(obedit->data, 0); DAG_id_tag_update(obedit->data, 0);
@@ -1037,7 +1037,7 @@ static int move_cursor(bContext *C, int type, int select)
if (ef->selstart) { if (ef->selstart) {
struct Main *bmain = CTX_data_main(C); struct Main *bmain = CTX_data_main(C);
ef->selstart = ef->selend = 0; ef->selstart = ef->selend = 0;
BKE_vfont_to_curve(bmain, scene, obedit, FO_SELCHANGE, NULL); BKE_vfont_to_curve(bmain, scene, obedit, FO_SELCHANGE);
} }
} }

View File

@@ -930,9 +930,6 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
if (cu1->vfontbi) cu1->vfontbi->id.us--; if (cu1->vfontbi) cu1->vfontbi->id.us--;
cu1->vfontbi = cu->vfontbi; cu1->vfontbi = cu->vfontbi;
id_us_plus((ID *)cu1->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)); BLI_strncpy(cu1->family, cu->family, sizeof(cu1->family));

View File

@@ -212,10 +212,6 @@ typedef struct Curve {
void *lastsel; void *lastsel;
/* font part */ /* 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; short lines;
char spacemode, pad1; char spacemode, pad1;
float spacing, linedist, shear, fsize, wordspace, ulpos, ulheight; float spacing, linedist, shear, fsize, wordspace, ulpos, ulheight;
@@ -235,7 +231,7 @@ typedef struct Curve {
int selstart, selend; int selstart, selend;
int pad2; int pad2;
char family[24]; char family[64];
struct VFont *vfont; struct VFont *vfont;
struct VFont *vfontb; struct VFont *vfontb;
struct VFont *vfonti; struct VFont *vfonti;

View File

@@ -1009,9 +1009,9 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
prop = RNA_def_property(srna, "family", PROP_STRING, PROP_NONE); prop = RNA_def_property(srna, "family", PROP_STRING, PROP_NONE);
RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2);
RNA_def_property_ui_text(prop, "Object Font", RNA_def_property_ui_text(prop, "Object Font",
"Use Blender Objects as font characters (give font objects a common name " "Use Objects as font characters (give font objects a common name "
"followed by the character they represent, eg. family_a, family_b, etc, " "followed by the character they represent, eg. 'family_a', 'family_b', etc, "
"and turn on Verts Duplication)"); "and set this to 'family_', turn on Vertex Duplication)");
RNA_def_property_update(prop, 0, "rna_Curve_update_data"); RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop = RNA_def_property(srna, "body", PROP_STRING, PROP_NONE); prop = RNA_def_property(srna, "body", PROP_STRING, PROP_NONE);