[Bf-blender-cvs] [bec3131] master: Font Preview: much better handling of i18n case.

Bastien Montagne noreply at git.blender.org
Mon Jun 1 19:45:20 CEST 2015


Commit: bec3131112bb1f568f948e244784389523927111
Author: Bastien Montagne
Date:   Mon Jun 1 19:21:27 2015 +0200
Branches: master
https://developer.blender.org/rBbec3131112bb1f568f948e244784389523927111

Font Preview: much better handling of i18n case.

We have to regenerate previews when we change language. But we also need to do it
when translation is changed or added for a language, etc.

Previously, we were storing one preview per language, which was also stuffing
preview dir with (potentially) tens of PNGs per font file, if user plays with translations.

Now we use a better system, which is storing an additional optional metadata in previews
(some hexdigest), that Blender can use in addition to datetime to decide when to regenerate
previews.

This is only used (and needed) by font previews so far, but can easily be reused for other
types of previews if needed.

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

M	source/blender/imbuf/IMB_thumbs.h
M	source/blender/imbuf/intern/thumbs.c
M	source/blender/imbuf/intern/thumbs_font.c

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

diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
index 2cb5683..f2f7597 100644
--- a/source/blender/imbuf/IMB_thumbs.h
+++ b/source/blender/imbuf/IMB_thumbs.h
@@ -63,6 +63,11 @@ typedef enum ThumbSource {
 
 #define PREVIEW_RENDER_DEFAULT_HEIGHT 128
 
+/* Note this can also be used as versionning system,
+ * to force refreshing all thumbnails if e.g. we change some thumb generating code or so.
+ * Only used by fonts so far. */
+#define THUMB_DEFAULT_HASH  "00000000000000000000000000000000"
+
 /* create thumbnail for file and returns new imbuf for thumbnail */
 ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, ImBuf *ibuf);
 
