improve mono font

This commit is contained in:
lixianjing 2021-03-24 17:15:28 +08:00
parent 49762b52ef
commit 932d0a182f
5 changed files with 119 additions and 10 deletions

View File

@ -116,7 +116,7 @@ if LCD == 'SDL_GPU':
elif LCD == 'SDL_FB_MONO':
NANOVG_BACKEND='AGGE'
COMMON_CCFLAGS = COMMON_CCFLAGS + ' -DWITH_LCD_MONO -DWITH_NANOVG_SOFT '
COMMON_CCFLAGS=COMMON_CCFLAGS+' -DWITH_FT_FONT '
COMMON_CCFLAGS=COMMON_CCFLAGS+' -DWITH_STB_FONT '
else:
COMMON_CCFLAGS=COMMON_CCFLAGS+' -DWITH_STB_FONT '
COMMON_CCFLAGS = COMMON_CCFLAGS + ' -DWITH_BITMAP_BGRA -DWITH_NANOVG_SOFT '

View File

@ -2,6 +2,7 @@
2021/03/24
* 修复file\_browser\_view控件返回上级目录时将文件夹显示为文件的问题感谢雨欣提供补丁
* 优化freetype获取灰度图字模型的效果添加stb二值化字模的功能并在mono模式下默认使用stb感谢雨欣提供补丁
2021/03/19
* 修复list view layout内存泄漏感谢兆坤提供补丁

View File

