35 #include FT_FREETYPE_H
63 # define FT_New_Face FT_New_Face__win32_compat
153 if (mat_changed || font_changed || shader_changed) {
187 int remain = gc->
bitmap_len - bitmap_len_landed;
188 int offset_x = bitmap_len_landed % tex_width;
189 int offset_y = bitmap_len_landed / tex_width;
193 int remain_row = tex_width - offset_x;
194 int width = remain > remain_row ? remain_row : remain;
205 bitmap_len_landed +=
width;
225 #ifndef BLF_STANDALONE
266 return FT_Init_FreeType(&
ft_lib);
293 err = FT_Set_Char_Size(font->
face, 0, ((FT_F26Dot6)(
size)) * 64, dpi, dpi);
296 printf(
"The current font don't support the size, %u and dpi, %u\n",
size, dpi);
318 if (glyph_ascii_table[
'0'] ==
NULL) {
320 for (
uint i = 0; i < 256; i++) {
323 FT_UInt glyph_index = FT_Get_Char_Index(font->
face, i);
326 glyph_ascii_table[i] = g;
330 return glyph_ascii_table;
335 const FT_UInt kern_mode)
341 if (!kc || kc->
mode != kern_mode) {
357 #define BLF_UTF8_NEXT_FAST(_font, _gc, _g, _str, _i, _c, _glyph_ascii_table) \
358 if (((_c) = (_str)[_i]) < 0x80) { \
359 _g = (_glyph_ascii_table)[_c]; \
362 else if ((_c = BLI_str_utf8_as_unicode_step(_str, &(_i))) != BLI_UTF8_ERR) { \
363 if ((_g = blf_glyph_search(_gc, _c)) == NULL) { \
364 _g = blf_glyph_add(_font, _gc, FT_Get_Char_Index((_font)->face, _c), _c); \
372 #define BLF_KERNING_VARS(_font, _has_kerning, _kern_mode) \
373 const bool _has_kerning = FT_HAS_KERNING((_font)->face) != 0; \
374 const FT_UInt _kern_mode = (_has_kerning == 0) ? 0 : \
375 (((_font)->flags & BLF_KERNING_DEFAULT) ? \
376 ft_kerning_default : \
377 (FT_UInt)FT_KERNING_UNFITTED)
382 #define BLF_KERNING_STEP_FAST(_font, _kern_mode, _g_prev, _g, _c_prev, _c, _pen_x) \
386 if (_c_prev < 0x80 && _c < 0x80) { \
387 _pen_x += (_font)->kerning_cache->table[_c][_c_prev]; \
389 else if (FT_Get_Kerning((_font)->face, (_g_prev)->idx, (_g)->idx, _kern_mode, &(_delta)) == \
391 _pen_x += (int)_delta.x >> 6; \
397 #define BLF_KERNING_STEP(_font, _kern_mode, _g_prev, _g, _delta, _pen_x) \
400 _delta.x = _delta.y = 0; \
401 if (FT_Get_Kerning((_font)->face, (_g_prev)->idx, (_g)->idx, _kern_mode, &(_delta)) == 0) { \
402 _pen_x += (int)_delta.x >> 6; \
433 while ((i <
len) &&
str[i]) {
458 r_info->
width = pen_x;
485 while ((
c = *(
str++)) &&
len--) {
487 if ((g = glyph_ascii_table[
c]) ==
NULL) {
506 r_info->
width = pen_x;
522 int col, columns = 0;
523 int pen_x = 0, pen_y = 0;
531 while ((i <
len) &&
str[i]) {
550 pen_x += cwidth *
col;
569 int pen_x = (int)font->
pos[0];
570 int pen_y_basis = (
int)font->
pos[1] + pen_y;
577 const float *b_col_float = buf_info->
col_float;
578 const unsigned char *b_col_char = buf_info->
col_char;
588 while ((i <
len) &&
str[i]) {
601 chx = pen_x + ((int)g->
pos[0]);
602 chy = pen_y_basis + g->
dims[1];
605 pen_y = pen_y_basis + (g->
dims[1] - g->
pos[1]);
608 pen_y = pen_y_basis - (g->
dims[1] - g->
pos[1]);
611 if ((chx + g->
dims[0]) >= 0 && chx < buf_info->
dims[0] && (pen_y + g->
dims[1]) >= 0 &&
612 pen_y < buf_info->dims[1]) {
614 int width_clip = g->
dims[0];
615 int height_clip = g->
dims[1];
616 int yb_start = g->
pitch < 0 ? 0 : g->
dims[1] - 1;
618 if (width_clip + chx > buf_info->
dims[0]) {
619 width_clip -= chx + width_clip - buf_info->
dims[0];
621 if (height_clip + pen_y > buf_info->
dims[1]) {
622 height_clip -= pen_y + height_clip - buf_info->
dims[1];
627 yb_start += (g->
pitch < 0) ? -pen_y : pen_y;
628 height_clip += pen_y;
632 if (buf_info->
fbuf) {
634 for (
y = ((chy >= 0) ? 0 : -chy);
y < height_clip;
y++) {
635 for (
x = ((chx >= 0) ? 0 : -chx);
x < width_clip;
x++) {
638 const float a = (a_byte / 255.0f) * b_col_float[3];
639 const size_t buf_ofs = (((size_t)(chx +
x) +
640 ((size_t)(pen_y +
y) * (size_t)buf_info->
dims[0])) *
641 (
size_t)buf_info->
ch);
642 float *fbuf = buf_info->
fbuf + buf_ofs;
645 font_pixel[0] = b_col_float[0] *
a;
646 font_pixel[1] = b_col_float[1] *
a;
647 font_pixel[2] = b_col_float[2] *
a;
662 if (buf_info->
cbuf) {
664 for (
y = ((chy >= 0) ? 0 : -chy);
y < height_clip;
y++) {
665 for (
x = ((chx >= 0) ? 0 : -chx);
x < width_clip;
x++) {
669 const float a = (a_byte / 255.0f) * b_col_float[3];
670 const size_t buf_ofs = (((size_t)(chx +
x) +
671 ((size_t)(pen_y +
y) * (size_t)buf_info->
dims[0])) *
672 (
size_t)buf_info->
ch);
673 unsigned char *cbuf = buf_info->
cbuf + buf_ofs;
676 font_pixel[0] = b_col_char[0];
677 font_pixel[1] = b_col_char[1];
678 font_pixel[2] = b_col_char[2];
701 r_info->
width = pen_x;
713 const bool has_kerning,
714 const FT_UInt kern_mode,
734 return (*pen_x >= width_i);
742 int pen_x, width_new;
747 const int width_i = (int)
width;
755 for (i_prev = i = 0, width_new = pen_x = 0, g_prev =
NULL, c_prev = 0; (i <
len) &&
str[i];
756 i_prev = i, width_new = pen_x, c_prev =
c, g_prev = g) {
760 font, has_kerning, kern_mode, c_prev,
c, g_prev, g, &pen_x, width_i)) {
766 *r_width = (
float)width_new;
778 int pen_x, width_new;
779 size_t i, i_prev, i_tmp;
784 const int width_i = (int)
width;
794 i = (size_t)((s !=
NULL) ? s -
str : 0);
796 i_prev = (size_t)((s_prev !=
NULL) ? s_prev -
str : 0);
800 for (width_new = pen_x = 0; (s !=
NULL);
801 i = i_prev, s = s_prev,
c = c_prev, g = g_prev, g_prev =
NULL, width_new = pen_x) {
803 i_prev = (size_t)((s_prev !=
NULL) ? s_prev -
str : 0);
805 if (s_prev !=
NULL) {
812 font, has_kerning, kern_mode, c_prev,
c, g_prev, g, &pen_x, width_i)) {
818 *r_width = (
float)width_new;
844 box->
xmin = 32000.0f;
845 box->
xmax = -32000.0f;
846 box->
ymin = 32000.0f;
847 box->
ymax = -32000.0f;
851 while ((i <
len) &&
str[i]) {
897 r_info->
width = pen_x;
936 int pen_x = 0, pen_y = 0;
946 struct WordWrapVars {
948 size_t start, last[2];
952 while ((i <
len) &&
str[i]) {
956 bool do_draw =
false;
984 wrap.last[0] = i + ((g->
c !=
'\n') ? 1 : 0);
989 wrap.last[0] = i_curr + 1;
993 else if (
UNLIKELY(g->
c !=
' ' && (g_prev ? g_prev->
c ==
' ' :
false))) {
994 wrap.last[0] = i_curr;
995 wrap.last[1] = i_curr;
1019 r_info->
lines = lines;
1021 r_info->
width = pen_x_next;
1046 rctf *box = userdata;
1055 box->
xmin = 32000.0f;
1056 box->
xmax = -32000.0f;
1057 box->
ymin = 32000.0f;
1058 box->
ymax = -32000.0f;
1156 const unsigned int c =
' ';
1192 size_t i = 0, i_curr;
1206 while ((i <
len) &&
str[i]) {
1237 r_info->
width = pen_x;
1266 if ((
c =
str[i]) < 0x80) {
1270 if (FT_Get_Char_Index((font)->face,
c) == 0) {
1290 FT_Done_Face(font->
face);
1307 font->
pos[0] = 0.0f;
1308 font->
pos[1] = 0.0f;
1311 for (
int i = 0; i < 16; i++) {
1316 font->
color[0] = 255;
1317 font->
color[1] = 255;
1319 font->
color[3] = 255;
1364 err = FT_Select_Charmap(font->
face, ft_encoding_unicode);
1366 printf(
"Can't set the unicode character map!\n");
1367 FT_Done_Face(font->
face);
1374 err = FT_Attach_File(font->
face, mfile);
1376 fprintf(stderr,
"FT_Attach_File failed to load '%s' with error %d\n", filename, (
int)
err);
1391 open.flags = FT_OPEN_MEMORY;
1392 open.memory_base = (
const FT_Byte *)mem;
1393 open.memory_size = mem_size;
1394 FT_Attach_Stream(font->
face, &open);
1403 err = FT_New_Memory_Face(
ft_lib, mem, mem_size, 0, &font->
face);
1409 err = FT_Select_Charmap(font->
face, ft_encoding_unicode);
1411 printf(
"Can't set the unicode character map!\n");
1412 FT_Done_Face(font->
face);
typedef float(TangentPoint)[2]
bool(* BLF_GlyphBoundsFn)(const char *str, const size_t str_step_ofs, const struct rcti *glyph_step_bounds, const int glyph_advance_x, const struct rctf *glyph_bounds, const int glyph_bearing[2], void *user_data)
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_mix_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void zero_v2(float r[2])
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
void BLI_rctf_union(struct rctf *rct1, const struct rctf *rct2)
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
size_t BLI_strnlen(const char *str, const size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_wcwidth(char32_t ucs)
char * BLI_str_find_prev_char_utf8(const char *str, const char *p) ATTR_NONNULL()
unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index) ATTR_NONNULL()
pthread_spinlock_t SpinLock
void BLI_spin_init(SpinLock *spin)
void BLI_spin_unlock(SpinLock *spin)
void BLI_spin_lock(SpinLock *spin)
void BLI_spin_end(SpinLock *spin)
#define GPU_batch_texture_bind(batch, name, tex)
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
#define GPU_BATCH_DISCARD_SAFE(batch)
void GPU_batch_instbuf_set(GPUBatch *, GPUVertBuf *, bool own_vbo)
GPUBatch * GPU_batch_create_ex(GPUPrimType prim, GPUVertBuf *vert, GPUIndexBuf *elem, eGPUBatchFlag owns_flag)
void GPU_batch_draw(GPUBatch *batch)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
void GPU_matrix_pop(void)
#define GPU_matrix_model_view_get(x)
#define GPU_matrix_set(x)
void GPU_matrix_push(void)
void GPU_blend(eGPUBlend blend)
void GPU_texture_update_sub(GPUTexture *tex, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
struct GPUTexture GPUTexture
int GPU_texture_width(const GPUTexture *tex)
void GPU_texture_unbind(GPUTexture *tex)
#define GPU_vertbuf_create_with_format(format)
struct GPUVertBuf GPUVertBuf
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len)
void GPU_vertbuf_use(GPUVertBuf *)
GPUVertBuf * GPU_vertbuf_create_with_format_ex(const GPUVertFormat *, GPUUsageType)
void GPU_vertbuf_data_len_set(GPUVertBuf *, uint v_len)
void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *, uint a_idx, GPUVertBufRaw *access)
Read Guarded memory(de)allocation.
void UI_widgetbase_draw_cache_flush(void)
char * blf_dir_metrics_search(const char *filename)
float blf_font_ascender(FontBLF *font)
void blf_font_draw_buffer(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
static bool blf_font_width_to_strlen_glyph_process(FontBLF *font, const bool has_kerning, const FT_UInt kern_mode, const uint c_prev, const uint c, GlyphBLF *g_prev, GlyphBLF *g, int *pen_x, const int width_i)
FontBLF * blf_font_new(const char *name, const char *filename)
static void blf_font_ensure_ascii_kerning(FontBLF *font, GlyphCacheBLF *gc, const FT_UInt kern_mode)
#define BLF_KERNING_STEP(_font, _kern_mode, _g_prev, _g, _delta, _pen_x)
void blf_batch_draw(void)
static void blf_font_fill(FontBLF *font)
static GPUTexture * blf_batch_cache_texture_load(void)
static SpinLock ft_lib_mutex
static void blf_font_draw_ex(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
void blf_font_width_and_height(FontBLF *font, const char *str, size_t len, float *r_width, float *r_height, struct ResultBLF *r_info)
void blf_font_boundbox_foreach_glyph(FontBLF *font, const char *str, size_t len, BLF_GlyphBoundsFn user_fn, void *user_data, struct ResultBLF *r_info)
void blf_font_boundbox(FontBLF *font, const char *str, size_t len, rctf *r_box, struct ResultBLF *r_info)
static void blf_font_draw_buffer_ex(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
static void blf_font_wrap_apply(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info, void(*callback)(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, int pen_y, void *userdata), void *userdata)
static void blf_font_draw__wrap_cb(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, int pen_y, void *UNUSED(userdata))
size_t blf_font_width_to_rstrlen(FontBLF *font, const char *str, size_t len, float width, float *r_width)
void blf_font_free(FontBLF *font)
int blf_font_count_missing_chars(FontBLF *font, const char *str, const size_t len, int *r_tot_chars)
FontBLF * blf_font_new_from_mem(const char *name, const unsigned char *mem, int mem_size)
void blf_font_draw_ascii(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
float blf_font_fixed_width(FontBLF *font)
#define BLF_KERNING_STEP_FAST(_font, _kern_mode, _g_prev, _g, _c_prev, _c, _pen_x)
static void blf_font_draw_ascii_ex(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
static void blf_batch_draw_end(void)
size_t blf_font_width_to_strlen(FontBLF *font, const char *str, size_t len, float width, float *r_width)
void blf_font_boundbox__wrap(FontBLF *font, const char *str, size_t len, rctf *box, struct ResultBLF *r_info)
int blf_font_width_max(FontBLF *font)
int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
void blf_font_attach_from_mem(FontBLF *font, const unsigned char *mem, int mem_size)
static GlyphBLF ** blf_font_ensure_ascii_table(FontBLF *font, GlyphCacheBLF *gc)
static void blf_batch_draw_exit(void)
void blf_batch_draw_begin(FontBLF *font)
static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, BLF_GlyphBoundsFn user_fn, void *user_data, struct ResultBLF *r_info, int pen_y)
static void blf_font_boundbox_ex(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, rctf *box, struct ResultBLF *r_info, int pen_y)
float blf_font_width(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
#define BLF_KERNING_VARS(_font, _has_kerning, _kern_mode)
float blf_font_descender(FontBLF *font)
#define BLF_UTF8_NEXT_FAST(_font, _gc, _g, _str, _i, _c, _glyph_ascii_table)
static SpinLock blf_glyph_cache_mutex
static void blf_font_boundbox_wrap_cb(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, int pen_y, void *userdata)
static void blf_batch_draw_init(void)
static void blf_font_draw_buffer__wrap_cb(FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, int pen_y, void *UNUSED(userdata))
float blf_font_height(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
void blf_font_draw(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
int blf_font_height_max(FontBLF *font)
void blf_font_draw_buffer__wrap(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
void blf_font_draw__wrap(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
GlyphBLF * blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, unsigned int c)
void blf_kerning_cache_clear(FontBLF *font)
GlyphCacheBLF * blf_glyph_cache_find(FontBLF *font, unsigned int size, unsigned int dpi)
KerningCacheBLF * blf_kerning_cache_new(FontBLF *font, GlyphCacheBLF *gc)
void blf_glyph_cache_free(GlyphCacheBLF *gc)
void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, float y)
void blf_glyph_cache_release(FontBLF *font)
GlyphBLF * blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
GlyphCacheBLF * blf_glyph_cache_acquire(FontBLF *font)
GlyphCacheBLF * blf_glyph_cache_new(FontBLF *font)
KerningCacheBLF * blf_kerning_cache_find(FontBLF *font)
#define BLF_BATCH_DRAW_LEN_MAX
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
DEGForeachIDComponentCallback callback
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
static GPUContext * wrap(Context *ctx)
struct GPUVertBuf * verts
struct GPUVertBufRaw pos_step col_step offset_step glyph_size_step
struct GlyphCacheBLF * glyph_cache
unsigned int glyph_size_loc
KerningCacheBLF * kerning_cache
SpinLock * glyph_cache_mutex
unsigned char col_char[4]
struct GlyphBLF * glyph_ascii_table[256]
int wrap_width(const struct SpaceText *st, struct ARegion *region)