WIP: UI: Refactor blf_glyph for C++ Features #117794
|
@ -101,7 +101,7 @@ void BLF_cache_clear()
|
|||
for (int i = 0; i < BLF_MAX_FONT; i++) {
|
||||
FontBLF *font = global_font[i];
|
||||
if (font) {
|
||||
blf_glyph_cache_clear(font);
|
||||
font->cache->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -420,7 +420,7 @@ BLI_INLINE GlyphBLF *blf_glyph_from_utf8_and_step(FontBLF *font,
|
|||
/* Invalid unicode sequences return the byte value, stepping forward one.
|
||||
* This allows `latin1` to display (which is sometimes used for file-paths). */
|
||||
BLI_assert(charcode != BLI_UTF8_ERR);
|
||||
GlyphBLF *g = blf_glyph_ensure(font, gc, charcode);
|
||||
GlyphBLF *g = GlyphBLF::glyph_ensure(font, gc, charcode);
|
||||
if (g && pen_x && !(font->flags & BLF_MONOSPACED)) {
|
||||
*pen_x += blf_kerning(font, g_prev, g);
|
||||
|
||||
|
@ -433,7 +433,7 @@ BLI_INLINE GlyphBLF *blf_glyph_from_utf8_and_step(FontBLF *font,
|
|||
#endif
|
||||
|
||||
#ifdef BLF_SUBPIXEL_AA
|
||||
g = blf_glyph_ensure_subpixel(font, gc, g, *pen_x);
|
||||
g = g->glyph_refine(font, gc, *pen_x);
|
||||
#endif
|
||||
}
|
||||
return g;
|
||||
|
@ -469,7 +469,7 @@ static void blf_font_draw_ex(FontBLF *font,
|
|||
continue;
|
||||
}
|
||||
/* Do not return this loop if clipped, we want every character tested. */
|
||||
blf_glyph_draw(font, gc, g, ft_pix_to_int_floor(pen_x), ft_pix_to_int_floor(pen_y));
|
||||
g->draw(font, gc, ft_pix_to_int_floor(pen_x), ft_pix_to_int_floor(pen_y));
|
||||
pen_x += g->advance_x;
|
||||
}
|
||||
|
||||
|
@ -482,9 +482,9 @@ static void blf_font_draw_ex(FontBLF *font,
|
|||
}
|
||||
void blf_font_draw(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
|
||||
{
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
|
||||
GlyphCacheBLF *gc = font->cache->acquire();
|
||||
blf_font_draw_ex(font, gc, str, str_len, r_info, 0);
|
||||
blf_glyph_cache_release(font);
|
||||
font->cache->release();
|
||||
}
|
||||
|
||||
int blf_font_draw_mono(
|
||||
|
@ -497,7 +497,7 @@ int blf_font_draw_mono(
|
|||
|
||||
size_t i = 0;
|
||||
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
|
||||
GlyphCacheBLF *gc = font->cache->acquire();
|
||||
|
||||
blf_batch_draw_begin(font);
|
||||
|
||||
|
@ -508,7 +508,7 @@ int blf_font_draw_mono(
|
|||
continue;
|
||||
}
|
||||
/* Do not return this loop if clipped, we want every character tested. */
|
||||
blf_glyph_draw(font, gc, g, ft_pix_to_int_floor(pen_x), ft_pix_to_int_floor(pen_y));
|
||||
g->draw(font, gc, ft_pix_to_int_floor(pen_x), ft_pix_to_int_floor(pen_y));
|
||||
|
||||
const int col = UNLIKELY(g->c == '\t') ? (tab_columns - (columns % tab_columns)) :
|
||||
BLI_wcwidth_safe(char32_t(g->c));
|
||||
|
@ -518,7 +518,7 @@ int blf_font_draw_mono(
|
|||
|
||||
blf_batch_draw_end();
|
||||
|
||||
blf_glyph_cache_release(font);
|
||||
font->cache->release();
|
||||
return columns;
|
||||
}
|
||||
|
||||
|
@ -674,9 +674,9 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
|
|||
|
||||
void blf_font_draw_buffer(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
|
||||
{
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
|
||||
GlyphCacheBLF *gc = font->cache->acquire();
|
||||
blf_font_draw_buffer_ex(font, gc, str, str_len, r_info, 0);
|
||||
blf_glyph_cache_release(font);
|
||||
font->cache->release();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -713,7 +713,7 @@ static bool blf_font_width_to_strlen_glyph_process(FontBLF *font,
|
|||
#endif
|
||||
|
||||
#ifdef BLF_SUBPIXEL_AA
|
||||
g = blf_glyph_ensure_subpixel(font, gc, g, *pen_x);
|
||||
g = g->glyph_refine(font, gc, *pen_x);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -731,7 +731,7 @@ size_t blf_font_width_to_strlen(
|
|||
ft_pix width_new;
|
||||
size_t i, i_prev;
|
||||
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
|
||||
GlyphCacheBLF *gc = font->cache->acquire();
|
||||
const int width_i = int(width);
|
||||
|
||||
for (i_prev = i = 0, width_new = pen_x = 0, g_prev = nullptr; (i < str_len) && str[i];
|
||||
|
@ -747,7 +747,7 @@ size_t blf_font_width_to_strlen(
|
|||
*r_width = ft_pix_to_int(width_new);
|
||||
}
|
||||
|
||||
blf_glyph_cache_release(font);
|
||||
font->cache->release();
|
||||
return i_prev;
|
||||
}
|
||||
|
||||
|
@ -759,7 +759,7 @@ size_t blf_font_width_to_rstrlen(
|
|||
size_t i, i_prev, i_tmp;
|
||||
const char *s, *s_prev;
|
||||
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
|
||||
GlyphCacheBLF *gc = font->cache->acquire();
|
||||
|
||||
i = BLI_strnlen(str, str_len);
|
||||
s = BLI_str_find_prev_char_utf8(&str[i], str);
|
||||
|
@ -790,7 +790,7 @@ size_t blf_font_width_to_rstrlen(
|
|||
*r_width = ft_pix_to_int(width_new);
|
||||
}
|
||||
|
||||
blf_glyph_cache_release(font);
|
||||
font->cache->release();
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -867,9 +867,9 @@ static void blf_font_boundbox_ex(FontBLF *font,
|
|||
void blf_font_boundbox(
|
||||
FontBLF *font, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
|
||||
{
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
|
||||
GlyphCacheBLF *gc = font->cache->acquire();
|
||||
blf_font_boundbox_ex(font, gc, str, str_len, r_box, r_info, 0);
|
||||
blf_glyph_cache_release(font);
|
||||
font->cache->release();
|
||||
}
|
||||
|
||||
void blf_font_width_and_height(FontBLF *font,
|
||||
|
@ -945,9 +945,9 @@ float blf_font_height(FontBLF *font, const char *str, const size_t str_len, Resu
|
|||
|
||||
float blf_font_fixed_width(FontBLF *font)
|
||||
{
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
|
||||
GlyphCacheBLF *gc = font->cache->acquire();
|
||||
float width = (gc) ? float(gc->fixed_width) : font->size / 2.0f;
|
||||
blf_glyph_cache_release(font);
|
||||
font->cache->release();
|
||||
return width;
|
||||
}
|
||||
|
||||
|
@ -966,7 +966,7 @@ void blf_font_boundbox_foreach_glyph(FontBLF *font,
|
|||
ft_pix pen_x = 0;
|
||||
size_t i = 0;
|
||||
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
|
||||
GlyphCacheBLF *gc = font->cache->acquire();
|
||||
|
||||
while ((i < str_len) && str[i]) {
|
||||
const size_t i_curr = i;
|
||||
|
@ -987,7 +987,7 @@ void blf_font_boundbox_foreach_glyph(FontBLF *font,
|
|||
pen_x += g->advance_x;
|
||||
}
|
||||
|
||||
blf_glyph_cache_release(font);
|
||||
font->cache->release();
|
||||
}
|
||||
|
||||
struct CursorPositionForeachGlyph_Data {
|
||||
|
@ -1104,7 +1104,7 @@ static void blf_font_wrap_apply(FontBLF *font,
|
|||
|
||||
ft_pix line_height = blf_font_height_max_ft_pix(font);
|
||||
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
|
||||
GlyphCacheBLF *gc = font->cache->acquire();
|
||||
|
||||
struct WordWrapVars {
|
||||
ft_pix wrap_width;
|
||||
|
@ -1183,7 +1183,7 @@ static void blf_font_wrap_apply(FontBLF *font,
|
|||
r_info->width = ft_pix_to_int(pen_x_next);
|
||||
}
|
||||
|
||||
blf_glyph_cache_release(font);
|
||||
font->cache->release();
|
||||
}
|
||||
|
||||
/** Utility for #blf_font_draw__wrap. */
|
||||
|
@ -1376,7 +1376,6 @@ static void blf_font_fill(FontBLF *font)
|
|||
font->char_width = 1.0f;
|
||||
font->char_spacing = 0.0f;
|
||||
|
||||
BLI_listbase_clear(&font->cache);
|
||||
font->kerning_cache = nullptr;
|
||||
#if BLF_BLUR_ENABLE
|
||||
font->blur = 0;
|
||||
|
@ -1738,6 +1737,8 @@ static FontBLF *blf_font_new_impl(const char *filepath,
|
|||
{
|
||||
FontBLF *font = (FontBLF *)MEM_callocN(sizeof(FontBLF), "blf_font_new");
|
||||
|
||||
font->cache = new GlyphCacheListBLF(font);
|
||||
|
||||
font->mem_name = mem_name ? BLI_strdup(mem_name) : nullptr;
|
||||
font->filepath = filepath ? BLI_strdup(filepath) : nullptr;
|
||||
if (mem) {
|
||||
|
@ -1756,8 +1757,6 @@ static FontBLF *blf_font_new_impl(const char *filepath,
|
|||
|
||||
font->ft_lib = ft_library ? (FT_Library)ft_library : ft_lib;
|
||||
|
||||
BLI_mutex_init(&font->glyph_cache_mutex);
|
||||
|
||||
/* If we have static details about this font file, we don't have to load the Face yet. */
|
||||
bool face_needed = true;
|
||||
|
||||
|
@ -1826,7 +1825,7 @@ void blf_font_attach_from_mem(FontBLF *font, const uchar *mem, const size_t mem_
|
|||
|
||||
void blf_font_free(FontBLF *font)
|
||||
{
|
||||
blf_glyph_cache_clear(font);
|
||||
delete font->cache;
|
||||
|
||||
if (font->kerning_cache) {
|
||||
MEM_freeN(font->kerning_cache);
|
||||
|
@ -1854,8 +1853,6 @@ void blf_font_free(FontBLF *font)
|
|||
MEM_freeN(font->mem_name);
|
||||
}
|
||||
|
||||
BLI_mutex_end(&font->glyph_cache_mutex);
|
||||
|
||||
MEM_freeN(font);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,40 +71,115 @@ static float from_16dot16(FT_Fixed value)
|
|||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Glyph Cache
|
||||
/** \name Glyph Cache List
|
||||
* \{ */
|
||||
|
||||
static GlyphCacheBLF *blf_glyph_cache_find(const FontBLF *font, const float size)
|
||||
GlyphCacheListBLF::GlyphCacheListBLF(FontBLF *font) : list{}, font(font)
|
||||
{
|
||||
GlyphCacheBLF *gc = (GlyphCacheBLF *)font->cache.first;
|
||||
while (gc) {
|
||||
if (gc->size == size && (gc->bold == ((font->flags & BLF_BOLD) != 0)) &&
|
||||
(gc->italic == ((font->flags & BLF_ITALIC) != 0)) &&
|
||||
(gc->char_weight == font->char_weight) && (gc->char_slant == font->char_slant) &&
|
||||
(gc->char_width == font->char_width) && (gc->char_spacing == font->char_spacing))
|
||||
{
|
||||
return gc;
|
||||
BLI_mutex_init(&glyph_cache_mutex);
|
||||
};
|
||||
|
||||
GlyphCacheListBLF ::~GlyphCacheListBLF()
|
||||
{
|
||||
clear();
|
||||
BLI_mutex_end(&glyph_cache_mutex);
|
||||
};
|
||||
|
||||
GlyphCacheBLF *GlyphCacheListBLF::acquire()
|
||||
{
|
||||
BLI_mutex_lock(&glyph_cache_mutex);
|
||||
|
||||
GlyphCacheBLF *gc = nullptr;
|
||||
|
||||
for (auto &entry : list) {
|
||||
if (entry->matches(font)) {
|
||||
gc = entry;
|
||||
break;
|
||||
}
|
||||
gc = gc->next;
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
if (!gc) {
|
||||
gc = new GlyphCacheBLF();
|
||||
gc->init(font);
|
||||
list.push_back(gc);
|
||||
}
|
||||
|
||||
return gc;
|
||||
}
|
||||
|
||||
static GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
|
||||
void GlyphCacheListBLF::release()
|
||||
{
|
||||
GlyphCacheBLF *gc = (GlyphCacheBLF *)MEM_callocN(sizeof(GlyphCacheBLF), "blf_glyph_cache_new");
|
||||
BLI_mutex_unlock(&glyph_cache_mutex);
|
||||
}
|
||||
|
||||
gc->next = nullptr;
|
||||
gc->prev = nullptr;
|
||||
gc->size = font->size;
|
||||
gc->bold = ((font->flags & BLF_BOLD) != 0);
|
||||
gc->italic = ((font->flags & BLF_ITALIC) != 0);
|
||||
gc->char_weight = font->char_weight;
|
||||
gc->char_slant = font->char_slant;
|
||||
gc->char_width = font->char_width;
|
||||
gc->char_spacing = font->char_spacing;
|
||||
void GlyphCacheListBLF::clear()
|
||||
{
|
||||
BLI_mutex_lock(&glyph_cache_mutex);
|
||||
for (auto &entry : list) {
|
||||
delete entry;
|
||||
}
|
||||
list.clear();
|
||||
BLI_mutex_unlock(&glyph_cache_mutex);
|
||||
}
|
||||
|
||||
memset(gc->bucket, 0, sizeof(gc->bucket));
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Glyph Cache Entry
|
||||
* \{ */
|
||||
|
||||
GlyphCacheBLF::GlyphCacheBLF()
|
||||
: next(nullptr),
|
||||
prev(nullptr),
|
||||
size(11.0f),
|
||||
char_weight(400),
|
||||
char_slant(0.0f),
|
||||
char_width(1.0f),
|
||||
char_spacing(1.0f),
|
||||
bold(false),
|
||||
italic(false),
|
||||
bucket{nullptr, nullptr},
|
||||
fixed_width(6),
|
||||
texture(nullptr),
|
||||
bitmap_result(nullptr),
|
||||
bitmap_len(0),
|
||||
bitmap_len_landed(0),
|
||||
bitmap_len_alloc(0)
|
||||
{
|
||||
}
|
||||
|
||||
GlyphCacheBLF::~GlyphCacheBLF()
|
||||
{
|
||||
for (uint i = 0; i < ARRAY_SIZE(bucket); i++) {
|
||||
while (GlyphBLF *g = static_cast<GlyphBLF *>(BLI_pophead(&bucket[i]))) {
|
||||
delete g;
|
||||
}
|
||||
}
|
||||
if (texture) {
|
||||
GPU_texture_free(texture);
|
||||
}
|
||||
if (bitmap_result) {
|
||||
MEM_freeN(bitmap_result);
|
||||
}
|
||||
}
|
||||
|
||||
bool GlyphCacheBLF::matches(FontBLF *font) const
|
||||
{
|
||||
return (size == font->size && (bold == ((font->flags & BLF_BOLD) != 0)) &&
|
||||
(italic == ((font->flags & BLF_ITALIC) != 0)) && (char_weight == font->char_weight) &&
|
||||
(char_slant == font->char_slant) && (char_width == font->char_width) &&
|
||||
(char_spacing == font->char_spacing));
|
||||
}
|
||||
|
||||
void GlyphCacheBLF::init(FontBLF *font)
|
||||
{
|
||||
size = font->size;
|
||||
char_weight = font->char_weight;
|
||||
char_slant = font->char_slant;
|
||||
char_width = font->char_width;
|
||||
char_spacing = font->char_spacing;
|
||||
bold = (font->flags & BLF_BOLD) != 0;
|
||||
italic = ((font->flags & BLF_ITALIC) != 0);
|
||||
|
||||
blf_ensure_size(font);
|
||||
|
||||
|
@ -114,82 +189,63 @@ static GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
|
|||
FT_Fixed advance = 0;
|
||||
FT_Get_Advance(font->face, gindex, FT_LOAD_NO_HINTING, &advance);
|
||||
/* Use CSS 'ch unit' width, advance of zero character. */
|
||||
gc->fixed_width = int(advance >> 16);
|
||||
fixed_width = int(advance >> 16);
|
||||
}
|
||||
else {
|
||||
/* Font does not have a face or does not contain "0" so use CSS fallback of 1/2 of em. */
|
||||
gc->fixed_width = int((font->ft_size->metrics.height / 2) >> 6);
|
||||
fixed_width = int((font->ft_size->metrics.height / 2) >> 6);
|
||||
}
|
||||
if (gc->fixed_width < 1) {
|
||||
gc->fixed_width = 1;
|
||||
if (fixed_width < 1) {
|
||||
fixed_width = 1;
|
||||
}
|
||||
|
||||
BLI_addhead(&font->cache, gc);
|
||||
return gc;
|
||||
}
|
||||
|
||||
GlyphCacheBLF *blf_glyph_cache_acquire(FontBLF *font)
|
||||
void GlyphCacheBLF::cache_glyph(GlyphBLF *glyph, uint charcode, uint8_t subpixel)
|
||||
{
|
||||
BLI_mutex_lock(&font->glyph_cache_mutex);
|
||||
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_find(font, font->size);
|
||||
|
||||
if (!gc) {
|
||||
gc = blf_glyph_cache_new(font);
|
||||
}
|
||||
|
||||
return gc;
|
||||
BLI_addhead(&(bucket[blf_hash(charcode << 6 | subpixel)]), glyph);
|
||||
}
|
||||
|
||||
void blf_glyph_cache_release(FontBLF *font)
|
||||
GlyphBLF *GlyphCacheBLF::find_glyph(uint charcode, uint8_t subpixel) const
|
||||
{
|
||||
BLI_mutex_unlock(&font->glyph_cache_mutex);
|
||||
GlyphBLF *g = static_cast<GlyphBLF *>(bucket[blf_hash(charcode << 6 | subpixel)].first);
|
||||
return GlyphBLF::cache_match(g, charcode, subpixel);
|
||||
}
|
||||
|
||||
static void blf_glyph_cache_free(GlyphCacheBLF *gc)
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name GlyphBLF
|
||||
* \{ */
|
||||
|
||||
GlyphBLF::GlyphBLF()
|
||||
: next(nullptr),
|
||||
prev(nullptr),
|
||||
c(0),
|
||||
idx(0),
|
||||
box_xmin(0),
|
||||
box_xmax(INT_MAX),
|
||||
box_ymin(0),
|
||||
box_ymax(INT_MAX),
|
||||
advance_x(0),
|
||||
subpixel(0),
|
||||
lsb_delta(0),
|
||||
rsb_delta(0),
|
||||
offset(0),
|
||||
bitmap(nullptr),
|
||||
dims{0, 0},
|
||||
pitch(0),
|
||||
depth(0),
|
||||
render_mode(0),
|
||||
pos{0, 0},
|
||||
glyph_cache(nullptr)
|
||||
{
|
||||
for (uint i = 0; i < ARRAY_SIZE(gc->bucket); i++) {
|
||||
while (GlyphBLF *g = static_cast<GlyphBLF *>(BLI_pophead(&gc->bucket[i]))) {
|
||||
blf_glyph_free(g);
|
||||
}
|
||||
}
|
||||
if (gc->texture) {
|
||||
GPU_texture_free(gc->texture);
|
||||
}
|
||||
if (gc->bitmap_result) {
|
||||
MEM_freeN(gc->bitmap_result);
|
||||
}
|
||||
MEM_freeN(gc);
|
||||
}
|
||||
|
||||
void blf_glyph_cache_clear(FontBLF *font)
|
||||
GlyphBLF::~GlyphBLF()
|
||||
{
|
||||
BLI_mutex_lock(&font->glyph_cache_mutex);
|
||||
|
||||
while (GlyphCacheBLF *gc = static_cast<GlyphCacheBLF *>(BLI_pophead(&font->cache))) {
|
||||
blf_glyph_cache_free(gc);
|
||||
if (bitmap) {
|
||||
MEM_freeN(bitmap);
|
||||
}
|
||||
|
||||
BLI_mutex_unlock(&font->glyph_cache_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find a glyph in cache.
|
||||
*
|
||||
* \return nullptr if not found.
|
||||
*/
|
||||
static GlyphBLF *blf_glyph_cache_find_glyph(const GlyphCacheBLF *gc,
|
||||
uint charcode,
|
||||
uint8_t subpixel)
|
||||
{
|
||||
GlyphBLF *g = static_cast<GlyphBLF *>(gc->bucket[blf_hash(charcode << 6 | subpixel)].first);
|
||||
while (g) {
|
||||
if (g->c == charcode && g->subpixel == subpixel) {
|
||||
return g;
|
||||
}
|
||||
g = g->next;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef BLF_GAMMA_CORRECT_GLYPHS
|
||||
|
@ -232,14 +288,11 @@ static uchar blf_glyph_gamma(uchar c)
|
|||
/**
|
||||
* Add a rendered glyph to a cache.
|
||||
*/
|
||||
static GlyphBLF *blf_glyph_cache_add_glyph(FontBLF *font,
|
||||
GlyphCacheBLF *gc,
|
||||
FT_GlyphSlot glyph,
|
||||
uint charcode,
|
||||
FT_UInt glyph_index,
|
||||
uint8_t subpixel)
|
||||
GlyphBLF *GlyphBLF::create(
|
||||
FontBLF *font, FT_GlyphSlot glyph, uint charcode, FT_UInt glyph_index, uint8_t subpixel)
|
||||
{
|
||||
GlyphBLF *g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_get");
|
||||
GlyphBLF *g = new GlyphBLF();
|
||||
|
||||
g->c = charcode;
|
||||
g->idx = glyph_index;
|
||||
g->advance_x = (ft_pix)glyph->advance.x;
|
||||
|
@ -291,7 +344,7 @@ static GlyphBLF *blf_glyph_cache_add_glyph(FontBLF *font,
|
|||
}
|
||||
|
||||
const int buffer_size = g->dims[0] * g->dims[1] * g->depth;
|
||||
g->bitmap = static_cast<uchar *>(MEM_mallocN(size_t(buffer_size), "glyph bitmap"));
|
||||
g->bitmap = static_cast<uchar *>(MEM_mallocN(size_t(buffer_size), __func__));
|
||||
|
||||
if (ELEM(glyph->bitmap.pixel_mode,
|
||||
FT_PIXEL_MODE_GRAY,
|
||||
|
@ -351,12 +404,20 @@ static GlyphBLF *blf_glyph_cache_add_glyph(FontBLF *font,
|
|||
memcpy(g->bitmap, glyph->bitmap.buffer, size_t(buffer_size));
|
||||
}
|
||||
}
|
||||
|
||||
BLI_addhead(&(gc->bucket[blf_hash(g->c << 6 | subpixel)]), g);
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
GlyphBLF *GlyphBLF::cache_match(GlyphBLF *glyph, uint charcode, uint8_t subpixel)
|
||||
{
|
||||
while (glyph) {
|
||||
if (glyph->c == charcode && glyph->subpixel == subpixel) {
|
||||
return glyph;
|
||||
}
|
||||
glyph = glyph->next;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -791,7 +852,7 @@ static FT_UInt blf_glyph_index_from_charcode(FontBLF **font, const uint charcode
|
|||
/**
|
||||
* Load a glyph into the glyph slot of a font's face object.
|
||||
*/
|
||||
static FT_GlyphSlot blf_glyph_load(FontBLF *font, FT_UInt glyph_index, bool outline_only)
|
||||
static FT_GlyphSlot blf_glyph_load(FontBLF *font, FT_UInt glyph_index, bool outline_only = false)
|
||||
{
|
||||
int load_flags;
|
||||
|
||||
|
@ -1202,7 +1263,7 @@ static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font,
|
|||
uint charcode,
|
||||
uint8_t subpixel,
|
||||
int fixed_width,
|
||||
bool outline_only)
|
||||
bool outline_only = false)
|
||||
{
|
||||
Harley marked this conversation as resolved
Outdated
|
||||
if (glyph_font != settings_font) {
|
||||
blf_font_size(glyph_font, settings_font->size);
|
||||
|
@ -1231,7 +1292,7 @@ static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font,
|
|||
/* Font variations need to be set before glyph loading. Even if new value is zero. */
|
||||
|
||||
if (glyph_font->variations) {
|
||||
FT_Fixed coords[BLF_VARIATIONS_MAX];
|
||||
FT_Fixed coords[BLF_VARIATIONS_MAX] = {0};
|
||||
/* Load current design coordinates. */
|
||||
FT_Get_Var_Design_Coordinates(glyph_font->face, BLF_VARIATIONS_MAX, &coords[0]);
|
||||
/* Update design coordinates with new values. */
|
||||
|
@ -1285,12 +1346,12 @@ static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static GlyphBLF *blf_glyph_ensure_ex(FontBLF *font,
|
||||
GlyphCacheBLF *gc,
|
||||
const uint charcode,
|
||||
uint8_t subpixel)
|
||||
GlyphBLF *GlyphBLF::glyph_ensure(FontBLF *font,
|
||||
GlyphCacheBLF *gc,
|
||||
const uint charcode,
|
||||
uint8_t subpixel)
|
||||
Hans Goudey
commented
It feels a bit for a class to return a pointer to itself or potentially create a new instance. Just that it's handling logic that isn't really "self contained". So maybe going with a free function would be clearer here too It feels a bit for a class to return a pointer to itself or potentially create a new instance. Just that it's handling logic that isn't really "self contained". So maybe going with a free function would be clearer here too
|
||||
{
|
||||
GlyphBLF *g = blf_glyph_cache_find_glyph(gc, charcode, subpixel);
|
||||
GlyphBLF *g = gc->find_glyph(charcode, subpixel);
|
||||
if (g) {
|
||||
return g;
|
||||
}
|
||||
|
@ -1304,81 +1365,69 @@ static GlyphBLF *blf_glyph_ensure_ex(FontBLF *font,
|
|||
}
|
||||
|
||||
FT_GlyphSlot glyph = blf_glyph_render(
|
||||
font, font_with_glyph, glyph_index, charcode, subpixel, gc->fixed_width, false);
|
||||
font, font_with_glyph, glyph_index, charcode, subpixel, gc->fixed_width);
|
||||
|
||||
if (glyph) {
|
||||
/* Save this glyph in the initial font's cache. */
|
||||
g = blf_glyph_cache_add_glyph(font, gc, glyph, charcode, glyph_index, subpixel);
|
||||
g = GlyphBLF::create(font, glyph, charcode, glyph_index, subpixel);
|
||||
gc->cache_glyph(g, charcode, subpixel);
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
GlyphBLF *blf_glyph_ensure(FontBLF *font, GlyphCacheBLF *gc, const uint charcode)
|
||||
{
|
||||
return blf_glyph_ensure_ex(font, gc, charcode, 0);
|
||||
}
|
||||
|
||||
#ifdef BLF_SUBPIXEL_AA
|
||||
GlyphBLF *blf_glyph_ensure_subpixel(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, int32_t pen_x)
|
||||
GlyphBLF *GlyphBLF::glyph_refine(FontBLF *font, GlyphCacheBLF *gc, int32_t pen_x)
|
||||
{
|
||||
if (!(font->flags & BLF_RENDER_SUBPIXELAA)) {
|
||||
/* Not if we are in mono mode (aliased) or the feature is turned off. */
|
||||
return g;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (font->size > 35.0f || g->dims[0] == 0 || g->advance_x < 0) {
|
||||
if (font->size > 35.0f || dims[0] == 0 || advance_x < 0) {
|
||||
/* Single position for large sizes, spaces, and combining characters. */
|
||||
return g;
|
||||
return this;
|
||||
}
|
||||
|
||||
/* Four sub-pixel positions up to 16 point, 2 until 35 points. */
|
||||
const uint8_t subpixel = uint8_t(pen_x & ((font->size > 16.0f) ? 32L : 48L));
|
||||
|
||||
if (g->subpixel != subpixel) {
|
||||
g = blf_glyph_ensure_ex(font, gc, g->c, subpixel);
|
||||
if (subpixel != subpixel) {
|
||||
return GlyphBLF::glyph_ensure(font, gc, c, subpixel);
|
||||
}
|
||||
return g;
|
||||
|
||||
return this;
|
||||
}
|
||||
#endif
|
||||
|
||||
void blf_glyph_free(GlyphBLF *g)
|
||||
{
|
||||
if (g->bitmap) {
|
||||
MEM_freeN(g->bitmap);
|
||||
}
|
||||
MEM_freeN(g);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Glyph Bounds Calculation
|
||||
* \{ */
|
||||
|
||||
static void blf_glyph_calc_rect(rcti *rect, GlyphBLF *g, const int x, const int y)
|
||||
void GlyphBLF::calc_rect(rcti *rect, const int x, const int y) const
|
||||
{
|
||||
rect->xmin = x + g->pos[0];
|
||||
rect->xmax = rect->xmin + g->dims[0];
|
||||
rect->ymin = y + g->pos[1];
|
||||
rect->ymax = rect->ymin - g->dims[1];
|
||||
rect->xmin = x + pos[0];
|
||||
rect->xmax = rect->xmin + dims[0];
|
||||
rect->ymin = y + pos[1];
|
||||
rect->ymax = rect->ymin - dims[1];
|
||||
}
|
||||
|
||||
static void blf_glyph_calc_rect_test(rcti *rect, GlyphBLF *g, const int x, const int y)
|
||||
void GlyphBLF::calc_rect_test(rcti *rect, const int x, const int y)
|
||||
{
|
||||
/* Intentionally check with `g->advance`, because this is the
|
||||
* width used by BLF_width. This allows that the text slightly
|
||||
* overlaps the clipping border to achieve better alignment. */
|
||||
rect->xmin = x + abs(g->pos[0]) + 1;
|
||||
rect->xmax = x + std::min(ft_pix_to_int(g->advance_x), g->dims[0]);
|
||||
rect->xmin = x + abs(pos[0]) + 1;
|
||||
rect->xmax = x + std::min(ft_pix_to_int(advance_x), dims[0]);
|
||||
rect->ymin = y;
|
||||
rect->ymax = rect->ymin - g->dims[1];
|
||||
rect->ymax = rect->ymin - dims[1];
|
||||
}
|
||||
|
||||
static void blf_glyph_calc_rect_shadow(
|
||||
rcti *rect, GlyphBLF *g, const int x, const int y, FontBLF *font)
|
||||
void GlyphBLF::calc_rect_shadow(rcti *rect, const int x, const int y, FontBLF *font) const
|
||||
{
|
||||
blf_glyph_calc_rect(rect, g, x + font->shadow_x, y + font->shadow_y);
|
||||
calc_rect(rect, x + font->shadow_x, y + font->shadow_y);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -1387,13 +1436,12 @@ static void blf_glyph_calc_rect_shadow(
|
|||
/** \name Glyph Drawing
|
||||
* \{ */
|
||||
|
||||
static void blf_texture_draw(GlyphBLF *g,
|
||||
const uchar color[4],
|
||||
const int glyph_size[2],
|
||||
const int x1,
|
||||
const int y1,
|
||||
const int x2,
|
||||
const int y2)
|
||||
void GlyphBLF::texture_draw(const uchar color[4],
|
||||
const int glyph_size[2],
|
||||
const int x1,
|
||||
const int y1,
|
||||
const int x2,
|
||||
const int y2) const
|
||||
{
|
||||
/* Only one vertex per glyph, geometry shader expand it into a quad. */
|
||||
/* TODO: Get rid of Geom Shader because it's not optimal AT ALL for the GPU. */
|
||||
|
@ -1404,9 +1452,9 @@ static void blf_texture_draw(GlyphBLF *g,
|
|||
float(y2 + g_batch.ofs[1]));
|
||||
copy_v4_v4_uchar(static_cast<uchar *>(GPU_vertbuf_raw_step(&g_batch.col_step)), color);
|
||||
copy_v2_v2_int(static_cast<int *>(GPU_vertbuf_raw_step(&g_batch.glyph_size_step)), glyph_size);
|
||||
*((int *)GPU_vertbuf_raw_step(&g_batch.offset_step)) = g->offset;
|
||||
*((int *)GPU_vertbuf_raw_step(&g_batch.glyph_comp_len_step)) = g->depth;
|
||||
*((int *)GPU_vertbuf_raw_step(&g_batch.glyph_mode_step)) = g->render_mode;
|
||||
*((int *)GPU_vertbuf_raw_step(&g_batch.offset_step)) = offset;
|
||||
*((int *)GPU_vertbuf_raw_step(&g_batch.glyph_comp_len_step)) = depth;
|
||||
*((int *)GPU_vertbuf_raw_step(&g_batch.glyph_mode_step)) = render_mode;
|
||||
|
||||
g_batch.glyph_len++;
|
||||
/* Flush cache if it's full. */
|
||||
|
@ -1415,42 +1463,42 @@ static void blf_texture_draw(GlyphBLF *g,
|
|||
}
|
||||
}
|
||||
|
||||
static void blf_texture5_draw(
|
||||
GlyphBLF *g, const uchar color_in[4], const int x1, const int y1, const int x2, const int y2)
|
||||
void GlyphBLF::texture5_draw(
|
||||
const uchar color_in[4], const int x1, const int y1, const int x2, const int y2) const
|
||||
{
|
||||
int glyph_size_flag[2];
|
||||
int glyph_size_flag[2] = {0};
|
||||
/* flag the x and y component signs for 5x5 blurring */
|
||||
glyph_size_flag[0] = -g->dims[0];
|
||||
glyph_size_flag[1] = -g->dims[1];
|
||||
glyph_size_flag[0] = -dims[0];
|
||||
glyph_size_flag[1] = -dims[1];
|
||||
|
||||
blf_texture_draw(g, color_in, glyph_size_flag, x1, y1, x2, y2);
|
||||
texture_draw(color_in, glyph_size_flag, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
static void blf_texture3_draw(
|
||||
GlyphBLF *g, const uchar color_in[4], const int x1, const int y1, const int x2, const int y2)
|
||||
void GlyphBLF::texture3_draw(
|
||||
const uchar color_in[4], const int x1, const int y1, const int x2, const int y2) const
|
||||
{
|
||||
int glyph_size_flag[2];
|
||||
int glyph_size_flag[2] = {0};
|
||||
/* flag the x component sign for 3x3 blurring */
|
||||
glyph_size_flag[0] = -g->dims[0];
|
||||
glyph_size_flag[1] = g->dims[1];
|
||||
glyph_size_flag[0] = -dims[0];
|
||||
glyph_size_flag[1] = dims[1];
|
||||
|
||||
blf_texture_draw(g, color_in, glyph_size_flag, x1, y1, x2, y2);
|
||||
texture_draw(color_in, glyph_size_flag, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
void blf_glyph_draw(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, const int x, const int y)
|
||||
void GlyphBLF::draw(FontBLF *font, GlyphCacheBLF *gc, const int x, const int y)
|
||||
{
|
||||
if ((!g->dims[0]) || (!g->dims[1])) {
|
||||
if ((!dims[0]) || (!dims[1])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g->glyph_cache == nullptr) {
|
||||
if (glyph_cache == nullptr) {
|
||||
if (font->tex_size_max == -1) {
|
||||
font->tex_size_max = GPU_max_texture_size();
|
||||
}
|
||||
|
||||
g->offset = gc->bitmap_len;
|
||||
offset = gc->bitmap_len;
|
||||
|
||||
int buff_size = g->dims[0] * g->dims[1] * g->depth;
|
||||
int buff_size = dims[0] * dims[1] * depth;
|
||||
int bitmap_len = gc->bitmap_len + buff_size;
|
||||
|
||||
if (bitmap_len > gc->bitmap_len_alloc) {
|
||||
|
@ -1471,10 +1519,10 @@ void blf_glyph_draw(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, const int x,
|
|||
gc->bitmap_len_landed = 0;
|
||||
}
|
||||
|
||||
memcpy(&gc->bitmap_result[gc->bitmap_len], g->bitmap, size_t(buff_size));
|
||||
memcpy(&gc->bitmap_result[gc->bitmap_len], bitmap, size_t(buff_size));
|
||||
gc->bitmap_len = bitmap_len;
|
||||
|
||||
g->glyph_cache = gc;
|
||||
glyph_cache = gc;
|
||||
}
|
||||
|
||||
if (font->flags & BLF_CLIPPING) {
|
||||
|
@ -1490,57 +1538,52 @@ void blf_glyph_draw(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, const int x,
|
|||
}
|
||||
|
||||
rcti rect_test;
|
||||
blf_glyph_calc_rect_test(&rect_test, g, int(float(x) * xa), int(float(y) * ya));
|
||||
calc_rect_test(&rect_test, int(float(x) * xa), int(float(y) * ya));
|
||||
BLI_rcti_translate(&rect_test, font->pos[0], font->pos[1]);
|
||||
if (!BLI_rcti_inside_rcti(&font->clip_rec, &rect_test)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_batch.glyph_cache != g->glyph_cache) {
|
||||
if (g_batch.glyph_cache != glyph_cache) {
|
||||
blf_batch_draw();
|
||||
g_batch.glyph_cache = g->glyph_cache;
|
||||
g_batch.glyph_cache = glyph_cache;
|
||||
}
|
||||
|
||||
if (font->flags & BLF_SHADOW) {
|
||||
rcti rect_ofs;
|
||||
blf_glyph_calc_rect_shadow(&rect_ofs, g, x, y, font);
|
||||
calc_rect_shadow(&rect_ofs, x, y, font);
|
||||
|
||||
if (font->shadow == 0) {
|
||||
blf_texture_draw(g,
|
||||
font->shadow_color,
|
||||
g->dims,
|
||||
rect_ofs.xmin,
|
||||
rect_ofs.ymin,
|
||||
rect_ofs.xmax,
|
||||
rect_ofs.ymax);
|
||||
texture_draw(
|
||||
font->shadow_color, dims, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
|
||||
}
|
||||
else if (font->shadow <= 4) {
|
||||
blf_texture3_draw(
|
||||
g, font->shadow_color, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
|
||||
texture3_draw(
|
||||
font->shadow_color, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
|
||||
}
|
||||
else {
|
||||
blf_texture5_draw(
|
||||
g, font->shadow_color, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
|
||||
texture5_draw(
|
||||
font->shadow_color, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
|
||||
}
|
||||
}
|
||||
|
||||
rcti rect;
|
||||
blf_glyph_calc_rect(&rect, g, x, y);
|
||||
calc_rect(&rect, x, y);
|
||||
|
||||
#if BLF_BLUR_ENABLE
|
||||
switch (font->blur) {
|
||||
case 3:
|
||||
blf_texture3_draw(g, font->color, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
texture3_draw(font->color, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
break;
|
||||
case 5:
|
||||
blf_texture5_draw(g, font->color, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
texture5_draw(font->color, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
break;
|
||||
default:
|
||||
blf_texture_draw(g, font->color, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
texture_draw(font->color, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
}
|
||||
#else
|
||||
blf_texture_draw(g, font->color, g->dims, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
texture_draw(font->color, dims, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#pragma once
|
||||
|
||||
struct FontBLF;
|
||||
struct GlyphBLF;
|
||||
struct GlyphCacheBLF;
|
||||
class GlyphBLF;
|
||||
class GlyphCacheBLF;
|
||||
struct ResultBLF;
|
||||
struct rcti;
|
||||
|
||||
|
@ -166,22 +166,6 @@ void blf_str_offset_to_glyph_bounds(struct FontBLF *font,
|
|||
|
||||
void blf_font_free(struct FontBLF *font);
|
||||
|
||||
struct GlyphCacheBLF *blf_glyph_cache_acquire(struct FontBLF *font);
|
||||
void blf_glyph_cache_release(struct FontBLF *font);
|
||||
void blf_glyph_cache_clear(struct FontBLF *font);
|
||||
|
||||
/**
|
||||
* Create (or load from cache) a fully-rendered bitmap glyph.
|
||||
*/
|
||||
struct GlyphBLF *blf_glyph_ensure(struct FontBLF *font, struct GlyphCacheBLF *gc, uint charcode);
|
||||
|
||||
#ifdef BLF_SUBPIXEL_AA
|
||||
struct GlyphBLF *blf_glyph_ensure_subpixel(struct FontBLF *font,
|
||||
struct GlyphCacheBLF *gc,
|
||||
struct GlyphBLF *g,
|
||||
int32_t pen_x);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Convert a character's outlines into curves.
|
||||
*/
|
||||
|
@ -190,10 +174,6 @@ float blf_character_to_curves(FontBLF *font,
|
|||
struct ListBase *nurbsbase,
|
||||
const float scale);
|
||||
|
||||
void blf_glyph_free(struct GlyphBLF *g);
|
||||
void blf_glyph_draw(
|
||||
struct FontBLF *font, struct GlyphCacheBLF *gc, struct GlyphBLF *g, int x, int y);
|
||||
|
||||
#ifdef WIN32
|
||||
/* `blf_font_win32_compat.cc` */
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "GPU_texture.h"
|
||||
#include "GPU_vertex_buffer.h"
|
||||
|
||||
|
@ -93,7 +95,7 @@ typedef struct BatchBLF {
|
|||
/* Previous call `modelmatrix`. */
|
||||
float mat[4][4];
|
||||
bool enabled, active, simple_shader;
|
||||
struct GlyphCacheBLF *glyph_cache;
|
||||
GlyphCacheBLF *glyph_cache;
|
||||
} BatchBLF;
|
||||
|
||||
extern BatchBLF g_batch;
|
||||
|
@ -106,9 +108,31 @@ typedef struct KerningCacheBLF {
|
|||
int ascii_table[KERNING_CACHE_TABLE_SIZE][KERNING_CACHE_TABLE_SIZE];
|
||||
} KerningCacheBLF;
|
||||
|
||||
typedef struct GlyphCacheBLF {
|
||||
struct GlyphCacheBLF *next;
|
||||
struct GlyphCacheBLF *prev;
|
||||
class GlyphCacheListBLF {
|
||||
private:
|
||||
/**
|
||||
* List of glyph caches (#GlyphCacheBLF) for this font for size, DPI, bold, italic.
|
||||
* Use font->cache->acquire() and font->cache->release() to access cache!
|
||||
*/
|
||||
std::vector<GlyphCacheBLF *> list;
|
||||
|
||||
FontBLF *font;
|
||||
|
||||
/** Mutex lock for glyph cache. */
|
||||
ThreadMutex glyph_cache_mutex;
|
||||
|
||||
public:
|
||||
GlyphCacheListBLF(FontBLF *font);
|
||||
~GlyphCacheListBLF();
|
||||
GlyphCacheBLF *acquire();
|
||||
void release();
|
||||
void clear();
|
||||
};
|
||||
|
||||
class GlyphCacheBLF {
|
||||
private:
|
||||
GlyphCacheBLF *next;
|
||||
GlyphCacheBLF *prev;
|
||||
|
||||
/** Font size. */
|
||||
float size;
|
||||
|
@ -121,12 +145,13 @@ typedef struct GlyphCacheBLF {
|
|||
bool bold;
|
||||
bool italic;
|
||||
|
||||
/** Column width when printing monospaced. */
|
||||
int fixed_width;
|
||||
|
||||
/** The glyphs. */
|
||||
ListBase bucket[257];
|
||||
|
||||
public:
|
||||
/** Column width when printing monospaced. */
|
||||
int fixed_width;
|
||||
|
||||
/** Texture array, to draw the glyphs. */
|
||||
GPUTexture *texture;
|
||||
char *bitmap_result;
|
||||
|
@ -134,12 +159,21 @@ typedef struct GlyphCacheBLF {
|
|||
int bitmap_len_landed;
|
||||
int bitmap_len_alloc;
|
||||
|
||||
} GlyphCacheBLF;
|
||||
GlyphCacheBLF();
|
||||
~GlyphCacheBLF();
|
||||
bool matches(FontBLF *font) const;
|
||||
void init(FontBLF *font);
|
||||
void cache_glyph(GlyphBLF *glyph, uint charcode, uint8_t subpixel);
|
||||
GlyphBLF *find_glyph(uint charcode, uint8_t subpixel) const;
|
||||
};
|
||||
|
||||
typedef struct GlyphBLF {
|
||||
struct GlyphBLF *next;
|
||||
struct GlyphBLF *prev;
|
||||
class GlyphBLF {
|
||||
private:
|
||||
GlyphBLF *next;
|
||||
GlyphBLF *prev;
|
||||
GlyphCacheBLF *glyph_cache;
|
||||
|
||||
public:
|
||||
/** The character, as UTF-32. */
|
||||
unsigned int c;
|
||||
|
||||
|
@ -183,8 +217,41 @@ typedef struct GlyphBLF {
|
|||
*/
|
||||
int pos[2];
|
||||
|
||||
struct GlyphCacheBLF *glyph_cache;
|
||||
} GlyphBLF;
|
||||
void calc_rect(rcti *rect, const int x, const int y) const;
|
||||
void calc_rect_test(rcti *rect, const int x, const int y);
|
||||
void calc_rect_shadow(rcti *rect, const int x, const int y, FontBLF *font) const;
|
||||
|
||||
void texture_draw(const uchar color[4],
|
||||
const int glyph_size[2],
|
||||
const int x1,
|
||||
const int y1,
|
||||
const int x2,
|
||||
const int y2) const;
|
||||
void texture5_draw(
|
||||
const uchar color_in[4], const int x1, const int y1, const int x2, const int y2) const;
|
||||
void texture3_draw(
|
||||
const uchar color_in[4], const int x1, const int y1, const int x2, const int y2) const;
|
||||
|
||||
static GlyphBLF *create(
|
||||
FontBLF *font, FT_GlyphSlot glyph, uint charcode, FT_UInt glyph_index, uint8_t subpixel);
|
||||
|
||||
public:
|
||||
GlyphBLF();
|
||||
~GlyphBLF();
|
||||
|
||||
static GlyphBLF *glyph_ensure(struct FontBLF *font,
|
||||
GlyphCacheBLF *gc,
|
||||
uint charcode,
|
||||
uint8_t subpixel = 0);
|
||||
|
||||
#ifdef BLF_SUBPIXEL_AA
|
||||
GlyphBLF *glyph_refine(struct FontBLF *font, GlyphCacheBLF *gc, int32_t pen_x);
|
||||
#endif
|
||||
|
||||
void draw(FontBLF *font, GlyphCacheBLF *gc, const int x, const int y);
|
||||
|
||||
static GlyphBLF *cache_match(GlyphBLF *glyph, uint charcode, uint8_t subpixel);
|
||||
};
|
||||
|
||||
typedef struct FontBufInfoBLF {
|
||||
/** For draw to buffer, always set this to NULL after finish! */
|
||||
|
@ -355,9 +422,9 @@ typedef struct FontBLF {
|
|||
|
||||
/**
|
||||
* List of glyph caches (#GlyphCacheBLF) for this font for size, DPI, bold, italic.
|
||||
* Use blf_glyph_cache_acquire(font) and blf_glyph_cache_release(font) to access cache!
|
||||
* Use GlyphCacheBLF::cache_acquire(font) and GlyphCacheBLF::cache_release(font) to access cache!
|
||||
*/
|
||||
ListBase cache;
|
||||
GlyphCacheListBLF *cache;
|
||||
|
||||
/** Cache of unscaled kerning values. Will be NULL if font does not have kerning. */
|
||||
KerningCacheBLF *kerning_cache;
|
||||
|
@ -379,7 +446,4 @@ typedef struct FontBLF {
|
|||
|
||||
/** Data for buffer usage (drawing into a texture buffer) */
|
||||
FontBufInfoBLF buf_info;
|
||||
|
||||
/** Mutex lock for glyph cache. */
|
||||
ThreadMutex glyph_cache_mutex;
|
||||
} FontBLF;
|
||||
|
|
Loading…
Reference in New Issue
Isn't this array initialized by
FT_Get_Var_Design_Coordinates
? If so, zero initializing it here seems redundant