diff options
Diffstat (limited to 'source/blender/blenfont')
-rw-r--r-- | source/blender/blenfont/BLF_api.h | 3 | ||||
-rw-r--r-- | source/blender/blenfont/BLF_translation.h | 112 | ||||
-rw-r--r-- | source/blender/blenfont/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/blenfont/SConscript | 32 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf.c | 27 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_dir.c | 1 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_font.c | 34 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_glyph.c | 32 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_internal.h | 1 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_internal_types.h | 2 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_lang.c | 146 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_translation.c | 118 |
12 files changed, 416 insertions, 93 deletions
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index 6f348ccc267..fd8bd196717 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -37,6 +37,7 @@ struct ColorManagedDisplay; int BLF_init(int points, int dpi); void BLF_exit(void); +void BLF_default_dpi(int dpi); void BLF_cache_clear(void); @@ -76,6 +77,7 @@ void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t l /* Draw the string using the current font. */ void BLF_draw(int fontid, const char *str, size_t len); void BLF_draw_ascii(int fontid, const char *str, size_t len); +int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth); /* This function return the bounding box of the string * and are not multiplied by the aspect. @@ -182,6 +184,7 @@ void BLF_dir_free(char **dirs, int count); #define BLF_KERNING_DEFAULT (1 << 3) #define BLF_MATRIX (1 << 4) #define BLF_ASPECT (1 << 5) +#define BLF_HINTING (1 << 6) #define BLF_DRAW_STR_DUMMY_MAX 1024 diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h index 159d4b067b6..dc72c77b3bf 100644 --- a/source/blender/blenfont/BLF_translation.h +++ b/source/blender/blenfont/BLF_translation.h @@ -33,6 +33,8 @@ #ifndef __BLF_TRANSLATION_H__ #define __BLF_TRANSLATION_H__ +#include "BLI_utildefines.h" /* for bool type */ + #define TEXT_DOMAIN_NAME "blender" /* blf_lang.c */ @@ -48,26 +50,37 @@ void BLF_lang_free(void); /* Set the current locale. */ void BLF_lang_set(const char *); -/* Get the current locale (short code, e.g. es_ES). */ +/* Get the current locale ([partial] ISO code, e.g. es_ES). */ const char *BLF_lang_get(void); +/* Get locale's elements (if relevant pointer is not NULL and element actually exists, e.g. if there is no variant, + * *variant and *language_variant will always be NULL). + * Non-null elements are always MEM_mallocN'ed, it's the caller's responsibility to free them. + * NOTE: Always available, even in non-WITH_INTERNATIONAL builds. + */ +void BLF_locale_explode(const char *locale, char **language, char **country, char **variant, + char **language_country, char **language_variant); + /* Get EnumPropertyItem's for translations menu. */ struct EnumPropertyItem *BLF_RNA_lang_enum_properties(void); /* blf_translation.c */ -#ifdef WITH_INTERNATIONAL unsigned char *BLF_get_unifont(int *unifont_size); void BLF_free_unifont(void); -#endif +unsigned char *BLF_get_unifont_mono(int *unifont_size); +void BLF_free_unifont_mono(void); +bool BLF_is_default_context(const char *msgctxt); const char *BLF_pgettext(const char *msgctxt, const char *msgid); /* translation */ -int BLF_translate_iface(void); -int BLF_translate_tooltips(void); +bool BLF_translate_iface(void); +bool BLF_translate_tooltips(void); +bool BLF_translate_new_dataname(void); const char *BLF_translate_do_iface(const char *msgctxt, const char *msgid); const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid); +const char *BLF_translate_do_new_dataname(const char *msgctxt, const char *msgid); /* The "translation-marker" macro. */ @@ -76,22 +89,26 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid); /* Those macros should be used everywhere in UI code. */ #ifdef WITH_INTERNATIONAL -/* #define _(msgid) BLF_gettext(msgid) */ - #define IFACE_(msgid) BLF_translate_do_iface(NULL, msgid) - #define TIP_(msgid) BLF_translate_do_tooltip(NULL, msgid) - #define CTX_IFACE_(context, msgid) BLF_translate_do_iface(context, msgid) - #define CTX_TIP_(context, msgid) BLF_translate_do_tooltip(context, msgid) +/*# define _(msgid) BLF_gettext(msgid) */ +# define IFACE_(msgid) BLF_translate_do_iface(NULL, msgid) +# define TIP_(msgid) BLF_translate_do_tooltip(NULL, msgid) +# define DATA_(msgid) BLF_translate_do_new_dataname(NULL, msgid) +# define CTX_IFACE_(context, msgid) BLF_translate_do_iface(context, msgid) +# define CTX_TIP_(context, msgid) BLF_translate_do_tooltip(context, msgid) +# define CTX_DATA_(context, msgid) BLF_translate_do_new_dataname(context, msgid) #else -/* #define _(msgid) msgid */ - #define IFACE_(msgid) msgid - #define TIP_(msgid) msgid - #define CTX_IFACE_(context, msgid) ((void)context, msgid) - #define CTX_TIP_(context, msgid) ((void)context, msgid) +/*# define _(msgid) msgid */ +# define IFACE_(msgid) msgid +# define TIP_(msgid) msgid +# define DATA_(msgid) msgid +# define CTX_IFACE_(context, msgid) msgid +# define CTX_TIP_(context, msgid) msgid +# define CTX_DATA_(context, msgid) msgid #endif /* Helper macro, when we want to define a same msgid for multiple msgctxt... * Does nothing in C, but is "parsed" by our i18n py tools. - * XXX Currently limited to at most 16 contexts at most + * XXX Currently limited to at most 16 contexts at once * (but you can call it several times with the same msgid, should you need more contexts!). */ #define BLF_I18N_MSGID_MULTI_CTXT(msgid, ...) @@ -100,10 +117,19 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid); * All i18n contexts must be defined here. * This is a nice way to be sure not to use a context twice for different * things, and limit the number of existing contexts! + * WARNING! Contexts should not be longer than BKE_ST_MAXNAME - 1! */ -/* Default, void context. Just in case... */ -#define BLF_I18NCONTEXT_DEFAULT "" +/* Default, void context. + * WARNING! The "" context is not the same as no (NULL) context at mo/boost::locale level! + * NOTE: We translate BLF_I18NCONTEXT_DEFAULT as BLF_I18NCONTEXT_DEFAULT_BPY in Python, as we can't use "natural" + * None value in rna string properties... :/ + * The void string "" is also interpreted as BLF_I18NCONTEXT_DEFAULT. + * For perf reason, we only use the first char to detect this context, so other contexts should never start + * with the same char! + */ +#define BLF_I18NCONTEXT_DEFAULT NULL +#define BLF_I18NCONTEXT_DEFAULT_BPYRNA "*" /* Default context for operator names/labels. */ #define BLF_I18NCONTEXT_OPERATOR_DEFAULT "Operator" @@ -115,6 +141,7 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid); #define BLF_I18NCONTEXT_ID_BRUSH "Brush" #define BLF_I18NCONTEXT_ID_CAMERA "Camera" #define BLF_I18NCONTEXT_ID_CURVE "Curve" +#define BLF_I18NCONTEXT_ID_FREESTYLELINESTYLE "FreestyleLineStyle" #define BLF_I18NCONTEXT_ID_GPENCIL "GPencil" #define BLF_I18NCONTEXT_ID_GROUP "Group" #define BLF_I18NCONTEXT_ID_ID "ID" @@ -143,4 +170,53 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid); #define BLF_I18NCONTEXT_ID_MOVIECLIP "MovieClip" #define BLF_I18NCONTEXT_ID_MASK "Mask" +/* Helper for bpy.app.i18n object... */ +typedef struct +{ + const char *c_id; + const char *py_id; + const char *value; +} BLF_i18n_contexts_descriptor; + +#define BLF_I18NCONTEXTS_ITEM(ctxt_id, py_id) {#ctxt_id, py_id, ctxt_id} + +#define BLF_I18NCONTEXTS_DESC { \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT, "default_real"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT_BPYRNA, "default"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "operator_default"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ACTION, "id_action"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ARMATURE, "id_armature"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_BRUSH, "id_brush"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_CAMERA, "id_camera"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_CURVE, "id_curve"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_GPENCIL, "id_gpencil"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_GROUP, "id_group"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ID, "id_id"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_IMAGE, "id_image"), \ + /*BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_IPO, "id_ipo"),*/ \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SHAPEKEY, "id_shapekey"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LAMP, "id_lamp"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LIBRARY, "id_library"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LATTICE, "id_lattice"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MATERIAL, "id_material"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_METABALL, "id_metaball"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MESH, "id_mesh"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_NODETREE, "id_nodetree"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_OBJECT, "id_object"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_PARTICLESETTINGS, "id_particlesettings"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SCENE, "id_scene"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SCREEN, "id_screen"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SEQUENCE, "id_sequence"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SPEAKER, "id_speaker"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SOUND, "id_sound"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_TEXTURE, "id_texture"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_TEXT, "id_text"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_VFONT, "id_vfont"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_WORLD, "id_world"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_WINDOWMANAGER, "id_windowmanager"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MOVIECLIP, "id_movieclip"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MASK, "id_mask"), \ + {NULL, NULL, NULL} \ +} + #endif /* __BLF_TRANSLATION_H__ */ diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt index 90baef14a74..7bb80c34323 100644 --- a/source/blender/blenfont/CMakeLists.txt +++ b/source/blender/blenfont/CMakeLists.txt @@ -29,6 +29,7 @@ set(INC ../editors/include ../makesdna ../makesrna + ../python ../imbuf ../../../intern/guardedalloc ../../../intern/locale diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript index c0591c877ef..3529330a308 100644 --- a/source/blender/blenfont/SConscript +++ b/source/blender/blenfont/SConscript @@ -1,11 +1,37 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys Import ('env') sources = env.Glob('intern/*.c') incs = '. intern #/intern/guardedalloc #/intern/locale ../blenkernel ../blenlib ../blenloader' -incs += ' ../makesdna ../makesrna ../imbuf ../editors/include' +incs += ' ../makesdna ../makesrna ../python ../imbuf ../editors/include' incs += ' #/extern/glew/include' incs += ' ' + env['BF_FREETYPE_INC'] @@ -17,4 +43,4 @@ if sys.platform == 'win32' or env['OURPLATFORM'] == 'linuxcross': if env['WITH_BF_INTERNATIONAL']: defs.append('WITH_INTERNATIONAL') -env.BlenderLib ( 'bf_blenfont', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[210,210] ) +env.BlenderLib ( 'bf_blenfont', sources, Split(incs), defines=defs, libtype=['core','player'], priority=[210,210] ) diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 778b6c11e5a..6523aa87473 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -43,6 +43,8 @@ #include "DNA_listBase.h" #include "DNA_vec_types.h" +#include "BLI_math.h" + #include "BIF_gl.h" #include "BLF_api.h" @@ -87,6 +89,11 @@ int BLF_init(int points, int dpi) return blf_font_init(); } +void BLF_default_dpi(int dpi) +{ + global_font_dpi = dpi; +} + void BLF_exit(void) { FontBLF *font; @@ -511,8 +518,8 @@ static void blf_draw__start(FontBLF *font, GLint *mode, GLint *param) if (font->flags & BLF_ASPECT) glScalef(font->aspect[0], font->aspect[1], font->aspect[2]); - if (font->flags & BLF_ROTATION) - glRotatef(font->angle, 0.0f, 0.0f, 1.0f); + if (font->flags & BLF_ROTATION) /* radians -> degrees */ + glRotatef(font->angle * (float)(180.0 / M_PI), 0.0f, 0.0f, 1.0f); if (font->shadow || font->blur) glGetFloatv(GL_CURRENT_COLOR, font->orig_col); @@ -569,6 +576,21 @@ void BLF_draw_ascii(int fontid, const char *str, size_t len) } } +int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth) +{ + FontBLF *font = blf_get(fontid); + GLint mode, param; + int columns = 0; + + if (font && font->glyph_cache) { + blf_draw__start(font, &mode, ¶m); + columns = blf_font_draw_mono(font, str, len, cwidth); + blf_draw__end(mode, param); + } + + return columns; +} + void BLF_boundbox(int fontid, const char *str, rctf *box) { FontBLF *font = blf_get(fontid); @@ -597,6 +619,7 @@ void BLF_width_and_height_default(const char *str, float *width, float *height) return; } + BLF_size(global_font_default, global_font_points, global_font_dpi); BLF_width_and_height(global_font_default, str, width, height); } diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c index b6a98faa48c..116a55c0579 100644 --- a/source/blender/blenfont/intern/blf_dir.c +++ b/source/blender/blenfont/intern/blf_dir.c @@ -41,6 +41,7 @@ #include "DNA_vec_types.h" +#include "BLI_utildefines.h" #include "BLI_fileops.h" #include "BLI_listbase.h" #include "BLI_path_util.h" diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 1900efa2dbc..f2c36475870 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -219,6 +219,40 @@ void blf_font_draw_ascii(FontBLF *font, const char *str, size_t len) } } +/* use fixed column width, but an utf8 character may occupy multiple columns */ +int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth) +{ + unsigned int c; + GlyphBLF *g; + int col, columns = 0; + int pen_x = 0, pen_y = 0; + size_t i = 0; + GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table; + + blf_font_ensure_ascii_table(font); + + while ((i < len) && str[i]) { + BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table); + + if (c == BLI_UTF8_ERR) + break; + if (g == NULL) + continue; + + /* do not return this loop if clipped, we want every character tested */ + blf_glyph_render(font, g, (float)pen_x, (float)pen_y); + + col = BLI_wcwidth((wchar_t)c); + if (col < 0) + col = 1; + + columns += col; + pen_x += cwidth * col; + } + + return columns; +} + /* Sanity checks are done by BLF_draw_buffer() */ void blf_font_buffer(FontBLF *font, const char *str) { diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 91ecded88be..a6b04b24399 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -83,7 +83,7 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font) memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table)); memset(gc->bucket, 0, sizeof(gc->bucket)); - gc->textures = (GLuint *)malloc(sizeof(GLuint) * 256); + gc->textures = (GLuint *)MEM_mallocN(sizeof(GLuint) * 256, __func__); gc->ntex = 256; gc->cur_tex = -1; gc->x_offs = 0; @@ -150,7 +150,7 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc) if (gc->cur_tex + 1 > 0) glDeleteTextures(gc->cur_tex + 1, gc->textures); - free((void *)gc->textures); + MEM_freeN((void *)gc->textures); MEM_freeN(gc); } @@ -178,8 +178,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc) gc->p2_height = font->max_tex_size; tot_mem = gc->p2_width * gc->p2_height; - buf = (unsigned char *)malloc(tot_mem); - memset((void *)buf, 0, tot_mem); + buf = (unsigned char *)MEM_callocN(tot_mem, __func__); glGenTextures(1, &gc->textures[gc->cur_tex]); glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = gc->textures[gc->cur_tex])); @@ -189,7 +188,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, gc->p2_width, gc->p2_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buf); - free((void *)buf); + MEM_freeN((void *)buf); } GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c) @@ -214,6 +213,7 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) FT_Error err; FT_Bitmap bitmap, tempbitmap; int sharp = (U.text_render & USER_TEXT_DISABLE_AA); + int flags = FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; FT_BBox bbox; unsigned int key; @@ -221,10 +221,13 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) if (g) return g; + if (font->flags & BLF_HINTING) + flags &= ~FT_LOAD_NO_HINTING; + if (sharp) err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_MONO); else - err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP); /* Sure about NO_* flags? */ + err = FT_Load_Glyph(font->face, (FT_UInt)index, flags); if (err) return NULL; @@ -383,7 +386,7 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y) if (gc->cur_tex == -1) { blf_glyph_cache_texture(font, gc); gc->x_offs = gc->pad; - gc->y_offs = gc->pad; + gc->y_offs = 0; } if (gc->x_offs > (gc->p2_width - gc->max_glyph_width)) { @@ -391,7 +394,7 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y) gc->y_offs += gc->max_glyph_height; if (gc->y_offs > (gc->p2_height - gc->max_glyph_height)) { - gc->y_offs = gc->pad; + gc->y_offs = 0; blf_glyph_cache_texture(font, gc); } } @@ -400,6 +403,19 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y) g->xoff = gc->x_offs; g->yoff = gc->y_offs; + /* prevent glTexSubImage2D from failing if the character + * asks for pixels out of bounds, this tends only to happen + * with very small sizes (5px high or less) */ + if (UNLIKELY((g->xoff + g->width) > gc->p2_width)) { + g->width -= (g->xoff + g->width) - gc->p2_width; + BLI_assert(g->width > 0); + } + if (UNLIKELY((g->yoff + g->height) > gc->p2_height)) { + g->height -= (g->yoff + g->height) - gc->p2_height; + BLI_assert(g->height > 0); + } + + glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h index 65a54783978..b1301be46fd 100644 --- a/source/blender/blenfont/intern/blf_internal.h +++ b/source/blender/blenfont/intern/blf_internal.h @@ -53,6 +53,7 @@ void blf_font_attach_from_mem(struct FontBLF *font, const unsigned char *mem, in void blf_font_size(struct FontBLF *font, int size, int dpi); void blf_font_draw(struct FontBLF *font, const char *str, size_t len); void blf_font_draw_ascii(struct FontBLF *font, const char *str, size_t len); +int blf_font_draw_mono(struct FontBLF *font, const char *str, size_t len, int cwidth); void blf_font_buffer(struct FontBLF *font, const char *str); void blf_font_boundbox(struct FontBLF *font, const char *str, struct rctf *box); void blf_font_width_and_height(struct FontBLF *font, const char *str, float *width, float *height); diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index 1acc3dad4cf..de6e70e4461 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -166,7 +166,7 @@ typedef struct FontBLF { /* initial position for draw the text. */ float pos[3]; - /* angle in degrees. */ + /* angle in radians. */ float angle; /* blur: 3 or 5 large kernel */ diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index 0ed48623dd5..65abfc52ee5 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -27,30 +27,28 @@ * \ingroup blf */ - -#include "BLF_translation.h" /* own include */ - -#ifdef WITH_INTERNATIONAL - #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "boost_locale_wrapper.h" - -#include "BKE_global.h" - -#include "DNA_userdef_types.h" - #include "RNA_types.h" -#include "MEM_guardedalloc.h" +#include "BLF_translation.h" /* own include */ #include "BLI_fileops.h" #include "BLI_linklist.h" #include "BLI_path_util.h" #include "BLI_string.h" -#include "BLI_utildefines.h" + +#include "BKE_global.h" + +#include "DNA_userdef_types.h" + +#include "MEM_guardedalloc.h" + +#ifdef WITH_INTERNATIONAL + +#include "boost_locale_wrapper.h" /* Locale options. */ static const char **locales = NULL; @@ -58,9 +56,6 @@ static int num_locales = 0; static EnumPropertyItem *locales_menu = NULL; static int num_locales_menu = 0; -#define ULANGUAGE ((U.language >= 0 && U.language < num_locales) ? U.language : 0) -#define LOCALE(_id) (locales ? locales[_id] : "") - static void free_locales(void) { if (locales) { @@ -83,15 +78,16 @@ static void free_locales(void) static void fill_locales(void) { - char *languages_path = BLI_get_folder(BLENDER_DATAFILES, "locale"); + const char * const languages_path = BLI_get_folder(BLENDER_DATAFILES, "locale"); + char languages[FILE_MAX]; LinkNode *lines = NULL, *line; char *str; int idx = 0; free_locales(); - BLI_join_dirfile(languages_path, FILE_MAX, languages_path, "languages"); - line = lines = BLI_file_read_as_lines(languages_path); + BLI_join_dirfile(languages, FILE_MAX, languages_path, "languages"); + line = lines = BLI_file_read_as_lines(languages); /* This whole "parsing" code is a bit weak, in that it expects strictly formated input file... * Should not be a problem, though, as this file is script-generated! */ @@ -99,7 +95,7 @@ static void fill_locales(void) /* First loop to find highest locale ID */ while (line) { int t; - str = (char*) line->link; + str = (char *)line->link; if (str[0] == '#' || str[0] == '\0') { line = line->next; continue; /* Comment or void... */ @@ -112,17 +108,17 @@ static void fill_locales(void) } num_locales_menu++; /* The "closing" void item... */ - /* And now, buil locales and locale_menu! */ + /* And now, build locales and locale_menu! */ locales_menu = MEM_callocN(num_locales_menu * sizeof(EnumPropertyItem), __func__); line = lines; /* Do not allocate locales with zero-sized mem, as LOCALE macro uses NULL locales as invalid marker! */ if (num_locales > 0) { - locales = MEM_callocN(num_locales * sizeof(char*), __func__); + locales = MEM_callocN(num_locales * sizeof(char *), __func__); while (line) { int id; char *loc, *sep1, *sep2, *sep3; - str = (char*) line->link; + str = (char *)line->link; if (str[0] == '#' || str[0] == '\0') { line = line->next; continue; @@ -176,15 +172,21 @@ static void fill_locales(void) BLI_file_free_lines(lines); } +#endif /* WITH_INTERNATIONAL */ EnumPropertyItem *BLF_RNA_lang_enum_properties(void) { +#ifdef WITH_INTERNATIONAL return locales_menu; +#else + return NULL; +#endif } void BLF_lang_init(void) { - char *messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale"); +#ifdef WITH_INTERNATIONAL + const char * const messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale"); if (messagepath) { bl_locale_init(messagepath, TEXT_DOMAIN_NAME); @@ -193,15 +195,26 @@ void BLF_lang_init(void) else { printf("%s: 'locale' data path for translations not found, continuing\n", __func__); } +#else +#endif } void BLF_lang_free(void) { +#ifdef WITH_INTERNATIONAL free_locales(); +#else +#endif } +#ifdef WITH_INTERNATIONAL +# define ULANGUAGE ((U.language >= 0 && U.language < num_locales) ? U.language : 0) +# define LOCALE(_id) (locales ? locales[(_id)] : "") +#endif + void BLF_lang_set(const char *str) { +#ifdef WITH_INTERNATIONAL int ulang = ULANGUAGE; const char *short_locale = str ? str : LOCALE(ulang); const char *short_locale_utf8 = NULL; @@ -229,40 +242,79 @@ void BLF_lang_set(const char *str) bl_locale_set(short_locale_utf8); if (short_locale[0]) { - MEM_freeN((void*)short_locale_utf8); + MEM_freeN((void *)short_locale_utf8); } +#else + (void)str; +#endif } +/* Get the current locale (short code, e.g. es_ES). */ const char *BLF_lang_get(void) { - int uilang = ULANGUAGE; - return LOCALE(uilang); +#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(); + } + return locale; +#else + return ""; +#endif } #undef LOCALE #undef ULANGUAGE -#else /* ! WITH_INTERNATIONAL */ - -void BLF_lang_init(void) +/* Get locale's elements (if relevant pointer is not NULL and element actually exists, e.g. if there is no variant, + * *variant and *language_variant will always be NULL). + * Non-null elements are always MEM_mallocN'ed, it's the caller's responsibility to free them. + * NOTE: Keep that one always available, you never know, may become useful even in no-WITH_INTERNATIONAL context... + */ +void BLF_locale_explode(const char *locale, char **language, char **country, char **variant, + char **language_country, char **language_variant) { - return; -} + char *m1, *m2, *_t = NULL; -void BLF_lang_free(void) -{ - return; -} + m1 = strchr(locale, '_'); + m2 = strchr(locale, '@'); -void BLF_lang_set(const char *str) -{ - (void)str; - return; -} - -const char *BLF_lang_get(void) -{ - return ""; + if (language || language_variant) { + if (m1 || m2) { + _t = m1 ? BLI_strdupn(locale, m1 - locale) : BLI_strdupn(locale, m2 - locale); + if (language) + *language = _t; + } + else if (language) { + *language = BLI_strdup(locale); + } + } + if (country) { + if (m1) + *country = m2 ? BLI_strdupn(m1 + 1, m2 - (m1 + 1)) : BLI_strdup(m1 + 1); + else + *country = NULL; + } + if (variant) { + if (m2) + *variant = BLI_strdup(m2 + 1); + else + *variant = NULL; + } + if (language_country) { + if (m1) + *language_country = m2 ? BLI_strdupn(locale, m2 - locale) : BLI_strdup(locale); + else + *language_country = NULL; + } + if (language_variant) { + if (m2) + *language_variant = m1 ? BLI_strdupcat(_t, m2) : BLI_strdup(locale); + else + *language_variant = NULL; + } + if (_t && !language) { + MEM_freeN(_t); + } } - -#endif /* WITH_INTERNATIONAL */ diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c index 5d4b631688a..57f442f8bfc 100644 --- a/source/blender/blenfont/intern/blf_translation.c +++ b/source/blender/blenfont/intern/blf_translation.c @@ -33,28 +33,33 @@ #include "BLF_translation.h" -#ifdef WITH_INTERNATIONAL - -#include "boost_locale_wrapper.h" - #include "MEM_guardedalloc.h" -#include "BLI_utildefines.h" +#include "BLI_fileops.h" #include "BLI_path_util.h" #include "BLI_string.h" -#include "BLI_path_util.h" -#include "BLI_fileops.h" #include "DNA_userdef_types.h" /* For user settings. */ +#include "BPY_extern.h" + +#ifdef WITH_INTERNATIONAL + +#include "boost_locale_wrapper.h" + static const char unifont_filename[] = "droidsans.ttf.gz"; static unsigned char *unifont_ttf = NULL; static int unifont_size = 0; +static const char unifont_mono_filename[] = "bmonofont-i18n.ttf.gz"; +static unsigned char *unifont_mono_ttf = NULL; +static int unifont_mono_size = 0; +#endif /* WITH_INTERNATIONAL */ unsigned char *BLF_get_unifont(int *unifont_size_r) { +#ifdef WITH_INTERNATIONAL if (unifont_ttf == NULL) { - char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts"); + const char * const fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts"); if (fontpath) { char unifont_path[1024]; @@ -70,44 +75,114 @@ unsigned char *BLF_get_unifont(int *unifont_size_r) *unifont_size_r = unifont_size; return unifont_ttf; +#else + (void)unifont_size_r; + return NULL; +#endif } void BLF_free_unifont(void) { +#ifdef WITH_INTERNATIONAL if (unifont_ttf) MEM_freeN(unifont_ttf); +#else +#endif +} + +unsigned char *BLF_get_unifont_mono(int *unifont_size_r) +{ +#ifdef WITH_INTERNATIONAL + if (unifont_mono_ttf == NULL) { + const char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts"); + if (fontpath) { + char unifont_path[1024]; + + BLI_snprintf(unifont_path, sizeof(unifont_path), "%s/%s", fontpath, unifont_mono_filename); + + unifont_mono_ttf = (unsigned char *)BLI_file_ungzip_to_mem(unifont_path, &unifont_mono_size); + } + else { + printf("%s: 'fonts' data path not found for international monospace font, continuing\n", __func__); + } + } + + *unifont_size_r = unifont_mono_size; + + return unifont_mono_ttf; +#else + (void)unifont_size_r; + return NULL; +#endif } +void BLF_free_unifont_mono(void) +{ +#ifdef WITH_INTERNATIONAL + if (unifont_mono_ttf) + MEM_freeN(unifont_mono_ttf); +#else #endif +} + +bool BLF_is_default_context(const char *msgctxt) +{ + /* We use the "short" test, a more complete one could be: + * return (!msgctxt || !msgctxt[0] || !strcmp(msgctxt == BLF_I18NCONTEXT_DEFAULT_BPYRNA)) + */ + /* Note: trying without the void string check for now, it *should* not be necessary... */ + return (!msgctxt || msgctxt[0] == BLF_I18NCONTEXT_DEFAULT_BPYRNA[0]); +} const char *BLF_pgettext(const char *msgctxt, const char *msgid) { #ifdef WITH_INTERNATIONAL + const char *ret = msgid; + if (msgid && msgid[0]) { - return bl_locale_pgettext(msgctxt, msgid); + if (BLF_is_default_context(msgctxt)) { + msgctxt = BLF_I18NCONTEXT_DEFAULT; + } + ret = bl_locale_pgettext(msgctxt, 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! + */ + if (ret == msgid) { + ret = BPY_app_translations_py_pgettext(msgctxt, msgid); + } } - return ""; + + return ret; #else (void)msgctxt; return msgid; #endif } -int BLF_translate_iface(void) +bool BLF_translate_iface(void) { #ifdef WITH_INTERNATIONAL return (U.transopts & USER_DOTRANSLATE) && (U.transopts & USER_TR_IFACE); #else - return 0; + return false; #endif } -int BLF_translate_tooltips(void) +bool BLF_translate_tooltips(void) { #ifdef WITH_INTERNATIONAL return (U.transopts & USER_DOTRANSLATE) && (U.transopts & USER_TR_TOOLTIPS); #else - return 0; + return false; +#endif +} + +bool BLF_translate_new_dataname(void) +{ +#ifdef WITH_INTERNATIONAL + return (U.transopts & USER_DOTRANSLATE) && (U.transopts & USER_TR_NEWDATANAME); +#else + return false; #endif } @@ -140,3 +215,18 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid) return msgid; #endif } + +const char *BLF_translate_do_new_dataname(const char *msgctxt, const char *msgid) +{ +#ifdef WITH_INTERNATIONAL + if (BLF_translate_new_dataname()) { + return BLF_pgettext(msgctxt, msgid); + } + else { + return msgid; + } +#else + (void)msgctxt; + return msgid; +#endif +} |