[Bf-blender-cvs] [524a9e3db81] master: BLF: Fallback Font Stack
Harley Acheson
noreply at git.blender.org
Fri Jun 17 19:31:57 CEST 2022
Commit: 524a9e3db8102c89abf3b80cddaea60c314d67ae
Author: Harley Acheson
Date: Fri Jun 17 10:30:34 2022 -0700
Branches: master
https://developer.blender.org/rB524a9e3db8102c89abf3b80cddaea60c314d67ae
BLF: Fallback Font Stack
Allow use of multiple fonts acting together like a fallback stack,
where if a glyph is not found in one it can be retrieved from another.
See D12622 for much more detail
Differential Revision: https://developer.blender.org/D12622
Reviewed by Brecht Van Lommel
===================================================================
M source/blender/blenfont/BLF_api.h
M source/blender/blenfont/intern/blf.c
M source/blender/blenfont/intern/blf_font.c
M source/blender/blenfont/intern/blf_font_default.c
M source/blender/blenfont/intern/blf_glyph.c
M source/blender/blenfont/intern/blf_internal.h
M source/blender/blenfont/intern/blf_internal_types.h
M source/blender/blenlib/intern/string_utf8.c
M source/blender/editors/interface/interface_style.cc
M source/blender/windowmanager/intern/wm_playanim.c
===================================================================
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index e5e2b1711b1..78c8612f7f5 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -14,6 +14,15 @@
extern "C" {
#endif
+/* Name of subfolder inside BLENDER_DATAFILES that contains font files. */
+#define BLF_DATAFILES_FONTS_DIR "fonts"
+
+/* File name of the default variable-width font. */
+#define BLF_DEFAULT_PROPORTIONAL_FONT "droidsans.ttf"
+
+/* File name of the default fixed-pitch font. */
+#define BLF_DEFAULT_MONOSPACED_FONT "bmonofont-i18n.ttf"
+
/* enable this only if needed (unused circa 2016) */
#define BLF_BLUR_ENABLE 0
@@ -37,12 +46,14 @@ void BLF_cache_flush_set_fn(void (*cache_flush_fn)(void));
*/
int BLF_load(const char *name) ATTR_NONNULL();
int BLF_load_mem(const char *name, const unsigned char *mem, int mem_size) ATTR_NONNULL();
+bool BLF_is_loaded(const char *name) ATTR_NONNULL();
int BLF_load_unique(const char *name) ATTR_NONNULL();
int BLF_load_mem_unique(const char *name, const unsigned char *mem, int mem_size) ATTR_NONNULL();
void BLF_unload(const char *name) ATTR_NONNULL();
void BLF_unload_id(int fontid);
+void BLF_unload_all(void);
char *BLF_display_name_from_file(const char *filepath);
@@ -312,6 +323,7 @@ int BLF_set_default(void);
int BLF_load_default(bool unique);
int BLF_load_mono_default(bool unique);
+void BLF_load_font_stack(void);
#ifdef DEBUG
void BLF_state_print(int fontid);
@@ -331,6 +343,9 @@ void BLF_state_print(int fontid);
#define BLF_HINTING_FULL (1 << 10)
#define BLF_BOLD (1 << 11)
#define BLF_ITALIC (1 << 12)
+#define BLF_MONOSPACED (1 << 13) /* Intended USE is monospaced, regardless of font type. */
+#define BLF_DEFAULT (1 << 14) /* A font within the default stack of fonts. */
+#define BLF_LAST_RESORT (1 << 15) /* Must only be used as last font in the stack. */
#define BLF_DRAW_STR_DUMMY_MAX 1024
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index a944ab332bd..a1fcc17ca3f 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -34,13 +34,6 @@
#include "blf_internal.h"
#include "blf_internal_types.h"
-/* Max number of font in memory.
- * Take care that now every font have a glyph cache per size/dpi,
- * so we don't need load the same font with different size, just
- * load one and call BLF_size.
- */
-#define BLF_MAX_FONT 16
-
#define BLF_RESULT_CHECK_INIT(r_info) \
if (r_info) { \
memset(r_info, 0, sizeof(*(r_info))); \
@@ -48,7 +41,7 @@
((void)0)
/* Font array. */
-static FontBLF *global_font[BLF_MAX_FONT] = {NULL};
+FontBLF *global_font[BLF_MAX_FONT] = {NULL};
/* XXX: should these be made into global_font_'s too? */
@@ -134,6 +127,11 @@ bool BLF_has_glyph(int fontid, unsigned int unicode)
return false;
}
+bool BLF_is_loaded(const char *name)
+{
+ return blf_search(name) >= 0;
+}
+
int BLF_load(const char *name)
{
/* check if we already load this font. */
@@ -255,6 +253,20 @@ void BLF_unload_id(int fontid)
}
}
+void BLF_unload_all(void)
+{
+ for (int i = 0; i < BLF_MAX_FONT; i++) {
+ FontBLF *font = global_font[i];
+ if (font) {
+ blf_font_free(font);
+ global_font[i] = NULL;
+ }
+ }
+ blf_mono_font = -1;
+ blf_mono_font_render = -1;
+ BLF_default_set(-1);
+}
+
void BLF_enable(int fontid, int option)
{
FontBLF *font = blf_get(fontid);
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index a170f27d247..26a72fcb95a 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -18,6 +18,7 @@
#include FT_FREETYPE_H
#include FT_GLYPH_H
+#include FT_TRUETYPE_TABLES_H /* For TT_OS2 */
#include "MEM_guardedalloc.h"
@@ -1288,6 +1289,25 @@ FontBLF *blf_font_new(const char *name, const char *filepath)
font->filepath = BLI_strdup(filepath);
blf_font_fill(font);
+ /* Save TrueType table with bits to quickly test most unicode block coverage. */
+ TT_OS2 *os2_table = (TT_OS2 *)FT_Get_Sfnt_Table(font->face, FT_SFNT_OS2);
+ if (os2_table) {
+ font->UnicodeRanges[0] = (uint)os2_table->ulUnicodeRange1;
+ font->UnicodeRanges[1] = (uint)os2_table->ulUnicodeRange2;
+ font->UnicodeRanges[2] = (uint)os2_table->ulUnicodeRange3;
+ font->UnicodeRanges[3] = (uint)os2_table->ulUnicodeRange4;
+ }
+
+ /* Detect "Last resort" fonts. They have everything. Usually except last 5 bits. */
+ if (font->UnicodeRanges[0] == 0xffffffffU && font->UnicodeRanges[1] == 0xffffffffU &&
+ font->UnicodeRanges[2] == 0xffffffffU && font->UnicodeRanges[3] >= 0x7FFFFFFU) {
+ font->flags |= BLF_LAST_RESORT;
+ }
+
+ if (FT_IS_FIXED_WIDTH(font->face)) {
+ font->flags |= BLF_MONOSPACED;
+ }
+
if (FT_HAS_KERNING(font->face)) {
/* Create kerning cache table and fill with value indicating "unset". */
font->kerning_cache = MEM_mallocN(sizeof(KerningCacheBLF), __func__);
diff --git a/source/blender/blenfont/intern/blf_font_default.c b/source/blender/blenfont/intern/blf_font_default.c
index 3a68423e64e..1bde25b5776 100644
--- a/source/blender/blenfont/intern/blf_font_default.c
+++ b/source/blender/blenfont/intern/blf_font_default.c
@@ -11,13 +11,14 @@
#include "BLF_api.h"
+#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BKE_appdir.h"
static int blf_load_font_default(const char *filename, const bool unique)
{
- const char *dir = BKE_appdir_folder_id(BLENDER_DATAFILES, "fonts");
+ const char *dir = BKE_appdir_folder_id(BLENDER_DATAFILES, BLF_DATAFILES_FONTS_DIR);
if (dir == NULL) {
fprintf(stderr,
"%s: 'fonts' data path not found for '%s', will not be able to display text\n",
@@ -34,10 +35,46 @@ static int blf_load_font_default(const char *filename, const bool unique)
int BLF_load_default(const bool unique)
{
- return blf_load_font_default("droidsans.ttf", unique);
+ int font_id = blf_load_font_default(BLF_DEFAULT_PROPORTIONAL_FONT, unique);
+ BLF_enable(font_id, BLF_DEFAULT);
+ return font_id;
}
int BLF_load_mono_default(const bool unique)
{
- return blf_load_font_default("bmonofont-i18n.ttf", unique);
+ int font_id = blf_load_font_default(BLF_DEFAULT_MONOSPACED_FONT, unique);
+ BLF_enable(font_id, BLF_MONOSPACED | BLF_DEFAULT);
+ return font_id;
+}
+
+void BLF_load_font_stack()
+{
+ /* Load these if not already, might have been replaced by user custom. */
+ BLF_load_default(false);
+ BLF_load_mono_default(false);
+
+ const char *path = BKE_appdir_folder_id(BLENDER_DATAFILES, BLF_DATAFILES_FONTS_DIR SEP_STR);
+ if (path && BLI_exists(path)) {
+ struct direntry *dir;
+ uint num_files = BLI_filelist_dir_contents(path, &dir);
+ for (int f = 0; f < num_files; f++) {
+ if (!FILENAME_IS_CURRPAR(dir[f].relname) && !BLI_is_dir(dir[f].path)) {
+ if (!BLF_is_loaded(dir[f].path)) {
+ int font_id = BLF_load(dir[f].path);
+ if (font_id == -1) {
+ fprintf(stderr, "Unable to load font: %s\n", dir[f].path);
+ }
+ else {
+ BLF_enable(font_id, BLF_DEFAULT);
+ /* TODO: FontBLF will later load FT_Face on demand. When this is in
+ * place we can drop this face now since we have all needed data. */
+ }
+ }
+ }
+ }
+ BLI_filelist_free(dir, num_files);
+ }
+ else {
+ fprintf(stderr, "Fonts not found at %s\n", path);
+ }
}
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 2694b179a11..32d4be3be0c 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -39,6 +39,7 @@
#include "BLI_math_vector.h"
#include "BLI_strict_flags.h"
+#include "BLI_string_utf8.h"
/* -------------------------------------------------------------------- */
/** \name Internal Utilities
@@ -222,6 +223,335 @@ static GlyphBLF *blf_glyph_cache_add_glyph(
return g;
}
+/* This table can be used to find a coverage bit based on a charcode. later we can get default
+ * language and script from codepoint. */
+
+typedef struct eUnicodeBlock {
+ unsigned int first;
+ unsigned int last;
+ int coverage_bit; /* 0-122. -1 is N/A. */
+ /* Later we add primary script and language for Harfbuzz, data from
+ * https://en.wikipedia.org/wiki/Unicode_block */
+} eUnicodeBlock;
+
+static eUnicodeBlock unicode_blocks[] = {
+ /* Must be in ascending order by start of range. */
+ {0x0, 0x7F, 0}, /* Basic Latin. */
+ {0x80, 0xFF, 1}, /* Latin-1 Supplement. */
+ {0x100, 0x17F, 2}, /* Latin Extended-A. */
+ {0x180, 0x24F, 3}, /* Latin Extended-B. */
+ {0x250, 0x2AF, 4}, /* IPA Extensions. */
+ {0x2B0, 0x2FF, 5}, /* Spacing Modifier Letters. */
+ {0x300, 0x36F, 6}, /* Combining Diacritical Marks. */
+ {0x370, 0x3FF, 7}, /* Greek. */
+ {0x400, 0x52F, 9}, /* Cyrillic. */
+ {0x530, 0x58F, 10}, /* Armenian. */
+ {0x590, 0x5FF, 11}, /* Hebrew. */
+ {0x600, 0x6FF, 13}, /* Arabic. */
+ {0x700, 0x74F, 71}, /* Syriac. */
+ {0x750, 0x77F, 13}, /* Arabic Supplement. */
+ {0x780, 0x7BF, 72}, /* Thaana. */
+ {0x7C0, 0x7FF, 14}, /* NKo. */
+ {0x800, 0x83F, -1}, /* Samaritan. */
+ {0x840, 0x85F, -1}, /* Mandaic. */
+ {0x900, 0x97F, 15}, /* Devanagari. */
+ {0x980, 0x9FF, 16}, /* Bengali. */
+ {0xA00, 0xA7F, 17}, /* Gurmukhi. */
+ {0xA80, 0xAFF, 18}, /* Gujarati. */
+ {0xB00, 0xB7F, 19}, /* Oriya. */
+ {0xB80, 0xBFF, 20}, /* Tamil. */
+ {0xC00, 0xC7F, 21}, /* Telugu. */
+ {0xC80, 0xCFF, 22}, /* Kannada. */
+ {0xD00, 0xD7F, 23}, /* Malayalam. */
+ {0xD80, 0xDFF, 73}, /* Sinhala. */
+ {0xE00, 0xE7F, 24}, /* Thai. */
+ {0xE80, 0xEFF, 25}, /* Lao. */
+ {0xF00, 0xFFF, 70}, /* Tibetan. */
+ {0x1000, 0x109F, 74}, /* Myanmar. */
+ {0x10A0, 0x10FF, 26}, /* Georgian. */
+ {0x1100, 0x11FF, 28}, /* Hangul Jamo. */
+ {0x1200, 0x139F, 75}, /* Ethiopic. */
+ {0
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list