diff --git a/awtk_config.py b/awtk_config.py index ea6414be7..716de8ba3 100644 --- a/awtk_config.py +++ b/awtk_config.py @@ -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 ' diff --git a/docs/changes.md b/docs/changes.md index 59edc0c48..764668727 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -2,6 +2,7 @@ 2021/03/24 * 修复file\_browser\_view控件返回上级目录时将文件夹显示为文件的问题(感谢雨欣提供补丁) + * 优化freetype获取灰度图字模型的效果,添加stb二值化字模的功能并在mono模式下默认使用stb(感谢雨欣提供补丁) 2021/03/19 * 修复list view layout内存泄漏(感谢兆坤提供补丁) diff --git a/src/font_loader/font_loader_ft.c b/src/font_loader/font_loader_ft.c index d208d0dbe..8e2e7eb1a 100644 --- a/src/font_loader/font_loader_ft.c +++ b/src/font_loader/font_loader_ft.c @@ -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; diff --git a/src/font_loader/font_loader_stb.c b/src/font_loader/font_loader_stb.c index c22e66ec8..36ba6816f 100644 --- a/src/font_loader/font_loader_stb.c +++ b/src/font_loader/font_loader_stb.c @@ -16,6 +16,7 @@ * History: * ================================================================ * 2018-01-21 Li XianJing created + * 2021-03-22 Li YuXin 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*/ diff --git a/src/font_loader/font_loader_stb.h b/src/font_loader/font_loader_stb.h index 0f8bee786..7e0b6ce75 100644 --- a/src/font_loader/font_loader_stb.h +++ b/src/font_loader/font_loader_stb.h @@ -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*/