diff options
Diffstat (limited to 'source/blender/blenfont/intern')
-rw-r--r-- | source/blender/blenfont/intern/blf_font.c | 41 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_glyph.c | 8 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_internal.h | 3 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_internal_types.h | 4 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_lang.c | 13 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_thumbs.c | 121 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_translation.c | 28 |
7 files changed, 201 insertions, 17 deletions
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 087c7c7345e..2057b0f6bbf 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -286,10 +286,9 @@ void blf_font_buffer(FontBLF *font, const char *str) (unsigned char)(buf_info->col[2] * 255), (unsigned char)(buf_info->col[3] * 255)}; - unsigned char *cbuf; int chx, chy; int y, x; - float a, *fbuf; + float a; BLF_KERNING_VARS(font, has_kerning, kern_mode); @@ -349,8 +348,12 @@ void blf_font_buffer(FontBLF *font, const char *str) a = *(g->bitmap + x + (yb * g->pitch)) / 255.0f; if (a > 0.0f) { + const size_t buf_ofs = ( + ((size_t)(chx + x) + ((size_t)(pen_y + y) * (size_t)buf_info->w)) * + (size_t)buf_info->ch); + float *fbuf = buf_info->fbuf + buf_ofs; float alphatest; - fbuf = buf_info->fbuf + buf_info->ch * ((chx + x) + ((pen_y + y) * buf_info->w)); + if (a >= 1.0f) { fbuf[0] = b_col_float[0]; fbuf[1] = b_col_float[1]; @@ -375,13 +378,17 @@ void blf_font_buffer(FontBLF *font, const char *str) if (buf_info->cbuf) { int yb = yb_start; - for (y = 0; y < height_clip; y++) { - for (x = 0; x < width_clip; x++) { + for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) { + for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) { a = *(g->bitmap + x + (yb * g->pitch)) / 255.0f; if (a > 0.0f) { + const size_t buf_ofs = ( + ((size_t)(chx + x) + ((size_t)(pen_y + y) * (size_t)buf_info->w)) * + (size_t)buf_info->ch); + unsigned char *cbuf = buf_info->cbuf + buf_ofs; int alphatest; - cbuf = buf_info->cbuf + buf_info->ch * ((chx + x) + ((pen_y + y) * buf_info->w)); + if (a >= 1.0f) { cbuf[0] = b_col_char[0]; cbuf[1] = b_col_char[1]; @@ -667,6 +674,28 @@ float blf_font_fixed_width(FontBLF *font) return g->advance; } +int blf_font_count_missing_chars(FontBLF *font, const char *str, const size_t len, int *r_tot_chars) +{ + int missing = 0; + size_t i = 0; + + *r_tot_chars = 0; + while (i < len) { + unsigned int c; + + if ((c = str[i]) < 0x80) { + i++; + } + else if ((c = BLI_str_utf8_as_unicode_step(str, &i)) != BLI_UTF8_ERR) { + if (FT_Get_Char_Index((font)->face, c) == 0) { + missing++; + } + } + (*r_tot_chars)++; + } + return missing; +} + void blf_font_free(FontBLF *font) { GlyphCacheBLF *gc; diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index c65a0825a49..215d2484c18 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -199,7 +199,7 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) GlyphBLF *g; FT_Error err; FT_Bitmap bitmap, tempbitmap; - int sharp = (U.text_render & USER_TEXT_DISABLE_AA); + const bool is_sharp = (U.text_render & USER_TEXT_DISABLE_AA) != 0; int flags = FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; FT_BBox bbox; unsigned int key; @@ -224,7 +224,7 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) if (font->flags & BLF_HINTING) flags &= ~FT_LOAD_NO_HINTING; - if (sharp) + if (is_sharp) err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_MONO); else err = FT_Load_Glyph(font->face, (FT_UInt)index, flags); @@ -237,7 +237,7 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) /* get the glyph. */ slot = font->face->glyph; - if (sharp) { + if (is_sharp) { err = FT_Render_Glyph(slot, FT_RENDER_MODE_MONO); /* Convert result from 1 bit per pixel to 8 bit per pixel */ @@ -266,7 +266,7 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) g->height = (int)bitmap.rows; if (g->width && g->height) { - if (sharp) { + if (is_sharp) { /* Font buffer uses only 0 or 1 values, Blender expects full 0..255 range */ int i; for (i = 0; i < (g->width * g->height); i++) { diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h index 39b3e3397be..85410a4d856 100644 --- a/source/blender/blenfont/intern/blf_internal.h +++ b/source/blender/blenfont/intern/blf_internal.h @@ -62,6 +62,9 @@ void blf_font_width_and_height(struct FontBLF *font, const char *str, size_t len float blf_font_width(struct FontBLF *font, const char *str, size_t len); float blf_font_height(struct FontBLF *font, const char *str, size_t len); float blf_font_fixed_width(struct FontBLF *font); + +int blf_font_count_missing_chars(struct FontBLF *font, const char *str, const size_t len, int *r_tot_chars); + void blf_font_free(struct FontBLF *font); struct GlyphCacheBLF *blf_glyph_cache_find(struct FontBLF *font, unsigned int size, unsigned int dpi); diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index da756d65483..1404b9de250 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -48,7 +48,7 @@ typedef struct GlyphCacheBLF { struct GlyphBLF *glyph_ascii_table[256]; /* texture array, to draw the glyphs. */ - GLuint *textures; + unsigned int *textures; /* size of the array. */ unsigned int ntex; @@ -103,7 +103,7 @@ typedef struct GlyphBLF { int advance_i; /* texture id where this glyph is store. */ - GLuint tex; + unsigned int tex; /* position inside the texture where this glyph is store. */ int xoff; diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index 99e1aa5d3e3..4683081a1ed 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -284,12 +284,15 @@ void BLF_lang_set(const char *str) const char *BLF_lang_get(void) { #ifdef WITH_INTERNATIONAL - const char *locale = LOCALE(ULANGUAGE); - if (locale[0] == '\0') { - /* Default locale, we have to find which one we are actually using! */ - locale = bl_locale_get(); + if (BLF_translate()) { + const char *locale = LOCALE(ULANGUAGE); + if (locale[0] == '\0') { + /* Default locale, we have to find which one we are actually using! */ + locale = bl_locale_get(); + } + return locale; } - return locale; + return "en_US"; /* Kind of default locale in Blender when no translation enabled. */ #else return ""; #endif diff --git a/source/blender/blenfont/intern/blf_thumbs.c b/source/blender/blenfont/intern/blf_thumbs.c new file mode 100644 index 00000000000..4b7a568b8b0 --- /dev/null +++ b/source/blender/blenfont/intern/blf_thumbs.c @@ -0,0 +1,121 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Thomas Beck + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenfont/intern/blf_thumbs.c + * \ingroup blf + * + * Utility function to generate font preview images. + * + * Isolate since this needs to be called by #ImBuf code (bad level call). + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <ft2build.h> + +#include FT_FREETYPE_H + +#include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_rect.h" +#include "BLI_threads.h" + +#include "blf_internal.h" +#include "blf_internal_types.h" + +#include "BLF_api.h" +#include "BLF_translation.h" + +#include "BLI_strict_flags.h" + +/** + * This function is used for generating thumbnail previews. + * + * \note called from a thread, so it bypasses the normal BLF_* api (which isn't thread-safe). + */ +void BLF_thumb_preview( + const char *filename, + const char **draw_str, const unsigned char draw_str_lines, + const float font_color[4], const int font_size, + unsigned char *buf, int w, int h, int channels) +{ + const unsigned int dpi = 72; + const int font_size_min = 6; + int font_size_curr; + /* shrink 1/th each line */ + int font_shrink = 4; + + FontBLF *font; + int i; + + /* Create a new blender font obj and fill it with default values */ + font = blf_font_new("thumb_font", filename); + if (!font) { + printf("Info: Can't load font '%s', no preview possible\n", filename); + return; + } + + /* Would be done via the BLF API, but we're not using a fontid here */ + font->buf_info.cbuf = buf; + font->buf_info.ch = channels; + font->buf_info.w = w; + font->buf_info.h = h; + + /* Always create the image with a white font, + * the caller can theme how it likes */ + memcpy(font->buf_info.col, font_color, sizeof(font->buf_info.col)); + font->pos[1] = (float)h; + + font_size_curr = font_size; + + for (i = 0; i < draw_str_lines; i++) { + const char *draw_str_i18n = BLF_translate_do(BLF_I18NCONTEXT_DEFAULT, draw_str[i]); + const size_t draw_str_i18n_len = strlen(draw_str_i18n); + int draw_str_i18n_nbr = 0; + + blf_font_size(font, (unsigned int)MAX2(font_size_min, font_size_curr), dpi); + + /* decrease font size each time */ + font_size_curr -= (font_size_curr / font_shrink); + font_shrink += 1; + + font->pos[1] -= font->glyph_cache->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, since many fonts will then show + * nothing but ugly 'missing char' in their preview). + * Does not handle all cases, but much better than nothing. + */ + if (blf_font_count_missing_chars( + font, draw_str_i18n, draw_str_i18n_len, &draw_str_i18n_nbr) > (draw_str_i18n_nbr / 2)) + { + blf_font_buffer(font, draw_str[i]); + } + else { + blf_font_buffer(font, draw_str_i18n); + } + } + + blf_font_free(font); +} diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c index 2a4a152f0eb..5d828d9b7be 100644 --- a/source/blender/blenfont/intern/blf_translation.c +++ b/source/blender/blenfont/intern/blf_translation.c @@ -46,7 +46,9 @@ #include "DNA_userdef_types.h" /* For user settings. */ +#ifdef WITH_PYTHON #include "BPY_extern.h" +#endif #ifdef WITH_INTERNATIONAL @@ -152,9 +154,11 @@ const char *BLF_pgettext(const char *msgctxt, const char *msgid) /* We assume if the returned string is the same (memory level) as the msgid, no translation was found, * and we can try py scripts' ones! */ +#ifdef WITH_PYTHON if (ret == msgid) { ret = BPY_app_translations_py_pgettext(msgctxt, msgid); } +#endif } return ret; @@ -164,6 +168,15 @@ const char *BLF_pgettext(const char *msgctxt, const char *msgid) #endif } +bool BLF_translate(void) +{ +#ifdef WITH_INTERNATIONAL + return (U.transopts & USER_DOTRANSLATE) != 0; +#else + return false; +#endif +} + bool BLF_translate_iface(void) { #ifdef WITH_INTERNATIONAL @@ -191,6 +204,21 @@ bool BLF_translate_new_dataname(void) #endif } +const char *BLF_translate_do(const char *msgctxt, const char *msgid) +{ +#ifdef WITH_INTERNATIONAL + if (BLF_translate()) { + return BLF_pgettext(msgctxt, msgid); + } + else { + return msgid; + } +#else + (void)msgctxt; + return msgid; +#endif +} + const char *BLF_translate_do_iface(const char *msgctxt, const char *msgid) { #ifdef WITH_INTERNATIONAL |