BLF: Subpixel Positioning, Anti-aliasing, Hinting #105441
|
@ -356,18 +356,6 @@ static void blf_batch_draw_end()
|
|||
/** \name Glyph Stepping Utilities (Internal)
|
||||
* \{ */
|
||||
|
||||
/* Fast path for runs of ASCII characters. Given that common UTF-8
|
||||
* input will consist of an overwhelming majority of ASCII
|
||||
* characters.
|
||||
*/
|
||||
|
||||
BLI_INLINE GlyphBLF *blf_glyph_from_utf8_and_step(
|
||||
FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t str_len, size_t *i_p)
|
||||
{
|
||||
uint charcode = BLI_str_utf8_as_unicode_step_safe(str, str_len, i_p);
|
||||
return blf_glyph_ensure(font, gc, charcode);
|
||||
}
|
||||
|
||||
BLI_INLINE ft_pix blf_kerning(FontBLF *font, const GlyphBLF *g_prev, const GlyphBLF *g)
|
||||
{
|
||||
ft_pix adjustment = 0;
|
||||
|
@ -403,6 +391,31 @@ BLI_INLINE ft_pix blf_kerning(FontBLF *font, const GlyphBLF *g_prev, const Glyph
|
|||
return adjustment;
|
||||
}
|
||||
|
||||
BLI_INLINE GlyphBLF *blf_glyph_from_utf8_and_step(FontBLF *font,
|
||||
GlyphCacheBLF *gc,
|
||||
GlyphBLF *g_prev,
|
||||
const char *str,
|
||||
size_t str_len,
|
||||
size_t *i_p,
|
||||
int32_t *pen_x)
|
||||
{
|
||||
uint charcode = BLI_str_utf8_as_unicode_step_safe(str, str_len, i_p);
|
||||
/* 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);
|
||||
if (g && pen_x && !(font->flags & BLF_MONOSPACED)) {
|
||||
*pen_x += blf_kerning(font, g_prev, g);
|
||||
#ifndef BLF_SUBPIXEL_POSITION
|
||||
*pen_x = FT_PIX_ROUND(*pen_x);
|
||||
#endif
|
||||
#ifdef BLF_SUBPIXEL_AA
|
||||
g = blf_glyph_ensure_subpixel(font, gc, g, *pen_x);
|
||||
#endif
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -416,7 +429,7 @@ static void blf_font_draw_ex(FontBLF *font,
|
|||
ResultBLF *r_info,
|
||||
const ft_pix pen_y)
|
||||
{
|
||||
GlyphBLF *g, *g_prev = nullptr;
|
||||
GlyphBLF *g = nullptr;
|
||||
ft_pix pen_x = 0;
|
||||
size_t i = 0;
|
||||
|
||||
|
@ -428,18 +441,13 @@ static void blf_font_draw_ex(FontBLF *font,
|
|||
blf_batch_draw_begin(font);
|
||||
|
||||
while ((i < str_len) && str[i]) {
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
|
||||
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, g, str, str_len, &i, &pen_x);
|
||||
if (UNLIKELY(g == nullptr)) {
|
||||
continue;
|
||||
}
|
||||
pen_x += blf_kerning(font, g_prev, g);
|
||||
|
||||
/* 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));
|
||||
|
||||
pen_x = ft_pix_round_advance(pen_x, g->advance_x);
|
||||
g_prev = g;
|
||||
pen_x += g->advance_x;
|
||||
}
|
||||
|
||||
blf_batch_draw_end();
|
||||
|
@ -470,7 +478,7 @@ int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, int
|
|||
blf_batch_draw_begin(font);
|
||||
|
||||
while ((i < str_len) && str[i]) {
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, nullptr, str, str_len, &i, nullptr);
|
||||
|
||||
if (UNLIKELY(g == nullptr)) {
|
||||
continue;
|
||||
|
@ -613,7 +621,7 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
|
|||
ResultBLF *r_info,
|
||||
ft_pix pen_y)
|
||||
{
|
||||
GlyphBLF *g, *g_prev = nullptr;
|
||||
GlyphBLF *g = nullptr;
|
||||
ft_pix pen_x = ft_pix_from_int(font->pos[0]);
|
||||
ft_pix pen_y_basis = ft_pix_from_int(font->pos[1]) + pen_y;
|
||||
size_t i = 0;
|
||||
|
@ -624,17 +632,13 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
|
|||
/* another buffer specific call for color conversion */
|
||||
|
||||
while ((i < str_len) && str[i]) {
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, g, str, str_len, &i, &pen_x);
|
||||
|
||||
if (UNLIKELY(g == nullptr)) {
|
||||
continue;
|
||||
}
|
||||
pen_x += blf_kerning(font, g_prev, g);
|
||||
|
||||
blf_glyph_draw_buffer(buf_info, g, pen_x, pen_y_basis);
|
||||
|
||||
pen_x = ft_pix_round_advance(pen_x, g->advance_x);
|
||||
g_prev = g;
|
||||
pen_x += g->advance_x;
|
||||
}
|
||||
|
||||
if (r_info) {
|
||||
|
@ -666,8 +670,7 @@ static bool blf_font_width_to_strlen_glyph_process(
|
|||
if (UNLIKELY(g == nullptr)) {
|
||||
return false; /* continue the calling loop. */
|
||||
}
|
||||
*pen_x += blf_kerning(font, g_prev, g);
|
||||
*pen_x = ft_pix_round_advance(*pen_x, g->advance_x);
|
||||
*pen_x += blf_kerning(font, g_prev, g) + g->advance_x;
|
||||
|
||||
/* When true, break the calling loop. */
|
||||
return (ft_pix_to_int(*pen_x) >= width_i);
|
||||
|
@ -687,8 +690,7 @@ size_t blf_font_width_to_strlen(
|
|||
for (i_prev = i = 0, width_new = pen_x = 0, g_prev = nullptr; (i < str_len) && str[i];
|
||||
i_prev = i, width_new = pen_x, g_prev = g)
|
||||
{
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
|
||||
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, nullptr, str, str_len, &i, nullptr);
|
||||
if (blf_font_width_to_strlen_glyph_process(font, g_prev, g, &pen_x, width_i)) {
|
||||
break;
|
||||
}
|
||||
|
@ -719,7 +721,7 @@ size_t blf_font_width_to_rstrlen(
|
|||
i_prev = size_t(s_prev - str);
|
||||
|
||||
i_tmp = i;
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i_tmp);
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, nullptr, str, str_len, &i_tmp, nullptr);
|
||||
for (width_new = pen_x = 0; (s != nullptr);
|
||||
i = i_prev, s = s_prev, g = g_prev, g_prev = nullptr, width_new = pen_x)
|
||||
{
|
||||
|
@ -728,7 +730,7 @@ size_t blf_font_width_to_rstrlen(
|
|||
|
||||
if (s_prev != nullptr) {
|
||||
i_tmp = i_prev;
|
||||
g_prev = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i_tmp);
|
||||
g_prev = blf_glyph_from_utf8_and_step(font, gc, nullptr, str, str_len, &i_tmp, nullptr);
|
||||
BLI_assert(i_tmp == i);
|
||||
}
|
||||
|
||||
|
@ -759,7 +761,7 @@ static void blf_font_boundbox_ex(FontBLF *font,
|
|||
ResultBLF *r_info,
|
||||
ft_pix pen_y)
|
||||
{
|
||||
GlyphBLF *g, *g_prev = nullptr;
|
||||
GlyphBLF *g = nullptr;
|
||||
ft_pix pen_x = 0;
|
||||
size_t i = 0;
|
||||
|
||||
|
@ -769,13 +771,12 @@ static void blf_font_boundbox_ex(FontBLF *font,
|
|||
ft_pix box_ymax = ft_pix_from_int(-32000);
|
||||
|
||||
while ((i < str_len) && str[i]) {
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, g, str, str_len, &i, &pen_x);
|
||||
|
||||
if (UNLIKELY(g == nullptr)) {
|
||||
continue;
|
||||
}
|
||||
pen_x += blf_kerning(font, g_prev, g);
|
||||
const ft_pix pen_x_next = ft_pix_round_advance(pen_x, g->advance_x);
|
||||
const ft_pix pen_x_next = pen_x + g->advance_x;
|
||||
|
||||
const ft_pix gbox_xmin = pen_x;
|
||||
const ft_pix gbox_xmax = pen_x_next;
|
||||
|
@ -797,7 +798,6 @@ static void blf_font_boundbox_ex(FontBLF *font,
|
|||
}
|
||||
|
||||
pen_x = pen_x_next;
|
||||
g_prev = g;
|
||||
}
|
||||
|
||||
if (box_xmin > box_xmax) {
|
||||
|
@ -910,7 +910,7 @@ void blf_font_boundbox_foreach_glyph(FontBLF *font,
|
|||
BLF_GlyphBoundsFn user_fn,
|
||||
void *user_data)
|
||||
{
|
||||
GlyphBLF *g, *g_prev = nullptr;
|
||||
GlyphBLF *g = nullptr;
|
||||
ft_pix pen_x = 0;
|
||||
size_t i = 0, i_curr;
|
||||
|
||||
|
@ -923,13 +923,11 @@ void blf_font_boundbox_foreach_glyph(FontBLF *font,
|
|||
|
||||
while ((i < str_len) && str[i]) {
|
||||
i_curr = i;
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, g, str, str_len, &i, &pen_x);
|
||||
|
||||
if (UNLIKELY(g == nullptr)) {
|
||||
continue;
|
||||
}
|
||||
pen_x += blf_kerning(font, g_prev, g);
|
||||
|
||||
rcti bounds;
|
||||
bounds.xmin = ft_pix_to_int_floor(pen_x) + ft_pix_to_int_floor(g->box_xmin);
|
||||
bounds.xmax = ft_pix_to_int_floor(pen_x) + ft_pix_to_int_ceil(g->box_xmax);
|
||||
|
@ -939,8 +937,7 @@ void blf_font_boundbox_foreach_glyph(FontBLF *font,
|
|||
if (user_fn(str, i_curr, &bounds, user_data) == false) {
|
||||
break;
|
||||
}
|
||||
pen_x = ft_pix_round_advance(pen_x, g->advance_x);
|
||||
g_prev = g;
|
||||
pen_x += g->advance_x;
|
||||
}
|
||||
|
||||
blf_glyph_cache_release(font);
|
||||
|
@ -1050,7 +1047,8 @@ static void blf_font_wrap_apply(FontBLF *font,
|
|||
void *userdata),
|
||||
void *userdata)
|
||||
{
|
||||
GlyphBLF *g, *g_prev = nullptr;
|
||||
GlyphBLF *g = nullptr;
|
||||
GlyphBLF *g_prev = nullptr;
|
||||
ft_pix pen_x = 0;
|
||||
ft_pix pen_y = 0;
|
||||
size_t i = 0;
|
||||
|
@ -1073,12 +1071,11 @@ static void blf_font_wrap_apply(FontBLF *font,
|
|||
size_t i_curr = i;
|
||||
bool do_draw = false;
|
||||
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
|
||||
g = blf_glyph_from_utf8_and_step(font, gc, g_prev, str, str_len, &i, &pen_x);
|
||||
|
||||
if (UNLIKELY(g == nullptr)) {
|
||||
continue;
|
||||
}
|
||||
pen_x += blf_kerning(font, g_prev, g);
|
||||
|
||||
/**
|
||||
* Implementation Detail (utf8).
|
||||
|
@ -1088,7 +1085,7 @@ static void blf_font_wrap_apply(FontBLF *font,
|
|||
*
|
||||
* This is _only_ done when we know for sure the character is ascii (newline or a space).
|
||||
*/
|
||||
pen_x_next = ft_pix_round_advance(pen_x, g->advance_x);
|
||||
pen_x_next = pen_x + g->advance_x;
|
||||
if (UNLIKELY((pen_x_next >= wrap.wrap_width) && (wrap.start != wrap.last[0]))) {
|
||||
do_draw = true;
|
||||
}
|
||||
|
@ -1422,16 +1419,6 @@ bool blf_ensure_face(FontBLF *font)
|
|||
|
||||
font->face_flags = font->face->face_flags;
|
||||
|
||||
/* XXX: Temporarily disable kerning in our main font. Kerning had been accidentally removed
|
||||
* from our font in 3.1. In 3.4 we disable kerning here in the new version to keep spacing the
|
||||
* same
|
||||
* (#101506). Enable again later with change of font, placement, or rendering - Harley. */
|
||||
if (font && font->filepath &&
|
||||
(BLI_path_cmp(BLI_path_basename(font->filepath), BLF_DEFAULT_PROPORTIONAL_FONT) == 0))
|
||||
{
|
||||
font->face_flags &= ~FT_FACE_FLAG_KERNING;
|
||||
}
|
||||
|
||||
if (FT_HAS_MULTIPLE_MASTERS(font)) {
|
||||
FT_Get_MM_Var(font->face, &(font->variations));
|
||||
}
|
||||
|
|
|
@ -94,7 +94,6 @@ static GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
|
|||
gc->char_width = font->char_width;
|
||||
gc->char_spacing = font->char_spacing;
|
||||
|
||||
memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table));
|
||||
memset(gc->bucket, 0, sizeof(gc->bucket));
|
||||
|
||||
blf_ensure_size(font);
|
||||
|
@ -169,15 +168,13 @@ void blf_glyph_cache_clear(FontBLF *font)
|
|||
*
|
||||
* \return nullptr if not found.
|
||||
*/
|
||||
static GlyphBLF *blf_glyph_cache_find_glyph(const GlyphCacheBLF *gc, uint charcode)
|
||||
static GlyphBLF *blf_glyph_cache_find_glyph(const GlyphCacheBLF *gc,
|
||||
uint charcode,
|
||||
uint8_t subpixel)
|
||||
{
|
||||
if (charcode < GLYPH_ASCII_TABLE_SIZE) {
|
||||
return gc->glyph_ascii_table[charcode];
|
||||
}
|
||||
|
||||
GlyphBLF *g = static_cast<GlyphBLF *>(gc->bucket[blf_hash(charcode)].first);
|
||||
GlyphBLF *g = static_cast<GlyphBLF *>(gc->bucket[blf_hash(charcode << 6 | subpixel)].first);
|
||||
while (g) {
|
||||
if (g->c == charcode) {
|
||||
if (g->c == charcode && g->subpixel == subpixel) {
|
||||
return g;
|
||||
}
|
||||
g = g->next;
|
||||
|
@ -225,8 +222,12 @@ 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)
|
||||
static GlyphBLF *blf_glyph_cache_add_glyph(FontBLF *font,
|
||||
GlyphCacheBLF *gc,
|
||||
FT_GlyphSlot glyph,
|
||||
uint charcode,
|
||||
FT_UInt glyph_index,
|
||||
uint8_t subpixel)
|
||||
{
|
||||
GlyphBLF *g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_get");
|
||||
g->c = charcode;
|
||||
|
@ -237,6 +238,7 @@ static GlyphBLF *blf_glyph_cache_add_glyph(
|
|||
g->dims[0] = int(glyph->bitmap.width);
|
||||
g->dims[1] = int(glyph->bitmap.rows);
|
||||
g->pitch = glyph->bitmap.pitch;
|
||||
g->subpixel = subpixel;
|
||||
|
||||
FT_BBox bbox;
|
||||
FT_Outline_Get_CBox(&(glyph->outline), &bbox);
|
||||
|
@ -269,11 +271,7 @@ static GlyphBLF *blf_glyph_cache_add_glyph(
|
|||
memcpy(g->bitmap, glyph->bitmap.buffer, size_t(buffer_size));
|
||||
}
|
||||
|
||||
const uint key = blf_hash(g->c);
|
||||
BLI_addhead(&(gc->bucket[key]), g);
|
||||
if (charcode < GLYPH_ASCII_TABLE_SIZE) {
|
||||
gc->glyph_ascii_table[charcode] = g;
|
||||
}
|
||||
BLI_addhead(&(gc->bucket[blf_hash(g->c << 6 | subpixel)]), g);
|
||||
|
||||
return g;
|
||||
}
|
||||
|
@ -731,9 +729,8 @@ static FT_GlyphSlot blf_glyph_load(FontBLF *font, FT_UInt glyph_index)
|
|||
load_flags |= FT_LOAD_TARGET_NORMAL;
|
||||
}
|
||||
else {
|
||||
/* Default, hinting disabled until FreeType has been upgraded
|
||||
* to give good results on all platforms. */
|
||||
load_flags |= FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING;
|
||||
/* Default "Auto" is Slight (vertical only) hinting. */
|
||||
load_flags |= FT_LOAD_TARGET_LIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -998,6 +995,7 @@ static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font,
|
|||
FontBLF *glyph_font,
|
||||
FT_UInt glyph_index,
|
||||
uint charcode,
|
||||
uint8_t subpixel,
|
||||
int fixed_width)
|
||||
{
|
||||
if (glyph_font != settings_font) {
|
||||
|
@ -1071,15 +1069,20 @@ static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font,
|
|||
blf_glyph_transform_spacing(glyph, spacing);
|
||||
}
|
||||
|
||||
FT_Outline_Translate(&glyph->outline, (FT_Pos)subpixel, 0);
|
||||
|
||||
if (blf_glyph_render_bitmap(glyph_font, glyph)) {
|
||||
return glyph;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GlyphBLF *blf_glyph_ensure(FontBLF *font, GlyphCacheBLF *gc, const uint charcode)
|
||||
static GlyphBLF *blf_glyph_ensure_ex(FontBLF *font,
|
||||
GlyphCacheBLF *gc,
|
||||
const uint charcode,
|
||||
uint8_t subpixel)
|
||||
{
|
||||
GlyphBLF *g = blf_glyph_cache_find_glyph(gc, charcode);
|
||||
GlyphBLF *g = blf_glyph_cache_find_glyph(gc, charcode, subpixel);
|
||||
if (g) {
|
||||
return g;
|
||||
}
|
||||
|
@ -1093,16 +1096,44 @@ GlyphBLF *blf_glyph_ensure(FontBLF *font, GlyphCacheBLF *gc, const uint charcode
|
|||
}
|
||||
|
||||
FT_GlyphSlot glyph = blf_glyph_render(
|
||||
font, font_with_glyph, glyph_index, charcode, gc->fixed_width);
|
||||
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);
|
||||
g = blf_glyph_cache_add_glyph(font, gc, glyph, charcode, glyph_index, 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)
|
||||
{
|
||||
if (font->flags & BLF_HINTING_NONE) {
|
||||
/* Not if we are not also hinting.*/
|
||||
return g;
|
||||
}
|
||||
|
||||
if (font->size > 35.0f || g->dims[0] == 0 || g->advance_x < 0) {
|
||||
/* Single position for large sizes, spaces, and combining characters. */
|
||||
return g;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
return g;
|
||||
}
|
||||
#endif
|
||||
|
||||
void blf_glyph_free(GlyphBLF *g)
|
||||
{
|
||||
if (g->bitmap) {
|
||||
|
@ -1130,8 +1161,8 @@ static void blf_glyph_calc_rect_test(rcti *rect, GlyphBLF *g, const int x, const
|
|||
/* 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;
|
||||
rect->xmax = rect->xmin + MIN2(ft_pix_to_int(g->advance_x), g->dims[0]);
|
||||
rect->xmin = x + g->pos[0] + 1;
|
||||
rect->xmax = x + MIN2(ft_pix_to_int(g->advance_x), g->dims[0]);
|
||||
rect->ymin = y;
|
||||
rect->ymax = rect->ymin - g->dims[1];
|
||||
}
|
||||
|
|
|
@ -24,6 +24,16 @@ struct rcti;
|
|||
*/
|
||||
#define BLF_MAX_FONT 64
|
||||
|
||||
/**
|
||||
* If enabled, glyphs positions are on 64ths of a pixel. Disabled, they are on whole pixels.
|
||||
*/
|
||||
#define BLF_SUBPIXEL_POSITION
|
||||
|
||||
/**
|
||||
* If enabled, glyphs are rendered at multiple horizontal subpixel positions.
|
||||
*/
|
||||
#define BLF_SUBPIXEL_AA
|
||||
|
||||
/** Maximum number of opened FT_Face objects managed by cache. 0 is default of 2. */
|
||||
#define BLF_CACHE_MAX_FACES 4
|
||||
/** Maximum number of opened FT_Size objects managed by cache. 0 is default of 4 */
|
||||
|
@ -168,6 +178,13 @@ void blf_glyph_cache_clear(struct FontBLF *font);
|
|||
*/
|
||||
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
|
||||
|
||||
void blf_glyph_free(struct GlyphBLF *g);
|
||||
void blf_glyph_draw(
|
||||
struct FontBLF *font, struct GlyphCacheBLF *gc, struct GlyphBLF *g, int x, int y);
|
||||
|
|
|
@ -44,31 +44,13 @@ typedef int32_t ft_pix;
|
|||
|
||||
/* Macros copied from `include/freetype/internal/ftobjs.h`. */
|
||||
|
||||
/**
|
||||
* FIXME(@ideasman42): Follow rounding from Blender 3.1x and older.
|
||||
* This is what users will expect and changing this creates wider spaced text.
|
||||
* Use this macro to communicate that rounding should be used, using floor is to avoid
|
||||
* user visible changes, which can be reviewed and handled separately.
|
||||
*/
|
||||
#define USE_LEGACY_SPACING
|
||||
|
||||
#define FT_PIX_FLOOR(x) ((x) & ~63)
|
||||
#define FT_PIX_ROUND(x) FT_PIX_FLOOR((x) + 32)
|
||||
#define FT_PIX_CEIL(x) ((x) + 63)
|
||||
|
||||
#ifdef USE_LEGACY_SPACING
|
||||
# define FT_PIX_DEFAULT_ROUNDING(x) FT_PIX_FLOOR(x)
|
||||
#else
|
||||
# define FT_PIX_DEFAULT_ROUNDING(x) FT_PIX_ROUND(x)
|
||||
#endif
|
||||
|
||||
BLI_INLINE int ft_pix_to_int(ft_pix v)
|
||||
{
|
||||
#ifdef USE_LEGACY_SPACING
|
||||
return (int)(v >> 6);
|
||||
#else
|
||||
return (int)(FT_PIX_DEFAULT_ROUNDING(v) >> 6);
|
||||
#endif
|
||||
}
|
||||
|
||||
BLI_INLINE int ft_pix_to_int_floor(ft_pix v)
|
||||
|
@ -91,23 +73,10 @@ BLI_INLINE ft_pix ft_pix_from_float(float v)
|
|||
return lroundf(v * 64.0f);
|
||||
}
|
||||
|
||||
BLI_INLINE ft_pix ft_pix_round_advance(ft_pix v, ft_pix step)
|
||||
{
|
||||
/** See #USE_LEGACY_SPACING, rounding logic could change here. */
|
||||
return FT_PIX_DEFAULT_ROUNDING(v) + FT_PIX_DEFAULT_ROUNDING(step);
|
||||
}
|
||||
|
||||
#undef FT_PIX_ROUND
|
||||
#undef FT_PIX_CEIL
|
||||
#undef FT_PIX_DEFAULT_ROUNDING
|
||||
|
||||
/** \} */
|
||||
|
||||
#define BLF_BATCH_DRAW_LEN_MAX 2048 /* in glyph */
|
||||
|
||||
/** Number of characters in #GlyphCacheBLF.glyph_ascii_table. */
|
||||
#define GLYPH_ASCII_TABLE_SIZE 128
|
||||
|
||||
/** Number of characters in #KerningCacheBLF.table. */
|
||||
#define KERNING_CACHE_TABLE_SIZE 128
|
||||
|
||||
|
@ -161,9 +130,6 @@ typedef struct GlyphCacheBLF {
|
|||
/** The glyphs. */
|
||||
ListBase bucket[257];
|
||||
|
||||
/** Fast ascii lookup */
|
||||
struct GlyphBLF *glyph_ascii_table[GLYPH_ASCII_TABLE_SIZE];
|
||||
|
||||
/** Texture array, to draw the glyphs. */
|
||||
GPUTexture *texture;
|
||||
char *bitmap_result;
|
||||
|
@ -190,6 +156,7 @@ typedef struct GlyphBLF {
|
|||
ft_pix box_ymax;
|
||||
|
||||
ft_pix advance_x;
|
||||
uint8_t subpixel;
|
||||
|
||||
/** The difference in bearings when hinting is active, zero otherwise. */
|
||||
ft_pix lsb_delta;
|
||||
|
|
|
@ -1656,7 +1656,7 @@ float UI_text_clip_middle_ex(const uiFontStyle *fstyle,
|
|||
strwidth = BLF_width(fstyle->uifont_id, str, max_len);
|
||||
}
|
||||
|
||||
BLI_assert((strwidth <= okwidth) || (okwidth <= 0.0f));
|
||||
BLI_assert((strwidth <= (okwidth + 1)) || (okwidth <= 0.0f));
|
||||
|
||||
return strwidth;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue