From 173b998735ee30bdb4335ae2c65cf656d9249504 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 3 Aug 2012 15:03:40 +0000 Subject: fix/edits to vector font handling - don't overwrite the font path with "" when the font file cant be found, it caused bad problems when loading files on someone elses systems when paths couldn't be found blender would silently clobber paths (tsk tsk). - when fonts are freed their temp data is now freed too. - assigning a new filepath to a font now refreshes the object data. --- source/blender/blenkernel/BKE_font.h | 5 +- source/blender/blenkernel/intern/depsgraph.c | 12 +++++ source/blender/blenkernel/intern/font.c | 66 +++++++++++++++++++------- source/blender/blenlib/intern/freetypefont.c | 2 +- source/blender/makesrna/intern/rna_vfont.c | 23 ++++++++- source/blender/windowmanager/intern/wm_files.c | 4 +- 6 files changed, 90 insertions(+), 22 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h index 6636a70e94d..d1f0f8c8c23 100644 --- a/source/blender/blenkernel/BKE_font.h +++ b/source/blender/blenkernel/BKE_font.h @@ -73,11 +73,14 @@ typedef struct EditFont { void BKE_vfont_builtin_register(void *mem, int size); +void BKE_vfont_free_data(struct VFont *vf); void BKE_vfont_free(struct VFont *sc); void BKE_vfont_free_global_ttf(void); struct VFont *BKE_vfont_builtin_get(void); struct VFont *BKE_vfont_load(struct Main *bmain, const char *name); -struct TmpFont *BKE_vfont_find_tmpfont(struct VFont *vfont); + +struct TmpFont *BKE_vfont_tmpfont_find(struct VFont *vfont); +void BKE_vfont_tmpfont_remove(struct VFont *vfont); struct chartrans *BKE_vfont_to_curve(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 636f60c7ce1..87ebc597ecd 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2846,6 +2846,18 @@ void DAG_id_tag_update(ID *id, short flag) } } } + else if (idtype == ID_VF) { + /* this is weak still, should be done delayed as well */ + for (ob = bmain->object.first; ob; ob = ob->id.next) { + if (ob->type == OB_FONT) { + Curve *cu = ob->data; + + if (ELEM4((struct VFont *)id, cu->vfont, cu->vfontb, cu->vfonti, cu->vfontbi)) { + ob->recalc |= (flag & OB_RECALC_ALL); + } + } + } + } else { /* disable because this is called on various ID types automatically. * where printing warning is not useful. for now just ignore */ diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 050f921998d..1ea8291adb1 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -63,26 +63,34 @@ static ListBase ttfdata = {NULL, NULL}; /* The vfont code */ -void BKE_vfont_free(struct VFont *vf) -{ - if (vf == NULL) return; +void BKE_vfont_free_data(struct VFont *vf) +{ if (vf->data) { while (vf->data->characters.first) { VChar *che = vf->data->characters.first; - + while (che->nurbsbase.first) { Nurb *nu = che->nurbsbase.first; if (nu->bezt) MEM_freeN(nu->bezt); BLI_freelinkN(&che->nurbsbase, nu); } - + BLI_freelinkN(&vf->data->characters, che); } MEM_freeN(vf->data); vf->data = NULL; } + + BKE_vfont_tmpfont_remove(vf); +} + +void BKE_vfont_free(struct VFont *vf) +{ + if (vf == NULL) return; + + BKE_vfont_free_data(vf); if (vf->packedfile) { freePackedFile(vf->packedfile); @@ -115,34 +123,54 @@ static PackedFile *get_builtin_packedfile(void) } } +static void vfont_tmpfont_free(struct TmpFont *tf) +{ + if (tf->pf) { + freePackedFile(tf->pf); /* NULL when the font file can't be found on disk */ + } + MEM_freeN(tf); +} + void BKE_vfont_free_global_ttf(void) { - struct TmpFont *tf; + struct TmpFont *tf, *tf_next; - for (tf = ttfdata.first; tf; tf = tf->next) { - if (tf->pf) freePackedFile(tf->pf); /* NULL when the font file can't be found on disk */ - tf->pf = NULL; - tf->vfont = NULL; + for (tf = ttfdata.first; tf; tf = tf_next) { + tf_next = tf->next; + vfont_tmpfont_free(tf); } - BLI_freelistN(&ttfdata); + ttfdata.first = ttfdata.last = NULL; } -struct TmpFont *BKE_vfont_find_tmpfont(VFont *vfont) +struct TmpFont *BKE_vfont_tmpfont_find(VFont *vfont) { struct TmpFont *tmpfnt = NULL; if (vfont == NULL) return NULL; /* Try finding the font from font list */ - tmpfnt = ttfdata.first; - while (tmpfnt) { - if (tmpfnt->vfont == vfont) + for (tmpfnt = ttfdata.first; tmpfnt; tmpfnt = tmpfnt->next) { + if (tmpfnt->vfont == vfont) { break; - tmpfnt = tmpfnt->next; + } } + return tmpfnt; } +/* assumes a VFont's tmpfont can't be in the database more then once */ +void BKE_vfont_tmpfont_remove(VFont *vfont) +{ + struct TmpFont *tmpfnt; + + tmpfnt = BKE_vfont_tmpfont_find(vfont); + + if (tmpfnt) { + vfont_tmpfont_free(tmpfnt); + BLI_remlink(&ttfdata, tmpfnt); + } +} + static VFontData *vfont_get_data(Main *bmain, VFont *vfont) { struct TmpFont *tmpfnt = NULL; @@ -151,7 +179,7 @@ static VFontData *vfont_get_data(Main *bmain, VFont *vfont) if (vfont == NULL) return NULL; /* Try finding the font from font list */ - tmpfnt = BKE_vfont_find_tmpfont(vfont); + tmpfnt = BKE_vfont_tmpfont_find(vfont); /* And then set the data */ if (!vfont->data) { @@ -194,7 +222,11 @@ static VFontData *vfont_get_data(Main *bmain, VFont *vfont) if (!pf) { printf("Font file doesn't exist: %s\n", vfont->name); + /* DON'T DO THIS + * missing file shouldn't modifty path! - campbell */ +#if 0 strcpy(vfont->name, FO_BUILTIN_NAME); +#endif pf = get_builtin_packedfile(); } } diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 774e37a8476..60999e76c47 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -296,7 +296,7 @@ static int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode) struct TmpFont *tf; /* Find the correct FreeType font */ - tf = BKE_vfont_find_tmpfont(vfont); + tf = BKE_vfont_tmpfont_find(vfont); /* What, no font found. Something strange here */ if (!tf) return FALSE; diff --git a/source/blender/makesrna/intern/rna_vfont.c b/source/blender/makesrna/intern/rna_vfont.c index ad9c91b3623..b65db1c809c 100644 --- a/source/blender/makesrna/intern/rna_vfont.c +++ b/source/blender/makesrna/intern/rna_vfont.c @@ -32,19 +32,37 @@ #include "DNA_vfont_types.h" +#include "WM_types.h" + + #ifdef RNA_RUNTIME +#include "BKE_font.h" +#include "BKE_depsgraph.h" +#include "DNA_object_types.h" + +#include "WM_api.h" + /* matching fnction in rna_ID.c */ static int rna_VectorFont_filepath_editable(PointerRNA *ptr) { - VFont *vf = (VFont *)ptr->data; + VFont *vf = ptr->id.data; if (strcmp(vf->name, FO_BUILTIN_NAME) == 0) { return 0; } - return 1; } +static void rna_VectorFont_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + VFont *vf = ptr->id.data; + BKE_vfont_free_data(vf); + + /* update */ + WM_main_add_notifier(NC_GEOM | ND_DATA, NULL); + DAG_id_tag_update(&vf->id, OB_RECALC_OB | OB_RECALC_DATA); +} + #else void RNA_def_vfont(BlenderRNA *brna) @@ -61,6 +79,7 @@ void RNA_def_vfont(BlenderRNA *brna) RNA_def_property_string_sdna(prop, NULL, "name"); RNA_def_property_editable_func(prop, "rna_VectorFont_filepath_editable"); RNA_def_property_ui_text(prop, "File Path", ""); + RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_VectorFont_reload_update"); prop = RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "packedfile"); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index a90a1dfe43a..d4b55677af1 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -380,6 +380,8 @@ void WM_read_file(bContext *C, const char *filepath, ReportList *reports) /* assume automated tasks with background, don't write recent file list */ const int do_history = (G.background == FALSE) && (CTX_wm_manager(C)->op_undo_depth == 0); + BKE_vfont_free_global_ttf(); + /* put aside screens to match with persistent windows later */ /* also exit screens and editors */ wm_window_match_init(C, &wmbase); @@ -489,7 +491,7 @@ int WM_read_homefile(bContext *C, ReportList *UNUSED(reports), short from_memory char tstr[FILE_MAX]; int success = 0; - BKE_vfont_free_global_ttf(); /* still weird... what does it here? */ + BKE_vfont_free_global_ttf(); G.relbase_valid = 0; if (!from_memory) { -- cgit v1.2.3