Blender  V2.93
blf_font.c
Go to the documentation of this file.
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 
28 #include <math.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.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_math_color_blend.h"
45 #include "BLI_rect.h"
46 #include "BLI_string.h"
47 #include "BLI_string_utf8.h"
48 #include "BLI_threads.h"
49 
50 #include "BLF_api.h"
51 
52 #include "UI_interface.h"
53 
54 #include "GPU_batch.h"
55 #include "GPU_matrix.h"
56 
57 #include "blf_internal.h"
58 #include "blf_internal_types.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. */
68 
69 /* freetype2 handle ONLY for this file!. */
70 static FT_Library ft_lib;
73 
74 /* -------------------------------------------------------------------- */
84 static void blf_batch_draw_init(void)
85 {
86  GPUVertFormat format = {0};
92  &format, "glyph_size", GPU_COMP_I32, 2, GPU_FETCH_INT);
93 
96 
101  g_batch.glyph_len = 0;
102 
103  /* A dummy VBO containing 4 points, attributes are not used. */
105  GPU_vertbuf_data_alloc(vbo, 4);
106 
107  /* We render a quad as a triangle strip and instance it for each glyph. */
110 }
111 
112 static void blf_batch_draw_exit(void)
113 {
115 }
116 
118 {
119  if (g_batch.batch == NULL) {
121  }
122 
123  const bool font_changed = (g_batch.font != font);
124  const bool simple_shader = ((font->flags & (BLF_ROTATION | BLF_MATRIX | BLF_ASPECT)) == 0);
125  const bool shader_changed = (simple_shader != g_batch.simple_shader);
126 
127  g_batch.active = g_batch.enabled && simple_shader;
128 
129  if (simple_shader) {
130  /* Offset is applied to each glyph. */
131  g_batch.ofs[0] = floorf(font->pos[0]);
132  g_batch.ofs[1] = floorf(font->pos[1]);
133  }
134  else {
135  /* Offset is baked in modelview mat. */
137  }
138 
139  if (g_batch.active) {
140  float gpumat[4][4];
142 
143  bool mat_changed = (memcmp(gpumat, g_batch.mat, sizeof(g_batch.mat)) != 0);
144 
145  if (mat_changed) {
146  /* Modelviewmat is no longer the same.
147  * Flush cache but with the previous mat. */
148  GPU_matrix_push();
150  }
151 
152  /* flush cache if config is not the same. */
153  if (mat_changed || font_changed || shader_changed) {
154  blf_batch_draw();
155  g_batch.simple_shader = simple_shader;
156  g_batch.font = font;
157  }
158  else {
159  /* Nothing changed continue batching. */
160  return;
161  }
162 
163  if (mat_changed) {
164  GPU_matrix_pop();
165  /* Save for next memcmp. */
166  memcpy(g_batch.mat, gpumat, sizeof(g_batch.mat));
167  }
168  }
169  else {
170  /* flush cache */
171  blf_batch_draw();
172  g_batch.font = font;
173  g_batch.simple_shader = simple_shader;
174  }
175 }
176 
178 {
180  BLI_assert(gc);
181  BLI_assert(gc->bitmap_len > 0);
182 
183  if (gc->bitmap_len > gc->bitmap_len_landed) {
184  const int tex_width = GPU_texture_width(gc->texture);
185 
186  int bitmap_len_landed = gc->bitmap_len_landed;
187  int remain = gc->bitmap_len - bitmap_len_landed;
188  int offset_x = bitmap_len_landed % tex_width;
189  int offset_y = bitmap_len_landed / tex_width;
190 
191  /* TODO(germano): Update more than one row in a single call. */
192  while (remain) {
193  int remain_row = tex_width - offset_x;
194  int width = remain > remain_row ? remain_row : remain;
197  &gc->bitmap_result[bitmap_len_landed],
198  offset_x,
199  offset_y,
200  0,
201  width,
202  1,
203  0);
204 
205  bitmap_len_landed += width;
206  remain -= width;
207  offset_x = 0;
208  offset_y += 1;
209  }
210 
211  gc->bitmap_len_landed = bitmap_len_landed;
212  }
213 
214  return gc->texture;
215 }
216 
217 void blf_batch_draw(void)
218 {
219  if (g_batch.glyph_len == 0) {
220  return;
221  }
222 
224 
225 #ifndef BLF_STANDALONE
226  /* We need to flush widget base first to ensure correct ordering. */
228 #endif
229 
232  GPU_vertbuf_use(g_batch.verts); /* send data */
233 
237 
239 
241 
242  /* restart to 1st vertex data pointers */
247  g_batch.glyph_len = 0;
248 }
249 
250 static void blf_batch_draw_end(void)
251 {
252  if (!g_batch.active) {
253  blf_batch_draw();
254  }
255 }
256 
259 /* -------------------------------------------------------------------- */
260 
261 int blf_font_init(void)
262 {
263  memset(&g_batch, 0, sizeof(g_batch));
266  return FT_Init_FreeType(&ft_lib);
267 }
268 
269 void blf_font_exit(void)
270 {
271  FT_Done_FreeType(ft_lib);
275 }
276 
277 void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
278 {
279  GlyphCacheBLF *gc;
280  FT_Error err;
281 
283 
284  gc = blf_glyph_cache_find(font, size, dpi);
285  if (gc) {
286  /* Optimization: do not call FT_Set_Char_Size if size did not change. */
287  if (font->size == size && font->dpi == dpi) {
289  return;
290  }
291  }
292 
293  err = FT_Set_Char_Size(font->face, 0, ((FT_F26Dot6)(size)) * 64, dpi, dpi);
294  if (err) {
295  /* FIXME: here we can go through the fixed size and choice a close one */
296  printf("The current font don't support the size, %u and dpi, %u\n", size, dpi);
297 
299  return;
300  }
301 
302  font->size = size;
303  font->dpi = dpi;
304 
305  if (!gc) {
306  blf_glyph_cache_new(font);
307  }
309 }
310 
312 {
313  GlyphBLF **glyph_ascii_table;
314 
315  glyph_ascii_table = gc->glyph_ascii_table;
316 
317  /* build ascii on demand */
318  if (glyph_ascii_table['0'] == NULL) {
319  GlyphBLF *g;
320  for (uint i = 0; i < 256; i++) {
321  g = blf_glyph_search(gc, i);
322  if (!g) {
323  FT_UInt glyph_index = FT_Get_Char_Index(font->face, i);
324  g = blf_glyph_add(font, gc, glyph_index, i);
325  }
326  glyph_ascii_table[i] = g;
327  }
328  }
329 
330  return glyph_ascii_table;
331 }
332 
334  GlyphCacheBLF *gc,
335  const FT_UInt kern_mode)
336 {
337  KerningCacheBLF *kc = font->kerning_cache;
338 
339  font->kerning_mode = kern_mode;
340 
341  if (!kc || kc->mode != kern_mode) {
342  font->kerning_cache = kc = blf_kerning_cache_find(font);
343  if (!kc) {
344  font->kerning_cache = kc = blf_kerning_cache_new(font, gc);
345  }
346  }
347 }
348 
349 /* Fast path for runs of ASCII characters. Given that common UTF-8
350  * input will consist of an overwhelming majority of ASCII
351  * characters.
352  */
353 
354 /* Note,
355  * blf_font_ensure_ascii_table(font, gc); must be called before this macro */
356 
357 #define BLF_UTF8_NEXT_FAST(_font, _gc, _g, _str, _i, _c, _glyph_ascii_table) \
358  if (((_c) = (_str)[_i]) < 0x80) { \
359  _g = (_glyph_ascii_table)[_c]; \
360  _i++; \
361  } \
362  else if ((_c = BLI_str_utf8_as_unicode_step(_str, &(_i))) != BLI_UTF8_ERR) { \
363  if ((_g = blf_glyph_search(_gc, _c)) == NULL) { \
364  _g = blf_glyph_add(_font, _gc, FT_Get_Char_Index((_font)->face, _c), _c); \
365  } \
366  } \
367  else { \
368  _g = NULL; \
369  } \
370  (void)0
371 
372 #define BLF_KERNING_VARS(_font, _has_kerning, _kern_mode) \
373  const bool _has_kerning = FT_HAS_KERNING((_font)->face) != 0; \
374  const FT_UInt _kern_mode = (_has_kerning == 0) ? 0 : \
375  (((_font)->flags & BLF_KERNING_DEFAULT) ? \
376  ft_kerning_default : \
377  (FT_UInt)FT_KERNING_UNFITTED)
378 
379 /* Note,
380  * blf_font_ensure_ascii_kerning(font, gc, kern_mode); must be called before this macro */
381 
382 #define BLF_KERNING_STEP_FAST(_font, _kern_mode, _g_prev, _g, _c_prev, _c, _pen_x) \
383  { \
384  if (_g_prev) { \
385  FT_Vector _delta; \
386  if (_c_prev < 0x80 && _c < 0x80) { \
387  _pen_x += (_font)->kerning_cache->table[_c][_c_prev]; \
388  } \
389  else if (FT_Get_Kerning((_font)->face, (_g_prev)->idx, (_g)->idx, _kern_mode, &(_delta)) == \
390  0) { \
391  _pen_x += (int)_delta.x >> 6; \
392  } \
393  } \
394  } \
395  (void)0
396 
397 #define BLF_KERNING_STEP(_font, _kern_mode, _g_prev, _g, _delta, _pen_x) \
398  { \
399  if (_g_prev) { \
400  _delta.x = _delta.y = 0; \
401  if (FT_Get_Kerning((_font)->face, (_g_prev)->idx, (_g)->idx, _kern_mode, &(_delta)) == 0) { \
402  _pen_x += (int)_delta.x >> 6; \
403  } \
404  } \
405  } \
406  (void)0
407 
408 static void blf_font_draw_ex(FontBLF *font,
409  GlyphCacheBLF *gc,
410  const char *str,
411  size_t len,
412  struct ResultBLF *r_info,
413  int pen_y)
414 {
415  unsigned int c, c_prev = BLI_UTF8_ERR;
416  GlyphBLF *g, *g_prev = NULL;
417  int pen_x = 0;
418  size_t i = 0;
419 
420  if (len == 0) {
421  /* early output, don't do any IMM OpenGL. */
422  return;
423  }
424 
425  GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
426 
427  BLF_KERNING_VARS(font, has_kerning, kern_mode);
428 
429  blf_font_ensure_ascii_kerning(font, gc, kern_mode);
430 
431  blf_batch_draw_begin(font);
432 
433  while ((i < len) && str[i]) {
434  BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
435 
436  if (UNLIKELY(c == BLI_UTF8_ERR)) {
437  break;
438  }
439  if (UNLIKELY(g == NULL)) {
440  continue;
441  }
442  if (has_kerning) {
443  BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
444  }
445 
446  /* do not return this loop if clipped, we want every character tested */
447  blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y);
448 
449  pen_x += g->advance_i;
450  g_prev = g;
451  c_prev = c;
452  }
453 
455 
456  if (r_info) {
457  r_info->lines = 1;
458  r_info->width = pen_x;
459  }
460 }
461 void blf_font_draw(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
462 {
464  blf_font_draw_ex(font, gc, str, len, r_info, 0);
466 }
467 
468 /* faster version of blf_font_draw, ascii only for view dimensions */
470  FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
471 {
472  unsigned int c, c_prev = BLI_UTF8_ERR;
473  GlyphBLF *g, *g_prev = NULL;
474  int pen_x = 0;
475 
477  GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
478 
479  BLF_KERNING_VARS(font, has_kerning, kern_mode);
480 
481  blf_font_ensure_ascii_kerning(font, gc, kern_mode);
482 
483  blf_batch_draw_begin(font);
484 
485  while ((c = *(str++)) && len--) {
486  BLI_assert(c < 128);
487  if ((g = glyph_ascii_table[c]) == NULL) {
488  continue;
489  }
490  if (has_kerning) {
491  BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
492  }
493 
494  /* do not return this loop if clipped, we want every character tested */
495  blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y);
496 
497  pen_x += g->advance_i;
498  g_prev = g;
499  c_prev = c;
500  }
501 
503 
504  if (r_info) {
505  r_info->lines = 1;
506  r_info->width = pen_x;
507  }
508 
510 }
511 
512 void blf_font_draw_ascii(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
513 {
514  blf_font_draw_ascii_ex(font, str, len, r_info, 0);
515 }
516 
517 /* use fixed column width, but an utf8 character may occupy multiple columns */
518 int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
519 {
520  unsigned int c;
521  GlyphBLF *g;
522  int col, columns = 0;
523  int pen_x = 0, pen_y = 0;
524  size_t i = 0;
525 
527  GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
528 
529  blf_batch_draw_begin(font);
530 
531  while ((i < len) && str[i]) {
532  BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
533 
534  if (UNLIKELY(c == BLI_UTF8_ERR)) {
535  break;
536  }
537  if (UNLIKELY(g == NULL)) {
538  continue;
539  }
540 
541  /* do not return this loop if clipped, we want every character tested */
542  blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y);
543 
544  col = BLI_wcwidth((char32_t)c);
545  if (col < 0) {
546  col = 1;
547  }
548 
549  columns += col;
550  pen_x += cwidth * col;
551  }
552 
554 
556  return columns;
557 }
558 
559 /* Sanity checks are done by BLF_draw_buffer() */
561  GlyphCacheBLF *gc,
562  const char *str,
563  size_t len,
564  struct ResultBLF *r_info,
565  int pen_y)
566 {
567  unsigned int c, c_prev = BLI_UTF8_ERR;
568  GlyphBLF *g, *g_prev = NULL;
569  int pen_x = (int)font->pos[0];
570  int pen_y_basis = (int)font->pos[1] + pen_y;
571  size_t i = 0;
572 
573  GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
574 
575  /* buffer specific vars */
576  FontBufInfoBLF *buf_info = &font->buf_info;
577  const float *b_col_float = buf_info->col_float;
578  const unsigned char *b_col_char = buf_info->col_char;
579  int chx, chy;
580  int y, x;
581 
582  BLF_KERNING_VARS(font, has_kerning, kern_mode);
583 
584  blf_font_ensure_ascii_kerning(font, gc, kern_mode);
585 
586  /* another buffer specific call for color conversion */
587 
588  while ((i < len) && str[i]) {
589  BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
590 
591  if (UNLIKELY(c == BLI_UTF8_ERR)) {
592  break;
593  }
594  if (UNLIKELY(g == NULL)) {
595  continue;
596  }
597  if (has_kerning) {
598  BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
599  }
600 
601  chx = pen_x + ((int)g->pos[0]);
602  chy = pen_y_basis + g->dims[1];
603 
604  if (g->pitch < 0) {
605  pen_y = pen_y_basis + (g->dims[1] - g->pos[1]);
606  }
607  else {
608  pen_y = pen_y_basis - (g->dims[1] - g->pos[1]);
609  }
610 
611  if ((chx + g->dims[0]) >= 0 && chx < buf_info->dims[0] && (pen_y + g->dims[1]) >= 0 &&
612  pen_y < buf_info->dims[1]) {
613  /* don't draw beyond the buffer bounds */
614  int width_clip = g->dims[0];
615  int height_clip = g->dims[1];
616  int yb_start = g->pitch < 0 ? 0 : g->dims[1] - 1;
617 
618  if (width_clip + chx > buf_info->dims[0]) {
619  width_clip -= chx + width_clip - buf_info->dims[0];
620  }
621  if (height_clip + pen_y > buf_info->dims[1]) {
622  height_clip -= pen_y + height_clip - buf_info->dims[1];
623  }
624 
625  /* drawing below the image? */
626  if (pen_y < 0) {
627  yb_start += (g->pitch < 0) ? -pen_y : pen_y;
628  height_clip += pen_y;
629  pen_y = 0;
630  }
631 
632  if (buf_info->fbuf) {
633  int yb = yb_start;
634  for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
635  for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
636  const char a_byte = *(g->bitmap + x + (yb * g->pitch));
637  if (a_byte) {
638  const float a = (a_byte / 255.0f) * b_col_float[3];
639  const size_t buf_ofs = (((size_t)(chx + x) +
640  ((size_t)(pen_y + y) * (size_t)buf_info->dims[0])) *
641  (size_t)buf_info->ch);
642  float *fbuf = buf_info->fbuf + buf_ofs;
643 
644  float font_pixel[4];
645  font_pixel[0] = b_col_float[0] * a;
646  font_pixel[1] = b_col_float[1] * a;
647  font_pixel[2] = b_col_float[2] * a;
648  font_pixel[3] = a;
649  blend_color_mix_float(fbuf, fbuf, font_pixel);
650  }
651  }
652 
653  if (g->pitch < 0) {
654  yb++;
655  }
656  else {
657  yb--;
658  }
659  }
660  }
661 
662  if (buf_info->cbuf) {
663  int yb = yb_start;
664  for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
665  for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
666  const char a_byte = *(g->bitmap + x + (yb * g->pitch));
667 
668  if (a_byte) {
669  const float a = (a_byte / 255.0f) * b_col_float[3];
670  const size_t buf_ofs = (((size_t)(chx + x) +
671  ((size_t)(pen_y + y) * (size_t)buf_info->dims[0])) *
672  (size_t)buf_info->ch);
673  unsigned char *cbuf = buf_info->cbuf + buf_ofs;
674 
675  uchar font_pixel[4];
676  font_pixel[0] = b_col_char[0];
677  font_pixel[1] = b_col_char[1];
678  font_pixel[2] = b_col_char[2];
679  font_pixel[3] = unit_float_to_uchar_clamp(a);
680  blend_color_mix_byte(cbuf, cbuf, font_pixel);
681  }
682  }
683 
684  if (g->pitch < 0) {
685  yb++;
686  }
687  else {
688  yb--;
689  }
690  }
691  }
692  }
693 
694  pen_x += g->advance_i;
695  g_prev = g;
696  c_prev = c;
697  }
698 
699  if (r_info) {
700  r_info->lines = 1;
701  r_info->width = pen_x;
702  }
703 }
704 
705 void blf_font_draw_buffer(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
706 {
708  blf_font_draw_buffer_ex(font, gc, str, len, r_info, 0);
710 }
711 
713  const bool has_kerning,
714  const FT_UInt kern_mode,
715  const uint c_prev,
716  const uint c,
717  GlyphBLF *g_prev,
718  GlyphBLF *g,
719  int *pen_x,
720  const int width_i)
721 {
722  if (UNLIKELY(c == BLI_UTF8_ERR)) {
723  return true; /* break the calling loop. */
724  }
725  if (UNLIKELY(g == NULL)) {
726  return false; /* continue the calling loop. */
727  }
728  if (has_kerning) {
729  BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, *pen_x);
730  }
731 
732  *pen_x += g->advance_i;
733 
734  return (*pen_x >= width_i);
735 }
736 
738  FontBLF *font, const char *str, size_t len, float width, float *r_width)
739 {
740  unsigned int c, c_prev = BLI_UTF8_ERR;
741  GlyphBLF *g, *g_prev;
742  int pen_x, width_new;
743  size_t i, i_prev;
744 
746  GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
747  const int width_i = (int)width;
748 
749  BLF_KERNING_VARS(font, has_kerning, kern_mode);
750 
751  if (has_kerning) {
752  blf_font_ensure_ascii_kerning(font, gc, kern_mode);
753  }
754 
755  for (i_prev = i = 0, width_new = pen_x = 0, g_prev = NULL, c_prev = 0; (i < len) && str[i];
756  i_prev = i, width_new = pen_x, c_prev = c, g_prev = g) {
757  BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
758 
760  font, has_kerning, kern_mode, c_prev, c, g_prev, g, &pen_x, width_i)) {
761  break;
762  }
763  }
764 
765  if (r_width) {
766  *r_width = (float)width_new;
767  }
768 
770  return i_prev;
771 }
772 
774  FontBLF *font, const char *str, size_t len, float width, float *r_width)
775 {
776  unsigned int c, c_prev = BLI_UTF8_ERR;
777  GlyphBLF *g, *g_prev;
778  int pen_x, width_new;
779  size_t i, i_prev, i_tmp;
780  char *s, *s_prev;
781 
783  GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
784  const int width_i = (int)width;
785 
786  BLF_KERNING_VARS(font, has_kerning, kern_mode);
787 
788  if (has_kerning) {
789  blf_font_ensure_ascii_kerning(font, gc, kern_mode);
790  }
791 
792  i = BLI_strnlen(str, len);
794  i = (size_t)((s != NULL) ? s - str : 0);
795  s_prev = BLI_str_find_prev_char_utf8(str, s);
796  i_prev = (size_t)((s_prev != NULL) ? s_prev - str : 0);
797 
798  i_tmp = i;
799  BLF_UTF8_NEXT_FAST(font, gc, g, str, i_tmp, c, glyph_ascii_table);
800  for (width_new = pen_x = 0; (s != NULL);
801  i = i_prev, s = s_prev, c = c_prev, g = g_prev, g_prev = NULL, width_new = pen_x) {
802  s_prev = BLI_str_find_prev_char_utf8(str, s);
803  i_prev = (size_t)((s_prev != NULL) ? s_prev - str : 0);
804 
805  if (s_prev != NULL) {
806  i_tmp = i_prev;
807  BLF_UTF8_NEXT_FAST(font, gc, g_prev, str, i_tmp, c_prev, glyph_ascii_table);
808  BLI_assert(i_tmp == i);
809  }
810 
812  font, has_kerning, kern_mode, c_prev, c, g_prev, g, &pen_x, width_i)) {
813  break;
814  }
815  }
816 
817  if (r_width) {
818  *r_width = (float)width_new;
819  }
820 
822  return i;
823 }
824 
825 static void blf_font_boundbox_ex(FontBLF *font,
826  GlyphCacheBLF *gc,
827  const char *str,
828  size_t len,
829  rctf *box,
830  struct ResultBLF *r_info,
831  int pen_y)
832 {
833  unsigned int c, c_prev = BLI_UTF8_ERR;
834  GlyphBLF *g, *g_prev = NULL;
835  int pen_x = 0;
836  size_t i = 0;
837 
838  GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
839 
840  rctf gbox;
841 
842  BLF_KERNING_VARS(font, has_kerning, kern_mode);
843 
844  box->xmin = 32000.0f;
845  box->xmax = -32000.0f;
846  box->ymin = 32000.0f;
847  box->ymax = -32000.0f;
848 
849  blf_font_ensure_ascii_kerning(font, gc, kern_mode);
850 
851  while ((i < len) && str[i]) {
852  BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
853 
854  if (UNLIKELY(c == BLI_UTF8_ERR)) {
855  break;
856  }
857  if (UNLIKELY(g == NULL)) {
858  continue;
859  }
860  if (has_kerning) {
861  BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
862  }
863 
864  gbox.xmin = (float)pen_x;
865  gbox.xmax = (float)pen_x + g->advance;
866  gbox.ymin = g->box.ymin + (float)pen_y;
867  gbox.ymax = g->box.ymax + (float)pen_y;
868 
869  if (gbox.xmin < box->xmin) {
870  box->xmin = gbox.xmin;
871  }
872  if (gbox.ymin < box->ymin) {
873  box->ymin = gbox.ymin;
874  }
875 
876  if (gbox.xmax > box->xmax) {
877  box->xmax = gbox.xmax;
878  }
879  if (gbox.ymax > box->ymax) {
880  box->ymax = gbox.ymax;
881  }
882 
883  pen_x += g->advance_i;
884  g_prev = g;
885  c_prev = c;
886  }
887 
888  if (box->xmin > box->xmax) {
889  box->xmin = 0.0f;
890  box->ymin = 0.0f;
891  box->xmax = 0.0f;
892  box->ymax = 0.0f;
893  }
894 
895  if (r_info) {
896  r_info->lines = 1;
897  r_info->width = pen_x;
898  }
899 }
901  FontBLF *font, const char *str, size_t len, rctf *r_box, struct ResultBLF *r_info)
902 {
904  blf_font_boundbox_ex(font, gc, str, len, r_box, r_info, 0);
906 }
907 
908 /* -------------------------------------------------------------------- */
921 static void blf_font_wrap_apply(FontBLF *font,
922  const char *str,
923  size_t len,
924  struct ResultBLF *r_info,
925  void (*callback)(FontBLF *font,
926  GlyphCacheBLF *gc,
927  const char *str,
928  size_t len,
929  int pen_y,
930  void *userdata),
931  void *userdata)
932 {
933  unsigned int c;
934  GlyphBLF *g, *g_prev = NULL;
935  FT_Vector delta;
936  int pen_x = 0, pen_y = 0;
937  size_t i = 0;
938  int lines = 0;
939  int pen_x_next = 0;
940 
942  GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
943 
944  BLF_KERNING_VARS(font, has_kerning, kern_mode);
945 
946  struct WordWrapVars {
947  int wrap_width;
948  size_t start, last[2];
949  } wrap = {font->wrap_width != -1 ? font->wrap_width : INT_MAX, 0, {0, 0}};
950 
951  // printf("%s wrapping (%d, %d) `%s`:\n", __func__, len, strlen(str), str);
952  while ((i < len) && str[i]) {
953 
954  /* wrap vars */
955  size_t i_curr = i;
956  bool do_draw = false;
957 
958  BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
959 
960  if (UNLIKELY(c == BLI_UTF8_ERR)) {
961  break;
962  }
963  if (UNLIKELY(g == NULL)) {
964  continue;
965  }
966  if (has_kerning) {
967  BLF_KERNING_STEP(font, kern_mode, g_prev, g, delta, pen_x);
968  }
969 
978  pen_x_next = pen_x + g->advance_i;
979  if (UNLIKELY((pen_x_next >= wrap.wrap_width) && (wrap.start != wrap.last[0]))) {
980  do_draw = true;
981  }
982  else if (UNLIKELY(((i < len) && str[i]) == 0)) {
983  /* need check here for trailing newline, else we draw it */
984  wrap.last[0] = i + ((g->c != '\n') ? 1 : 0);
985  wrap.last[1] = i;
986  do_draw = true;
987  }
988  else if (UNLIKELY(g->c == '\n')) {
989  wrap.last[0] = i_curr + 1;
990  wrap.last[1] = i;
991  do_draw = true;
992  }
993  else if (UNLIKELY(g->c != ' ' && (g_prev ? g_prev->c == ' ' : false))) {
994  wrap.last[0] = i_curr;
995  wrap.last[1] = i_curr;
996  }
997 
998  if (UNLIKELY(do_draw)) {
999  // printf("(%03d..%03d) `%.*s`\n",
1000  // wrap.start, wrap.last[0], (wrap.last[0] - wrap.start) - 1, &str[wrap.start]);
1001 
1002  callback(font, gc, &str[wrap.start], (wrap.last[0] - wrap.start) - 1, pen_y, userdata);
1003  wrap.start = wrap.last[0];
1004  i = wrap.last[1];
1005  pen_x = 0;
1006  pen_y -= gc->glyph_height_max;
1007  g_prev = NULL;
1008  lines += 1;
1009  continue;
1010  }
1011 
1012  pen_x = pen_x_next;
1013  g_prev = g;
1014  }
1015 
1016  // printf("done! lines: %d, width, %d\n", lines, pen_x_next);
1017 
1018  if (r_info) {
1019  r_info->lines = lines;
1020  /* width of last line only (with wrapped lines) */
1021  r_info->width = pen_x_next;
1022  }
1023 
1025 }
1026 
1027 /* blf_font_draw__wrap */
1029  GlyphCacheBLF *gc,
1030  const char *str,
1031  size_t len,
1032  int pen_y,
1033  void *UNUSED(userdata))
1034 {
1035  blf_font_draw_ex(font, gc, str, len, NULL, pen_y);
1036 }
1037 void blf_font_draw__wrap(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
1038 {
1040 }
1041 
1042 /* blf_font_boundbox__wrap */
1044  FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, int pen_y, void *userdata)
1045 {
1046  rctf *box = userdata;
1047  rctf box_single;
1048 
1049  blf_font_boundbox_ex(font, gc, str, len, &box_single, NULL, pen_y);
1050  BLI_rctf_union(box, &box_single);
1051 }
1053  FontBLF *font, const char *str, size_t len, rctf *box, struct ResultBLF *r_info)
1054 {
1055  box->xmin = 32000.0f;
1056  box->xmax = -32000.0f;
1057  box->ymin = 32000.0f;
1058  box->ymax = -32000.0f;
1059 
1060  blf_font_wrap_apply(font, str, len, r_info, blf_font_boundbox_wrap_cb, box);
1061 }
1062 
1063 /* blf_font_draw_buffer__wrap */
1065  GlyphCacheBLF *gc,
1066  const char *str,
1067  size_t len,
1068  int pen_y,
1069  void *UNUSED(userdata))
1070 {
1071  blf_font_draw_buffer_ex(font, gc, str, len, NULL, pen_y);
1072 }
1074  const char *str,
1075  size_t len,
1076  struct ResultBLF *r_info)
1077 {
1079 }
1080 
1084  const char *str,
1085  size_t len,
1086  float *r_width,
1087  float *r_height,
1088  struct ResultBLF *r_info)
1089 {
1090  float xa, ya;
1091  rctf box;
1092 
1093  if (font->flags & BLF_ASPECT) {
1094  xa = font->aspect[0];
1095  ya = font->aspect[1];
1096  }
1097  else {
1098  xa = 1.0f;
1099  ya = 1.0f;
1100  }
1101 
1102  if (font->flags & BLF_WORD_WRAP) {
1103  blf_font_boundbox__wrap(font, str, len, &box, r_info);
1104  }
1105  else {
1106  blf_font_boundbox(font, str, len, &box, r_info);
1107  }
1108  *r_width = (BLI_rctf_size_x(&box) * xa);
1109  *r_height = (BLI_rctf_size_y(&box) * ya);
1110 }
1111 
1112 float blf_font_width(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
1113 {
1114  float xa;
1115  rctf box;
1116 
1117  if (font->flags & BLF_ASPECT) {
1118  xa = font->aspect[0];
1119  }
1120  else {
1121  xa = 1.0f;
1122  }
1123 
1124  if (font->flags & BLF_WORD_WRAP) {
1125  blf_font_boundbox__wrap(font, str, len, &box, r_info);
1126  }
1127  else {
1128  blf_font_boundbox(font, str, len, &box, r_info);
1129  }
1130  return BLI_rctf_size_x(&box) * xa;
1131 }
1132 
1133 float blf_font_height(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
1134 {
1135  float ya;
1136  rctf box;
1137 
1138  if (font->flags & BLF_ASPECT) {
1139  ya = font->aspect[1];
1140  }
1141  else {
1142  ya = 1.0f;
1143  }
1144 
1145  if (font->flags & BLF_WORD_WRAP) {
1146  blf_font_boundbox__wrap(font, str, len, &box, r_info);
1147  }
1148  else {
1149  blf_font_boundbox(font, str, len, &box, r_info);
1150  }
1151  return BLI_rctf_size_y(&box) * ya;
1152 }
1153 
1155 {
1156  const unsigned int c = ' ';
1157 
1159  blf_font_ensure_ascii_table(font, gc);
1160 
1161  GlyphBLF *g = blf_glyph_search(gc, c);
1162  if (!g) {
1163  g = blf_glyph_add(font, gc, FT_Get_Char_Index(font->face, c), c);
1164 
1165  /* if we don't find the glyph. */
1166  if (!g) {
1168  return 0.0f;
1169  }
1170  }
1171 
1173  return g->advance;
1174 }
1175 
1176 /* -------------------------------------------------------------------- */
1181  GlyphCacheBLF *gc,
1182  const char *str,
1183  size_t len,
1184  BLF_GlyphBoundsFn user_fn,
1185  void *user_data,
1186  struct ResultBLF *r_info,
1187  int pen_y)
1188 {
1189  unsigned int c, c_prev = BLI_UTF8_ERR;
1190  GlyphBLF *g, *g_prev = NULL;
1191  int pen_x = 0;
1192  size_t i = 0, i_curr;
1193  rcti gbox;
1194 
1195  if (len == 0) {
1196  /* early output. */
1197  return;
1198  }
1199 
1200  GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
1201 
1202  BLF_KERNING_VARS(font, has_kerning, kern_mode);
1203 
1204  blf_font_ensure_ascii_kerning(font, gc, kern_mode);
1205 
1206  while ((i < len) && str[i]) {
1207  i_curr = i;
1208  BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
1209 
1210  if (UNLIKELY(c == BLI_UTF8_ERR)) {
1211  break;
1212  }
1213  if (UNLIKELY(g == NULL)) {
1214  continue;
1215  }
1216  if (has_kerning) {
1217  BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
1218  }
1219 
1220  gbox.xmin = pen_x;
1221  gbox.xmax = gbox.xmin + MIN2(g->advance_i, g->dims[0]);
1222  gbox.ymin = pen_y;
1223  gbox.ymax = gbox.ymin - g->dims[1];
1224 
1225  pen_x += g->advance_i;
1226 
1227  if (user_fn(str, i_curr, &gbox, g->advance_i, &g->box, g->pos, user_data) == false) {
1228  break;
1229  }
1230 
1231  g_prev = g;
1232  c_prev = c;
1233  }
1234 
1235  if (r_info) {
1236  r_info->lines = 1;
1237  r_info->width = pen_x;
1238  }
1239 }
1241  const char *str,
1242  size_t len,
1243  BLF_GlyphBoundsFn user_fn,
1244  void *user_data,
1245  struct ResultBLF *r_info)
1246 {
1248  blf_font_boundbox_foreach_glyph_ex(font, gc, str, len, user_fn, user_data, r_info, 0);
1250 }
1251 
1255  const char *str,
1256  const size_t len,
1257  int *r_tot_chars)
1258 {
1259  int missing = 0;
1260  size_t i = 0;
1261 
1262  *r_tot_chars = 0;
1263  while (i < len) {
1264  unsigned int c;
1265 
1266  if ((c = str[i]) < 0x80) {
1267  i++;
1268  }
1269  else if ((c = BLI_str_utf8_as_unicode_step(str, &i)) != BLI_UTF8_ERR) {
1270  if (FT_Get_Char_Index((font)->face, c) == 0) {
1271  missing++;
1272  }
1273  }
1274  (*r_tot_chars)++;
1275  }
1276  return missing;
1277 }
1278 
1280 {
1282  GlyphCacheBLF *gc;
1283 
1284  while ((gc = BLI_pophead(&font->cache))) {
1286  }
1287 
1289 
1290  FT_Done_Face(font->face);
1291  if (font->filename) {
1292  MEM_freeN(font->filename);
1293  }
1294  if (font->name) {
1295  MEM_freeN(font->name);
1296  }
1297  MEM_freeN(font);
1298 
1300 }
1301 
1302 static void blf_font_fill(FontBLF *font)
1303 {
1304  font->aspect[0] = 1.0f;
1305  font->aspect[1] = 1.0f;
1306  font->aspect[2] = 1.0f;
1307  font->pos[0] = 0.0f;
1308  font->pos[1] = 0.0f;
1309  font->angle = 0.0f;
1310 
1311  for (int i = 0; i < 16; i++) {
1312  font->m[i] = 0;
1313  }
1314 
1315  /* annoying bright color so we can see where to add BLF_color calls */
1316  font->color[0] = 255;
1317  font->color[1] = 255;
1318  font->color[2] = 0;
1319  font->color[3] = 255;
1320 
1321  font->clip_rec.xmin = 0.0f;
1322  font->clip_rec.xmax = 0.0f;
1323  font->clip_rec.ymin = 0.0f;
1324  font->clip_rec.ymax = 0.0f;
1325  font->flags = 0;
1326  font->dpi = 0;
1327  font->size = 0;
1328  BLI_listbase_clear(&font->cache);
1330  font->kerning_cache = NULL;
1331 #if BLF_BLUR_ENABLE
1332  font->blur = 0;
1333 #endif
1334  font->tex_size_max = -1;
1335 
1336  font->buf_info.fbuf = NULL;
1337  font->buf_info.cbuf = NULL;
1338  font->buf_info.dims[0] = 0;
1339  font->buf_info.dims[1] = 0;
1340  font->buf_info.ch = 0;
1341  font->buf_info.col_init[0] = 0;
1342  font->buf_info.col_init[1] = 0;
1343  font->buf_info.col_init[2] = 0;
1344  font->buf_info.col_init[3] = 0;
1345 
1346  font->ft_lib = ft_lib;
1347  font->ft_lib_mutex = &ft_lib_mutex;
1349 }
1350 
1351 FontBLF *blf_font_new(const char *name, const char *filename)
1352 {
1353  FontBLF *font;
1354  FT_Error err;
1355  char *mfile;
1356 
1357  font = (FontBLF *)MEM_callocN(sizeof(FontBLF), "blf_font_new");
1358  err = FT_New_Face(ft_lib, filename, 0, &font->face);
1359  if (err) {
1360  MEM_freeN(font);
1361  return NULL;
1362  }
1363 
1364  err = FT_Select_Charmap(font->face, ft_encoding_unicode);
1365  if (err) {
1366  printf("Can't set the unicode character map!\n");
1367  FT_Done_Face(font->face);
1368  MEM_freeN(font);
1369  return NULL;
1370  }
1371 
1372  mfile = blf_dir_metrics_search(filename);
1373  if (mfile) {
1374  err = FT_Attach_File(font->face, mfile);
1375  if (err) {
1376  fprintf(stderr, "FT_Attach_File failed to load '%s' with error %d\n", filename, (int)err);
1377  }
1378  MEM_freeN(mfile);
1379  }
1380 
1381  font->name = BLI_strdup(name);
1382  font->filename = BLI_strdup(filename);
1383  blf_font_fill(font);
1384  return font;
1385 }
1386 
1387 void blf_font_attach_from_mem(FontBLF *font, const unsigned char *mem, int mem_size)
1388 {
1389  FT_Open_Args open;
1390 
1391  open.flags = FT_OPEN_MEMORY;
1392  open.memory_base = (const FT_Byte *)mem;
1393  open.memory_size = mem_size;
1394  FT_Attach_Stream(font->face, &open);
1395 }
1396 
1397 FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int mem_size)
1398 {
1399  FontBLF *font;
1400  FT_Error err;
1401 
1402  font = (FontBLF *)MEM_callocN(sizeof(FontBLF), "blf_font_new_from_mem");
1403  err = FT_New_Memory_Face(ft_lib, mem, mem_size, 0, &font->face);
1404  if (err) {
1405  MEM_freeN(font);
1406  return NULL;
1407  }
1408 
1409  err = FT_Select_Charmap(font->face, ft_encoding_unicode);
1410  if (err) {
1411  printf("Can't set the unicode character map!\n");
1412  FT_Done_Face(font->face);
1413  MEM_freeN(font);
1414  return NULL;
1415  }
1416 
1417  font->name = BLI_strdup(name);
1418  font->filename = NULL;
1419  blf_font_fill(font);
1420  return font;
1421 }
1422 
1424 {
1425  int height_max;
1426 
1428  blf_font_ensure_ascii_table(font, gc);
1429  height_max = gc->glyph_height_max;
1430 
1432  return height_max;
1433 }
1434 
1436 {
1437  int width_max;
1438 
1440  blf_font_ensure_ascii_table(font, gc);
1441  width_max = gc->glyph_width_max;
1442 
1444  return width_max;
1445 }
1446 
1448 {
1449  float descender;
1450 
1452  blf_font_ensure_ascii_table(font, gc);
1453  descender = gc->descender;
1454 
1456  return descender;
1457 }
1458 
1460 {
1461  float ascender;
1462 
1464  blf_font_ensure_ascii_table(font, gc);
1465  ascender = gc->ascender;
1466 
1468  return ascender;
1469 }
typedef float(TangentPoint)[2]
#define BLF_ASPECT
Definition: BLF_api.h:274
#define BLF_ROTATION
Definition: BLF_api.h:269
bool(* BLF_GlyphBoundsFn)(const char *str, const size_t str_step_ofs, const struct rcti *glyph_step_bounds, const int glyph_advance_x, const struct rctf *glyph_bounds, const int glyph_bearing[2], void *user_data)
Definition: BLF_api.h:107
#define BLF_MATRIX
Definition: BLF_api.h:273
#define BLF_WORD_WRAP
Definition: BLF_api.h:275
#define BLI_assert(a)
Definition: BLI_assert.h:58
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:257
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_mix_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void zero_v2(float r[2])
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:161
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:165
void BLI_rctf_union(struct rctf *rct1, const struct rctf *rct2)
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:70
size_t BLI_strnlen(const char *str, const size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:878
int BLI_wcwidth(char32_t ucs)
Definition: string_utf8.c:409
char * BLI_str_find_prev_char_utf8(const char *str, const char *p) ATTR_NONNULL()
Definition: string_utf8.c:782
#define BLI_UTF8_ERR
unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index) ATTR_NONNULL()
Definition: string_utf8.c:585
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
pthread_spinlock_t SpinLock
Definition: BLI_threads.h:111
void BLI_spin_init(SpinLock *spin)
Definition: threads.cc:447
void BLI_spin_unlock(SpinLock *spin)
Definition: threads.cc:480
void BLI_spin_lock(SpinLock *spin)
Definition: threads.cc:461
void BLI_spin_end(SpinLock *spin)
Definition: threads.cc:495
#define UNUSED(x)
#define UNLIKELY(x)
#define MIN2(a, b)
#define GPU_batch_texture_bind(batch, name, tex)
Definition: GPU_batch.h:149
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
Definition: gpu_batch.cc:299
#define GPU_BATCH_DISCARD_SAFE(batch)
Definition: GPU_batch.h:199
void GPU_batch_instbuf_set(GPUBatch *, GPUVertBuf *, bool own_vbo)
Definition: gpu_batch.cc:141
GPUBatch * GPU_batch_create_ex(GPUPrimType prim, GPUVertBuf *vert, GPUIndexBuf *elem, eGPUBatchFlag owns_flag)
Definition: gpu_batch.cc:60
void GPU_batch_draw(GPUBatch *batch)
Definition: gpu_batch.cc:234
@ GPU_BATCH_OWNS_VBO
Definition: GPU_batch.h:45
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:142
#define GPU_matrix_model_view_get(x)
Definition: GPU_matrix.h:226
#define GPU_matrix_set(x)
Definition: GPU_matrix.h:224
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:135
@ GPU_PRIM_TRI_STRIP
Definition: GPU_primitive.h:40
@ GPU_SHADER_TEXT
Definition: GPU_shader.h:161
@ GPU_BLEND_NONE
Definition: GPU_state.h:55
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
void GPU_texture_update_sub(GPUTexture *tex, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
Definition: gpu_texture.cc:356
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
int GPU_texture_width(const GPUTexture *tex)
Definition: gpu_texture.cc:527
@ GPU_DATA_UBYTE
Definition: GPU_texture.h:175
void GPU_texture_unbind(GPUTexture *tex)
Definition: gpu_texture.cc:421
#define GPU_vertbuf_create_with_format(format)
struct GPUVertBuf GPUVertBuf
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len)
void GPU_vertbuf_use(GPUVertBuf *)
GPUVertBuf * GPU_vertbuf_create_with_format_ex(const GPUVertFormat *, GPUUsageType)
void GPU_vertbuf_data_len_set(GPUVertBuf *, uint v_len)
void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *, uint a_idx, GPUVertBufRaw *access)
@ GPU_USAGE_STREAM
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT_UNIT
@ GPU_FETCH_INT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
@ GPU_COMP_I32
@ GPU_COMP_U8
Read Guarded memory(de)allocation.
void UI_widgetbase_draw_cache_flush(void)
char * blf_dir_metrics_search(const char *filename)
Definition: blf_dir.c:158
float blf_font_ascender(FontBLF *font)
Definition: blf_font.c:1459
void blf_font_draw_buffer(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
Definition: blf_font.c:705
static bool blf_font_width_to_strlen_glyph_process(FontBLF *font, const bool has_kerning, const FT_UInt kern_mode, const uint c_prev, const uint c, GlyphBLF *g_prev, GlyphBLF *g, int *pen_x, const int width_i)
Definition: blf_font.c:712
FontBLF * blf_font_new(const char *name, const char *filename)
Definition: blf_font.c:1351
static void blf_font_ensure_ascii_kerning(FontBLF *font, GlyphCacheBLF *gc, const FT_UInt kern_mode)
Definition: blf_font.c:333
BatchBLF g_batch
Definition: blf_font.c:67
#define BLF_KERNING_STEP(_font, _kern_mode, _g_prev, _g, _delta, _pen_x)
Definition: blf_font.c:397
void blf_batch_draw(void)
Definition: blf_font.c:217
static void blf_font_fill(FontBLF *font)
Definition: blf_font.c:1302
static GPUTexture * blf_batch_cache_texture_load(void)
Definition: blf_font.c:177
void blf_font_exit(void)
Definition: blf_font.c:269
static SpinLock ft_lib_mutex
Definition: blf_font.c:71
static void blf_font_draw_ex(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
Definition: blf_font.c:408
void blf_font_width_and_height(FontBLF *font, const char *str, size_t len, float *r_width, float *r_height, struct ResultBLF *r_info)
Definition: blf_font.c:1083
void blf_font_boundbox_foreach_glyph(FontBLF *font, const char *str, size_t len, BLF_GlyphBoundsFn user_fn, void *user_data, struct ResultBLF *r_info)
Definition: blf_font.c:1240
void blf_font_boundbox(FontBLF *font, const char *str, size_t len, rctf *r_box, struct ResultBLF *r_info)
Definition: blf_font.c:900
static void blf_font_draw_buffer_ex(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
Definition: blf_font.c:560
void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
Definition: blf_font.c:277
static void blf_font_wrap_apply(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info, void(*callback)(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, int pen_y, void *userdata), void *userdata)
Definition: blf_font.c:921
static void blf_font_draw__wrap_cb(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, int pen_y, void *UNUSED(userdata))
Definition: blf_font.c:1028
size_t blf_font_width_to_rstrlen(FontBLF *font, const char *str, size_t len, float width, float *r_width)
Definition: blf_font.c:773
void blf_font_free(FontBLF *font)
Definition: blf_font.c:1279
int blf_font_count_missing_chars(FontBLF *font, const char *str, const size_t len, int *r_tot_chars)
Definition: blf_font.c:1254
static FT_Library ft_lib
Definition: blf_font.c:70
FontBLF * blf_font_new_from_mem(const char *name, const unsigned char *mem, int mem_size)
Definition: blf_font.c:1397
void blf_font_draw_ascii(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
Definition: blf_font.c:512
float blf_font_fixed_width(FontBLF *font)
Definition: blf_font.c:1154
#define BLF_KERNING_STEP_FAST(_font, _kern_mode, _g_prev, _g, _c_prev, _c, _pen_x)
Definition: blf_font.c:382
static void blf_font_draw_ascii_ex(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
Definition: blf_font.c:469
static void blf_batch_draw_end(void)
Definition: blf_font.c:250
size_t blf_font_width_to_strlen(FontBLF *font, const char *str, size_t len, float width, float *r_width)
Definition: blf_font.c:737
void blf_font_boundbox__wrap(FontBLF *font, const char *str, size_t len, rctf *box, struct ResultBLF *r_info)
Definition: blf_font.c:1052
int blf_font_width_max(FontBLF *font)
Definition: blf_font.c:1435
int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
Definition: blf_font.c:518
void blf_font_attach_from_mem(FontBLF *font, const unsigned char *mem, int mem_size)
Definition: blf_font.c:1387
static GlyphBLF ** blf_font_ensure_ascii_table(FontBLF *font, GlyphCacheBLF *gc)
Definition: blf_font.c:311
static void blf_batch_draw_exit(void)
Definition: blf_font.c:112
void blf_batch_draw_begin(FontBLF *font)
Definition: blf_font.c:117
static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, BLF_GlyphBoundsFn user_fn, void *user_data, struct ResultBLF *r_info, int pen_y)
Definition: blf_font.c:1180
static void blf_font_boundbox_ex(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, rctf *box, struct ResultBLF *r_info, int pen_y)
Definition: blf_font.c:825
float blf_font_width(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
Definition: blf_font.c:1112
#define BLF_KERNING_VARS(_font, _has_kerning, _kern_mode)
Definition: blf_font.c:372
float blf_font_descender(FontBLF *font)
Definition: blf_font.c:1447
#define BLF_UTF8_NEXT_FAST(_font, _gc, _g, _str, _i, _c, _glyph_ascii_table)
Definition: blf_font.c:357
static SpinLock blf_glyph_cache_mutex
Definition: blf_font.c:72
static void blf_font_boundbox_wrap_cb(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, int pen_y, void *userdata)
Definition: blf_font.c:1043
static void blf_batch_draw_init(void)
Definition: blf_font.c:84
int blf_font_init(void)
Definition: blf_font.c:261
static void blf_font_draw_buffer__wrap_cb(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, int pen_y, void *UNUSED(userdata))
Definition: blf_font.c:1064
float blf_font_height(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
Definition: blf_font.c:1133
void blf_font_draw(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
Definition: blf_font.c:461
int blf_font_height_max(FontBLF *font)
Definition: blf_font.c:1423
void blf_font_draw_buffer__wrap(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
Definition: blf_font.c:1073
void blf_font_draw__wrap(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
Definition: blf_font.c:1037
GlyphBLF * blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, unsigned int c)
Definition: blf_glyph.c:238
void blf_kerning_cache_clear(FontBLF *font)
Definition: blf_glyph.c:110
GlyphCacheBLF * blf_glyph_cache_find(FontBLF *font, unsigned int size, unsigned int dpi)
Definition: blf_glyph.c:116
KerningCacheBLF * blf_kerning_cache_new(FontBLF *font, GlyphCacheBLF *gc)
Definition: blf_glyph.c:73
void blf_glyph_cache_free(GlyphCacheBLF *gc)
Definition: blf_glyph.c:205
void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, float y)
Definition: blf_glyph.c:482
void blf_glyph_cache_release(FontBLF *font)
Definition: blf_glyph.c:187
GlyphBLF * blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
Definition: blf_glyph.c:222
GlyphCacheBLF * blf_glyph_cache_acquire(FontBLF *font)
Definition: blf_glyph.c:174
GlyphCacheBLF * blf_glyph_cache_new(FontBLF *font)
Definition: blf_glyph.c:132
KerningCacheBLF * blf_kerning_cache_find(FontBLF *font)
Definition: blf_glyph.c:58
#define BLF_BATCH_DRAW_LEN_MAX
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
void * user_data
DEGForeachIDComponentCallback callback
#define str(s)
static FT_Error err
Definition: freetypefont.c:52
uint col
#define floorf(x)
format
Definition: logImageCore.h:47
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
static GPUContext * wrap(Context *ctx)
unsigned int pos_loc
struct GPUBatch * batch
unsigned int col_loc
unsigned int offset_loc
struct GPUVertBuf * verts
struct FontBLF * font
float mat[4][4]
struct GPUVertBufRaw pos_step col_step offset_step glyph_size_step
struct GlyphCacheBLF * glyph_cache
float ofs[2]
unsigned int glyph_len
unsigned int glyph_size_loc
FT_UInt kerning_mode
KerningCacheBLF * kerning_cache
unsigned int dpi
SpinLock * glyph_cache_mutex
unsigned char color[4]
ListBase kerning_caches
unsigned int size
float aspect[3]
float pos[3]
SpinLock * ft_lib_mutex
FT_Library ft_lib
ListBase cache
FontBufInfoBLF buf_info
float m[16]
unsigned char col_char[4]
unsigned char * cbuf
unsigned char * bitmap
unsigned int c
struct GlyphBLF * glyph_ascii_table[256]
GPUTexture * texture
int lines
Definition: BLF_api.h:296
int width
Definition: BLF_api.h:300
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79
int wrap_width(const struct SpaceText *st, struct ARegion *region)
uint len