Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarley Acheson <harley.acheson@gmail.com>2020-06-06 01:39:17 +0300
committerHarley Acheson <harley.acheson@gmail.com>2020-06-06 01:39:17 +0300
commitb74cc23dc478f2c4260e2e4269c8450e3d5c450e (patch)
treee540058bab2816422cff19043ffb1766a804f6e8 /source/blender/blenfont
parentfc672ce8e24e5fc62a42010dad790324f2b99a2d (diff)
UI: Ability to Print Bold and Italics
Adds the ability to print text in bold or italics style, synthesized from a single base UI font. Differential Revision: https://developer.blender.org/D7893 Reviewed by Brecht Van Lommel
Diffstat (limited to 'source/blender/blenfont')
-rw-r--r--source/blender/blenfont/BLF_api.h2
-rw-r--r--source/blender/blenfont/intern/blf_font.c11
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c81
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h10
-rw-r--r--source/blender/blenfont/intern/blf_thumbs.c9
5 files changed, 67 insertions, 46 deletions
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index ddb88cf61ed..1d0cb2f524c 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -279,6 +279,8 @@ void BLF_state_print(int fontid);
#define BLF_HINTING_NONE (1 << 8)
#define BLF_HINTING_SLIGHT (1 << 9)
#define BLF_HINTING_FULL (1 << 10)
+#define BLF_BOLD (1 << 11)
+#define BLF_ITALIC (1 << 12)
#define BLF_DRAW_STR_DUMMY_MAX 1024
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index e5e03418073..da6224cff7f 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -290,7 +290,6 @@ void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
gc = blf_glyph_cache_find(font, size, dpi);
if (gc) {
- font->glyph_cache = gc;
/* Optimization: do not call FT_Set_Char_Size if size did not change. */
if (font->size == size && font->dpi == dpi) {
blf_glyph_cache_release(font);
@@ -311,13 +310,7 @@ void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
font->dpi = dpi;
if (!gc) {
- gc = blf_glyph_cache_new(font);
- if (gc) {
- font->glyph_cache = gc;
- }
- else {
- font->glyph_cache = NULL;
- }
+ blf_glyph_cache_new(font);
}
blf_glyph_cache_release(font);
}
@@ -1309,7 +1302,6 @@ void blf_font_free(FontBLF *font)
BLI_spin_lock(&blf_glyph_cache_mutex);
GlyphCacheBLF *gc;
- font->glyph_cache = NULL;
while ((gc = BLI_pophead(&font->cache))) {
blf_glyph_cache_free(gc);
}
@@ -1356,7 +1348,6 @@ static void blf_font_fill(FontBLF *font)
font->size = 0;
BLI_listbase_clear(&font->cache);
BLI_listbase_clear(&font->kerning_caches);
- font->glyph_cache = NULL;
font->kerning_cache = NULL;
#if BLF_BLUR_ENABLE
font->blur = 0;
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index ce17069e53f..1867df3100c 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -119,7 +119,8 @@ GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, unsigned int size, unsigned i
p = (GlyphCacheBLF *)font->cache.first;
while (p) {
- if (p->size == size && p->dpi == dpi) {
+ if (p->size == size && p->dpi == dpi && (p->bold == ((font->flags & BLF_BOLD) != 0)) &&
+ (p->italic == ((font->flags & BLF_ITALIC) != 0))) {
return p;
}
p = p->next;
@@ -127,7 +128,7 @@ GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, unsigned int size, unsigned i
return NULL;
}
-/* Create a new glyph cache for the current size and dpi. */
+/* Create a new glyph cache for the current size, dpi, bold, italic. */
GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
{
GlyphCacheBLF *gc;
@@ -137,6 +138,8 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
gc->prev = NULL;
gc->size = font->size;
gc->dpi = font->dpi;
+ gc->bold = ((font->flags & BLF_BOLD) != 0);
+ gc->italic = ((font->flags & BLF_ITALIC) != 0);
memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table));
memset(gc->bucket, 0, sizeof(gc->bucket));
@@ -172,20 +175,13 @@ GlyphCacheBLF *blf_glyph_cache_acquire(FontBLF *font)
{
BLI_spin_lock(font->glyph_cache_mutex);
- GlyphCacheBLF *gc;
+ GlyphCacheBLF *gc = blf_glyph_cache_find(font, font->size, font->dpi);
- if (!font->glyph_cache) {
+ if (!gc) {
gc = blf_glyph_cache_new(font);
- if (gc) {
- font->glyph_cache = gc;
- }
- else {
- font->glyph_cache = NULL;
- return NULL;
- }
}
- return font->glyph_cache;
+ return gc;
}
void blf_glyph_cache_release(FontBLF *font)
@@ -202,7 +198,6 @@ void blf_glyph_cache_clear(FontBLF *font)
while ((gc = BLI_pophead(&font->cache))) {
blf_glyph_cache_free(gc);
}
- font->glyph_cache = NULL;
BLI_spin_unlock(font->glyph_cache_mutex);
}
@@ -269,28 +264,65 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
return g;
}
+ int load_flags;
+ int render_mode;
+
if (font->flags & BLF_MONOCHROME) {
- err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_MONO);
+ load_flags = FT_LOAD_TARGET_MONO;
+ render_mode = FT_RENDER_MODE_MONO;
}
else {
- int flags = FT_LOAD_NO_BITMAP;
-
+ load_flags = FT_LOAD_NO_BITMAP;
+ render_mode = FT_RENDER_MODE_NORMAL;
if (font->flags & BLF_HINTING_NONE) {
- flags |= FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING;
+ load_flags |= FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING;
}
else if (font->flags & BLF_HINTING_SLIGHT) {
- flags |= FT_LOAD_TARGET_LIGHT;
+ load_flags |= FT_LOAD_TARGET_LIGHT;
}
else if (font->flags & BLF_HINTING_FULL) {
- flags |= FT_LOAD_TARGET_NORMAL;
+ load_flags |= FT_LOAD_TARGET_NORMAL;
}
else {
/* Default, hinting disabled until FreeType has been upgraded
* to give good results on all platforms. */
- flags |= FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING;
+ load_flags |= FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING;
}
+ }
- err = FT_Load_Glyph(font->face, (FT_UInt)index, flags);
+ err = FT_Load_Glyph(font->face, (FT_UInt)index, load_flags);
+
+ /* Do not oblique a font that is designed to be italic! */
+ if (((font->flags & BLF_ITALIC) != 0) && !(font->face->style_flags & FT_STYLE_FLAG_ITALIC) &&
+ (font->face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)) {
+ /* For (fake) italic: a shear transform with a 6 degree angle. */
+ FT_Matrix transform;
+ transform.xx = 0x10000L;
+ transform.yx = 0x00000L;
+ transform.xy = 0x03000L;
+ transform.yy = 0x10000L;
+ FT_Outline_Transform(&font->face->glyph->outline, &transform);
+ }
+
+ /* Do not embolden an already bold font! */
+ if (((font->flags & BLF_BOLD) != 0) &&
+ !(font->face->style_flags & FT_STYLE_FLAG_BOLD) &
+ (font->face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)) {
+ /* Strengthen the width more than the height. */
+ const FT_Pos extra_x = FT_MulFix(font->face->units_per_EM, font->face->size->metrics.x_scale) /
+ 14;
+ const FT_Pos extra_y = FT_MulFix(font->face->units_per_EM, font->face->size->metrics.y_scale) /
+ 28;
+ FT_Outline_EmboldenXY(&font->face->glyph->outline, extra_x, extra_y);
+ if ((font->face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) == 0) {
+ /* Need to increase advance, but not for fixed-width fonts. */
+ font->face->glyph->advance.x += (int) (extra_x * 1.05f);
+ font->face->glyph->advance.y += extra_y;
+ }
+ else {
+ /* Widened fixed-pitch font gets a nudge left. */
+ FT_Outline_Translate(&font->face->glyph->outline, (extra_x / -2), 0);
+ }
}
if (err) {
@@ -300,23 +332,18 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
/* get the glyph. */
slot = font->face->glyph;
+ err = FT_Render_Glyph(slot, render_mode);
if (font->flags & BLF_MONOCHROME) {
- err = FT_Render_Glyph(slot, FT_RENDER_MODE_MONO);
-
/* Convert result from 1 bit per pixel to 8 bit per pixel */
/* Accum errors for later, fine if not interested beyond "ok vs any error" */
FT_Bitmap_New(&tempbitmap);
/* Does Blender use Pitch 1 always? It works so far */
err += FT_Bitmap_Convert(font->ft_lib, &slot->bitmap, &tempbitmap, 1);
-
err += FT_Bitmap_Copy(font->ft_lib, &tempbitmap, &slot->bitmap);
err += FT_Bitmap_Done(font->ft_lib, &tempbitmap);
}
- else {
- err = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);
- }
if (err || slot->format != FT_GLYPH_FORMAT_BITMAP) {
BLI_spin_unlock(font->ft_lib_mutex);
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 362cbf6730f..34b674670fd 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -65,6 +65,9 @@ typedef struct GlyphCacheBLF {
/* and dpi. */
unsigned int dpi;
+ bool bold;
+ bool italic;
+
/* and the glyphs. */
ListBase bucket[257];
@@ -218,13 +221,10 @@ typedef struct FontBLF {
/* font options. */
int flags;
- /* list of glyph cache for this font. */
- ListBase cache;
-
- /* current glyph cache, size and dpi.
+ /* List of glyph caches (GlyphCacheBLF) for this font for size, dpi, bold, italic.
* Use blf_glyph_cache_acquire(font) and blf_glyph_cache_release(font) to access cache!
*/
- GlyphCacheBLF *glyph_cache;
+ ListBase cache;
/* list of kerning cache for this font. */
ListBase kerning_caches;
diff --git a/source/blender/blenfont/intern/blf_thumbs.c b/source/blender/blenfont/intern/blf_thumbs.c
index 37eed29f6fe..6aa39e3aa71 100644
--- a/source/blender/blenfont/intern/blf_thumbs.c
+++ b/source/blender/blenfont/intern/blf_thumbs.c
@@ -66,6 +66,7 @@ void BLF_thumb_preview(const char *filename,
int font_shrink = 4;
FontBLF *font;
+ GlyphCacheBLF *gc;
int i;
/* Create a new blender font obj and fill it with default values */
@@ -96,9 +97,9 @@ void BLF_thumb_preview(const char *filename,
int draw_str_i18n_nbr = 0;
blf_font_size(font, (unsigned int)MAX2(font_size_min, font_size_curr), dpi);
-
- /* font->glyph_cache remains NULL if blf_font_size() failed to set font size */
- if (!font->glyph_cache) {
+ gc = blf_glyph_cache_find(font, font->size, font->dpi);
+ /* There will be no matching glyph cache if blf_font_size() failed to set font size. */
+ if (!gc) {
break;
}
@@ -106,7 +107,7 @@ void BLF_thumb_preview(const char *filename,
font_size_curr -= (font_size_curr / font_shrink);
font_shrink += 1;
- font->pos[1] -= font->glyph_cache->ascender * 1.1f;
+ font->pos[1] -= gc->ascender * 1.1f;
/* We fallback to default english strings in case not enough chars are available in current
* font for given translated string (useful in non-latin i18n context, like Chinese,