Blender V4.5
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{
227 int i = blf_search_by_mem_name(name);
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, int option)
321{
322 FontBLF *font = blf_get(fontid);
323
324 if (font) {
325 font->flags |= option;
326 }
327}
328
329void BLF_disable(int fontid, int option)
330{
331 FontBLF *font = blf_get(fontid);
332
333 if (font) {
334 font->flags &= ~option;
335 }
336}
337
338bool BLF_is_builtin(int fontid)
339{
340 FontBLF *font = blf_get(fontid);
341 return font ? (font->flags & BLF_DEFAULT) : false;
342}
343
344void BLF_character_weight(int fontid, int weight)
345{
346 FontBLF *font = blf_get(fontid);
347 if (font) {
348 font->char_weight = weight;
349 }
350}
351
352int BLF_default_weight(int fontid)
353{
354 FontBLF *font = blf_get(fontid);
355 if (font) {
356 return font->metrics.weight;
357 }
358 return 400;
359}
360
362{
363 const FontBLF *font = blf_get(fontid);
364 if (font && font->variations) {
365 for (int i = 0; i < int(font->variations->num_axis); i++) {
366 if (font->variations->axis[i].tag == BLF_VARIATION_AXIS_WEIGHT) {
367 return true;
368 }
369 }
370 }
371 return false;
372}
373
374void BLF_aspect(int fontid, float x, float y, float z)
375{
376 FontBLF *font = blf_get(fontid);
377
378 if (font) {
379 font->aspect[0] = x;
380 font->aspect[1] = y;
381 font->aspect[2] = z;
382 }
383}
384
385void BLF_position(int fontid, float x, float y, float z)
386{
387 FontBLF *font = blf_get(fontid);
388
389 if (font) {
390 float xa, ya, za;
391 float remainder;
392
393 if (font->flags & BLF_ASPECT) {
394 xa = font->aspect[0];
395 ya = font->aspect[1];
396 za = font->aspect[2];
397 }
398 else {
399 xa = 1.0f;
400 ya = 1.0f;
401 za = 1.0f;
402 }
403
404 remainder = x - floorf(x);
405 if (remainder > 0.4f && remainder < 0.6f) {
406 if (remainder < 0.5f) {
407 x -= 0.1f * xa;
408 }
409 else {
410 x += 0.1f * xa;
411 }
412 }
413
414 remainder = y - floorf(y);
415 if (remainder > 0.4f && remainder < 0.6f) {
416 if (remainder < 0.5f) {
417 y -= 0.1f * ya;
418 }
419 else {
420 y += 0.1f * ya;
421 }
422 }
423
424 remainder = z - floorf(z);
425 if (remainder > 0.4f && remainder < 0.6f) {
426 if (remainder < 0.5f) {
427 z -= 0.1f * za;
428 }
429 else {
430 z += 0.1f * za;
431 }
432 }
433
434 font->pos[0] = round_fl_to_int(x);
435 font->pos[1] = round_fl_to_int(y);
436 font->pos[2] = round_fl_to_int(z);
437 }
438}
439
440void BLF_size(int fontid, float size)
441{
442 FontBLF *font = blf_get(fontid);
443
444 if (font) {
445 blf_font_size(font, size);
446 }
447}
448
449void BLF_color4ubv(int fontid, const uchar rgba[4])
450{
451 FontBLF *font = blf_get(fontid);
452
453 if (font) {
454 font->color[0] = rgba[0];
455 font->color[1] = rgba[1];
456 font->color[2] = rgba[2];
457 font->color[3] = rgba[3];
458 }
459}
460
461void BLF_color3ubv_alpha(int fontid, const uchar rgb[3], uchar alpha)
462{
463 FontBLF *font = blf_get(fontid);
464
465 if (font) {
466 font->color[0] = rgb[0];
467 font->color[1] = rgb[1];
468 font->color[2] = rgb[2];
469 font->color[3] = alpha;
470 }
471}
472
473void BLF_color3ubv(int fontid, const uchar rgb[3])
474{
475 BLF_color3ubv_alpha(fontid, rgb, 255);
476}
477
478void BLF_color4ub(int fontid, uchar r, uchar g, uchar b, uchar alpha)
479{
480 FontBLF *font = blf_get(fontid);
481
482 if (font) {
483 font->color[0] = r;
484 font->color[1] = g;
485 font->color[2] = b;
486 font->color[3] = alpha;
487 }
488}
489
490void BLF_color3ub(int fontid, uchar r, uchar g, uchar b)
491{
492 FontBLF *font = blf_get(fontid);
493
494 if (font) {
495 font->color[0] = r;
496 font->color[1] = g;
497 font->color[2] = b;
498 font->color[3] = 255;
499 }
500}
501
502void BLF_color4fv(int fontid, const float rgba[4])
503{
504 FontBLF *font = blf_get(fontid);
505
506 if (font) {
507 rgba_float_to_uchar(font->color, rgba);
508 }
509}
510
511void BLF_color4f(int fontid, float r, float g, float b, float a)
512{
513 const float rgba[4] = {r, g, b, a};
514 BLF_color4fv(fontid, rgba);
515}
516
517void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha)
518{
519 float rgba[4];
520 copy_v3_v3(rgba, rgb);
521 rgba[3] = alpha;
522 BLF_color4fv(fontid, rgba);
523}
524
525void BLF_color3f(int fontid, float r, float g, float b)
526{
527 const float rgba[4] = {r, g, b, 1.0f};
528 BLF_color4fv(fontid, rgba);
529}
530
532{
533 BLI_assert(g_batch.enabled == false);
534 g_batch.enabled = true;
535}
536
538{
539 if (g_batch.enabled) {
541 }
542}
543
545{
546 BLI_assert(g_batch.enabled == true);
547 blf_batch_draw(); /* Draw remaining glyphs */
548 g_batch.enabled = false;
549}
550
551static void blf_draw_gpu__start(const FontBLF *font)
552{
553 /*
554 * The pixmap alignment hack is handle
555 * in BLF_position (old ui_rasterpos_safe).
556 */
557
558 if ((font->flags & (BLF_ROTATION | BLF_ASPECT)) == 0) {
559 return; /* glyphs will be translated individually and batched. */
560 }
561
563
564 GPU_matrix_translate_3f(font->pos[0], font->pos[1], font->pos[2]);
565
566 if (font->flags & BLF_ASPECT) {
568 }
569
570 if (font->flags & BLF_ROTATION) {
572 }
573}
574
575static void blf_draw_gpu__end(const FontBLF *font)
576{
577 if ((font->flags & (BLF_ROTATION | BLF_ASPECT)) != 0) {
579 }
580}
581
582void BLF_draw(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
583{
584 BLF_RESULT_CHECK_INIT(r_info);
585
586 if (str_len == 0 || str[0] == '\0') {
587 return;
588 }
589
590 FontBLF *font = blf_get(fontid);
591
592 if (font) {
593
594 /* Avoid bgl usage to corrupt BLF drawing. */
595 GPU_bgl_end();
596
598 if (font->flags & BLF_WORD_WRAP) {
599 blf_font_draw__wrap(font, str, str_len, r_info);
600 }
601 else {
602 blf_font_draw(font, str, str_len, r_info);
603 }
604 blf_draw_gpu__end(font);
605 }
606}
607
608int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth, int tab_columns)
609{
610 if (str_len == 0 || str[0] == '\0') {
611 return 0;
612 }
613
614 FontBLF *font = blf_get(fontid);
615 int columns = 0;
616
617 if (font) {
619 columns = blf_font_draw_mono(font, str, str_len, cwidth, tab_columns);
620 blf_draw_gpu__end(font);
621 }
622
623 return columns;
624}
625
627 float x,
628 float y,
629 float size,
630 const float color[4],
631 float outline_alpha,
632 bool multicolor,
633 blender::FunctionRef<void(std::string &)> edit_source_cb)
634{
635#ifndef WITH_HEADLESS
636 FontBLF *font = global_font[0];
637 if (font) {
638 /* Avoid bgl usage to corrupt BLF drawing. */
639 GPU_bgl_end();
641 blf_draw_svg_icon(font, icon_id, x, y, size, color, outline_alpha, multicolor, edit_source_cb);
642 blf_draw_gpu__end(font);
643 }
644#else
645 UNUSED_VARS(icon_id, x, y, size, color, outline_alpha, multicolor, edit_source_cb);
646#endif /* WITH_HEADLESS */
647}
648
650 float size,
651 int *r_width,
652 int *r_height,
653 bool multicolor,
654 blender::FunctionRef<void(std::string &)> edit_source_cb)
655{
656#ifndef WITH_HEADLESS
657 FontBLF *font = global_font[0];
658 if (font) {
659 return blf_svg_icon_bitmap(font, icon_id, size, r_width, r_height, multicolor, edit_source_cb);
660 }
661#else
662 UNUSED_VARS(icon_id, size, r_width, r_height, multicolor, edit_source_cb);
663#endif /* WITH_HEADLESS */
664 return {};
665}
666
668 int fontid, const char *str, size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data)
669{
670 FontBLF *font = blf_get(fontid);
671
672 if (font) {
673 if (font->flags & BLF_WORD_WRAP) {
674 /* TODO: word-wrap support. */
675 BLI_assert(0);
676 }
677 else {
678 blf_font_boundbox_foreach_glyph(font, str, str_len, user_fn, user_data);
679 }
680 }
681}
682
684 const char *str,
685 size_t str_len,
686 int location_x)
687{
688 FontBLF *font = blf_get(fontid);
689 if (font) {
690 return blf_str_offset_from_cursor_position(font, str, str_len, location_x);
691 }
692 return 0;
693}
694
696 const char *str,
697 size_t str_offset,
698 rcti *r_glyph_bounds)
699{
700 FontBLF *font = blf_get(fontid);
701 if (font) {
702 blf_str_offset_to_glyph_bounds(font, str, str_offset, r_glyph_bounds);
703 return true;
704 }
705 return false;
706}
707
709 const char *str,
710 const size_t str_len,
711 const size_t str_offset,
712 const int cursor_width)
713{
714 FontBLF *font = blf_get(fontid);
715 if (font) {
716 return blf_str_offset_to_cursor(font, str, str_len, str_offset, cursor_width);
717 }
718 return 0;
719}
720
722 int fontid, const char *str, size_t str_len, size_t sel_start, size_t sel_length)
723{
724 FontBLF *font = blf_get(fontid);
725 if (font) {
726 return blf_str_selection_boxes(font, str, str_len, sel_start, sel_length);
727 }
728 return {};
729}
730
732 int fontid, const char *str, const size_t str_len, float width, float *r_width)
733{
734 FontBLF *font = blf_get(fontid);
735
736 if (font) {
737 const float xa = (font->flags & BLF_ASPECT) ? font->aspect[0] : 1.0f;
738 size_t ret;
739 int width_result;
740 ret = blf_font_width_to_strlen(font, str, str_len, width / xa, &width_result);
741 if (r_width) {
742 *r_width = float(width_result) * xa;
743 }
744 return ret;
745 }
746
747 if (r_width) {
748 *r_width = 0.0f;
749 }
750 return 0;
751}
752
754 int fontid, const char *str, const size_t str_len, float width, float *r_width)
755{
756 FontBLF *font = blf_get(fontid);
757
758 if (font) {
759 const float xa = (font->flags & BLF_ASPECT) ? font->aspect[0] : 1.0f;
760 size_t ret;
761 int width_result;
762 ret = blf_font_width_to_rstrlen(font, str, str_len, width / xa, &width_result);
763 if (r_width) {
764 *r_width = float(width_result) * xa;
765 }
766 return ret;
767 }
768
769 if (r_width) {
770 *r_width = 0.0f;
771 }
772 return 0;
773}
774
776 int fontid, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
777{
778 FontBLF *font = blf_get(fontid);
779
780 BLF_RESULT_CHECK_INIT(r_info);
781
782 if (font) {
783 if (font->flags & BLF_WORD_WRAP) {
784 blf_font_boundbox__wrap(font, str, str_len, r_box, r_info);
785 }
786 else {
787 blf_font_boundbox(font, str, str_len, r_box, r_info);
788 }
789 }
790}
791
793 int fontid, const char *str, const size_t str_len, float *r_width, float *r_height)
794{
795 FontBLF *font = blf_get(fontid);
796
797 if (font) {
798 blf_font_width_and_height(font, str, str_len, r_width, r_height, nullptr);
799 }
800 else {
801 *r_width = *r_height = 0.0f;
802 }
803}
804
805float BLF_width(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
806{
807 FontBLF *font = blf_get(fontid);
808
809 BLF_RESULT_CHECK_INIT(r_info);
810
811 if (font) {
812 return blf_font_width(font, str, str_len, r_info);
813 }
814
815 return 0.0f;
816}
817
818float BLF_fixed_width(int fontid)
819{
820 FontBLF *font = blf_get(fontid);
821
822 if (font) {
823 return blf_font_fixed_width(font);
824 }
825
826 return 0.0f;
827}
828
829int BLF_glyph_advance(int fontid, const char *str)
830{
831 FontBLF *font = blf_get(fontid);
832
833 if (font) {
834 return blf_font_glyph_advance(font, str);
835 }
836
837 return 0;
838}
839
840float BLF_height(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
841{
842 FontBLF *font = blf_get(fontid);
843
844 BLF_RESULT_CHECK_INIT(r_info);
845
846 if (font) {
847 return blf_font_height(font, str, str_len, r_info);
848 }
849
850 return 0.0f;
851}
852
853int BLF_height_max(int fontid)
854{
855 FontBLF *font = blf_get(fontid);
856
857 if (font) {
858 return blf_font_height_max(font);
859 }
860
861 return 0;
862}
863
864int BLF_width_max(int fontid)
865{
866 FontBLF *font = blf_get(fontid);
867
868 if (font) {
869 return blf_font_width_max(font);
870 }
871
872 return 0;
873}
874
875int BLF_descender(int fontid)
876{
877 FontBLF *font = blf_get(fontid);
878
879 if (font) {
880 return blf_font_descender(font);
881 }
882
883 return 0;
884}
885
886int BLF_ascender(int fontid)
887{
888 FontBLF *font = blf_get(fontid);
889
890 if (font) {
891 return blf_font_ascender(font);
892 }
893
894 return 0.0f;
895}
896
897void BLF_rotation(int fontid, float angle)
898{
899 FontBLF *font = blf_get(fontid);
900
901 if (font) {
902 font->angle = angle;
903 }
904}
905
906void BLF_clipping(int fontid, int xmin, int ymin, int xmax, int ymax)
907{
908 FontBLF *font = blf_get(fontid);
909
910 if (font) {
911 font->clip_rec.xmin = xmin;
912 font->clip_rec.ymin = ymin;
913 font->clip_rec.xmax = xmax;
914 font->clip_rec.ymax = ymax;
915 }
916}
917
918void BLF_wordwrap(int fontid, int wrap_width, BLFWrapMode mode)
919{
920 FontBLF *font = blf_get(fontid);
921
922 if (font) {
923 font->wrap_width = wrap_width;
924 font->wrap_mode = mode;
925 }
926}
927
928void BLF_shadow(int fontid, FontShadowType type, const float rgba[4])
929{
930 FontBLF *font = blf_get(fontid);
931
932 if (font) {
933 font->shadow = type;
934 if (rgba) {
936 }
937 }
938}
939
940void BLF_shadow_offset(int fontid, int x, int y)
941{
942 FontBLF *font = blf_get(fontid);
943
944 if (font) {
945 font->shadow_x = x;
946 font->shadow_y = y;
947 }
948}
949
951 int fontid, float *fbuf, uchar *cbuf, int w, int h, const ColorManagedDisplay *display)
952{
953 FontBLF *font = blf_get(fontid);
954
955 if (font) {
956 font->buf_info.fbuf = fbuf;
957 font->buf_info.cbuf = cbuf;
958 font->buf_info.dims[0] = w;
959 font->buf_info.dims[1] = h;
960 font->buf_info.display = display;
961 }
962}
963
974
976{
977 FontBLF *font = blf_get(fontid);
978 if (font) {
979 BLFBufferState *buffer_state = MEM_new<BLFBufferState>(__func__);
980 buffer_state->fontid = fontid;
981 buffer_state->font = font;
982 buffer_state->buf_info = font->buf_info;
983 return buffer_state;
984 }
985 return nullptr;
986}
987
989{
990 FontBLF *font = blf_get(buffer_state->fontid);
991 /* It's possible the font has been removed as this is called from Python. */
992 if (font == buffer_state->font) {
993 /* From the callers perspective, don't consider the color part of the buffer info.
994 *
995 * NOTE(@ideasman42) This is done because the color is not logically part of the image binding.
996 * It looks like we can refactor color out of #FontBufInfoBLF::col_init,
997 * and use #FontBLF::color instead. */
998 copy_v4_v4(buffer_state->buf_info.col_init, font->buf_info.col_init);
999
1000 font->buf_info = buffer_state->buf_info;
1001 }
1002 BLF_buffer_state_free(buffer_state);
1003}
1004
1006{
1007 MEM_delete(buffer_state);
1008}
1009
1010void BLF_buffer_col(int fontid, const float rgba[4])
1011{
1012 FontBLF *font = blf_get(fontid);
1013
1014 if (font) {
1015 copy_v4_v4(font->buf_info.col_init, rgba);
1016 }
1017}
1018
1020{
1021 FontBufInfoBLF *buf_info = &font->buf_info;
1022
1023 rgba_float_to_uchar(buf_info->col_char, buf_info->col_init);
1024
1025 if (buf_info->display) {
1026 copy_v4_v4(buf_info->col_float, buf_info->col_init);
1028 }
1029 else {
1030 srgb_to_linearrgb_v4(buf_info->col_float, buf_info->col_init);
1031 }
1032}
1034
1035void BLF_draw_buffer(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
1036{
1037 FontBLF *font = blf_get(fontid);
1038
1039 if (font && (font->buf_info.fbuf || font->buf_info.cbuf)) {
1041 if (font->flags & BLF_WORD_WRAP) {
1042 blf_font_draw_buffer__wrap(font, str, str_len, r_info);
1043 }
1044 else {
1045 blf_font_draw_buffer(font, str, str_len, r_info);
1046 }
1048 }
1049}
1050
1053 const int max_pixel_width,
1054 BLFWrapMode mode)
1055{
1056 FontBLF *font = blf_get(fontid);
1057 if (!font) {
1058 return {};
1059 }
1060 return blf_font_string_wrap(font, str, max_pixel_width, mode);
1061}
1062
1063char *BLF_display_name_from_file(const char *filepath)
1064{
1065 /* While listing font directories this function can be called simultaneously from a greater
1066 * number of threads than we want the FreeType cache to keep open at a time. Therefore open
1067 * with a separate FT_Library object and use FreeType calls directly to avoid any contention. */
1068 char *name = nullptr;
1069 FT_Library ft_library;
1070 if (FT_Init_FreeType(&ft_library) == FT_Err_Ok) {
1071 FT_Face face;
1072 if (FT_New_Face(ft_library, filepath, 0, &face) == FT_Err_Ok) {
1073 if (face->family_name) {
1074 name = BLI_sprintfN("%s %s", face->family_name, face->style_name);
1075 }
1076 FT_Done_Face(face);
1077 }
1078 FT_Done_FreeType(ft_library);
1079 }
1080 return name;
1081}
1082
1084{
1085 FontBLF *font = blf_get(fontid);
1086 if (!font) {
1087 return nullptr;
1088 }
1089
1090 return blf_display_name(font);
1091}
1092
1093bool BLF_get_vfont_metrics(int fontid, float *ascend_ratio, float *em_ratio, float *scale)
1094{
1095 FontBLF *font = blf_get(fontid);
1096 if (!font) {
1097 return false;
1098 }
1099
1100 if (!blf_ensure_face(font)) {
1101 return false;
1102 }
1103
1104 /* Copied without change from vfontdata_freetype.cc to ensure consistent sizing. */
1105
1106 /* Blender default BFont is not "complete". */
1107 const bool complete_font = (font->face->ascender != 0) && (font->face->descender != 0) &&
1108 (font->face->ascender != font->face->descender);
1109
1110 if (complete_font) {
1111 /* We can get descender as well, but we simple store descender in relation to the ascender.
1112 * Also note that descender is stored as a negative number. */
1113 *ascend_ratio = float(font->face->ascender) / (font->face->ascender - font->face->descender);
1114 }
1115 else {
1118 }
1119
1120 /* Adjust font size */
1121 if (font->face->bbox.yMax != font->face->bbox.yMin) {
1122 *scale = float(1.0 / double(font->face->bbox.yMax - font->face->bbox.yMin));
1123
1124 if (complete_font) {
1125 *em_ratio = float(font->face->ascender - font->face->descender) /
1126 (font->face->bbox.yMax - font->face->bbox.yMin);
1127 }
1128 }
1129 else {
1131 }
1132
1133 return true;
1134}
1135
1137 int fontid, uint unicode, ListBase *nurbsbase, const float scale, bool use_fallback)
1138{
1139 FontBLF *font = blf_get(fontid);
1140 if (!font) {
1141 return 0.0f;
1142 }
1143 return blf_character_to_curves(font, unicode, nurbsbase, scale, use_fallback);
1144}
1145
1146#ifndef NDEBUG
1147void BLF_state_print(int fontid)
1148{
1149 FontBLF *font = blf_get(fontid);
1150 if (font) {
1151 printf("fontid %d %p\n", fontid, (void *)font);
1152 printf(" mem_name: '%s'\n", font->mem_name ? font->mem_name : "<none>");
1153 printf(" filepath: '%s'\n", font->filepath ? font->filepath : "<none>");
1154 printf(" size: %f\n", font->size);
1155 printf(" pos: %d %d %d\n", UNPACK3(font->pos));
1156 printf(" aspect: (%d) %.6f %.6f %.6f\n",
1157 (font->flags & BLF_ROTATION) != 0,
1158 UNPACK3(font->aspect));
1159 printf(" angle: (%d) %.6f\n", (font->flags & BLF_ASPECT) != 0, font->angle);
1160 printf(" flag: %d\n", font->flags);
1161 }
1162 else {
1163 printf("fontid %d (nullptr)\n", fontid);
1164 }
1165 fflush(stdout);
1166}
1167#endif
BLFWrapMode
Definition BLF_api.hh:44
void BLF_default_set(int fontid)
#define BLF_VFONT_METRICS_EM_RATIO_DEFAULT
Definition BLF_api.hh:124
int blf_mono_font_render
Definition blf.cc:49
@ BLF_ROTATION
Definition BLF_api.hh:433
@ BLF_WORD_WRAP
Definition BLF_api.hh:439
@ BLF_ASPECT
Definition BLF_api.hh:438
@ BLF_DEFAULT
Definition BLF_api.hh:450
int BLF_default()
bool(*)(const char *str, size_t str_step_ofs, const rcti *bounds, void *user_dataconst) BLF_GlyphBoundsFn
Definition BLF_api.hh:205
int blf_mono_font
Definition blf.cc:48
blender::ocio::Display ColorManagedDisplay
Definition BLF_api.hh:35
FontShadowType
Definition BLF_api.hh:37
#define BLF_VFONT_METRICS_SCALE_DEFAULT
Definition BLF_api.hh:123
#define BLF_VFONT_METRICS_ASCEND_RATIO_DEFAULT
Definition BLF_api.hh:125
#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:373
MINLINE int round_fl_to_int(float a)
MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4])
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()
void GPU_bgl_end()
Definition gpu_state.cc:360
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
void IMB_colormanagement_display_to_scene_linear_v3(float pixel[3], const ColorManagedDisplay *display)
volatile int lock
void BLF_color3ubv(int fontid, const uchar rgb[3])
Definition blf.cc:473
size_t BLF_width_to_rstrlen(int fontid, const char *str, const size_t str_len, float width, float *r_width)
Definition blf.cc:753
void BLF_state_print(int fontid)
Definition blf.cc:1147
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:478
void BLF_color4ubv(int fontid, const uchar rgba[4])
Definition blf.cc:449
int BLF_load(const char *filepath)
Definition blf.cc:175
void BLF_size(int fontid, float size)
Definition blf.cc:440
void BLF_buffer_state_free(BLFBufferState *buffer_state)
Definition blf.cc:1005
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:626
int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth, int tab_columns)
Definition blf.cc:608
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:988
void BLF_aspect(int fontid, float x, float y, float z)
Definition blf.cc:374
void blf_draw_buffer__start(FontBLF *font)
Definition blf.cc:1019
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:721
float BLF_width(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:805
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:906
size_t BLF_width_to_strlen(int fontid, const char *str, const size_t str_len, float width, float *r_width)
Definition blf.cc:731
void BLF_boundbox(int fontid, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
Definition blf.cc:775
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:1051
void BLF_draw_buffer(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:1035
void BLF_color3ub(int fontid, uchar r, uchar g, uchar b)
Definition blf.cc:490
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:461
void BLF_color3f(int fontid, float r, float g, float b)
Definition blf.cc:525
float BLF_fixed_width(int fontid)
Definition blf.cc:818
char * BLF_display_name_from_id(int fontid)
Definition blf.cc:1083
void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha)
Definition blf.cc:517
void BLF_color4fv(int fontid, const float rgba[4])
Definition blf.cc:502
#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:708
char * BLF_display_name_from_file(const char *filepath)
Definition blf.cc:1063
bool BLF_get_vfont_metrics(int fontid, float *ascend_ratio, float *em_ratio, float *scale)
Definition blf.cc:1093
void BLF_shadow_offset(int fontid, int x, int y)
Definition blf.cc:940
static void blf_draw_gpu__end(const FontBLF *font)
Definition blf.cc:575
int BLF_width_max(int fontid)
Definition blf.cc:864
int BLF_ascender(int fontid)
Definition blf.cc:886
void BLF_batch_draw_begin()
Definition blf.cc:531
BLFBufferState * BLF_buffer_state_push(int fontid)
Definition blf.cc:975
int BLF_load_mem_unique(const char *name, const uchar *mem, int mem_size)
Definition blf.cc:234
void BLF_boundbox_foreach_glyph(int fontid, const char *str, size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data)
Definition blf.cc:667
void BLF_disable(int fontid, int option)
Definition blf.cc:329
void BLF_rotation(int fontid, float angle)
Definition blf.cc:897
void BLF_metrics_attach(const int fontid, const uchar *mem, const int mem_size)
Definition blf.cc:216
void BLF_buffer_col(int fontid, const float rgba[4])
Definition blf.cc:1010
void BLF_batch_draw_end()
Definition blf.cc:544
static void blf_draw_gpu__start(const FontBLF *font)
Definition blf.cc:551
int BLF_glyph_advance(int fontid, const char *str)
Definition blf.cc:829
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:683
int BLF_descender(int fontid)
Definition blf.cc:875
FontBLF * global_font[BLF_MAX_FONT]
Definition blf.cc:44
void BLF_exit()
Definition blf.cc:70
void BLF_buffer(int fontid, float *fbuf, uchar *cbuf, int w, int h, const ColorManagedDisplay *display)
Definition blf.cc:950
void BLF_cache_clear()
Definition blf.cc:98
int BLF_default_weight(int fontid)
Definition blf.cc:352
void BLF_draw(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:582
float BLF_character_to_curves(int fontid, uint unicode, ListBase *nurbsbase, const float scale, bool use_fallback)
Definition blf.cc:1136
void BLF_batch_draw_flush()
Definition blf.cc:537
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:649
void BLF_enable(int fontid, int option)
Definition blf.cc:320
void BLF_shadow(int fontid, FontShadowType type, const float rgba[4])
Definition blf.cc:928
void BLF_width_and_height(int fontid, const char *str, const size_t str_len, float *r_width, float *r_height)
Definition blf.cc:792
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:695
int BLF_load_unique(const char *filepath)
Definition blf.cc:188
int BLF_init()
Definition blf.cc:61
void BLF_color4f(int fontid, float r, float g, float b, float a)
Definition blf.cc:511
static blender::Mutex g_blf_load_mutex
Definition blf.cc:51
bool BLF_has_variable_weight(int fontid)
Definition blf.cc:361
void blf_draw_buffer__end()
Definition blf.cc:1033
void BLF_character_weight(int fontid, int weight)
Definition blf.cc:344
int BLF_height_max(int fontid)
Definition blf.cc:853
void BLF_position(int fontid, float x, float y, float z)
Definition blf.cc:385
float BLF_height(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:840
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:918
size_t blf_str_offset_from_cursor_position(FontBLF *font, const char *str, size_t str_len, int location_x)
Definition blf_font.cc:1141
void blf_str_offset_to_glyph_bounds(FontBLF *font, const char *str, size_t str_offset, rcti *r_glyph_bounds)
Definition blf_font.cc:1191
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:864
int blf_font_ascender(FontBLF *font)
Definition blf_font.cc:1583
void blf_draw_svg_icon(FontBLF *font, 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_font.cc:546
blender::Vector< blender::StringRef > blf_font_string_wrap(FontBLF *font, blender::StringRef str, int max_pixel_width, BLFWrapMode mode)
Definition blf_font.cc:1530
float blf_font_width(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:1013
bool blf_ensure_face(FontBLF *font)
Definition blf_font.cc:1892
void blf_font_draw_buffer(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:784
int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, int cwidth, int tab_columns)
Definition blf_font.cc:510
blender::Array< uchar > blf_svg_icon_bitmap(FontBLF *font, uint icon_id, float size, int *r_width, int *r_height, bool multicolor, blender::FunctionRef< void(std::string &)> edit_source_cb)
Definition blf_font.cc:592
void blf_font_free(FontBLF *font)
Definition blf_font.cc:2117
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:1080
bool blf_font_size(FontBLF *font, float size)
Definition blf_font.cc:2177
float blf_font_fixed_width(FontBLF *font)
Definition blf_font.cc:1055
float blf_font_height(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:1034
int blf_font_init()
Definition blf_font.cc:1603
int blf_font_width_max(FontBLF *font)
Definition blf_font.cc:1572
void blf_batch_draw()
Definition blf_font.cc:324
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:1473
void blf_font_exit()
Definition blf_font.cc:1624
void blf_font_boundbox(FontBLF *font, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
Definition blf_font.cc:976
int blf_font_glyph_advance(FontBLF *font, const char *str)
Definition blf_font.cc:1063
uint blf_get_char_index(FontBLF *font, uint charcode)
Definition blf_font.cc:148
char * blf_display_name(FontBLF *font)
Definition blf_font.cc:1589
FontBLF * blf_font_new_from_mem(const char *mem_name, const uchar *mem, const size_t mem_size)
Definition blf_font.cc:2100
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:1204
void blf_font_attach_from_mem(FontBLF *font, const uchar *mem, const size_t mem_size)
Definition blf_font.cc:2105
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:835
int blf_font_descender(FontBLF *font)
Definition blf_font.cc:1577
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:984
void blf_font_draw(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:503
FontBLF * blf_font_new_from_filepath(const char *filepath)
Definition blf_font.cc:2095
void blf_font_draw_buffer__wrap(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:1501
int blf_font_height_max(FontBLF *font)
Definition blf_font.cc:1560
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:1249
void blf_font_draw__wrap(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:1447
void blf_glyph_cache_clear(FontBLF *font)
Definition blf_glyph.cc:162
float blf_character_to_curves(FontBLF *font, uint unicode, ListBase *nurbsbase, const float scale, bool use_fallback)
#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
#define floorf(x)
#define str(s)
#define printf(...)
std::mutex Mutex
Definition BLI_mutex.hh:47
return ret
FontBufInfoBLF buf_info
Definition blf.cc:972
const FontBLF * font
Definition blf.cc:970
unsigned char color[4]
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 ColorManagedDisplay * display
unsigned char col_char[4]
unsigned char * cbuf
int ymin
int ymax
int xmin
int xmax
i
Definition text_draw.cc:230