@ -69,7 +69,7 @@ static ret_t font_ft_get_glyph(font_t* f, wchar_t c, font_size_t font_size, glyp
ft_fontinfo* sf = &(font->ft_font);
FT_Glyph glyph;
FT_GlyphSlot glyf;
uint32_t flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER;
uint32_t flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER | FT_LOAD_NO_AUTOHINT | FT_OUTLINE_HIGH_PRECISION;
g->data = NULL;
if (glyph_cache_lookup(&(font->cache), c, font_size, g) == RET_OK) {
@ -162,7 +162,8 @@ static ret_t destroy_glyph(void* data) {
return glyph_ft_destory((glyph_ft_t*)(data));
}
font_t* font_ft_create_ex(const char* name, const uint8_t* buff, uint32_t size, bool_t mono) {
static font_t* font_ft_create_ex(const char* name, const uint8_t* buff, uint32_t size,
bool_t mono) {
font_ft_t* f = NULL;
return_value_if_fail(buff != NULL && name != NULL, NULL);
@ -233,7 +234,7 @@ static font_t* font_ft_load_mono(font_loader_t* loader, const char* name, const
return font_ft_create_ex(name, buff, buff_size, TRUE);
}
font_loader_t* font_loader_mono_ft(void) {
font_loader_t* font_loader_ft_mono(void) {
static font_loader_t loader;
loader.type = ASSET_TYPE_FONT_TTF;
loader.load = font_ft_load_mono;

View File

@ -16,6 +16,7 @@
* History:
* ================================================================
* 2018-01-21 Li XianJing <xianjimli@hotmail.com> created
* 2021-03-22 Li YuXin <liuyuxin@zlg.cn> improve mono
*
*/
@ -42,9 +43,42 @@ typedef struct _font_stb_t {
int ascent;
int descent;
int line_gap;
bool_t mono;
} font_stb_t;
static ret_t font_stb_gray_to_mono_by_threshold(const glyph_t* gray, glyph_t* mono,
uint32_t threshold) {
return_value_if_fail(gray != NULL && mono != NULL && gray->format == GLYPH_FMT_ALPHA,
RET_BAD_PARAMS);
uint32_t i = 0;
uint32_t j = 0;
uint16_t h = gray->h;
uint16_t w = gray->w;
mono->format = GLYPH_FMT_MONO;
mono->h = h;
mono->w = w;
mono->pitch = ((mono->w + 15) >> 4) << 1;
mono->x = gray->x;
mono->y = gray->y;
mono->advance = gray->advance;
uint32_t nmemb = mono->pitch * h;
uint8_t* bitmap = TKMEM_CALLOC(nmemb, sizeof(uint8_t));
return_value_if_fail(bitmap != NULL, RET_OOM);
for (j = 0; j < h; ++j) {
for (i = 0; i < w; ++i) {
if (gray->data[w * j + i] > threshold) {
uint32_t offset = j * mono->pitch + (i >> 3);
uint32_t offset_bit = 7 - (i % 8);
bitmap[offset] += 0x1 << offset_bit;
}
}
}
mono->data = bitmap;
return RET_OK;
}
static bool_t font_stb_match(font_t* f, const char* name, font_size_t font_size) {
(void)font_size;
return (name == NULL || strcmp(name, f->name) == 0);
@ -70,6 +104,7 @@ static ret_t font_stb_get_glyph(font_t* f, wchar_t c, font_size_t font_size, gly
int h = 0;
int lsb = 0;
int advance = 0;
uint8_t* bitmap = NULL;
font_stb_t* font = (font_stb_t*)f;
stbtt_fontinfo* sf = &(font->stb_font);
float scale = stbtt_ScaleForPixelHeight(sf, font_size);
@ -78,7 +113,7 @@ static ret_t font_stb_get_glyph(font_t* f, wchar_t c, font_size_t font_size, gly
return RET_OK;
}
g->data = stbtt_GetCodepointBitmap(sf, 0, scale, c, &w, &h, &x, &y);
bitmap = stbtt_GetCodepointBitmap(sf, 0, scale, c, &w, &h, &x, &y);
stbtt_GetCodepointHMetrics(sf, c, &advance, &lsb);
g->x = x;
@ -87,8 +122,24 @@ static ret_t font_stb_get_glyph(font_t* f, wchar_t c, font_size_t font_size, gly
g->h = h;
g->format = GLYPH_FMT_ALPHA;
g->advance = advance * scale;
g->data = NULL;
if (bitmap != NULL) {
if (font->mono) {
glyph_t* gray_g = glyph_clone(g);
gray_g->data = bitmap;
uint32_t threshold =
font_size > 24
? (font_size > 48 ? (font_size > 71 ? (font_size > 95 ? 195 : 175) : 160) : 118)
: 95;
font_stb_gray_to_mono_by_threshold(gray_g, g, threshold);
STBTT_free(bitmap, NULL);
glyph_destroy(gray_g);
} else {
g->data = bitmap;
}
return_value_if_fail(g->data != NULL, RET_FAIL);
if (g->data != NULL) {
glyph_t* gg = glyph_clone(g);
if (gg != NULL) {
if (glyph_cache_add(&(font->cache), c, font_size, gg) != RET_OK) {
@ -131,19 +182,21 @@ static ret_t destroy_glyph(void* data) {
return RET_OK;
}
font_t* font_stb_create(const char* name, const uint8_t* buff, uint32_t buff_size) {
static font_t* font_stb_create_ex(const char* name, const uint8_t* buff, uint32_t buff_size,
bool_t mono) {
font_stb_t* f = NULL;
return_value_if_fail(buff != NULL && name != NULL, NULL);
f = TKMEM_ZALLOC(font_stb_t);
return_value_if_fail(f != NULL, NULL);
f->mono = mono;
f->base.match = font_stb_match;
f->base.destroy = font_stb_destroy;
f->base.get_glyph = font_stb_get_glyph;
f->base.get_vmetrics = font_stb_get_vmetrics;
f->base.shrink_cache = font_stb_shrink_cache;
f->base.desc = "truetype(stb)";
f->base.desc = mono ? "mono(stb)" : "truetype(stb)";
tk_strncpy(f->base.name, name, TK_NAME_LEN);
@ -154,6 +207,18 @@ font_t* font_stb_create(const char* name, const uint8_t* buff, uint32_t buff_siz
return &(f->base);
}
font_t* font_stb_mono_create(const char* name, const uint8_t* buff, uint32_t size) {
return font_stb_create_ex(name, buff, size, TRUE);
}
font_t* font_stb_create(const char* name, const uint8_t* buff, uint32_t size) {
#ifdef WITH_LCD_MONO
return font_stb_create_ex(name, buff, size, TRUE);
#else
return font_stb_create_ex(name, buff, size, FALSE);
#endif
}
static font_t* font_stb_load(font_loader_t* loader, const char* name, const uint8_t* buff,
uint32_t buff_size) {
(void)loader;
@ -168,12 +233,31 @@ font_loader_t* font_loader_stb(void) {
return &loader;
}
static font_t* font_stb_load_mono(font_loader_t* loader, const char* name, const uint8_t* buff,
uint32_t buff_size) {
(void)loader;
return font_stb_create_ex(name, buff, buff_size, TRUE);
}
font_loader_t* font_loader_stb_mono(void) {
static font_loader_t loader;
loader.type = ASSET_TYPE_FONT_TTF;
loader.load = font_stb_load_mono;
return &loader;
}
#else
font_loader_t* font_loader_stb(void) {
return NULL;
}
font_t* font_stb_create(const char* name, const uint8_t* buff, uint32_t buff_size) {
font_t* font_stb_mono_create(const char* name, const uint8_t* buff, uint32_t size) {
return NULL;
}
font_t* font_stb_create(const char* name, const uint8_t* buff, uint32_t size) {
return NULL;
}
#endif /*WITH_STB_FONT*/

View File

@ -60,6 +60,29 @@ font_loader_t* font_loader_stb(void);
*/
font_t* font_stb_create(const char* name, const uint8_t* buff, uint32_t size);
/**
* @method font_loader_stb_mono
* @annotation ["constructor"]
*
* stb mono字体加载器对象
*
* @return {font_loader_t*}
*/
font_loader_t* font_loader_stb_mono(void);
/**
* @method font_stb_mono_create
* @annotation ["static"]
*
* stb mono字体对象
* @param {const char*} name
* @param {const uint8_t* buff}
* @param {uint32_t} size
*
* @return {font_t*}
*/
font_t* font_stb_mono_create(const char* name, const uint8_t* buff, uint32_t size);
END_C_DECLS
#endif /*TK_FONT_LOADER_STB_H*/