Blender V5.0
blf.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009-2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12
13#include <cmath>
14#include <cstdio>
15#include <cstdlib>
16#include <cstring>
17
18#include <ft2build.h>
19
20#include FT_FREETYPE_H
21#include FT_GLYPH_H
22
23#include "BLI_fileops.h"
24#include "BLI_math_rotation.h"
25#include "BLI_path_utils.hh"
26#include "BLI_string.h"
27
28#include "BLF_api.hh"
29
31
32#include "GPU_matrix.hh"
33#include "GPU_state.hh"
34
35#include "blf_internal.hh"
36#include "blf_internal_types.hh"
37
38#define BLF_RESULT_CHECK_INIT(r_info) \
39 if (r_info) { \
40 memset(r_info, 0, sizeof(*(r_info))); \
41 } \
42 ((void)0)
43
45
46/* XXX: should these be made into global_font_'s too? */
47
50
52
53static FontBLF *blf_get(int fontid)
54{
55 if (fontid >= 0 && fontid < BLF_MAX_FONT) {
56 return global_font[fontid];
57 }
58 return nullptr;
59}
60
62{
63 for (int i = 0; i < BLF_MAX_FONT; i++) {
64 global_font[i] = nullptr;
65 }
66
67 return blf_font_init();
68}
69
71{
72 for (int i = 0; i < BLF_MAX_FONT; i++) {
73 FontBLF *font = global_font[i];
74 if (font) {
75 blf_font_free(font);
76 global_font[i] = nullptr;
77 }
78 }
79
81}
82
84{
85 const int def_font = BLF_default();
86 for (int i = 0; i < BLF_MAX_FONT; i++) {
87 FontBLF *font = global_font[i];
88 if (font && !ELEM(i, def_font, blf_mono_font, blf_mono_font_render) &&
89 !(font->flags & BLF_DEFAULT))
90 {
91 /* Remove fonts that are not used in the UI or part of the stack. */
92 blf_font_free(font);
93 global_font[i] = nullptr;
94 }
95 }
96}
97
99{
100 for (int i = 0; i < BLF_MAX_FONT; i++) {
101 FontBLF *font = global_font[i];
102 if (font) {
104 }
105 }
106}
107
108static int blf_search_by_mem_name(const char *mem_name)
109{
110 std::lock_guard lock(g_blf_load_mutex);
111 for (int i = 0; i < BLF_MAX_FONT; i++) {
112 const FontBLF *font = global_font[i];
113 if ((font == nullptr) || (font->mem_name == nullptr)) {
114 continue;
115 }
116 if (STREQ(font->mem_name, mem_name)) {
117 return i;
118 }
119 }
120
121 return -1;
122}
123
124static int blf_search_by_filepath(const char *filepath)
125{
126 std::lock_guard lock(g_blf_load_mutex);
127 for (int i = 0; i < BLF_MAX_FONT; i++) {
128 const FontBLF *font = global_font[i];
129 if ((font == nullptr) || (font->filepath == nullptr)) {
130 continue;
131 }
132 if (BLI_path_cmp(font->filepath, filepath) == 0) {
133 return i;
134 }
135 }
136
137 return -1;
138}
139
141{
142 for (int i = 0; i < BLF_MAX_FONT; i++) {
143 if (!global_font[i]) {
144 return i;
145 }
146 }
147
148 return -1;
149}
150
151bool BLF_has_glyph(int fontid, uint unicode)
152{
153 FontBLF *font = blf_get(fontid);
154 if (font) {
155 return blf_get_char_index(font, unicode) != FT_Err_Ok;
156 }
157 return false;
158}
159
160bool BLF_is_loaded(const char *filepath)
161{
162 return blf_search_by_filepath(filepath) >= 0;
163}
164
165bool BLF_is_loaded_mem(const char *name)
166{
167 return blf_search_by_mem_name(name) >= 0;
168}
169
170bool BLF_is_loaded_id(int fontid)
171{
172 return blf_get(fontid) != nullptr;
173}
174
175int BLF_load(const char *filepath)
176{
177 /* check if we already load this font. */
178 int i = blf_search_by_filepath(filepath);
179 if (i >= 0) {
180 FontBLF *font = global_font[i];
181 font->reference_count++;
182 return i;
183 }
184
185 return BLF_load_unique(filepath);
186}
187
188int BLF_load_unique(const char *filepath)
189{
190 std::lock_guard lock(g_blf_load_mutex);
191 int i = blf_search_available();
192 if (i == -1) {
193 printf("Too many fonts!!!\n");
194 return -1;
195 }
196
197 /* This isn't essential, it will just cause confusing behavior to load a font
198 * that appears to succeed, then doesn't show up. */
199 if (!BLI_exists(filepath)) {
200 printf("Can't find font: %s\n", filepath);
201 return -1;
202 }
203
204 FontBLF *font = blf_font_new_from_filepath(filepath);
205
206 if (!font) {
207 printf("Can't load font: %s\n", filepath);
208 return -1;
209 }
210
211 font->reference_count = 1;
212 global_font[i] = font;
213 return i;
214}
215
216void BLF_metrics_attach(const int fontid, const uchar *mem, const int mem_size)
217{
218 FontBLF *font = blf_get(fontid);
219
220 if (font) {
221 blf_font_attach_from_mem(font, mem, mem_size);
222 }
223}
224
225int BLF_load_mem(const char *name, const uchar *mem, int mem_size)
226{
228 if (i >= 0) {
229 return i;
230 }
231 return BLF_load_mem_unique(name, mem, mem_size);
232}
233
234int BLF_load_mem_unique(const char *name, const uchar *mem, int mem_size)
235{
236 std::lock_guard lock(g_blf_load_mutex);
237 int i = blf_search_available();
238 if (i == -1) {
239 printf("Too many fonts!!!\n");
240 return -1;
241 }
242
243 if (!mem_size) {
244 printf("Can't load font: %s from memory!!\n", name);
245 return -1;
246 }
247
248 FontBLF *font = blf_font_new_from_mem(name, mem, mem_size);
249 if (!font) {
250 printf("Can't load font: %s from memory!!\n", name);
251 return -1;
252 }
253
254 font->reference_count = 1;
255 global_font[i] = font;
256 return i;
257}
258
259void BLF_unload(const char *filepath)
260{
261 std::lock_guard lock(g_blf_load_mutex);
262 for (int i = 0; i < BLF_MAX_FONT; i++) {
263 FontBLF *font = global_font[i];
264 if (font == nullptr || font->filepath == nullptr) {
265 continue;
266 }
267
268 if (BLI_path_cmp(font->filepath, filepath) == 0) {
269 BLI_assert(font->reference_count > 0);
270 font->reference_count--;
271
272 if (font->reference_count == 0) {
273 blf_font_free(font);
274 global_font[i] = nullptr;
275 }
276 }
277 }
278}
279
280bool BLF_unload_id(int fontid)
281{
282 std::lock_guard lock(g_blf_load_mutex);
283 FontBLF *font = blf_get(fontid);
284 if (font) {
285 BLI_assert(font->reference_count > 0);
286 font->reference_count--;
287
288 if (font->reference_count == 0) {
289 blf_font_free(font);
290 global_font[fontid] = nullptr;
291 return true;
292 }
293 }
294 return false;
295}
296
298{
299 for (int i = 0; i < BLF_MAX_FONT; i++) {
300 FontBLF *font = global_font[i];
301 if (font) {
302 blf_font_free(font);
303 global_font[i] = nullptr;
304 }
305 }
306 blf_mono_font = -1;
308 BLF_default_set(-1);
309}
310
311void BLF_addref_id(int fontid)
312{
313 std::lock_guard lock(g_blf_load_mutex);
314 FontBLF *font = blf_get(fontid);
315 if (font) {
316 font->reference_count++;
317 }
318}
319
320void BLF_enable(int fontid, FontFlags flag)
321{
322 FontBLF *font = blf_get(fontid);
323
324 if (font) {
325 font->flags |= flag;
326 }
327}
328
329void BLF_disable(int fontid, FontFlags flag)
330{
331 FontBLF *font = blf_get(fontid);
332
333 if (font) {
334 font->flags &= ~flag;
335 }
336}
337
338bool BLF_is_builtin(int fontid)
339{
340 FontBLF *font = blf_get(fontid);
341 if (font) {
342 return font->flags & BLF_DEFAULT;
343 }
344 return false;
345}
346
347void BLF_character_weight(int fontid, int weight)
348{
349 FontBLF *font = blf_get(fontid);
350 if (font) {
351 font->char_weight = weight;
352 }
353}
354
355int BLF_default_weight(int fontid)
356{
357 FontBLF *font = blf_get(fontid);
358 if (font) {
359 return font->metrics.weight;
360 }
361 return 400;
362}
363
365{
366 const FontBLF *font = blf_get(fontid);
367 if (font && font->variations) {
368 for (int i = 0; i < int(font->variations->num_axis); i++) {
369 if (font->variations->axis[i].tag == BLF_VARIATION_AXIS_WEIGHT) {
370 return true;
371 }
372 }
373 }
374 return false;
375}
376
377void BLF_aspect(int fontid, float x, float y, float z)
378{
379 FontBLF *font = blf_get(fontid);
380
381 if (font) {
382 font->aspect[0] = x;
383 font->aspect[1] = y;
384 font->aspect[2] = z;
385 }
386}
387
388void BLF_position(int fontid, float x, float y, float z)
389{
390 FontBLF *font = blf_get(fontid);
391
392 if (font) {
393 float xa, ya, za;
394 float remainder;
395
396 if (font->flags & BLF_ASPECT) {
397 xa = font->aspect[0];
398 ya = font->aspect[1];
399 za = font->aspect[2];
400 }
401 else {
402 xa = 1.0f;
403 ya = 1.0f;
404 za = 1.0f;
405 }
406
407 remainder = x - floorf(x);
408 if (remainder > 0.4f && remainder < 0.6f) {
409 if (remainder < 0.5f) {
410 x -= 0.1f * xa;
411 }
412 else {
413 x += 0.1f * xa;
414 }
415 }
416
417 remainder = y - floorf(y);
418 if (remainder > 0.4f && remainder < 0.6f) {
419 if (remainder < 0.5f) {
420 y -= 0.1f * ya;
421 }
422 else {
423 y += 0.1f * ya;
424 }
425 }
426
427 remainder = z - floorf(z);
428 if (remainder > 0.4f && remainder < 0.6f) {
429 if (remainder < 0.5f) {
430 z -= 0.1f * za;
431 }
432 else {
433 z += 0.1f * za;
434 }
435 }
436
437 font->pos[0] = round_fl_to_int(x);
438 font->pos[1] = round_fl_to_int(y);
439 font->pos[2] = round_fl_to_int(z);
440 }
441}
442
443void BLF_size(int fontid, float size)
444{
445 FontBLF *font = blf_get(fontid);
446
447 if (font) {
448 blf_font_size(font, size);
449 }
450}
451
452void BLF_color4ubv(int fontid, const uchar rgba[4])
453{
454 FontBLF *font = blf_get(fontid);
455
456 if (font) {
457 font->color[0] = rgba[0];
458 font->color[1] = rgba[1];
459 font->color[2] = rgba[2];
460 font->color[3] = rgba[3];
461 }
462}
463
464void BLF_color3ubv_alpha(int fontid, const uchar rgb[3], uchar alpha)
465{
466 FontBLF *font = blf_get(fontid);
467
468 if (font) {
469 font->color[0] = rgb[0];
470 font->color[1] = rgb[1];
471 font->color[2] = rgb[2];
472 font->color[3] = alpha;
473 }
474}
475
476void BLF_color3ubv(int fontid, const uchar rgb[3])
477{
478 BLF_color3ubv_alpha(fontid, rgb, 255);
479}
480
481void BLF_color4ub(int fontid, uchar r, uchar g, uchar b, uchar alpha)
482{
483 FontBLF *font = blf_get(fontid);
484
485 if (font) {
486 font->color[0] = r;
487 font->color[1] = g;
488 font->color[2] = b;
489 font->color[3] = alpha;
490 }
491}
492
493void BLF_color3ub(int fontid, uchar r, uchar g, uchar b)
494{
495 FontBLF *font = blf_get(fontid);
496
497 if (font) {
498 font->color[0] = r;
499 font->color[1] = g;
500 font->color[2] = b;
501 font->color[3] = 255;
502 }
503}
504
505void BLF_color4fv(int fontid, const float rgba[4])
506{
507 FontBLF *font = blf_get(fontid);
508
509 if (font) {
510 rgba_float_to_uchar(font->color, rgba);
511 }
512}
513
514void BLF_color4f(int fontid, float r, float g, float b, float a)
515{
516 const float rgba[4] = {r, g, b, a};
517 BLF_color4fv(fontid, rgba);
518}
519
520void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha)
521{
522 float rgba[4];
523 copy_v3_v3(rgba, rgb);
524 rgba[3] = alpha;
525 BLF_color4fv(fontid, rgba);
526}
527
528void BLF_color3f(int fontid, float r, float g, float b)
529{
530 const float rgba[4] = {r, g, b, 1.0f};
531 BLF_color4fv(fontid, rgba);
532}
533
535{
536 BLI_assert(g_batch.enabled == false);
537 g_batch.enabled = true;
538}
539
541{
542 if (g_batch.enabled) {
544 }
545}
546
548{
549 BLI_assert(g_batch.enabled == true);
550 blf_batch_draw(); /* Draw remaining glyphs */
551 g_batch.enabled = false;
552}
553
554static void blf_draw_gpu__start(const FontBLF *font)
555{
556 /*
557 * The pixmap alignment hack is handle
558 * in BLF_position (old ui_rasterpos_safe).
559 */
560
561 if ((font->flags & (BLF_ROTATION | BLF_ASPECT)) == 0) {
562 return; /* glyphs will be translated individually and batched. */
563 }
564
566
567 GPU_matrix_translate_3f(font->pos[0], font->pos[1], font->pos[2]);
568
569 if (font->flags & BLF_ASPECT) {
571 }
572
573 if (font->flags & BLF_ROTATION) {
575 }
576}
577
578static void blf_draw_gpu__end(const FontBLF *font)
579{
580 if ((font->flags & (BLF_ROTATION | BLF_ASPECT)) != 0) {
582 }
583}
584
585void BLF_draw(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
586{
587 BLF_RESULT_CHECK_INIT(r_info);
588
589 if (str_len == 0 || str[0] == '\0') {
590 return;
591 }
592
593 FontBLF *font = blf_get(fontid);
594
595 if (font) {
597 if (font->flags & BLF_WORD_WRAP) {
598 blf_font_draw__wrap(font, str, str_len, r_info);
599 }
600 else {
601 blf_font_draw(font, str, str_len, r_info);
602 }
603 blf_draw_gpu__end(font);
604 }
605}
606
607int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth, int tab_columns)
608{
609 if (str_len == 0 || str[0] == '\0') {
610 return 0;
611 }
612
613 FontBLF *font = blf_get(fontid);
614 int columns = 0;
615
616 if (font) {
618 columns = blf_font_draw_mono(font, str, str_len, cwidth, tab_columns);
619 blf_draw_gpu__end(font);
620 }
621
622 return columns;
623}
624
626 float x,
627 float y,
628 float size,
629 const float color[4],
630 float outline_alpha,
631 bool multicolor,
632 blender::FunctionRef<void(std::string &)> edit_source_cb)
633{
634#ifndef WITH_HEADLESS
635 FontBLF *font = global_font[0];
636 if (font) {
638 blf_draw_svg_icon(font, icon_id, x, y, size, color, outline_alpha, multicolor, edit_source_cb);
639 blf_draw_gpu__end(font);
640 }
641#else
642 UNUSED_VARS(icon_id, x, y, size, color, outline_alpha, multicolor, edit_source_cb);
643#endif /* WITH_HEADLESS */
644}
645
647 float size,
648 int *r_width,
649 int *r_height,
650 bool multicolor,
651 blender::FunctionRef<void(std::string &)> edit_source_cb)
652{
653#ifndef WITH_HEADLESS
654 FontBLF *font = global_font[0];
655 if (font) {
656 return blf_svg_icon_bitmap(font, icon_id, size, r_width, r_height, multicolor, edit_source_cb);
657 }
658#else
659 UNUSED_VARS(icon_id, size, r_width, r_height, multicolor, edit_source_cb);
660#endif /* WITH_HEADLESS */
661 return {};
662}
663
665 int fontid, const char *str, size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data)
666{
667 FontBLF *font = blf_get(fontid);
668
669 if (font) {
670 if (font->flags & BLF_WORD_WRAP) {
671 /* TODO: word-wrap support. */
672 BLI_assert(0);
673 }
674 else {
675 blf_font_boundbox_foreach_glyph(font, str, str_len, user_fn, user_data);
676 }
677 }
678}
679
681 const char *str,
682 size_t str_len,
683 int location_x)
684{
685 FontBLF *font = blf_get(fontid);
686 if (font) {
687 return blf_str_offset_from_cursor_position(font, str, str_len, location_x);
688 }
689 return 0;
690}
691
693 const char *str,
694 size_t str_offset,
695 rcti *r_glyph_bounds)
696{
697 FontBLF *font = blf_get(fontid);
698 if (font) {
699 blf_str_offset_to_glyph_bounds(font, str, str_offset, r_glyph_bounds);
700 return true;
701 }
702 return false;
703}
704
706 const char *str,
707 const size_t str_len,
708 const size_t str_offset,
709 const int cursor_width)
710{
711 FontBLF *font = blf_get(fontid);
712 if (font) {
713 return blf_str_offset_to_cursor(font, str, str_len, str_offset, cursor_width);
714 }
715 return 0;
716}
717
719 int fontid, const char *str, size_t str_len, size_t sel_start, size_t sel_length)
720{
721 FontBLF *font = blf_get(fontid);
722 if (font) {
723 return blf_str_selection_boxes(font, str, str_len, sel_start, sel_length);
724 }
725 return {};
726}
727
729 int fontid, const char *str, const size_t str_len, float width, float *r_width)
730{
731 FontBLF *font = blf_get(fontid);
732
733 if (font) {
734 const float xa = (font->flags & BLF_ASPECT) ? font->aspect[0] : 1.0f;
735 size_t ret;
736 int width_result;
737 ret = blf_font_width_to_strlen(font, str, str_len, width / xa, &width_result);
738 if (r_width) {
739 *r_width = float(width_result) * xa;
740 }
741 return ret;
742 }
743
744 if (r_width) {
745 *r_width = 0.0f;
746 }
747 return 0;
748}
749
751 int fontid, const char *str, const size_t str_len, float width, float *r_width)
752{
753 FontBLF *font = blf_get(fontid);
754
755 if (font) {
756 const float xa = (font->flags & BLF_ASPECT) ? font->aspect[0] : 1.0f;
757 size_t ret;
758 int width_result;
759 ret = blf_font_width_to_rstrlen(font, str, str_len, width / xa, &width_result);
760 if (r_width) {
761 *r_width = float(width_result) * xa;
762 }
763 return ret;
764 }
765
766 if (r_width) {
767 *r_width = 0.0f;
768 }
769 return 0;
770}
771
773 int fontid, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
774{
775 FontBLF *font = blf_get(fontid);
776
777 BLF_RESULT_CHECK_INIT(r_info);
778
779 if (font) {
780 if (font->flags & BLF_WORD_WRAP) {
781 blf_font_boundbox__wrap(font, str, str_len, r_box, r_info);
782 }
783 else {
784 blf_font_boundbox(font, str, str_len, r_box, r_info);
785 }
786 }
787}
788
790 int fontid, const char *str, const size_t str_len, float *r_width, float *r_height)
791{
792 FontBLF *font = blf_get(fontid);
793
794 if (font) {
795 blf_font_width_and_height(font, str, str_len, r_width, r_height, nullptr);
796 }
797 else {
798 *r_width = *r_height = 0.0f;
799 }
800}
801
802float BLF_width(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
803{
804 FontBLF *font = blf_get(fontid);
805
806 BLF_RESULT_CHECK_INIT(r_info);
807
808 if (font) {
809 return blf_font_width(font, str, str_len, r_info);
810 }
811
812 return 0.0f;
813}
814
815float BLF_fixed_width(int fontid)
816{
817 FontBLF *font = blf_get(fontid);
818
819 if (font) {
820 return blf_font_fixed_width(font);
821 }
822
823 return 0.0f;
824}
825
826int BLF_glyph_advance(int fontid, const char *str)
827{
828 FontBLF *font = blf_get(fontid);
829
830 if (font) {
831 return blf_font_glyph_advance(font, str);
832 }
833
834 return 0;
835}
836
837float BLF_height(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
838{
839 FontBLF *font = blf_get(fontid);
840
841 BLF_RESULT_CHECK_INIT(r_info);
842
843 if (font) {
844 return blf_font_height(font, str, str_len, r_info);
845 }
846
847 return 0.0f;
848}
849
850int BLF_height_max(int fontid)
851{
852 FontBLF *font = blf_get(fontid);
853
854 if (font) {
855 return blf_font_height_max(font);
856 }
857
858 return 0;
859}
860
861int BLF_width_max(int fontid)
862{
863 FontBLF *font = blf_get(fontid);
864
865 if (font) {
866 return blf_font_width_max(font);
867 }
868
869 return 0;
870}
871
872int BLF_descender(int fontid)
873{
874 FontBLF *font = blf_get(fontid);
875
876 if (font) {
877 return blf_font_descender(font);
878 }
879
880 return 0;
881}
882
883int BLF_ascender(int fontid)
884{
885 FontBLF *font = blf_get(fontid);
886
887 if (font) {
888 return blf_font_ascender(font);
889 }
890
891 return 0.0f;
892}
893
894bool BLF_bounds_max(int fontid, rctf *r_bounds)
895{
896 FontBLF *font = blf_get(fontid);
897 if (font) {
898 return blf_font_bounds_max(font, r_bounds);
899 }
900 return false;
901}
902
903void BLF_rotation(int fontid, float angle)
904{
905 FontBLF *font = blf_get(fontid);
906
907 if (font) {
908 font->angle = angle;
909 }
910}
911
912void BLF_clipping(int fontid, int xmin, int ymin, int xmax, int ymax)
913{
914 FontBLF *font = blf_get(fontid);
915
916 if (font) {
917 font->clip_rec.xmin = xmin;
918 font->clip_rec.ymin = ymin;
919 font->clip_rec.xmax = xmax;
920 font->clip_rec.ymax = ymax;
921 }
922}
923
924void BLF_wordwrap(int fontid, int wrap_width, BLFWrapMode mode)
925{
926 FontBLF *font = blf_get(fontid);
927
928 if (font) {
929 font->wrap_width = wrap_width;
930 font->wrap_mode = mode;
931 }
932}
933
934void BLF_shadow(int fontid, FontShadowType type, const float rgba[4])
935{
936 FontBLF *font = blf_get(fontid);
937
938 if (font) {
939 font->shadow = type;
940 if (rgba) {
942 }
943 }
944}
945
946void BLF_shadow_offset(int fontid, int x, int y)
947{
948 FontBLF *font = blf_get(fontid);
949
950 if (font) {
951 font->shadow_x = x;
952 font->shadow_y = y;
953 }
954}
955
956void BLF_buffer(int fontid, float *fbuf, uchar *cbuf, int w, int h, const ColorSpace *colorspace)
957{
958 FontBLF *font = blf_get(fontid);
959
960 if (font) {
961 font->buf_info.fbuf = fbuf;
962 font->buf_info.cbuf = cbuf;
963 font->buf_info.dims[0] = w;
964 font->buf_info.dims[1] = h;
965 font->buf_info.colorspace = colorspace;
966 }
967}
968
979
981{
982 FontBLF *font = blf_get(fontid);
983 if (font) {
984 BLFBufferState *buffer_state = MEM_new<BLFBufferState>(__func__);
985 buffer_state->fontid = fontid;
986 buffer_state->font = font;
987 buffer_state->buf_info = font->buf_info;
988 return buffer_state;
989 }
990 return nullptr;
991}
992
994{
995 FontBLF *font = blf_get(buffer_state->fontid);
996 /* It's possible the font has been removed as this is called from Python. */
997 if (font == buffer_state->font) {
998 /* From the callers perspective, don't consider the color part of the buffer info.
999 *
1000 * NOTE(@ideasman42) This is done because the color is not logically part of the image binding.
1001 * It looks like we can refactor color out of #FontBufInfoBLF::col_init,
1002 * and use #FontBLF::color instead. */
1003 copy_v4_v4(buffer_state->buf_info.col_init, font->buf_info.col_init);
1004
1005 font->buf_info = buffer_state->buf_info;
1006 }
1007 BLF_buffer_state_free(buffer_state);
1008}
1009
1011{
1012 MEM_delete(buffer_state);
1013}
1014
1015void BLF_buffer_col(int fontid, const float srgb_color[4])
1016{
1017 FontBLF *font = blf_get(fontid);
1018
1019 if (font) {
1020 copy_v4_v4(font->buf_info.col_init, srgb_color);
1021 }
1022}
1023
1025{
1026 FontBufInfoBLF *buf_info = &font->buf_info;
1027
1028 /* This will be written to scene linear image buffer, so convert to that. */
1030 buf_info->col_float[3] = buf_info->col_init[3];
1031
1032 /* Convert to the colorspace of the byte image buffer, assumed sRGB if not specified. */
1033 if (buf_info->colorspace) {
1034 float col_char[4];
1035 copy_v4_v4(col_char, buf_info->col_float);
1037 rgba_float_to_uchar(buf_info->col_char, col_char);
1038 }
1039 else {
1040 rgba_float_to_uchar(buf_info->col_char, buf_info->col_init);
1041 }
1042}
1044
1045void BLF_draw_buffer(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
1046{
1047 FontBLF *font = blf_get(fontid);
1048
1049 if (font && (font->buf_info.fbuf || font->buf_info.cbuf)) {
1051 if (font->flags & BLF_WORD_WRAP) {
1052 blf_font_draw_buffer__wrap(font, str, str_len, r_info);
1053 }
1054 else {
1055 blf_font_draw_buffer(font, str, str_len, r_info);
1056 }
1058 }
1059}
1060
1063 const int max_pixel_width,
1064 BLFWrapMode mode)
1065{
1066 FontBLF *font = blf_get(fontid);
1067 if (!font) {
1068 return {};
1069 }
1070 return blf_font_string_wrap(font, str, max_pixel_width, mode);
1071}
1072
1073char *BLF_display_name_from_file(const char *filepath)
1074{
1075 /* While listing font directories this function can be called simultaneously from a greater
1076 * number of threads than we want the FreeType cache to keep open at a time. Therefore open
1077 * with a separate FT_Library object and use FreeType calls directly to avoid any contention. */
1078 char *name = nullptr;
1079 FT_Library ft_library;
1080 if (FT_Init_FreeType(&ft_library) == FT_Err_Ok) {
1081 FT_Face face;
1082 if (FT_New_Face(ft_library, filepath, 0, &face) == FT_Err_Ok) {
1083 if (face->family_name) {
1084 name = BLI_sprintfN("%s %s", face->family_name, face->style_name);
1085 }
1086 FT_Done_Face(face);
1087 }
1088 FT_Done_FreeType(ft_library);
1089 }
1090 return name;
1091}
1092
1094{
1095 FontBLF *font = blf_get(fontid);
1096 if (!font) {
1097 return nullptr;
1098 }
1099
1100 return blf_display_name(font);
1101}
1102
1103bool BLF_get_vfont_metrics(int fontid, float *ascend_ratio, float *em_ratio, float *scale)
1104{
1105 FontBLF *font = blf_get(fontid);
1106 if (!font) {
1107 return false;
1108 }
1109
1110 if (!blf_ensure_face(font)) {
1111 return false;
1112 }
1113
1114 /* Copied without change from vfontdata_freetype.cc to ensure consistent sizing. */
1115
1116 /* Blender default BFont is not "complete". */
1117 const bool complete_font = (font->face->ascender != 0) && (font->face->descender != 0) &&
1118 (font->face->ascender != font->face->descender);
1119
1120 if (complete_font) {
1121 /* We can get descender as well, but we simple store descender in relation to the ascender.
1122 * Also note that descender is stored as a negative number. */
1123 *ascend_ratio = float(font->face->ascender) / (font->face->ascender - font->face->descender);
1124 }
1125 else {
1128 }
1129
1130 /* Adjust font size */
1131 if (font->face->bbox.yMax != font->face->bbox.yMin) {
1132 *scale = float(1.0 / double(font->face->bbox.yMax - font->face->bbox.yMin));
1133
1134 if (complete_font) {
1135 *em_ratio = float(font->face->ascender - font->face->descender) /
1136 (font->face->bbox.yMax - font->face->bbox.yMin);
1137 }
1138 }
1139 else {
1141 }
1142
1143 return true;
1144}
1145
1147 uint unicode,
1148 ListBase *nurbsbase,
1149 const float scale,
1150 bool use_fallback,
1151 float *r_advance)
1152{
1153 FontBLF *font = blf_get(fontid);
1154 if (!font) {
1155 return false;
1156 }
1157 return blf_character_to_curves(font, unicode, nurbsbase, scale, use_fallback, r_advance);
1158}
1159
1160#ifndef NDEBUG
1161void BLF_state_print(int fontid)
1162{
1163 FontBLF *font = blf_get(fontid);
1164 if (font) {
1165 printf("fontid %d %p\n", fontid, (void *)font);
1166 printf(" mem_name: '%s'\n", font->mem_name ? font->mem_name : "<none>");
1167 printf(" filepath: '%s'\n", font->filepath ? font->filepath : "<none>");
1168 printf(" size: %f\n", font->size);
1169 printf(" pos: %d %d %d\n", UNPACK3(font->pos));
1170 printf(" aspect: (%d) %.6f %.6f %.6f\n",
1171 (font->flags & BLF_ROTATION) != 0,
1172 UNPACK3(font->aspect));
1173 printf(" angle: (%d) %.6f\n", (font->flags & BLF_ASPECT) != 0, font->angle);
1174 printf(" flag: %d\n", font->flags);
1175 }
1176 else {
1177 printf("fontid %d (nullptr)\n", fontid);
1178 }
1179 fflush(stdout);
1180}
1181#endif
void BLF_default_set(int fontid)
#define BLF_VFONT_METRICS_EM_RATIO_DEFAULT
Definition BLF_api.hh:113
int blf_mono_font_render
Definition blf.cc:49
int BLF_default()
bool(*)(const char *str, size_t str_step_ofs, const rcti *bounds, void *user_dataconst) BLF_GlyphBoundsFn
Definition BLF_api.hh:207
int blf_mono_font
Definition blf.cc:48
#define BLF_VFONT_METRICS_SCALE_DEFAULT
Definition BLF_api.hh:112
blender::ocio::ColorSpace ColorSpace
Definition BLF_api.hh:38
#define BLF_VFONT_METRICS_ASCEND_RATIO_DEFAULT
Definition BLF_api.hh:114
BLFWrapMode
Definition BLF_enums.hh:20
FontFlags
Definition BLF_enums.hh:31
@ BLF_ROTATION
Definition BLF_enums.hh:33
@ BLF_WORD_WRAP
Definition BLF_enums.hh:39
@ BLF_ASPECT
Definition BLF_enums.hh:38
@ BLF_DEFAULT
Definition BLF_enums.hh:50
FontShadowType
Definition BLF_enums.hh:13
#define BLI_assert(a)
Definition BLI_assert.h:46
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:360
MINLINE int round_fl_to_int(float a)
MINLINE void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
#define RAD2DEG(_rad)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define BLI_path_cmp
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
unsigned char uchar
unsigned int uint
#define UNUSED_VARS(...)
#define UNPACK3(a)
#define ELEM(...)
#define STREQ(a, b)
void GPU_matrix_push()
void GPU_matrix_scale_3fv(const float vec[3])
void GPU_matrix_rotate_2d(float deg)
void GPU_matrix_translate_3f(float x, float y, float z)
void GPU_matrix_pop()
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], const ColorSpace *colorspace)
BLI_INLINE void IMB_colormanagement_srgb_to_scene_linear_v3(float scene_linear[3], const float srgb[3])
volatile int lock
void BLF_color3ubv(int fontid, const uchar rgb[3])
Definition blf.cc:476
size_t BLF_width_to_rstrlen(int fontid, const char *str, const size_t str_len, float width, float *r_width)
Definition blf.cc:750
void BLF_state_print(int fontid)
Definition blf.cc:1161
static int blf_search_available()
Definition blf.cc:140
void BLF_color4ub(int fontid, uchar r, uchar g, uchar b, uchar alpha)
Definition blf.cc:481
void BLF_color4ubv(int fontid, const uchar rgba[4])
Definition blf.cc:452
int BLF_load(const char *filepath)
Definition blf.cc:175
void BLF_size(int fontid, float size)
Definition blf.cc:443
void BLF_buffer_state_free(BLFBufferState *buffer_state)
Definition blf.cc:1010
void BLF_draw_svg_icon(uint icon_id, float x, float y, float size, const float color[4], float outline_alpha, bool multicolor, blender::FunctionRef< void(std::string &)> edit_source_cb)
Definition blf.cc:625
int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth, int tab_columns)
Definition blf.cc:607
void BLF_enable(int fontid, FontFlags flag)
Definition blf.cc:320
void BLF_reset_fonts()
Definition blf.cc:83
void BLF_addref_id(int fontid)
Definition blf.cc:311
void BLF_buffer_state_pop(BLFBufferState *buffer_state)
Definition blf.cc:993
void BLF_aspect(int fontid, float x, float y, float z)
Definition blf.cc:377
void blf_draw_buffer__start(FontBLF *font)
Definition blf.cc:1024
void BLF_unload_all()
Definition blf.cc:297
bool BLF_has_glyph(int fontid, uint unicode)
Definition blf.cc:151
static FontBLF * blf_get(int fontid)
Definition blf.cc:53
blender::Vector< blender::Bounds< int > > BLF_str_selection_boxes(int fontid, const char *str, size_t str_len, size_t sel_start, size_t sel_length)
Definition blf.cc:718
float BLF_width(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:802
bool BLF_is_loaded(const char *filepath)
Definition blf.cc:160
void BLF_clipping(int fontid, int xmin, int ymin, int xmax, int ymax)
Definition blf.cc:912
size_t BLF_width_to_strlen(int fontid, const char *str, const size_t str_len, float width, float *r_width)
Definition blf.cc:728
void BLF_boundbox(int fontid, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
Definition blf.cc:772
bool BLF_is_loaded_id(int fontid)
Definition blf.cc:170
blender::Vector< blender::StringRef > BLF_string_wrap(int fontid, blender::StringRef str, const int max_pixel_width, BLFWrapMode mode)
Definition blf.cc:1061
void BLF_draw_buffer(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:1045
void BLF_color3ub(int fontid, uchar r, uchar g, uchar b)
Definition blf.cc:493
void BLF_unload(const char *filepath)
Definition blf.cc:259
void BLF_color3ubv_alpha(int fontid, const uchar rgb[3], uchar alpha)
Definition blf.cc:464
void BLF_color3f(int fontid, float r, float g, float b)
Definition blf.cc:528
float BLF_fixed_width(int fontid)
Definition blf.cc:815
char * BLF_display_name_from_id(int fontid)
Definition blf.cc:1093
void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha)
Definition blf.cc:520
void BLF_color4fv(int fontid, const float rgba[4])
Definition blf.cc:505
#define BLF_RESULT_CHECK_INIT(r_info)
Definition blf.cc:38
static int blf_search_by_filepath(const char *filepath)
Definition blf.cc:124
int BLF_str_offset_to_cursor(int fontid, const char *str, const size_t str_len, const size_t str_offset, const int cursor_width)
Definition blf.cc:705
char * BLF_display_name_from_file(const char *filepath)
Definition blf.cc:1073
bool BLF_get_vfont_metrics(int fontid, float *ascend_ratio, float *em_ratio, float *scale)
Definition blf.cc:1103
void BLF_shadow_offset(int fontid, int x, int y)
Definition blf.cc:946
static void blf_draw_gpu__end(const FontBLF *font)
Definition blf.cc:578
int BLF_width_max(int fontid)
Definition blf.cc:861
int BLF_ascender(int fontid)
Definition blf.cc:883
void BLF_batch_draw_begin()
Definition blf.cc:534
BLFBufferState * BLF_buffer_state_push(int fontid)
Definition blf.cc:980
int BLF_load_mem_unique(const char *name, const uchar *mem, int mem_size)
Definition blf.cc:234
bool BLF_bounds_max(int fontid, rctf *r_bounds)
Definition blf.cc:894
void BLF_boundbox_foreach_glyph(int fontid, const char *str, size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data)
Definition blf.cc:664
void BLF_rotation(int fontid, float angle)
Definition blf.cc:903
void BLF_metrics_attach(const int fontid, const uchar *mem, const int mem_size)
Definition blf.cc:216
void BLF_batch_draw_end()
Definition blf.cc:547
static void blf_draw_gpu__start(const FontBLF *font)
Definition blf.cc:554
int BLF_glyph_advance(int fontid, const char *str)
Definition blf.cc:826
static int blf_search_by_mem_name(const char *mem_name)
Definition blf.cc:108
size_t BLF_str_offset_from_cursor_position(int fontid, const char *str, size_t str_len, int location_x)
Definition blf.cc:680
int BLF_descender(int fontid)
Definition blf.cc:872
FontBLF * global_font[BLF_MAX_FONT]
Definition blf.cc:44
void BLF_exit()
Definition blf.cc:70
void BLF_cache_clear()
Definition blf.cc:98
int BLF_default_weight(int fontid)
Definition blf.cc:355
void BLF_draw(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:585
void BLF_batch_draw_flush()
Definition blf.cc:540
blender::Array< uchar > BLF_svg_icon_bitmap(uint icon_id, float size, int *r_width, int *r_height, bool multicolor, blender::FunctionRef< void(std::string &)> edit_source_cb)
Definition blf.cc:646
void BLF_shadow(int fontid, FontShadowType type, const float rgba[4])
Definition blf.cc:934
void BLF_disable(int fontid, FontFlags flag)
Definition blf.cc:329
void BLF_width_and_height(int fontid, const char *str, const size_t str_len, float *r_width, float *r_height)
Definition blf.cc:789
bool BLF_unload_id(int fontid)
Definition blf.cc:280
bool BLF_is_builtin(int fontid)
Definition blf.cc:338
bool BLF_is_loaded_mem(const char *name)
Definition blf.cc:165
bool BLF_str_offset_to_glyph_bounds(int fontid, const char *str, size_t str_offset, rcti *r_glyph_bounds)
Definition blf.cc:692
void BLF_buffer(int fontid, float *fbuf, uchar *cbuf, int w, int h, const ColorSpace *colorspace)
Definition blf.cc:956
int BLF_load_unique(const char *filepath)
Definition blf.cc:188
int BLF_init()
Definition blf.cc:61
bool BLF_character_to_curves(int fontid, uint unicode, ListBase *nurbsbase, const float scale, bool use_fallback, float *r_advance)
Definition blf.cc:1146
void BLF_color4f(int fontid, float r, float g, float b, float a)
Definition blf.cc:514
static blender::Mutex g_blf_load_mutex
Definition blf.cc:51
bool BLF_has_variable_weight(int fontid)
Definition blf.cc:364
void blf_draw_buffer__end()
Definition blf.cc:1043
void BLF_buffer_col(int fontid, const float srgb_color[4])
Definition blf.cc:1015
void BLF_character_weight(int fontid, int weight)
Definition blf.cc:347
int BLF_height_max(int fontid)
Definition blf.cc:850
void BLF_position(int fontid, float x, float y, float z)
Definition blf.cc:388
float BLF_height(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:837
int BLF_load_mem(const char *name, const uchar *mem, int mem_size)
Definition blf.cc:225
void BLF_wordwrap(int fontid, int wrap_width, BLFWrapMode mode)
Definition blf.cc:924
size_t blf_str_offset_from_cursor_position(FontBLF *font, const char *str, size_t str_len, int location_x)
Definition blf_font.cc:1126
void blf_str_offset_to_glyph_bounds(FontBLF *font, const char *str, size_t str_offset, rcti *r_glyph_bounds)
Definition blf_font.cc:1176
BatchBLF g_batch
Definition blf_font.cc:59
size_t blf_font_width_to_rstrlen(FontBLF *font, const char *str, const size_t str_len, int width, int *r_width)
Definition blf_font.cc:849
int blf_font_ascender(FontBLF *font)
Definition blf_font.cc:1568
blender::Vector< blender::StringRef > blf_font_string_wrap(FontBLF *font, blender::StringRef str, int max_pixel_width, BLFWrapMode mode)
Definition blf_font.cc:1515
int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, const int cwidth, const int tab_columns)
Definition blf_font.cc:494
float blf_font_width(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:998
bool blf_ensure_face(FontBLF *font)
Definition blf_font.cc:1890
bool blf_font_bounds_max(FontBLF *font, rctf *r_bounds)
Definition blf_font.cc:1574
void blf_font_draw_buffer(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:769
void blf_font_free(FontBLF *font)
Definition blf_font.cc:2114
void blf_font_boundbox_foreach_glyph(FontBLF *font, const char *str, const size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data)
Definition blf_font.cc:1065
bool blf_font_size(FontBLF *font, float size)
Definition blf_font.cc:2174
float blf_font_fixed_width(FontBLF *font)
Definition blf_font.cc:1040
float blf_font_height(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:1019
uint blf_get_char_index(FontBLF *font, const uint charcode)
Definition blf_font.cc:148
int blf_font_init()
Definition blf_font.cc:1601
int blf_font_width_max(FontBLF *font)
Definition blf_font.cc:1557
blender::Array< uchar > blf_svg_icon_bitmap(FontBLF *font, const uint icon_id, const float size, int *r_width, int *r_height, const bool multicolor, blender::FunctionRef< void(std::string &)> edit_source_cb)
Definition blf_font.cc:577
void blf_draw_svg_icon(FontBLF *font, const uint icon_id, const float x, const float y, const float size, const float color[4], const float outline_alpha, const bool multicolor, blender::FunctionRef< void(std::string &)> edit_source_cb)
Definition blf_font.cc:530
void blf_batch_draw()
Definition blf_font.cc:305
void blf_font_boundbox__wrap(FontBLF *font, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
Definition blf_font.cc:1458
void blf_font_exit()
Definition blf_font.cc:1622
void blf_font_boundbox(FontBLF *font, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
Definition blf_font.cc:961
int blf_font_glyph_advance(FontBLF *font, const char *str)
Definition blf_font.cc:1048
char * blf_display_name(FontBLF *font)
Definition blf_font.cc:1587
FontBLF * blf_font_new_from_mem(const char *mem_name, const uchar *mem, const size_t mem_size)
Definition blf_font.cc:2097
int blf_str_offset_to_cursor(FontBLF *font, const char *str, const size_t str_len, const size_t str_offset, const int cursor_width)
Definition blf_font.cc:1189
void blf_font_attach_from_mem(FontBLF *font, const uchar *mem, const size_t mem_size)
Definition blf_font.cc:2102
size_t blf_font_width_to_strlen(FontBLF *font, const char *str, const size_t str_len, int width, int *r_width)
Definition blf_font.cc:820
int blf_font_descender(FontBLF *font)
Definition blf_font.cc:1562
void blf_font_width_and_height(FontBLF *font, const char *str, const size_t str_len, float *r_width, float *r_height, ResultBLF *r_info)
Definition blf_font.cc:969
void blf_font_draw(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:487
FontBLF * blf_font_new_from_filepath(const char *filepath)
Definition blf_font.cc:2092
void blf_font_draw_buffer__wrap(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:1486
int blf_font_height_max(FontBLF *font)
Definition blf_font.cc:1545
blender::Vector< blender::Bounds< int > > blf_str_selection_boxes(FontBLF *font, const char *str, size_t str_len, size_t sel_start, size_t sel_length)
Definition blf_font.cc:1234
void blf_font_draw__wrap(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:1432
bool blf_character_to_curves(FontBLF *font, uint unicode, ListBase *nurbsbase, const float scale, bool use_fallback, float *r_advance)
void blf_glyph_cache_clear(FontBLF *font)
Definition blf_glyph.cc:162
#define BLF_MAX_FONT
#define BLF_VARIATION_AXIS_WEIGHT
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
nullptr float
#define str(s)
#define printf(...)
std::mutex Mutex
Definition BLI_mutex.hh:47
const char * name
return ret
#define floorf
FontBufInfoBLF buf_info
Definition blf.cc:977
const FontBLF * font
Definition blf.cc:975
unsigned char color[4]
FontFlags flags
FT_MM_Var * variations
std::atomic< uint32_t > reference_count
FontMetrics metrics
BLFWrapMode wrap_mode
FontBufInfoBLF buf_info
FontShadowType shadow
unsigned char shadow_color[4]
const ColorSpace * colorspace
unsigned char col_char[4]
unsigned char * cbuf
int ymin
int ymax
int xmin
int xmax
i
Definition text_draw.cc:230
uint8_t flag
Definition wm_window.cc:145