Cleanup: Split some code out of rna_access.c
[blender.git] / source / blender / blenfont / intern / blf_font.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2009 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup blf
22  *
23  * Deals with drawing text to OpenGL or bitmap buffers.
24  *
25  * Also low level functions for managing \a FontBLF.
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
32
33 #include <ft2build.h>
34
35 #include FT_FREETYPE_H
36 #include FT_GLYPH_H
37
38 #include "MEM_guardedalloc.h"
39
40 #include "DNA_vec_types.h"
41
42 #include "BLI_listbase.h"
43 #include "BLI_math.h"
44 #include "BLI_rect.h"
45 #include "BLI_string.h"
46 #include "BLI_string_utf8.h"
47 #include "BLI_threads.h"
48
49 #include "BLF_api.h"
50
51 #include "UI_interface.h"
52
53 #include "GPU_immediate.h"
54 #include "GPU_matrix.h"
55 #include "GPU_batch.h"
56
57 #include "blf_internal_types.h"
58 #include "blf_internal.h"
59
60 #include "BLI_strict_flags.h"
61
62 #ifdef WIN32
63 #  define FT_New_Face FT_New_Face__win32_compat
64 #endif
65
66 /* Batching buffer for drawing. */
67 BatchBLF g_batch;
68
69 /* freetype2 handle ONLY for this file!. */
70 static FT_Library ft_lib;
71 static SpinLock ft_lib_mutex;
72
73 /* -------------------------------------------------------------------- */
74 /** \name Glyph Batching
75  * \{ */
76
77 /**
78  * Drawcalls are precious! make them count!
79  * Since most of the Text elems are not covered by other UI elements, we can
80  * group some strings together and render them in one drawcall. This behavior
81  * is on demand only, between #BLF_batch_draw_begin() and #BLF_batch_draw_end().
82  */
83 static void blf_batch_draw_init(void)
84 {
85   GPUVertFormat format = {0};
86   g_batch.pos_loc = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
87   g_batch.tex_loc = GPU_vertformat_attr_add(&format, "tex", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
88   g_batch.col_loc = GPU_vertformat_attr_add(
89       &format, "col", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
90
91   g_batch.verts = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STREAM);
92   GPU_vertbuf_data_alloc(g_batch.verts, BLF_BATCH_DRAW_LEN_MAX);
93
94   GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step);
95   GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.tex_loc, &g_batch.tex_step);
96   GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step);
97   g_batch.glyph_len = 0;
98
99   g_batch.batch = GPU_batch_create_ex(GPU_PRIM_POINTS, g_batch.verts, NULL, GPU_BATCH_OWNS_VBO);
100 }
101
102 static void blf_batch_draw_exit(void)
103 {
104   GPU_BATCH_DISCARD_SAFE(g_batch.batch);
105 }
106
107 void blf_batch_draw_vao_clear(void)
108 {
109   if (g_batch.batch) {
110     GPU_batch_vao_cache_clear(g_batch.batch);
111   }
112 }
113
114 void blf_batch_draw_begin(FontBLF *font)
115 {
116   if (g_batch.batch == NULL) {
117     blf_batch_draw_init();
118   }
119
120   const bool font_changed = (g_batch.font != font);
121   const bool simple_shader = ((font->flags & (BLF_ROTATION | BLF_MATRIX | BLF_ASPECT)) == 0);
122   const bool shader_changed = (simple_shader != g_batch.simple_shader);
123
124   g_batch.active = g_batch.enabled && simple_shader;
125
126   if (simple_shader) {
127     /* Offset is applied to each glyph. */
128     g_batch.ofs[0] = floorf(font->pos[0]);
129     g_batch.ofs[1] = floorf(font->pos[1]);
130   }
131   else {
132     /* Offset is baked in modelview mat. */
133     zero_v2(g_batch.ofs);
134   }
135
136   if (g_batch.active) {
137     float gpumat[4][4];
138     GPU_matrix_model_view_get(gpumat);
139
140     bool mat_changed = (memcmp(gpumat, g_batch.mat, sizeof(g_batch.mat)) != 0);
141
142     if (mat_changed) {
143       /* Modelviewmat is no longer the same.
144        * Flush cache but with the previous mat. */
145       GPU_matrix_push();
146       GPU_matrix_set(g_batch.mat);
147     }
148
149     /* flush cache if config is not the same. */
150     if (mat_changed || font_changed || shader_changed) {
151       blf_batch_draw();
152       g_batch.simple_shader = simple_shader;
153       g_batch.font = font;
154     }
155     else {
156       /* Nothing changed continue batching. */
157       return;
158     }
159
160     if (mat_changed) {
161       GPU_matrix_pop();
162       /* Save for next memcmp. */
163       memcpy(g_batch.mat, gpumat, sizeof(g_batch.mat));
164     }
165   }
166   else {
167     /* flush cache */
168     blf_batch_draw();
169     g_batch.font = font;
170     g_batch.simple_shader = simple_shader;
171   }
172 }
173
174 void blf_batch_draw(void)
175 {
176   if (g_batch.glyph_len == 0) {
177     return;
178   }
179
180   GPU_blend(true);
181   GPU_blend_set_func_separate(
182       GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
183
184   /* We need to flush widget base first to ensure correct ordering. */
185   UI_widgetbase_draw_cache_flush();
186
187   GPU_texture_bind(g_batch.tex_bind_state, 0);
188   GPU_vertbuf_data_len_set(g_batch.verts, g_batch.glyph_len);
189   GPU_vertbuf_use(g_batch.verts); /* send data */
190
191   eGPUBuiltinShader shader = (g_batch.simple_shader) ? GPU_SHADER_TEXT_SIMPLE : GPU_SHADER_TEXT;
192   GPU_batch_program_set_builtin(g_batch.batch, shader);
193   GPU_batch_uniform_1i(g_batch.batch, "glyph", 0);
194   GPU_batch_draw(g_batch.batch);
195
196   GPU_blend(false);
197
198   /* restart to 1st vertex data pointers */
199   GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step);
200   GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.tex_loc, &g_batch.tex_step);
201   GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step);
202   g_batch.glyph_len = 0;
203 }
204
205 static void blf_batch_draw_end(void)
206 {
207   if (!g_batch.active) {
208     blf_batch_draw();
209   }
210 }
211
212 /** \} */
213
214 /* -------------------------------------------------------------------- */
215
216 int blf_font_init(void)
217 {
218   memset(&g_batch, 0, sizeof(g_batch));
219   BLI_spin_init(&ft_lib_mutex);
220   return FT_Init_FreeType(&ft_lib);
221 }
222
223 void blf_font_exit(void)
224 {
225   FT_Done_FreeType(ft_lib);
226   BLI_spin_end(&ft_lib_mutex);
227   blf_batch_draw_exit();
228 }
229
230 void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
231 {
232   GlyphCacheBLF *gc;
233   FT_Error err;
234
235   gc = blf_glyph_cache_find(font, size, dpi);
236   if (gc) {
237     font->glyph_cache = gc;
238     /* Optimization: do not call FT_Set_Char_Size if size did not change. */
239     if (font->size == size && font->dpi == dpi) {
240       return;
241     }
242   }
243
244   err = FT_Set_Char_Size(font->face, 0, (FT_F26Dot6)(size * 64), dpi, dpi);
245   if (err) {
246     /* FIXME: here we can go through the fixed size and choice a close one */
247     printf("The current font don't support the size, %u and dpi, %u\n", size, dpi);
248     return;
249   }
250
251   font->size = size;
252   font->dpi = dpi;
253
254   if (!gc) {
255     gc = blf_glyph_cache_new(font);
256     if (gc) {
257       font->glyph_cache = gc;
258     }
259     else {
260       font->glyph_cache = NULL;
261     }
262   }
263 }
264
265 static void blf_font_ensure_ascii_table(FontBLF *font)
266 {
267   GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
268
269   /* build ascii on demand */
270   if (glyph_ascii_table['0'] == NULL) {
271     GlyphBLF *g;
272     unsigned int i;
273     for (i = 0; i < 256; i++) {
274       g = blf_glyph_search(font->glyph_cache, i);
275       if (!g) {
276         FT_UInt glyph_index = FT_Get_Char_Index(font->face, i);
277         g = blf_glyph_add(font, glyph_index, i);
278       }
279       glyph_ascii_table[i] = g;
280     }
281   }
282 }
283
284 static void blf_font_ensure_ascii_kerning(FontBLF *font, const FT_UInt kern_mode)
285 {
286   KerningCacheBLF *kc = font->kerning_cache;
287
288   font->kerning_mode = kern_mode;
289
290   if (!kc || kc->mode != kern_mode) {
291     font->kerning_cache = kc = blf_kerning_cache_find(font);
292     if (!kc) {
293       font->kerning_cache = kc = blf_kerning_cache_new(font);
294     }
295   }
296 }
297
298 /* Fast path for runs of ASCII characters. Given that common UTF-8
299  * input will consist of an overwhelming majority of ASCII
300  * characters.
301  */
302
303 /* Note,
304  * blf_font_ensure_ascii_table(font); must be called before this macro */
305
306 #define BLF_UTF8_NEXT_FAST(_font, _g, _str, _i, _c, _glyph_ascii_table) \
307   if (((_c) = (_str)[_i]) < 0x80) { \
308     _g = (_glyph_ascii_table)[_c]; \
309     _i++; \
310   } \
311   else if ((_c = BLI_str_utf8_as_unicode_step(_str, &(_i))) != BLI_UTF8_ERR) { \
312     if ((_g = blf_glyph_search((_font)->glyph_cache, _c)) == NULL) { \
313       _g = blf_glyph_add(_font, FT_Get_Char_Index((_font)->face, _c), _c); \
314     } \
315   } \
316   (void)0
317
318 #define BLF_KERNING_VARS(_font, _has_kerning, _kern_mode) \
319   const bool _has_kerning = FT_HAS_KERNING((_font)->face) != 0; \
320   const FT_UInt _kern_mode = (_has_kerning == 0) ? 0 : \
321                                                    (((_font)->flags & BLF_KERNING_DEFAULT) ? \
322                                                         ft_kerning_default : \
323                                                         (FT_UInt)FT_KERNING_UNFITTED)
324
325 /* Note,
326  * blf_font_ensure_ascii_kerning(font, kern_mode); must be called before this macro */
327
328 #define BLF_KERNING_STEP_FAST(_font, _kern_mode, _g_prev, _g, _c_prev, _c, _pen_x) \
329   { \
330     if (_g_prev) { \
331       FT_Vector _delta; \
332       if (_c_prev < 0x80 && _c < 0x80) { \
333         _pen_x += (_font)->kerning_cache->table[_c][_c_prev]; \
334       } \
335       else if (FT_Get_Kerning((_font)->face, (_g_prev)->idx, (_g)->idx, _kern_mode, &(_delta)) == \
336                0) { \
337         _pen_x += (int)_delta.x >> 6; \
338       } \
339     } \
340   } \
341   (void)0
342
343 #define BLF_KERNING_STEP(_font, _kern_mode, _g_prev, _g, _delta, _pen_x) \
344   { \
345     if (_g_prev) { \
346       _delta.x = _delta.y = 0; \
347       if (FT_Get_Kerning((_font)->face, (_g_prev)->idx, (_g)->idx, _kern_mode, &(_delta)) == 0) { \
348         _pen_x += (int)_delta.x >> 6; \
349       } \
350     } \
351   } \
352   (void)0
353
354 static void blf_font_draw_ex(
355     FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
356 {
357   unsigned int c, c_prev = BLI_UTF8_ERR;
358   GlyphBLF *g, *g_prev = NULL;
359   int pen_x = 0;
360   size_t i = 0;
361   GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
362
363   if (len == 0) {
364     /* early output, don't do any IMM OpenGL. */
365     return;
366   }
367
368   BLF_KERNING_VARS(font, has_kerning, kern_mode);
369
370   blf_font_ensure_ascii_table(font);
371   blf_font_ensure_ascii_kerning(font, kern_mode);
372
373   blf_batch_draw_begin(font);
374
375   while ((i < len) && str[i]) {
376     BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
377
378     if (UNLIKELY(c == BLI_UTF8_ERR)) {
379       break;
380     }
381     if (UNLIKELY(g == NULL)) {
382       continue;
383     }
384     if (has_kerning) {
385       BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
386     }
387
388     /* do not return this loop if clipped, we want every character tested */
389     blf_glyph_render(font, g, (float)pen_x, (float)pen_y);
390
391     pen_x += g->advance_i;
392     g_prev = g;
393     c_prev = c;
394   }
395
396   blf_batch_draw_end();
397
398   if (r_info) {
399     r_info->lines = 1;
400     r_info->width = pen_x;
401   }
402 }
403 void blf_font_draw(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
404 {
405   blf_font_draw_ex(font, str, len, r_info, 0);
406 }
407
408 /* faster version of blf_font_draw, ascii only for view dimensions */
409 static void blf_font_draw_ascii_ex(
410     FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
411 {
412   unsigned int c, c_prev = BLI_UTF8_ERR;
413   GlyphBLF *g, *g_prev = NULL;
414   int pen_x = 0;
415   GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
416
417   BLF_KERNING_VARS(font, has_kerning, kern_mode);
418
419   blf_font_ensure_ascii_table(font);
420   blf_font_ensure_ascii_kerning(font, kern_mode);
421
422   blf_batch_draw_begin(font);
423
424   while ((c = *(str++)) && len--) {
425     BLI_assert(c < 128);
426     if ((g = glyph_ascii_table[c]) == NULL) {
427       continue;
428     }
429     if (has_kerning) {
430       BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
431     }
432
433     /* do not return this loop if clipped, we want every character tested */
434     blf_glyph_render(font, g, (float)pen_x, (float)pen_y);
435
436     pen_x += g->advance_i;
437     g_prev = g;
438     c_prev = c;
439   }
440
441   blf_batch_draw_end();
442
443   if (r_info) {
444     r_info->lines = 1;
445     r_info->width = pen_x;
446   }
447 }
448 void blf_font_draw_ascii(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
449 {
450   blf_font_draw_ascii_ex(font, str, len, r_info, 0);
451 }
452
453 /* use fixed column width, but an utf8 character may occupy multiple columns */
454 int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
455 {
456   unsigned int c;
457   GlyphBLF *g;
458   int col, columns = 0;
459   int pen_x = 0, pen_y = 0;
460   size_t i = 0;
461   GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
462
463   blf_font_ensure_ascii_table(font);
464
465   blf_batch_draw_begin(font);
466
467   while ((i < len) && str[i]) {
468     BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
469
470     if (UNLIKELY(c == BLI_UTF8_ERR)) {
471       break;
472     }
473     if (UNLIKELY(g == NULL)) {
474       continue;
475     }
476
477     /* do not return this loop if clipped, we want every character tested */
478     blf_glyph_render(font, g, (float)pen_x, (float)pen_y);
479
480     col = BLI_wcwidth((wchar_t)c);
481     if (col < 0) {
482       col = 1;
483     }
484
485     columns += col;
486     pen_x += cwidth * col;
487   }
488
489   blf_batch_draw_end();
490
491   return columns;
492 }
493
494 /* Sanity checks are done by BLF_draw_buffer() */
495 static void blf_font_draw_buffer_ex(
496     FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
497 {
498   unsigned int c, c_prev = BLI_UTF8_ERR;
499   GlyphBLF *g, *g_prev = NULL;
500   int pen_x = (int)font->pos[0];
501   int pen_y_basis = (int)font->pos[1] + pen_y;
502   size_t i = 0;
503   GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
504
505   /* buffer specific vars */
506   FontBufInfoBLF *buf_info = &font->buf_info;
507   const float *b_col_float = buf_info->col_float;
508   const unsigned char *b_col_char = buf_info->col_char;
509   int chx, chy;
510   int y, x;
511
512   BLF_KERNING_VARS(font, has_kerning, kern_mode);
513
514   blf_font_ensure_ascii_table(font);
515   blf_font_ensure_ascii_kerning(font, kern_mode);
516
517   /* another buffer specific call for color conversion */
518
519   while ((i < len) && str[i]) {
520     BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
521
522     if (UNLIKELY(c == BLI_UTF8_ERR)) {
523       break;
524     }
525     if (UNLIKELY(g == NULL)) {
526       continue;
527     }
528     if (has_kerning) {
529       BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
530     }
531
532     chx = pen_x + ((int)g->pos_x);
533     chy = pen_y_basis + g->height;
534
535     if (g->pitch < 0) {
536       pen_y = pen_y_basis + (g->height - (int)g->pos_y);
537     }
538     else {
539       pen_y = pen_y_basis - (g->height - (int)g->pos_y);
540     }
541
542     if ((chx + g->width) >= 0 && chx < buf_info->w && (pen_y + g->height) >= 0 &&
543         pen_y < buf_info->h) {
544       /* don't draw beyond the buffer bounds */
545       int width_clip = g->width;
546       int height_clip = g->height;
547       int yb_start = g->pitch < 0 ? 0 : g->height - 1;
548
549       if (width_clip + chx > buf_info->w) {
550         width_clip -= chx + width_clip - buf_info->w;
551       }
552       if (height_clip + pen_y > buf_info->h) {
553         height_clip -= pen_y + height_clip - buf_info->h;
554       }
555
556       /* drawing below the image? */
557       if (pen_y < 0) {
558         yb_start += (g->pitch < 0) ? -pen_y : pen_y;
559         height_clip += pen_y;
560         pen_y = 0;
561       }
562
563       if (buf_info->fbuf) {
564         int yb = yb_start;
565         for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
566           for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
567             const char a_byte = *(g->bitmap + x + (yb * g->pitch));
568             if (a_byte) {
569               const float a = (a_byte / 255.0f) * b_col_float[3];
570               const size_t buf_ofs = (((size_t)(chx + x) +
571                                        ((size_t)(pen_y + y) * (size_t)buf_info->w)) *
572                                       (size_t)buf_info->ch);
573               float *fbuf = buf_info->fbuf + buf_ofs;
574
575               if (a >= 1.0f) {
576                 fbuf[0] = b_col_float[0];
577                 fbuf[1] = b_col_float[1];
578                 fbuf[2] = b_col_float[2];
579                 fbuf[3] = 1.0f;
580               }
581               else {
582                 fbuf[0] = (b_col_float[0] * a) + (fbuf[0] * (1.0f - a));
583                 fbuf[1] = (b_col_float[1] * a) + (fbuf[1] * (1.0f - a));
584                 fbuf[2] = (b_col_float[2] * a) + (fbuf[2] * (1.0f - a));
585                 fbuf[3] = MIN2(fbuf[3] + a, 1.0f); /* clamp to 1.0 */
586               }
587             }
588           }
589
590           if (g->pitch < 0) {
591             yb++;
592           }
593           else {
594             yb--;
595           }
596         }
597       }
598
599       if (buf_info->cbuf) {
600         int yb = yb_start;
601         for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
602           for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
603             const char a_byte = *(g->bitmap + x + (yb * g->pitch));
604
605             if (a_byte) {
606               const float a = (a_byte / 255.0f) * b_col_float[3];
607               const size_t buf_ofs = (((size_t)(chx + x) +
608                                        ((size_t)(pen_y + y) * (size_t)buf_info->w)) *
609                                       (size_t)buf_info->ch);
610               unsigned char *cbuf = buf_info->cbuf + buf_ofs;
611
612               if (a >= 1.0f) {
613                 cbuf[0] = b_col_char[0];
614                 cbuf[1] = b_col_char[1];
615                 cbuf[2] = b_col_char[2];
616                 cbuf[3] = 255;
617               }
618               else {
619                 cbuf[0] = (unsigned char)((b_col_char[0] * a) + (cbuf[0] * (1.0f - a)));
620                 cbuf[1] = (unsigned char)((b_col_char[1] * a) + (cbuf[1] * (1.0f - a)));
621                 cbuf[2] = (unsigned char)((b_col_char[2] * a) + (cbuf[2] * (1.0f - a)));
622                 /* clamp to 255 */
623                 cbuf[3] = (unsigned char)MIN2((int)cbuf[3] + (int)(a * 255), 255);
624               }
625             }
626           }
627
628           if (g->pitch < 0) {
629             yb++;
630           }
631           else {
632             yb--;
633           }
634         }
635       }
636     }
637
638     pen_x += g->advance_i;
639     g_prev = g;
640     c_prev = c;
641   }
642
643   if (r_info) {
644     r_info->lines = 1;
645     r_info->width = pen_x;
646   }
647 }
648 void blf_font_draw_buffer(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
649 {
650   blf_font_draw_buffer_ex(font, str, len, r_info, 0);
651 }
652
653 static bool blf_font_width_to_strlen_glyph_process(FontBLF *font,
654                                                    const bool has_kerning,
655                                                    const FT_UInt kern_mode,
656                                                    const uint c_prev,
657                                                    const uint c,
658                                                    GlyphBLF *g_prev,
659                                                    GlyphBLF *g,
660                                                    int *pen_x,
661                                                    const int width_i)
662 {
663   if (UNLIKELY(c == BLI_UTF8_ERR)) {
664     return true; /* break the calling loop. */
665   }
666   if (UNLIKELY(g == NULL)) {
667     return false; /* continue the calling loop. */
668   }
669   if (has_kerning) {
670     BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, *pen_x);
671   }
672
673   *pen_x += g->advance_i;
674
675   return (*pen_x >= width_i);
676 }
677
678 size_t blf_font_width_to_strlen(
679     FontBLF *font, const char *str, size_t len, float width, float *r_width)
680 {
681   unsigned int c, c_prev;
682   GlyphBLF *g, *g_prev;
683   int pen_x, width_new;
684   size_t i, i_prev;
685   GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
686   const int width_i = (int)width;
687
688   BLF_KERNING_VARS(font, has_kerning, kern_mode);
689
690   blf_font_ensure_ascii_table(font);
691   if (has_kerning) {
692     blf_font_ensure_ascii_kerning(font, kern_mode);
693   }
694
695   for (i_prev = i = 0, width_new = pen_x = 0, g_prev = NULL, c_prev = 0; (i < len) && str[i];
696        i_prev = i, width_new = pen_x, c_prev = c, g_prev = g) {
697     BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
698
699     if (blf_font_width_to_strlen_glyph_process(
700             font, has_kerning, kern_mode, c_prev, c, g_prev, g, &pen_x, width_i)) {
701       break;
702     }
703   }
704
705   if (r_width) {
706     *r_width = (float)width_new;
707   }
708
709   return i_prev;
710 }
711
712 size_t blf_font_width_to_rstrlen(
713     FontBLF *font, const char *str, size_t len, float width, float *r_width)
714 {
715   unsigned int c, c_prev;
716   GlyphBLF *g, *g_prev;
717   int pen_x, width_new;
718   size_t i, i_prev, i_tmp;
719   char *s, *s_prev;
720   GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
721   const int width_i = (int)width;
722
723   BLF_KERNING_VARS(font, has_kerning, kern_mode);
724
725   blf_font_ensure_ascii_table(font);
726   if (has_kerning) {
727     blf_font_ensure_ascii_kerning(font, kern_mode);
728   }
729
730   i = BLI_strnlen(str, len);
731   s = BLI_str_find_prev_char_utf8(str, &str[i]);
732   i = (size_t)((s != NULL) ? s - str : 0);
733   s_prev = BLI_str_find_prev_char_utf8(str, s);
734   i_prev = (size_t)((s_prev != NULL) ? s_prev - str : 0);
735
736   i_tmp = i;
737   BLF_UTF8_NEXT_FAST(font, g, str, i_tmp, c, glyph_ascii_table);
738   for (width_new = pen_x = 0; (s != NULL);
739        i = i_prev, s = s_prev, c = c_prev, g = g_prev, g_prev = NULL, width_new = pen_x) {
740     s_prev = BLI_str_find_prev_char_utf8(str, s);
741     i_prev = (size_t)((s_prev != NULL) ? s_prev - str : 0);
742
743     if (s_prev != NULL) {
744       i_tmp = i_prev;
745       BLF_UTF8_NEXT_FAST(font, g_prev, str, i_tmp, c_prev, glyph_ascii_table);
746       BLI_assert(i_tmp == i);
747     }
748
749     if (blf_font_width_to_strlen_glyph_process(
750             font, has_kerning, kern_mode, c_prev, c, g_prev, g, &pen_x, width_i)) {
751       break;
752     }
753   }
754
755   if (r_width) {
756     *r_width = (float)width_new;
757   }
758
759   return i;
760 }
761
762 static void blf_font_boundbox_ex(
763     FontBLF *font, const char *str, size_t len, rctf *box, struct ResultBLF *r_info, int pen_y)
764 {
765   unsigned int c, c_prev = BLI_UTF8_ERR;
766   GlyphBLF *g, *g_prev = NULL;
767   int pen_x = 0;
768   size_t i = 0;
769   GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
770
771   rctf gbox;
772
773   BLF_KERNING_VARS(font, has_kerning, kern_mode);
774
775   box->xmin = 32000.0f;
776   box->xmax = -32000.0f;
777   box->ymin = 32000.0f;
778   box->ymax = -32000.0f;
779
780   blf_font_ensure_ascii_table(font);
781   blf_font_ensure_ascii_kerning(font, kern_mode);
782
783   while ((i < len) && str[i]) {
784     BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
785
786     if (UNLIKELY(c == BLI_UTF8_ERR)) {
787       break;
788     }
789     if (UNLIKELY(g == NULL)) {
790       continue;
791     }
792     if (has_kerning) {
793       BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
794     }
795
796     gbox.xmin = (float)pen_x;
797     gbox.xmax = (float)pen_x + g->advance;
798     gbox.ymin = g->box.ymin + (float)pen_y;
799     gbox.ymax = g->box.ymax + (float)pen_y;
800
801     if (gbox.xmin < box->xmin) {
802       box->xmin = gbox.xmin;
803     }
804     if (gbox.ymin < box->ymin) {
805       box->ymin = gbox.ymin;
806     }
807
808     if (gbox.xmax > box->xmax) {
809       box->xmax = gbox.xmax;
810     }
811     if (gbox.ymax > box->ymax) {
812       box->ymax = gbox.ymax;
813     }
814
815     pen_x += g->advance_i;
816     g_prev = g;
817     c_prev = c;
818   }
819
820   if (box->xmin > box->xmax) {
821     box->xmin = 0.0f;
822     box->ymin = 0.0f;
823     box->xmax = 0.0f;
824     box->ymax = 0.0f;
825   }
826
827   if (r_info) {
828     r_info->lines = 1;
829     r_info->width = pen_x;
830   }
831 }
832 void blf_font_boundbox(
833     FontBLF *font, const char *str, size_t len, rctf *r_box, struct ResultBLF *r_info)
834 {
835   blf_font_boundbox_ex(font, str, len, r_box, r_info, 0);
836 }
837
838 /* -------------------------------------------------------------------- */
839 /** \name Word-Wrap Support
840  * \{ */
841
842 /**
843  * Generic function to add word-wrap support for other existing functions.
844  *
845  * Wraps on spaces and respects newlines.
846  * Intentionally ignores non-unix newlines, tabs and more advanced text formatting.
847  *
848  * \note If we want rich text - we better have a higher level API to handle that
849  * (color, bold, switching fonts... etc).
850  */
851 static void blf_font_wrap_apply(
852     FontBLF *font,
853     const char *str,
854     size_t len,
855     struct ResultBLF *r_info,
856     void (*callback)(FontBLF *font, const char *str, size_t len, int pen_y, void *userdata),
857     void *userdata)
858 {
859   unsigned int c;
860   GlyphBLF *g, *g_prev = NULL;
861   FT_Vector delta;
862   int pen_x = 0, pen_y = 0;
863   size_t i = 0;
864   GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
865   int lines = 0;
866   int pen_x_next = 0;
867
868   BLF_KERNING_VARS(font, has_kerning, kern_mode);
869
870   struct WordWrapVars {
871     int wrap_width;
872     size_t start, last[2];
873   } wrap = {font->wrap_width != -1 ? font->wrap_width : INT_MAX, 0, {0, 0}};
874
875   blf_font_ensure_ascii_table(font);
876   // printf("%s wrapping (%d, %d) `%s`:\n", __func__, len, strlen(str), str);
877   while ((i < len) && str[i]) {
878
879     /* wrap vars */
880     size_t i_curr = i;
881     bool do_draw = false;
882
883     BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
884
885     if (UNLIKELY(c == BLI_UTF8_ERR)) {
886       break;
887     }
888     if (UNLIKELY(g == NULL)) {
889       continue;
890     }
891     if (has_kerning) {
892       BLF_KERNING_STEP(font, kern_mode, g_prev, g, delta, pen_x);
893     }
894
895     /**
896      * Implementation Detail (utf8).
897      *
898      * Take care with single byte offsets here,
899      * since this is utf8 we can't be sure a single byte is a single character.
900      *
901      * This is _only_ done when we know for sure the character is ascii (newline or a space).
902      */
903     pen_x_next = pen_x + g->advance_i;
904     if (UNLIKELY((pen_x_next >= wrap.wrap_width) && (wrap.start != wrap.last[0]))) {
905       do_draw = true;
906     }
907     else if (UNLIKELY(((i < len) && str[i]) == 0)) {
908       /* need check here for trailing newline, else we draw it */
909       wrap.last[0] = i + ((g->c != '\n') ? 1 : 0);
910       wrap.last[1] = i;
911       do_draw = true;
912     }
913     else if (UNLIKELY(g->c == '\n')) {
914       wrap.last[0] = i_curr + 1;
915       wrap.last[1] = i;
916       do_draw = true;
917     }
918     else if (UNLIKELY(g->c != ' ' && (g_prev ? g_prev->c == ' ' : false))) {
919       wrap.last[0] = i_curr;
920       wrap.last[1] = i_curr;
921     }
922
923     if (UNLIKELY(do_draw)) {
924       // printf("(%03d..%03d)  `%.*s`\n",
925       //        wrap.start, wrap.last[0], (wrap.last[0] - wrap.start) - 1, &str[wrap.start]);
926
927       callback(font, &str[wrap.start], (wrap.last[0] - wrap.start) - 1, pen_y, userdata);
928       wrap.start = wrap.last[0];
929       i = wrap.last[1];
930       pen_x = 0;
931       pen_y -= font->glyph_cache->glyph_height_max;
932       g_prev = NULL;
933       lines += 1;
934       continue;
935     }
936
937     pen_x = pen_x_next;
938     g_prev = g;
939   }
940
941   // printf("done! lines: %d, width, %d\n", lines, pen_x_next);
942
943   if (r_info) {
944     r_info->lines = lines;
945     /* width of last line only (with wrapped lines) */
946     r_info->width = pen_x_next;
947   }
948 }
949
950 /* blf_font_draw__wrap */
951 static void blf_font_draw__wrap_cb(
952     FontBLF *font, const char *str, size_t len, int pen_y, void *UNUSED(userdata))
953 {
954   blf_font_draw_ex(font, str, len, NULL, pen_y);
955 }
956 void blf_font_draw__wrap(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
957 {
958   blf_font_wrap_apply(font, str, len, r_info, blf_font_draw__wrap_cb, NULL);
959 }
960
961 /* blf_font_boundbox__wrap */
962 static void blf_font_boundbox_wrap_cb(
963     FontBLF *font, const char *str, size_t len, int pen_y, void *userdata)
964 {
965   rctf *box = userdata;
966   rctf box_single;
967
968   blf_font_boundbox_ex(font, str, len, &box_single, NULL, pen_y);
969   BLI_rctf_union(box, &box_single);
970 }
971 void blf_font_boundbox__wrap(
972     FontBLF *font, const char *str, size_t len, rctf *box, struct ResultBLF *r_info)
973 {
974   box->xmin = 32000.0f;
975   box->xmax = -32000.0f;
976   box->ymin = 32000.0f;
977   box->ymax = -32000.0f;
978
979   blf_font_wrap_apply(font, str, len, r_info, blf_font_boundbox_wrap_cb, box);
980 }
981
982 /* blf_font_draw_buffer__wrap */
983 static void blf_font_draw_buffer__wrap_cb(
984     FontBLF *font, const char *str, size_t len, int pen_y, void *UNUSED(userdata))
985 {
986   blf_font_draw_buffer_ex(font, str, len, NULL, pen_y);
987 }
988 void blf_font_draw_buffer__wrap(FontBLF *font,
989                                 const char *str,
990                                 size_t len,
991                                 struct ResultBLF *r_info)
992 {
993   blf_font_wrap_apply(font, str, len, r_info, blf_font_draw_buffer__wrap_cb, NULL);
994 }
995
996 /** \} */
997
998 void blf_font_width_and_height(FontBLF *font,
999                                const char *str,
1000                                size_t len,
1001                                float *r_width,
1002                                float *r_height,
1003                                struct ResultBLF *r_info)
1004 {
1005   float xa, ya;
1006   rctf box;
1007
1008   if (font->flags & BLF_ASPECT) {
1009     xa = font->aspect[0];
1010     ya = font->aspect[1];
1011   }
1012   else {
1013     xa = 1.0f;
1014     ya = 1.0f;
1015   }
1016
1017   if (font->flags & BLF_WORD_WRAP) {
1018     blf_font_boundbox__wrap(font, str, len, &box, r_info);
1019   }
1020   else {
1021     blf_font_boundbox(font, str, len, &box, r_info);
1022   }
1023   *r_width = (BLI_rctf_size_x(&box) * xa);
1024   *r_height = (BLI_rctf_size_y(&box) * ya);
1025 }
1026
1027 float blf_font_width(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
1028 {
1029   float xa;
1030   rctf box;
1031
1032   if (font->flags & BLF_ASPECT) {
1033     xa = font->aspect[0];
1034   }
1035   else {
1036     xa = 1.0f;
1037   }
1038
1039   if (font->flags & BLF_WORD_WRAP) {
1040     blf_font_boundbox__wrap(font, str, len, &box, r_info);
1041   }
1042   else {
1043     blf_font_boundbox(font, str, len, &box, r_info);
1044   }
1045   return BLI_rctf_size_x(&box) * xa;
1046 }
1047
1048 float blf_font_height(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
1049 {
1050   float ya;
1051   rctf box;
1052
1053   if (font->flags & BLF_ASPECT) {
1054     ya = font->aspect[1];
1055   }
1056   else {
1057     ya = 1.0f;
1058   }
1059
1060   if (font->flags & BLF_WORD_WRAP) {
1061     blf_font_boundbox__wrap(font, str, len, &box, r_info);
1062   }
1063   else {
1064     blf_font_boundbox(font, str, len, &box, r_info);
1065   }
1066   return BLI_rctf_size_y(&box) * ya;
1067 }
1068
1069 float blf_font_fixed_width(FontBLF *font)
1070 {
1071   const unsigned int c = ' ';
1072   GlyphBLF *g = blf_glyph_search(font->glyph_cache, c);
1073   if (!g) {
1074     g = blf_glyph_add(font, FT_Get_Char_Index(font->face, c), c);
1075
1076     /* if we don't find the glyph. */
1077     if (!g) {
1078       return 0.0f;
1079     }
1080   }
1081
1082   return g->advance;
1083 }
1084
1085 int blf_font_count_missing_chars(FontBLF *font,
1086                                  const char *str,
1087                                  const size_t len,
1088                                  int *r_tot_chars)
1089 {
1090   int missing = 0;
1091   size_t i = 0;
1092
1093   *r_tot_chars = 0;
1094   while (i < len) {
1095     unsigned int c;
1096
1097     if ((c = str[i]) < 0x80) {
1098       i++;
1099     }
1100     else if ((c = BLI_str_utf8_as_unicode_step(str, &i)) != BLI_UTF8_ERR) {
1101       if (FT_Get_Char_Index((font)->face, c) == 0) {
1102         missing++;
1103       }
1104     }
1105     (*r_tot_chars)++;
1106   }
1107   return missing;
1108 }
1109
1110 void blf_font_free(FontBLF *font)
1111 {
1112   GlyphCacheBLF *gc;
1113
1114   font->glyph_cache = NULL;
1115   while ((gc = BLI_pophead(&font->cache))) {
1116     blf_glyph_cache_free(gc);
1117   }
1118
1119   blf_kerning_cache_clear(font);
1120
1121   FT_Done_Face(font->face);
1122   if (font->filename) {
1123     MEM_freeN(font->filename);
1124   }
1125   if (font->name) {
1126     MEM_freeN(font->name);
1127   }
1128   MEM_freeN(font);
1129 }
1130
1131 static void blf_font_fill(FontBLF *font)
1132 {
1133   font->aspect[0] = 1.0f;
1134   font->aspect[1] = 1.0f;
1135   font->aspect[2] = 1.0f;
1136   font->pos[0] = 0.0f;
1137   font->pos[1] = 0.0f;
1138   font->angle = 0.0f;
1139
1140   for (int i = 0; i < 16; i++) {
1141     font->m[i] = 0;
1142   }
1143
1144   /* annoying bright color so we can see where to add BLF_color calls */
1145   font->color[0] = 255;
1146   font->color[1] = 255;
1147   font->color[2] = 0;
1148   font->color[3] = 255;
1149
1150   font->clip_rec.xmin = 0.0f;
1151   font->clip_rec.xmax = 0.0f;
1152   font->clip_rec.ymin = 0.0f;
1153   font->clip_rec.ymax = 0.0f;
1154   font->flags = 0;
1155   font->dpi = 0;
1156   font->size = 0;
1157   BLI_listbase_clear(&font->cache);
1158   BLI_listbase_clear(&font->kerning_caches);
1159   font->glyph_cache = NULL;
1160   font->kerning_cache = NULL;
1161 #if BLF_BLUR_ENABLE
1162   font->blur = 0;
1163 #endif
1164   font->tex_size_max = -1;
1165
1166   font->buf_info.fbuf = NULL;
1167   font->buf_info.cbuf = NULL;
1168   font->buf_info.w = 0;
1169   font->buf_info.h = 0;
1170   font->buf_info.ch = 0;
1171   font->buf_info.col_init[0] = 0;
1172   font->buf_info.col_init[1] = 0;
1173   font->buf_info.col_init[2] = 0;
1174   font->buf_info.col_init[3] = 0;
1175
1176   font->ft_lib = ft_lib;
1177   font->ft_lib_mutex = &ft_lib_mutex;
1178 }
1179
1180 FontBLF *blf_font_new(const char *name, const char *filename)
1181 {
1182   FontBLF *font;
1183   FT_Error err;
1184   char *mfile;
1185
1186   font = (FontBLF *)MEM_callocN(sizeof(FontBLF), "blf_font_new");
1187   err = FT_New_Face(ft_lib, filename, 0, &font->face);
1188   if (err) {
1189     MEM_freeN(font);
1190     return NULL;
1191   }
1192
1193   err = FT_Select_Charmap(font->face, ft_encoding_unicode);
1194   if (err) {
1195     printf("Can't set the unicode character map!\n");
1196     FT_Done_Face(font->face);
1197     MEM_freeN(font);
1198     return NULL;
1199   }
1200
1201   mfile = blf_dir_metrics_search(filename);
1202   if (mfile) {
1203     err = FT_Attach_File(font->face, mfile);
1204     if (err) {
1205       fprintf(stderr, "FT_Attach_File failed to load '%s' with error %d\n", filename, (int)err);
1206     }
1207     MEM_freeN(mfile);
1208   }
1209
1210   font->name = BLI_strdup(name);
1211   font->filename = BLI_strdup(filename);
1212   blf_font_fill(font);
1213   return font;
1214 }
1215
1216 void blf_font_attach_from_mem(FontBLF *font, const unsigned char *mem, int mem_size)
1217 {
1218   FT_Open_Args open;
1219
1220   open.flags = FT_OPEN_MEMORY;
1221   open.memory_base = (const FT_Byte *)mem;
1222   open.memory_size = mem_size;
1223   FT_Attach_Stream(font->face, &open);
1224 }
1225
1226 FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int mem_size)
1227 {
1228   FontBLF *font;
1229   FT_Error err;
1230
1231   font = (FontBLF *)MEM_callocN(sizeof(FontBLF), "blf_font_new_from_mem");
1232   err = FT_New_Memory_Face(ft_lib, mem, mem_size, 0, &font->face);
1233   if (err) {
1234     MEM_freeN(font);
1235     return NULL;
1236   }
1237
1238   err = FT_Select_Charmap(font->face, ft_encoding_unicode);
1239   if (err) {
1240     printf("Can't set the unicode character map!\n");
1241     FT_Done_Face(font->face);
1242     MEM_freeN(font);
1243     return NULL;
1244   }
1245
1246   font->name = BLI_strdup(name);
1247   font->filename = NULL;
1248   blf_font_fill(font);
1249   return font;
1250 }