diff options
author | Irie Shinsuke <irieshinsuke@yahoo.co.jp> | 2013-03-12 11:25:53 +0400 |
---|---|---|
committer | Irie Shinsuke <irieshinsuke@yahoo.co.jp> | 2013-03-12 11:25:53 +0400 |
commit | 5792e77239c43aea0afc21b2df96153ba31c5399 (patch) | |
tree | 47eb20f56f932f984800329781f2e75e38e7eb78 /source/blender/blenfont/intern | |
parent | 6669ee4784ac6591711298eb01f8e0b06793c60a (diff) |
Patch [#34373] Use i18n monospace font in Text editor and Python console
This patch allows Blender to display i18n monospace font in the text
editor and the Python interactive console. Wide characters that occupy
multiple columns such as CJK characters can be displayed correctly.
Furthermore, wrapping, selection, suggestion, cursor drawing, and
syntax highlighting should work.
Also fixes a bug [#34543]: In Text Editor false color in comment on cyrillic
To estimate how many columns each character occupies, this patch uses
wcwidth.c written by Markus Kuhn and distributed under MIT-style license:
http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
wcwidth.c is stored in extern/wcwidth and used as a static library.
This patch adds new API to blenfont, blenlib and blenkernel:
BLF_get_unifont_mono()
BLF_free_unifont_mono()
BLF_draw_mono()
BLI_wcwidth()
BLI_wcswidth()
BLI_str_utf8_char_width()
BLI_str_utf8_char_width_safe()
txt_utf8_offset_to_column()
txt_utf8_column_to_offset()
Diffstat (limited to 'source/blender/blenfont/intern')
-rw-r--r-- | source/blender/blenfont/intern/blf.c | 15 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_font.c | 34 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_internal.h | 1 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_translation.c | 38 |
4 files changed, 88 insertions, 0 deletions
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 061e8e28607..e7e277b7b34 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -576,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); 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_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_translation.c b/source/blender/blenfont/intern/blf_translation.c index f7ad5c07d50..3284225c457 100644 --- a/source/blender/blenfont/intern/blf_translation.c +++ b/source/blender/blenfont/intern/blf_translation.c @@ -50,6 +50,9 @@ 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) @@ -87,6 +90,41 @@ void BLF_free_unifont(void) #endif } +unsigned char *BLF_get_unifont_mono(int *unifont_size_r) +{ +#ifdef WITH_INTERNATIONAL + if(unifont_mono_ttf == NULL) { + 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 +} + const char *BLF_pgettext(const char *msgctxt, const char *msgid) { #ifdef WITH_INTERNATIONAL |