@@ -84,7 +89,7 @@ void   IMB_thumb_overlay_blend(unsigned int *thumb, int width, int height, float
 
 /* special function for previewing fonts */
 ImBuf *IMB_thumb_load_font(const char *filename, unsigned int x, unsigned int y);
-const char *IMB_thumb_load_font_get_language(void);
+bool IMB_thumb_load_font_get_hash(char *r_hash);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index 626f02e..b42ec46 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -200,6 +200,17 @@ static void escape_uri_string(const char *string, char *escaped_string, int esca
 
 /** ----- end of adapted code from glib --- */
 
+static bool thumbhash_from_path(const char *UNUSED(path), ThumbSource source, char *r_hash)
+{
+	switch (source) {
+		case THB_SOURCE_FONT:
+			return IMB_thumb_load_font_get_hash(r_hash);
+		default:
+			r_hash[0] = '\0';
+			return false;
+	}
+}
+
 static int uri_from_filename(const char *path, char *uri)
 {
 	char orig_uri[URI_MAX];
@@ -298,7 +309,8 @@ void IMB_thumb_makedirs(void)
 
 /* create thumbnail for file and returns new imbuf for thumbnail */
 static ImBuf *thumb_create_ex(
-        const char *file_path, const char *uri, const char *thumb, ThumbSize size, ThumbSource source, ImBuf *img)
+        const char *file_path, const char *uri, const char *thumb, const bool use_hash, const char *hash,
+        ThumbSize size, ThumbSource source, ImBuf *img)
 {
 	char desc[URI_MAX + 22];
 	char tpath[FILE_MAX];
@@ -420,6 +432,9 @@ static ImBuf *thumb_create_ex(
 		IMB_metadata_change_field(img, "Software", "Blender");
 		IMB_metadata_change_field(img, "Thumb::URI", uri);
 		IMB_metadata_change_field(img, "Thumb::MTime", mtime);
+		if (use_hash) {
+			IMB_metadata_change_field(img, "X-Blender::Hash", hash);
+		}
 		if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) {
 			IMB_metadata_change_field(img, "Thumb::Image::Width", cwidth);
 			IMB_metadata_change_field(img, "Thumb::Image::Height", cheight);
@@ -447,7 +462,7 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im
 	uri_from_filename(path, uri);
 	thumbname_from_uri(uri, thumb_name, sizeof(thumb_name));
 
-	return thumb_create_ex(path, uri, thumb_name, size, source, img);
+	return thumb_create_ex(path, uri, thumb_name, false, THUMB_DEFAULT_HASH, size, source, img);
 }
 
 /* read thumbnail for file and returns new imbuf for thumbnail */
@@ -495,15 +510,10 @@ ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source
 	char uri[URI_MAX];
 	const char *file_path;
 	const char *path;
-	char path_buff[FILE_MAX];
 	BLI_stat_t st;
 	ImBuf *img = NULL;
 
 	path = file_path = org_path;
-	if (source == THB_SOURCE_FONT) {
-		BLI_snprintf(path_buff, sizeof(path_buff), "%s.%s", org_path, IMB_thumb_load_font_get_language());
-		path = path_buff;
-	}
 
 	if (BLI_stat(file_path, &st) == -1) {
 		return NULL;
@@ -532,24 +542,38 @@ ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source
 			img = IMB_loadiffname(thumb_path, IB_rect | IB_metadata, NULL);
 			if (img) {
 				char mtime[40];
-				if (!IMB_metadata_get_field(img, "Thumb::MTime", mtime, 40)) {
+
+				if (!IMB_metadata_get_field(img, "Thumb::MTime", mtime, sizeof(mtime))) {
 					/* illegal thumb, forget it! */
 					IMB_freeImBuf(img);
 					img = NULL;
 				}
 				else {
 					time_t t = atol(mtime);
-					if (st.st_mtime != t) {
+					char thumb_hash[33];
+					char thumb_hash_curr[33];
+
+					const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash);
+
+					if (use_hash) {
+						if (!IMB_metadata_get_field(img, "X-Blender::Hash", thumb_hash_curr, sizeof(thumb_hash_curr))) {
+							thumb_hash_curr[0] = '\0';
+						}
+					}
+
+					if (st.st_mtime != t ||
+					    (use_hash && (thumb_hash_curr[0] == '\0' || !STREQ(thumb_hash, thumb_hash_curr)))) {
 						/* recreate all thumbs */
 						IMB_freeImBuf(img);
 						img = NULL;
 						IMB_thumb_delete(path, THB_NORMAL);
 						IMB_thumb_delete(path, THB_LARGE);
 						IMB_thumb_delete(path, THB_FAIL);
-						img = thumb_create_ex(file_path, uri, thumb_name, size, source, NULL);
+						img = thumb_create_ex(file_path, uri, thumb_name, use_hash, thumb_hash, size, source, NULL);
 						if (!img) {
 							/* thumb creation failed, write fail thumb */
-							img = thumb_create_ex(file_path, uri, thumb_name, THB_FAIL, source, NULL);
+							img = thumb_create_ex(
+							          file_path, uri, thumb_name, use_hash, thumb_hash, THB_FAIL, source, NULL);
 							if (img) {
 								/* we don't need failed thumb anymore */
 								IMB_freeImBuf(img);
@@ -560,10 +584,14 @@ ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source
 				}
 			}
 			else {
-				img = thumb_create_ex(file_path, uri, thumb_name, size, source, NULL);
+				char thumb_hash[33];
+
+				const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash);
+
+				img = thumb_create_ex(file_path, uri, thumb_name, use_hash, thumb_hash, size, source, NULL);
 				if (!img) {
 					/* thumb creation failed, write fail thumb */
-					img = thumb_create_ex(file_path, uri, thumb_name, THB_FAIL, source, NULL);
+					img = thumb_create_ex(file_path, uri, thumb_name, use_hash, thumb_hash, THB_FAIL, source, NULL);
 					if (img) {
 						/* we don't need failed thumb anymore */
 						IMB_freeImBuf(img);
diff --git a/source/blender/imbuf/intern/thumbs_font.c b/source/blender/imbuf/intern/thumbs_font.c
index 7c94742..4b024f3 100644
--- a/source/blender/imbuf/intern/thumbs_font.c
+++ b/source/blender/imbuf/intern/thumbs_font.c
@@ -25,6 +25,9 @@
  */
 
 #include "BLI_utildefines.h"
+#include "BLI_string.h"
+#include "BLI_fileops.h"
+#include "BLI_hash_md5.h"
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
@@ -36,18 +39,18 @@
 #include "../../blenfont/BLF_api.h"
 #include "../../blenfont/BLF_translation.h"  /* 'N_' macro and BLF_lang_get()... */
 
+static const char *thumb_str[] = {
+    N_("AaBbCc"),
+
+    N_("The quick"),
+    N_("brown fox"),
+    N_("jumps over"),
+    N_("the lazy dog"),
+};
 
 struct ImBuf *IMB_thumb_load_font(const char *filename, unsigned int x, unsigned int y)
 {
 	const int font_size = y / 4;
-	const char *thumb_str[] = {
-	    N_("AaBbCc"),
-
-	    N_("The quick"),
-	    N_("brown fox"),
-	    N_("jumps over"),
-	    N_("the lazy dog"),
-	};
 
 	struct ImBuf *ibuf;
 	float font_color[4];
@@ -72,7 +75,26 @@ struct ImBuf *IMB_thumb_load_font(const char *filename, unsigned int x, unsigned
 	return ibuf;
 }
 
-const char *IMB_thumb_load_font_get_language(void)
+bool IMB_thumb_load_font_get_hash(char *r_hash)
 {
-	return BLF_lang_get();
+	char buf[1024];
+	char *str = buf;
+	size_t len = 0;
+
+	int draw_str_lines = ARRAY_SIZE(thumb_str);
+	int i;
+
+	unsigned char digest[16];
+
+	len += BLI_strncpy_rlen(str + len, THUMB_DEFAULT_HASH, sizeof(buf) - len);
+
+	for (i = 0; (i < draw_str_lines) && (len < sizeof(buf)); i++) {
+		len += BLI_strncpy_rlen(str + len, BLF_translate_do(BLF_I18NCONTEXT_DEFAULT, thumb_str[i]), sizeof(buf) - len);
+	}
+
+	BLI_hash_md5_buffer(str, len, digest);
+	r_hash[0] = '\0';
+	BLI_hash_md5_to_hexdigest(digest, r_hash);
+
+	return true;
 }




More information about the Bf-blender-cvs mailing list