Blender V4.3
blf.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 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 "MEM_guardedalloc.h"
24
25#include "BLI_fileops.h"
26#include "BLI_math_rotation.h"
27#include "BLI_path_utils.hh"
28#include "BLI_string.h"
29#include "BLI_threads.h"
30
31#include "BLF_api.hh"
32
34
35#include "GPU_matrix.hh"
36#include "GPU_shader.hh"
37
38#include "blf_internal.hh"
39#include "blf_internal_types.hh"
40
41#define BLF_RESULT_CHECK_INIT(r_info) \
42 if (r_info) { \
43 memset(r_info, 0, sizeof(*(r_info))); \
44 } \
45 ((void)0)
46
48
49/* XXX: should these be made into global_font_'s too? */
50
53
54static FontBLF *blf_get(int fontid)
55{
56 if (fontid >= 0 && fontid < BLF_MAX_FONT) {
57 return global_font[fontid];
58 }
59 return nullptr;
60}
61
63{
64 for (int i = 0; i < BLF_MAX_FONT; i++) {
65 global_font[i] = nullptr;
66 }
67
68 return blf_font_init();
69}
70
72{
73 for (int i = 0; i < BLF_MAX_FONT; i++) {
74 FontBLF *font = global_font[i];
75 if (font) {
76 blf_font_free(font);
77 global_font[i] = nullptr;
78 }
79 }
80
82}
83
85{
86 const int def_font = BLF_default();
87 for (int i = 0; i < BLF_MAX_FONT; i++) {
88 FontBLF *font = global_font[i];
89 if (font && !ELEM(i, def_font, blf_mono_font, blf_mono_font_render) &&
90 !(font->flags & BLF_DEFAULT))
91 {
92 /* Remove fonts that are not used in the UI or part of the stack. */
93 blf_font_free(font);
94 global_font[i] = nullptr;
95 }
96 }
97}
98
100{
101 for (int i = 0; i < BLF_MAX_FONT; i++) {
102 FontBLF *font = global_font[i];
103 if (font) {
105 }
106 }
107}
108
109bool blf_font_id_is_valid(int fontid)
110{
111 return blf_get(fontid) != nullptr;
112}
113
114static int blf_search_by_mem_name(const char *mem_name)
115{
116 for (int i = 0; i < BLF_MAX_FONT; i++) {
117 const FontBLF *font = global_font[i];
118 if ((font == nullptr) || (font->mem_name == nullptr)) {
119 continue;
120 }
121 if (STREQ(font->mem_name, mem_name)) {
122 return i;
123 }
124 }
125
126 return -1;
127}
128
129static int blf_search_by_filepath(const char *filepath)
130{
131 for (int i = 0; i < BLF_MAX_FONT; i++) {
132 const FontBLF *font = global_font[i];
133 if ((font == nullptr) || (font->filepath == nullptr)) {
134 continue;
135 }
136 if (BLI_path_cmp(font->filepath, filepath) == 0) {
137 return i;
138 }
139 }
140
141 return -1;
142}
143
145{
146 for (int i = 0; i < BLF_MAX_FONT; i++) {
147 if (!global_font[i]) {
148 return i;
149 }
150 }
151
152 return -1;
153}
154
155bool BLF_has_glyph(int fontid, uint unicode)
156{
157 FontBLF *font = blf_get(fontid);
158 if (font) {
159 return blf_get_char_index(font, unicode) != FT_Err_Ok;
160 }
161 return false;
162}
163
164bool BLF_is_loaded(const char *filepath)
165{
166 return blf_search_by_filepath(filepath) >= 0;
167}
168
169bool BLF_is_loaded_mem(const char *name)
170{
171 return blf_search_by_mem_name(name) >= 0;
172}
173
174int BLF_load(const char *filepath)
175{
176 /* check if we already load this font. */
177 int i = blf_search_by_filepath(filepath);
178 if (i >= 0) {
179 FontBLF *font = global_font[i];
180 font->reference_count++;
181 return i;
182 }
183
184 return BLF_load_unique(filepath);
185}
186
187int BLF_load_unique(const char *filepath)
188{
189 /* Don't search in the cache!! make a new
190 * object font, this is for keep fonts threads safe.
191 */
192 int i = blf_search_available();
193 if (i == -1) {
194 printf("Too many fonts!!!\n");
195 return -1;
196 }
197
198 /* This isn't essential, it will just cause confusing behavior to load a font
199 * that appears to succeed, then doesn't show up. */
200 if (!BLI_exists(filepath)) {
201 printf("Can't find font: %s\n", filepath);
202 return -1;
203 }
204
205 FontBLF *font = blf_font_new_from_filepath(filepath);
206
207 if (!font) {
208 printf("Can't load font: %s\n", filepath);
209 return -1;
210 }
211
212 font->reference_count = 1;
213 global_font[i] = font;
214 return i;
215}
216
217void BLF_metrics_attach(const int fontid, const uchar *mem, const int mem_size)
218{
219 FontBLF *font = blf_get(fontid);
220
221 if (font) {
222 blf_font_attach_from_mem(font, mem, mem_size);
223 }
224}
225
226int BLF_load_mem(const char *name, const uchar *mem, int mem_size)
227{
228 int i = blf_search_by_mem_name(name);
229 if (i >= 0) {
230 // font = global_font[i]; /* UNUSED */
231 return i;
232 }
233 return BLF_load_mem_unique(name, mem, mem_size);
234}
235
236int BLF_load_mem_unique(const char *name, const uchar *mem, int mem_size)
237{
238 /*
239 * Don't search in the cache, make a new object font!
240 * this is to keep the font thread safe.
241 */
242 int i = blf_search_available();
243 if (i == -1) {
244 printf("Too many fonts!!!\n");
245 return -1;
246 }
247
248 if (!mem_size) {
249 printf("Can't load font: %s from memory!!\n", name);
250 return -1;
251 }
252
253 FontBLF *font = blf_font_new_from_mem(name, mem, mem_size);
254 if (!font) {
255 printf("Can't load font: %s from memory!!\n", name);
256 return -1;
257 }
258
259 font->reference_count = 1;
260 global_font[i] = font;
261 return i;
262}
263
264void BLF_unload(const char *filepath)
265{
266 for (int i = 0; i < BLF_MAX_FONT; i++) {
267 FontBLF *font = global_font[i];
268 if (font == nullptr || font->filepath == nullptr) {
269 continue;
270 }
271
272 if (BLI_path_cmp(font->filepath, filepath) == 0) {
273 BLI_assert(font->reference_count > 0);
274 font->reference_count--;
275
276 if (font->reference_count == 0) {
277 blf_font_free(font);
278 global_font[i] = nullptr;
279 }
280 }
281 }
282}
283
284void BLF_unload_id(int fontid)
285{
286 FontBLF *font = blf_get(fontid);
287 if (font) {
288 BLI_assert(font->reference_count > 0);
289 font->reference_count--;
290
291 if (font->reference_count == 0) {
292 blf_font_free(font);
293 global_font[fontid] = nullptr;
294 }
295 }
296}
297
299{
300 for (int i = 0; i < BLF_MAX_FONT; i++) {
301 FontBLF *font = global_font[i];
302 if (font) {
303 blf_font_free(font);
304 global_font[i] = nullptr;
305 }
306 }
307 blf_mono_font = -1;
309 BLF_default_set(-1);
310}
311
312void BLF_enable(int fontid, int option)
313{
314 FontBLF *font = blf_get(fontid);
315
316 if (font) {
317 font->flags |= option;
318 }
319}
320
321void BLF_disable(int fontid, int option)
322{
323 FontBLF *font = blf_get(fontid);
324
325 if (font) {
326 font->flags &= ~option;
327 }
328}
329
330void BLF_character_weight(int fontid, int weight)
331{
332 FontBLF *font = blf_get(fontid);
333 if (font) {
334 font->char_weight = weight;
335 }
336}
337
338int BLF_default_weight(int fontid)
339{
340 FontBLF *font = blf_get(fontid);
341 if (font) {
342 return font->metrics.weight;
343 }
344 return 400;
345}
346
348{
349 const FontBLF *font = blf_get(fontid);
350 if (font && font->variations) {
351 for (int i = 0; i < int(font->variations->num_axis); i++) {
352 if (font->variations->axis[i].tag == BLF_VARIATION_AXIS_WEIGHT) {
353 return true;
354 }
355 }
356 }
357 return false;
358}
359
360void BLF_aspect(int fontid, float x, float y, float z)
361{
362 FontBLF *font = blf_get(fontid);
363
364 if (font) {
365 font->aspect[0] = x;
366 font->aspect[1] = y;
367 font->aspect[2] = z;
368 }
369}
370
371void BLF_position(int fontid, float x, float y, float z)
372{
373 FontBLF *font = blf_get(fontid);
374
375 if (font) {
376 float xa, ya, za;
377 float remainder;
378
379 if (font->flags & BLF_ASPECT) {
380 xa = font->aspect[0];
381 ya = font->aspect[1];
382 za = font->aspect[2];
383 }
384 else {
385 xa = 1.0f;
386 ya = 1.0f;
387 za = 1.0f;
388 }
389
390 remainder = x - floorf(x);
391 if (remainder > 0.4f && remainder < 0.6f) {
392 if (remainder < 0.5f) {
393 x -= 0.1f * xa;
394 }
395 else {
396 x += 0.1f * xa;
397 }
398 }
399
400 remainder = y - floorf(y);
401 if (remainder > 0.4f && remainder < 0.6f) {
402 if (remainder < 0.5f) {
403 y -= 0.1f * ya;
404 }
405 else {
406 y += 0.1f * ya;
407 }
408 }
409
410 remainder = z - floorf(z);
411 if (remainder > 0.4f && remainder < 0.6f) {
412 if (remainder < 0.5f) {
413 z -= 0.1f * za;
414 }
415 else {
416 z += 0.1f * za;
417 }
418 }
419
420 font->pos[0] = round_fl_to_int(x);
421 font->pos[1] = round_fl_to_int(y);
422 font->pos[2] = round_fl_to_int(z);
423 }
424}
425
426void BLF_size(int fontid, float size)
427{
428 FontBLF *font = blf_get(fontid);
429
430 if (font) {
431 blf_font_size(font, size);
432 }
433}
434
435void BLF_color4ubv(int fontid, const uchar rgba[4])
436{
437 FontBLF *font = blf_get(fontid);
438
439 if (font) {
440 font->color[0] = rgba[0];
441 font->color[1] = rgba[1];
442 font->color[2] = rgba[2];
443 font->color[3] = rgba[3];
444 }
445}
446
447void BLF_color3ubv_alpha(int fontid, const uchar rgb[3], uchar alpha)
448{
449 FontBLF *font = blf_get(fontid);
450
451 if (font) {
452 font->color[0] = rgb[0];
453 font->color[1] = rgb[1];
454 font->color[2] = rgb[2];
455 font->color[3] = alpha;
456 }
457}
458
459void BLF_color3ubv(int fontid, const uchar rgb[3])
460{
461 BLF_color3ubv_alpha(fontid, rgb, 255);
462}
463
464void BLF_color4ub(int fontid, uchar r, uchar g, uchar b, uchar alpha)
465{
466 FontBLF *font = blf_get(fontid);
467
468 if (font) {
469 font->color[0] = r;
470 font->color[1] = g;
471 font->color[2] = b;
472 font->color[3] = alpha;
473 }
474}
475
476void BLF_color3ub(int fontid, uchar r, uchar g, uchar b)
477{
478 FontBLF *font = blf_get(fontid);
479
480 if (font) {
481 font->color[0] = r;
482 font->color[1] = g;
483 font->color[2] = b;
484 font->color[3] = 255;
485 }
486}
487
488void BLF_color4fv(int fontid, const float rgba[4])
489{
490 FontBLF *font = blf_get(fontid);
491
492 if (font) {
493 rgba_float_to_uchar(font->color, rgba);
494 }
495}
496
497void BLF_color4f(int fontid, float r, float g, float b, float a)
498{
499 const float rgba[4] = {r, g, b, a};
500 BLF_color4fv(fontid, rgba);
501}
502
503void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha)
504{
505 float rgba[4];
506 copy_v3_v3(rgba, rgb);
507 rgba[3] = alpha;
508 BLF_color4fv(fontid, rgba);
509}
510
511void BLF_color3f(int fontid, float r, float g, float b)
512{
513 const float rgba[4] = {r, g, b, 1.0f};
514 BLF_color4fv(fontid, rgba);
515}
516
518{
519 BLI_assert(g_batch.enabled == false);
520 g_batch.enabled = true;
521}
522
524{
525 if (g_batch.enabled) {
527 }
528}
529
531{
532 BLI_assert(g_batch.enabled == true);
533 blf_batch_draw(); /* Draw remaining glyphs */
534 g_batch.enabled = false;
535}
536
537static void blf_draw_gpu__start(const FontBLF *font)
538{
539 /*
540 * The pixmap alignment hack is handle
541 * in BLF_position (old ui_rasterpos_safe).
542 */
543
544 if ((font->flags & (BLF_ROTATION | BLF_ASPECT)) == 0) {
545 return; /* glyphs will be translated individually and batched. */
546 }
547
549
550 GPU_matrix_translate_3f(font->pos[0], font->pos[1], font->pos[2]);
551
552 if (font->flags & BLF_ASPECT) {
554 }
555
556 if (font->flags & BLF_ROTATION) {
558 }
559}
560
561static void blf_draw_gpu__end(const FontBLF *font)
562{
563 if ((font->flags & (BLF_ROTATION | BLF_ASPECT)) != 0) {
565 }
566}
567
568void BLF_draw(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
569{
570 BLF_RESULT_CHECK_INIT(r_info);
571
572 if (str_len == 0 || str[0] == '\0') {
573 return;
574 }
575
576 FontBLF *font = blf_get(fontid);
577
578 if (font) {
579
580 /* Avoid bgl usage to corrupt BLF drawing. */
581 GPU_bgl_end();
582
584 if (font->flags & BLF_WORD_WRAP) {
585 blf_font_draw__wrap(font, str, str_len, r_info);
586 }
587 else {
588 blf_font_draw(font, str, str_len, r_info);
589 }
590 blf_draw_gpu__end(font);
591 }
592}
593
594int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth, int tab_columns)
595{
596 if (str_len == 0 || str[0] == '\0') {
597 return 0;
598 }
599
600 FontBLF *font = blf_get(fontid);
601 int columns = 0;
602
603 if (font) {
605 columns = blf_font_draw_mono(font, str, str_len, cwidth, tab_columns);
606 blf_draw_gpu__end(font);
607 }
608
609 return columns;
610}
611
613 float x,
614 float y,
615 float size,
616 const float color[4],
617 float outline_alpha,
618 bool multicolor,
619 blender::FunctionRef<void(std::string &)> edit_source_cb)
620{
621#ifndef WITH_HEADLESS
622 FontBLF *font = global_font[0];
623 if (font) {
624 /* Avoid bgl usage to corrupt BLF drawing. */
625 GPU_bgl_end();
627 blf_draw_svg_icon(font, icon_id, x, y, size, color, outline_alpha, multicolor, edit_source_cb);
628 blf_draw_gpu__end(font);
629 }
630#else
631 UNUSED_VARS(icon_id, x, y, size, color, outline_alpha, multicolor, edit_source_cb);
632#endif /* WITH_HEADLESS */
633}
634
636 float size,
637 int *r_width,
638 int *r_height,
639 bool multicolor,
640 blender::FunctionRef<void(std::string &)> edit_source_cb)
641{
642#ifndef WITH_HEADLESS
643 FontBLF *font = global_font[0];
644 if (font) {
645 return blf_svg_icon_bitmap(font, icon_id, size, r_width, r_height, multicolor, edit_source_cb);
646 }
647#else
648 UNUSED_VARS(icon_id, size, r_width, r_height, multicolor, edit_source_cb);
649#endif /* WITH_HEADLESS */
650 return {};
651}
652
654 int fontid, const char *str, size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data)
655{
656 FontBLF *font = blf_get(fontid);
657
658 if (font) {
659 if (font->flags & BLF_WORD_WRAP) {
660 /* TODO: word-wrap support. */
661 BLI_assert(0);
662 }
663 else {
664 blf_font_boundbox_foreach_glyph(font, str, str_len, user_fn, user_data);
665 }
666 }
667}
668
670 const char *str,
671 size_t str_len,
672 int location_x)
673{
674 FontBLF *font = blf_get(fontid);
675 if (font) {
676 return blf_str_offset_from_cursor_position(font, str, str_len, location_x);
677 }
678 return 0;
679}
680
682 const char *str,
683 size_t str_offset,
684 rcti *r_glyph_bounds)
685{
686 FontBLF *font = blf_get(fontid);
687 if (font) {
688 blf_str_offset_to_glyph_bounds(font, str, str_offset, r_glyph_bounds);
689 return true;
690 }
691 return false;
692}
693
695 const char *str,
696 const size_t str_len,
697 const size_t str_offset,
698 const int cursor_width)
699{
700 FontBLF *font = blf_get(fontid);
701 if (font) {
702 return blf_str_offset_to_cursor(font, str, str_len, str_offset, cursor_width);
703 }
704 return 0;
705}
706
708 int fontid, const char *str, size_t str_len, size_t sel_start, size_t sel_length)
709{
710 FontBLF *font = blf_get(fontid);
711 if (font) {
712 return blf_str_selection_boxes(font, str, str_len, sel_start, sel_length);
713 }
714 return {};
715}
716
718 int fontid, const char *str, const size_t str_len, float width, float *r_width)
719{
720 FontBLF *font = blf_get(fontid);
721
722 if (font) {
723 const float xa = (font->flags & BLF_ASPECT) ? font->aspect[0] : 1.0f;
724 size_t ret;
725 int width_result;
726 ret = blf_font_width_to_strlen(font, str, str_len, width / xa, &width_result);
727 if (r_width) {
728 *r_width = float(width_result) * xa;
729 }
730 return ret;
731 }
732
733 if (r_width) {
734 *r_width = 0.0f;
735 }
736 return 0;
737}
738
740 int fontid, const char *str, const size_t str_len, float width, float *r_width)
741{
742 FontBLF *font = blf_get(fontid);
743
744 if (font) {
745 const float xa = (font->flags & BLF_ASPECT) ? font->aspect[0] : 1.0f;
746 size_t ret;
747 int width_result;
748 ret = blf_font_width_to_rstrlen(font, str, str_len, width / xa, &width_result);
749 if (r_width) {
750 *r_width = float(width_result) * xa;
751 }
752 return ret;
753 }
754
755 if (r_width) {
756 *r_width = 0.0f;
757 }
758 return 0;
759}
760
762 int fontid, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
763{
764 FontBLF *font = blf_get(fontid);
765
766 BLF_RESULT_CHECK_INIT(r_info);
767
768 if (font) {
769 if (font->flags & BLF_WORD_WRAP) {
770 blf_font_boundbox__wrap(font, str, str_len, r_box, r_info);
771 }
772 else {
773 blf_font_boundbox(font, str, str_len, r_box, r_info);
774 }
775 }
776}
777
779 int fontid, const char *str, const size_t str_len, float *r_width, float *r_height)
780{
781 FontBLF *font = blf_get(fontid);
782
783 if (font) {
784 blf_font_width_and_height(font, str, str_len, r_width, r_height, nullptr);
785 }
786 else {
787 *r_width = *r_height = 0.0f;
788 }
789}
790
791float BLF_width(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
792{
793 FontBLF *font = blf_get(fontid);
794
795 BLF_RESULT_CHECK_INIT(r_info);
796
797 if (font) {
798 return blf_font_width(font, str, str_len, r_info);
799 }
800
801 return 0.0f;
802}
803
804float BLF_fixed_width(int fontid)
805{
806 FontBLF *font = blf_get(fontid);
807
808 if (font) {
809 return blf_font_fixed_width(font);
810 }
811
812 return 0.0f;
813}
814
815float BLF_height(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
816{
817 FontBLF *font = blf_get(fontid);
818
819 BLF_RESULT_CHECK_INIT(r_info);
820
821 if (font) {
822 return blf_font_height(font, str, str_len, r_info);
823 }
824
825 return 0.0f;
826}
827
828int BLF_height_max(int fontid)
829{
830 FontBLF *font = blf_get(fontid);
831
832 if (font) {
833 return blf_font_height_max(font);
834 }
835
836 return 0;
837}
838
839int BLF_width_max(int fontid)
840{
841 FontBLF *font = blf_get(fontid);
842
843 if (font) {
844 return blf_font_width_max(font);
845 }
846
847 return 0;
848}
849
850int BLF_descender(int fontid)
851{
852 FontBLF *font = blf_get(fontid);
853
854 if (font) {
855 return blf_font_descender(font);
856 }
857
858 return 0;
859}
860
861int BLF_ascender(int fontid)
862{
863 FontBLF *font = blf_get(fontid);
864
865 if (font) {
866 return blf_font_ascender(font);
867 }
868
869 return 0.0f;
870}
871
872void BLF_rotation(int fontid, float angle)
873{
874 FontBLF *font = blf_get(fontid);
875
876 if (font) {
877 font->angle = angle;
878 }
879}
880
881void BLF_clipping(int fontid, int xmin, int ymin, int xmax, int ymax)
882{
883 FontBLF *font = blf_get(fontid);
884
885 if (font) {
886 font->clip_rec.xmin = xmin;
887 font->clip_rec.ymin = ymin;
888 font->clip_rec.xmax = xmax;
889 font->clip_rec.ymax = ymax;
890 }
891}
892
893void BLF_wordwrap(int fontid, int wrap_width)
894{
895 FontBLF *font = blf_get(fontid);
896
897 if (font) {
898 font->wrap_width = wrap_width;
899 }
900}
901
902void BLF_shadow(int fontid, FontShadowType type, const float rgba[4])
903{
904 FontBLF *font = blf_get(fontid);
905
906 if (font) {
907 font->shadow = type;
908 if (rgba) {
910 }
911 }
912}
913
914void BLF_shadow_offset(int fontid, int x, int y)
915{
916 FontBLF *font = blf_get(fontid);
917
918 if (font) {
919 font->shadow_x = x;
920 font->shadow_y = y;
921 }
922}
923
924void BLF_buffer(int fontid, float *fbuf, uchar *cbuf, int w, int h, ColorManagedDisplay *display)
925{
926 FontBLF *font = blf_get(fontid);
927
928 if (font) {
929 font->buf_info.fbuf = fbuf;
930 font->buf_info.cbuf = cbuf;
931 font->buf_info.dims[0] = w;
932 font->buf_info.dims[1] = h;
933 font->buf_info.display = display;
934 }
935}
936
937void BLF_buffer_col(int fontid, const float rgba[4])
938{
939 FontBLF *font = blf_get(fontid);
940
941 if (font) {
942 copy_v4_v4(font->buf_info.col_init, rgba);
943 }
944}
945
947{
948 FontBufInfoBLF *buf_info = &font->buf_info;
949
950 rgba_float_to_uchar(buf_info->col_char, buf_info->col_init);
951
952 if (buf_info->display) {
953 copy_v4_v4(buf_info->col_float, buf_info->col_init);
955 }
956 else {
957 srgb_to_linearrgb_v4(buf_info->col_float, buf_info->col_init);
958 }
959}
961
962void BLF_draw_buffer(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
963{
964 FontBLF *font = blf_get(fontid);
965
966 if (font && (font->buf_info.fbuf || font->buf_info.cbuf)) {
968 if (font->flags & BLF_WORD_WRAP) {
969 blf_font_draw_buffer__wrap(font, str, str_len, r_info);
970 }
971 else {
972 blf_font_draw_buffer(font, str, str_len, r_info);
973 }
975 }
976}
977
980 const int max_pixel_width)
981{
982 FontBLF *font = blf_get(fontid);
983 if (!font) {
984 return {};
985 }
986 return blf_font_string_wrap(font, str, max_pixel_width);
987}
988
989char *BLF_display_name_from_file(const char *filepath)
990{
991 /* While listing font directories this function can be called simultaneously from a greater
992 * number of threads than we want the FreeType cache to keep open at a time. Therefore open
993 * with a separate FT_Library object and use FreeType calls directly to avoid any contention. */
994 char *name = nullptr;
995 FT_Library ft_library;
996 if (FT_Init_FreeType(&ft_library) == FT_Err_Ok) {
997 FT_Face face;
998 if (FT_New_Face(ft_library, filepath, 0, &face) == FT_Err_Ok) {
999 if (face->family_name) {
1000 name = BLI_sprintfN("%s %s", face->family_name, face->style_name);
1001 }
1002 FT_Done_Face(face);
1003 }
1004 FT_Done_FreeType(ft_library);
1005 }
1006 return name;
1007}
1008
1010{
1011 FontBLF *font = blf_get(fontid);
1012 if (!font) {
1013 return nullptr;
1014 }
1015
1016 return blf_display_name(font);
1017}
1018
1019bool BLF_get_vfont_metrics(int fontid, float *ascend_ratio, float *em_ratio, float *scale)
1020{
1021 FontBLF *font = blf_get(fontid);
1022 if (!font) {
1023 return false;
1024 }
1025
1026 if (!blf_ensure_face(font)) {
1027 return false;
1028 }
1029
1030 /* Copied without change from vfontdata_freetype.cc to ensure consistent sizing. */
1031
1032 /* Blender default BFont is not "complete". */
1033 const bool complete_font = (font->face->ascender != 0) && (font->face->descender != 0) &&
1034 (font->face->ascender != font->face->descender);
1035
1036 if (complete_font) {
1037 /* We can get descender as well, but we simple store descender in relation to the ascender.
1038 * Also note that descender is stored as a negative number. */
1039 *ascend_ratio = float(font->face->ascender) / (font->face->ascender - font->face->descender);
1040 }
1041 else {
1042 *ascend_ratio = 0.8f;
1043 *em_ratio = 1.0f;
1044 }
1045
1046 /* Adjust font size */
1047 if (font->face->bbox.yMax != font->face->bbox.yMin) {
1048 *scale = float(1.0 / double(font->face->bbox.yMax - font->face->bbox.yMin));
1049
1050 if (complete_font) {
1051 *em_ratio = float(font->face->ascender - font->face->descender) /
1052 (font->face->bbox.yMax - font->face->bbox.yMin);
1053 }
1054 }
1055 else {
1056 *scale = 1.0f / 1000.0f;
1057 }
1058
1059 return true;
1060}
1061
1062float BLF_character_to_curves(int fontid, uint unicode, ListBase *nurbsbase, const float scale)
1063{
1064 FontBLF *font = blf_get(fontid);
1065 if (!font) {
1066 return 0.0f;
1067 }
1068 return blf_character_to_curves(font, unicode, nurbsbase, scale);
1069}
1070
1071#ifndef NDEBUG
1072void BLF_state_print(int fontid)
1073{
1074 FontBLF *font = blf_get(fontid);
1075 if (font) {
1076 printf("fontid %d %p\n", fontid, (void *)font);
1077 printf(" mem_name: '%s'\n", font->mem_name ? font->mem_name : "<none>");
1078 printf(" filepath: '%s'\n", font->filepath ? font->filepath : "<none>");
1079 printf(" size: %f\n", font->size);
1080 printf(" pos: %d %d %d\n", UNPACK3(font->pos));
1081 printf(" aspect: (%d) %.6f %.6f %.6f\n",
1082 (font->flags & BLF_ROTATION) != 0,
1083 UNPACK3(font->aspect));
1084 printf(" angle: (%d) %.6f\n", (font->flags & BLF_ASPECT) != 0, font->angle);
1085 printf(" flag: %d\n", font->flags);
1086 }
1087 else {
1088 printf("fontid %d (nullptr)\n", fontid);
1089 }
1090 fflush(stdout);
1091}
1092#endif
@ BLF_ROTATION
Definition BLF_api.hh:361
@ BLF_WORD_WRAP
Definition BLF_api.hh:367
@ BLF_ASPECT
Definition BLF_api.hh:366
@ BLF_DEFAULT
Definition BLF_api.hh:378
void BLF_default_set(int fontid)
int blf_mono_font_render
Definition blf.cc:52
int BLF_default()
int blf_mono_font
Definition blf.cc:51
bool(* BLF_GlyphBoundsFn)(const char *str, size_t str_step_ofs, const rcti *bounds, void *user_data)
Definition BLF_api.hh:167
FontShadowType
Definition BLF_api.hh:33
#define BLI_assert(a)
Definition BLI_assert.h:50
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:350
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:349
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:125
void IMB_colormanagement_display_to_scene_linear_v3(float pixel[3], ColorManagedDisplay *display)
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
void BLF_color3ubv(int fontid, const uchar rgb[3])
Definition blf.cc:459
size_t BLF_width_to_rstrlen(int fontid, const char *str, const size_t str_len, float width, float *r_width)
Definition blf.cc:739
void BLF_state_print(int fontid)
Definition blf.cc:1072
static int blf_search_available()
Definition blf.cc:144
void BLF_color4ub(int fontid, uchar r, uchar g, uchar b, uchar alpha)
Definition blf.cc:464
void BLF_color4ubv(int fontid, const uchar rgba[4])
Definition blf.cc:435
int BLF_load(const char *filepath)
Definition blf.cc:174
void BLF_size(int fontid, float size)
Definition blf.cc:426
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:612
int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth, int tab_columns)
Definition blf.cc:594
void BLF_reset_fonts()
Definition blf.cc:84
void BLF_aspect(int fontid, float x, float y, float z)
Definition blf.cc:360
void blf_draw_buffer__start(FontBLF *font)
Definition blf.cc:946
void BLF_unload_all()
Definition blf.cc:298
bool BLF_has_glyph(int fontid, uint unicode)
Definition blf.cc:155
static FontBLF * blf_get(int fontid)
Definition blf.cc:54
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:707
float BLF_width(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:791
bool BLF_is_loaded(const char *filepath)
Definition blf.cc:164
void BLF_clipping(int fontid, int xmin, int ymin, int xmax, int ymax)
Definition blf.cc:881
size_t BLF_width_to_strlen(int fontid, const char *str, const size_t str_len, float width, float *r_width)
Definition blf.cc:717
void BLF_boundbox(int fontid, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
Definition blf.cc:761
void BLF_draw_buffer(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:962
blender::Vector< blender::StringRef > BLF_string_wrap(int fontid, blender::StringRef str, const int max_pixel_width)
Definition blf.cc:978
void BLF_color3ub(int fontid, uchar r, uchar g, uchar b)
Definition blf.cc:476
void BLF_unload(const char *filepath)
Definition blf.cc:264
void BLF_color3ubv_alpha(int fontid, const uchar rgb[3], uchar alpha)
Definition blf.cc:447
void BLF_color3f(int fontid, float r, float g, float b)
Definition blf.cc:511
float BLF_fixed_width(int fontid)
Definition blf.cc:804
char * BLF_display_name_from_id(int fontid)
Definition blf.cc:1009
void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha)
Definition blf.cc:503
void BLF_color4fv(int fontid, const float rgba[4])
Definition blf.cc:488
#define BLF_RESULT_CHECK_INIT(r_info)
Definition blf.cc:41
bool blf_font_id_is_valid(int fontid)
Definition blf.cc:109
static int blf_search_by_filepath(const char *filepath)
Definition blf.cc:129
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:694
char * BLF_display_name_from_file(const char *filepath)
Definition blf.cc:989
bool BLF_get_vfont_metrics(int fontid, float *ascend_ratio, float *em_ratio, float *scale)
Definition blf.cc:1019
void BLF_shadow_offset(int fontid, int x, int y)
Definition blf.cc:914
static void blf_draw_gpu__end(const FontBLF *font)
Definition blf.cc:561
int BLF_width_max(int fontid)
Definition blf.cc:839
int BLF_ascender(int fontid)
Definition blf.cc:861
void BLF_batch_draw_begin()
Definition blf.cc:517
int BLF_load_mem_unique(const char *name, const uchar *mem, int mem_size)
Definition blf.cc:236
void BLF_buffer(int fontid, float *fbuf, uchar *cbuf, int w, int h, ColorManagedDisplay *display)
Definition blf.cc:924
void BLF_boundbox_foreach_glyph(int fontid, const char *str, size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data)
Definition blf.cc:653
void BLF_disable(int fontid, int option)
Definition blf.cc:321
void BLF_rotation(int fontid, float angle)
Definition blf.cc:872
void BLF_metrics_attach(const int fontid, const uchar *mem, const int mem_size)
Definition blf.cc:217
void BLF_buffer_col(int fontid, const float rgba[4])
Definition blf.cc:937
void BLF_batch_draw_end()
Definition blf.cc:530
static void blf_draw_gpu__start(const FontBLF *font)
Definition blf.cc:537
static int blf_search_by_mem_name(const char *mem_name)
Definition blf.cc:114
size_t BLF_str_offset_from_cursor_position(int fontid, const char *str, size_t str_len, int location_x)
Definition blf.cc:669
int BLF_descender(int fontid)
Definition blf.cc:850
void BLF_unload_id(int fontid)
Definition blf.cc:284
FontBLF * global_font[BLF_MAX_FONT]
Definition blf.cc:47
void BLF_exit()
Definition blf.cc:71
void BLF_cache_clear()
Definition blf.cc:99
int BLF_default_weight(int fontid)
Definition blf.cc:338
void BLF_draw(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:568
void BLF_batch_draw_flush()
Definition blf.cc:523
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:635
void BLF_enable(int fontid, int option)
Definition blf.cc:312
void BLF_shadow(int fontid, FontShadowType type, const float rgba[4])
Definition blf.cc:902
void BLF_width_and_height(int fontid, const char *str, const size_t str_len, float *r_width, float *r_height)
Definition blf.cc:778
bool BLF_is_loaded_mem(const char *name)
Definition blf.cc:169
bool BLF_str_offset_to_glyph_bounds(int fontid, const char *str, size_t str_offset, rcti *r_glyph_bounds)
Definition blf.cc:681
int BLF_load_unique(const char *filepath)
Definition blf.cc:187
int BLF_init()
Definition blf.cc:62
void BLF_color4f(int fontid, float r, float g, float b, float a)
Definition blf.cc:497
bool BLF_has_variable_weight(int fontid)
Definition blf.cc:347
void blf_draw_buffer__end()
Definition blf.cc:960
void BLF_character_weight(int fontid, int weight)
Definition blf.cc:330
float BLF_character_to_curves(int fontid, uint unicode, ListBase *nurbsbase, const float scale)
Definition blf.cc:1062
int BLF_height_max(int fontid)
Definition blf.cc:828
void BLF_wordwrap(int fontid, int wrap_width)
Definition blf.cc:893
void BLF_position(int fontid, float x, float y, float z)
Definition blf.cc:371
float BLF_height(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf.cc:815
int BLF_load_mem(const char *name, const uchar *mem, int mem_size)
Definition blf.cc:226
size_t blf_str_offset_from_cursor_position(FontBLF *font, const char *str, size_t str_len, int location_x)
Definition blf_font.cc:1105
void blf_str_offset_to_glyph_bounds(FontBLF *font, const char *str, size_t str_offset, rcti *r_glyph_bounds)
Definition blf_font.cc:1155
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:846
int blf_font_ascender(FontBLF *font)
Definition blf_font.cc:1469
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:528
float blf_font_width(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:994
bool blf_ensure_face(FontBLF *font)
Definition blf_font.cc:1781
blender::Vector< blender::StringRef > blf_font_string_wrap(FontBLF *font, blender::StringRef str, int max_pixel_width)
Definition blf_font.cc:1418
void blf_font_draw_buffer(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:766
int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, int cwidth, int tab_columns)
Definition blf_font.cc:492
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:574
void blf_font_free(FontBLF *font)
Definition blf_font.cc:2007
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:1044
bool blf_font_size(FontBLF *font, float size)
Definition blf_font.cc:2068
float blf_font_fixed_width(FontBLF *font)
Definition blf_font.cc:1036
float blf_font_height(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:1015
int blf_font_init()
Definition blf_font.cc:1489
int blf_font_width_max(FontBLF *font)
Definition blf_font.cc:1458
void blf_batch_draw()
Definition blf_font.cc:325
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:1373
void blf_font_exit()
Definition blf_font.cc:1511
void blf_font_boundbox(FontBLF *font, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
Definition blf_font.cc:957
uint blf_get_char_index(FontBLF *font, uint charcode)
Definition blf_font.cc:149
char * blf_display_name(FontBLF *font)
Definition blf_font.cc:1475
FontBLF * blf_font_new_from_mem(const char *mem_name, const uchar *mem, const size_t mem_size)
Definition blf_font.cc:1990
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:1168
void blf_font_attach_from_mem(FontBLF *font, const uchar *mem, const size_t mem_size)
Definition blf_font.cc:1995
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:817
int blf_font_descender(FontBLF *font)
Definition blf_font.cc:1463
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:965
void blf_font_draw(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:485
FontBLF * blf_font_new_from_filepath(const char *filepath)
Definition blf_font.cc:1985
void blf_font_draw_buffer__wrap(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:1395
int blf_font_height_max(FontBLF *font)
Definition blf_font.cc:1446
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:1213
void blf_font_draw__wrap(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
Definition blf_font.cc:1353
void blf_glyph_cache_clear(FontBLF *font)
Definition blf_glyph.cc:164
float blf_character_to_curves(FontBLF *font, uint unicode, ListBase *nurbsbase, const float scale)
#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
local_group_size(16, 16) .push_constant(Type b
#define printf
#define floorf(x)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
#define str(s)
return ret
unsigned char color[4]
FT_MM_Var * variations
FontMetrics metrics
unsigned int reference_count
FontBufInfoBLF buf_info
FontShadowType shadow
unsigned char shadow_color[4]
ColorManagedDisplay * display
unsigned char col_char[4]
unsigned char * cbuf
int ymin
int ymax
int xmin
int xmax