fix/edits to vector font handling
authorCampbell Barton <ideasman42@gmail.com>
Fri, 3 Aug 2012 15:03:40 +0000 (15:03 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 3 Aug 2012 15:03:40 +0000 (15:03 +0000)
- don't overwrite the font path with "<builtin>" 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
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/font.c
source/blender/blenlib/intern/freetypefont.c
source/blender/makesrna/intern/rna_vfont.c
source/blender/windowmanager/intern/wm_files.c

index 6636a70e94d5de8299a1ecc2ab698be465986a3f..d1f0f8c8c2335ca7eb06459be4485cdc9b337542 100644 (file)
@@ -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);
 
index 636f60c7ce133f160698161b3b50b58cfe947d1e..87ebc597ecd6ff16d3b15e442c23bd3adc297d99 100644 (file)
@@ -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 */
index 050f921998daae68a31fa86f2162dac20b2f6f8a..1ea8291adb1f7e936b93207262fceeb145fa8aec 100644 (file)
 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();
                        }
                }
index 774e37a847611c3e13ecf3e1c4bf9653501b51d8..60999e76c47333441880dfcd025626cef72bcbd0 100644 (file)
@@ -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;
index ad9c91b3623aa8d4dfe74b2c13e152b2ce9f2439..b65db1c809caaa5bf29a28b2c9966e7bff8dafe2 100644 (file)
 
 #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");
index a90a1dfe43a2eb8cb4dc450764d75382f2b442cc..d4b55677af1a9cc0c77fef883f22d13e754ec479 100644 (file)
@@ -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) {