From 9b85ed33e3348b4268ae65a02e6b37da25d9f3c5 Mon Sep 17 00:00:00 2001 From: Liu Date: Sun, 5 Jan 2025 19:07:36 +0800 Subject: [PATCH] feat: font alias --- README.zh-cn.md | 10 +- include/LCUI/fonts.h | 13 + lib/pandagl/include/pandagl/font.h | 104 +-- lib/pandagl/src/font/library.c | 1133 ++++++++++++++-------------- lib/ui/include/ui/text_style.h | 1 - src/lcui_fonts.c | 60 +- 6 files changed, 691 insertions(+), 630 deletions(-) create mode 100644 include/LCUI/fonts.h diff --git a/README.zh-cn.md b/README.zh-cn.md index 6464a596d..645068cce 100644 --- a/README.zh-cn.md +++ b/README.zh-cn.md @@ -20,13 +20,13 @@ - [目录](#%E7%9B%AE%E5%BD%95) - [介绍](#%E4%BB%8B%E7%BB%8D) - - [主要特性](#%E4%B8%BB%E8%A6%81%E7%89%B9%E6%80%A7) - - [一图速览](#%E4%B8%80%E5%9B%BE%E9%80%9F%E8%A7%88) - - [架构](#%E6%9E%B6%E6%9E%84) + - [主要特性](#%E4%B8%BB%E8%A6%81%E7%89%B9%E6%80%A7) + - [开发体验预览](#%E5%BC%80%E5%8F%91%E4%BD%93%E9%AA%8C%E9%A2%84%E8%A7%88) + - [架构](#%E6%9E%B6%E6%9E%84) - [快速体验](#%E5%BF%AB%E9%80%9F%E4%BD%93%E9%AA%8C) - [文档](#%E6%96%87%E6%A1%A3) - - [教程](#%E6%95%99%E7%A8%8B) - - [参考资料](#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99) + - [教程](#%E6%95%99%E7%A8%8B) + - [参考资料](#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99) - [路线图](#%E8%B7%AF%E7%BA%BF%E5%9B%BE) - [贡献](#%E8%B4%A1%E7%8C%AE) - [常见问题](#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) diff --git a/include/LCUI/fonts.h b/include/LCUI/fonts.h new file mode 100644 index 000000000..0a2d066a5 --- /dev/null +++ b/include/LCUI/fonts.h @@ -0,0 +1,13 @@ + +#ifndef LCUI_INCLUDE_LCUI_FONTS_H +#define LCUI_INCLUDE_LCUI_FONTS_H + +#include "common.h" + +LCUI_BEGIN_HEADER + +LCUI_API bool lcui_fonts_set_default(const char *family_name); + +#define lcui_set_default_font lcui_fonts_set_default + +#endif diff --git a/lib/pandagl/include/pandagl/font.h b/lib/pandagl/include/pandagl/font.h index 1dfdefd18..a82936a70 100644 --- a/lib/pandagl/include/pandagl/font.h +++ b/lib/pandagl/include/pandagl/font.h @@ -15,65 +15,65 @@ #include "common.h" typedef enum pd_font_style_t { - PD_FONT_STYLE_NORMAL, - PD_FONT_STYLE_ITALIC, - PD_FONT_STYLE_OBLIQUE, - PD_FONT_STYLE_TOTAL_NUM + PD_FONT_STYLE_NORMAL, + PD_FONT_STYLE_ITALIC, + PD_FONT_STYLE_OBLIQUE, + PD_FONT_STYLE_TOTAL_NUM } pd_font_style_t; typedef enum pd_font_weight_t { - PD_FONT_WEIGHT_NONE, - PD_FONT_WEIGHT_THIN, - PD_FONT_WEIGHT_EXTRA_LIGHT, - PD_FONT_WEIGHT_LIGHT, - PD_FONT_WEIGHT_NORMAL, - PD_FONT_WEIGHT_MEDIUM, - PD_FONT_WEIGHT_SEMI_BOLD, - PD_FONT_WEIGHT_BOLD, - PD_FONT_WEIGHT_EXTRA_BOLD, - PD_FONT_WEIGHT_BLACK, - PD_FONT_WEIGHT_TOTAL_NUM + PD_FONT_WEIGHT_NONE, + PD_FONT_WEIGHT_THIN, + PD_FONT_WEIGHT_EXTRA_LIGHT, + PD_FONT_WEIGHT_LIGHT, + PD_FONT_WEIGHT_NORMAL, + PD_FONT_WEIGHT_MEDIUM, + PD_FONT_WEIGHT_SEMI_BOLD, + PD_FONT_WEIGHT_BOLD, + PD_FONT_WEIGHT_EXTRA_BOLD, + PD_FONT_WEIGHT_BLACK, + PD_FONT_WEIGHT_TOTAL_NUM } pd_font_weight_t; typedef struct pd_font_bitmap { - int top; /**< 与顶边框的距离 */ - int left; /**< 与左边框的距离 */ - int width; /**< 位图宽度 */ - int rows; /**< 位图行数 */ - int pitch; - uint8_t *buffer; /**< 字体位图数据 */ - struct { - int hori_advance, vert_advance; - int bbox_width, bbox_height; - int ascender; - } metrics; + int top; /**< 与顶边框的距离 */ + int left; /**< 与左边框的距离 */ + int width; /**< 位图宽度 */ + int rows; /**< 位图行数 */ + int pitch; + uint8_t *buffer; /**< 字体位图数据 */ + struct { + int hori_advance, vert_advance; + int bbox_width, bbox_height; + int ascender; + } metrics; } pd_font_bitmap_t; typedef struct font_engine font_engine_t; typedef struct pd_font { - int id; /**< 字体信息ID */ - char *style_name; /**< 样式名称 */ - char *family_name; /**< 字族名称 */ - void *data; /**< 相关数据 */ - pd_font_style_t style; /**< 风格 */ - pd_font_weight_t weight; /**< 粗细程度 */ - font_engine_t *engine; /**< 所属的字体引擎 */ + int id; /**< 字体信息ID */ + char *style_name; /**< 样式名称 */ + char *family_name; /**< 字族名称 */ + void *data; /**< 相关数据 */ + pd_font_style_t style; /**< 风格 */ + pd_font_weight_t weight; /**< 粗细程度 */ + font_engine_t *engine; /**< 所属的字体引擎 */ } pd_font_t; struct font_engine { - char name[64]; - int (*open)(const char *, pd_font_t ***); - int (*render)(pd_font_bitmap_t *, unsigned, int, pd_font_t *); - void (*close)(void *); + char name[64]; + int (*open)(const char *, pd_font_t ***); + int (*render)(pd_font_bitmap_t *, unsigned, int, pd_font_t *); + void (*close)(void *); }; PD_BEGIN_DECLS /** 将字体位图绘制到目标图像上 */ PD_PUBLIC int pd_canvas_mix_font_bitmap(pd_canvas_t *graph, pd_pos_t pos, - const pd_font_bitmap_t *bmp, - pd_color_t color); + const pd_font_bitmap_t *bmp, + pd_color_t color); PD_PUBLIC char *pd_font_library_get_font_path(const char *name); @@ -91,7 +91,7 @@ PD_PUBLIC pd_font_style_t pd_font_library_detect_style(const char *str); /** 载入字体位图 */ PD_PUBLIC int pd_font_library_render_bitmap(pd_font_bitmap_t *buff, unsigned ch, - int font_id, int pixel_size); + int font_id, int pixel_size); /** 添加字体族,并返回该字族的ID */ PD_PUBLIC int pd_font_library_add_font(pd_font_t *font); @@ -103,8 +103,8 @@ PD_PUBLIC int pd_font_library_add_font(pd_font_t *font); * @param[in] weight 字体粗细程度,若为值 0,则默认为 PD_FONT_WEIGHT_NORMAL */ PD_PUBLIC int pd_font_library_get_font_id(const char *family_name, - pd_font_style_t style, - pd_font_weight_t weight); + pd_font_style_t style, + pd_font_weight_t weight); /** * 更新当前字体的粗细程度 @@ -113,8 +113,8 @@ PD_PUBLIC int pd_font_library_get_font_id(const char *family_name, * @params[out] new_font_ids 更新字体粗细程度后的字体 id 列表 */ PD_PUBLIC size_t pd_font_library_update_font_weight(const int *font_ids, - pd_font_weight_t weight, - int **new_font_ids); + pd_font_weight_t weight, + int **new_font_ids); /** * 更新当前字体的风格 @@ -123,8 +123,8 @@ PD_PUBLIC size_t pd_font_library_update_font_weight(const int *font_ids, * @params[out] new_font_ids 更新字体粗细程度后的字体 id 列表 */ PD_PUBLIC size_t pd_font_library_update_font_style(const int *font_ids, - pd_font_style_t style, - int **new_font_ids); + pd_font_style_t style, + int **new_font_ids); /** * 根据字族名称获取对应的字体 ID 列表 @@ -135,8 +135,8 @@ PD_PUBLIC size_t pd_font_library_update_font_style(const int *font_ids, * @return 获取到的字体 ID 的数量 */ PD_PUBLIC unsigned pd_font_library_query(int **font_ids, pd_font_style_t style, - pd_font_weight_t weight, - const char *const *names); + pd_font_weight_t weight, + const char *const *names); /** 获取指定字体ID的字体信息 */ PD_PUBLIC pd_font_t *pd_font_library_get_font(int id); @@ -144,9 +144,13 @@ PD_PUBLIC pd_font_t *pd_font_library_get_font(int id); /** 获取默认的字体ID */ PD_PUBLIC int pd_font_library_get_default_font(void); -/** 设定默认的字体 */ +/** 设置默认的字体 */ PD_PUBLIC void pd_font_library_set_default_font(int id); +/** 设置字体族的别名 */ +PD_PUBLIC bool pd_font_library_set_font_family_alias(const char *alias, + const char *family_name); + /** * 向字体缓存中添加字体位图 * @param[in] ch 字符码 @@ -169,7 +173,7 @@ PD_PUBLIC pd_font_bitmap_t *pd_font_library_add_bitmap( * 空间存储字体位图的拷贝。 */ PD_PUBLIC int pd_font_library_get_bitmap(unsigned ch, int font_id, int size, - const pd_font_bitmap_t **bmp); + const pd_font_bitmap_t **bmp); /** 载入字体至数据库中 */ PD_PUBLIC int pd_font_library_load_file(const char *filepath); diff --git a/lib/pandagl/src/font/library.c b/lib/pandagl/src/font/library.c index 7c92f2df5..a7d8d4440 100644 --- a/lib/pandagl/src/font/library.c +++ b/lib/pandagl/src/font/library.c @@ -1,5 +1,6 @@ /* - * lib/pandagl/src/font/library.c: -- The font info and font bitmap cache module. + * lib/pandagl/src/font/library.c: -- The font info and font bitmap cache + * module. * * Copyright (c) 2018-2024, Liu chao All rights reserved. * @@ -50,39 +51,46 @@ typedef struct font_family_node { } font_family_node_t; static struct font_library_module { - int count; /**< 计数器,主要用于为字体信息生成标识号 */ - int font_cache_num; /**< 字体信息缓存区的数量 */ - bool active; /**< 标记,指示数据库是否初始化 */ - dict_t *font_families; /**< 字族信息库,以字族名称索引字体信息 */ - dict_type_t font_families_type; /**< 字族信息库的字典类型数据 */ - rbtree_t bitmap_cache; /**< 字体位图缓存区 */ - font_cache_t **font_cache; /**< 字体信息缓存区 */ - pd_font_t *default_font; /**< 默认字体的信息 */ - pd_font_t *incore_font; /**< 内置字体的信息 */ - font_engine_t engines[2]; /**< 当前可用字体引擎列表 */ - font_engine_t *engine; /**< 当前选择的字体引擎 */ + int count; + int font_cache_num; + bool active; + + /** dict_t */ + dict_t *font_families; + + /** dict_t */ + dict_t *font_family_aliases; + + /** rbtree_t>> */ + rbtree_t bitmap_cache; + + font_cache_t **font_cache; + pd_font_t *default_font; + pd_font_t *incore_font; + font_engine_t engines[2]; + font_engine_t *engine; } fontlib; /* clang-format on */ PD_INLINE rbtree_t *select_char_cache(wchar_t ch) { - return rbtree_get_data_by_key(&fontlib.bitmap_cache, ch); + return rbtree_get_data_by_key(&fontlib.bitmap_cache, ch); } PD_INLINE rbtree_t *select_font_cache(rbtree_t *font_cache, int font_id) { - return rbtree_get_data_by_key(font_cache, font_id); + return rbtree_get_data_by_key(font_cache, font_id); } PD_INLINE pd_font_bitmap_t *select_bitmap_cache(rbtree_t *bmp_cache, int size) { - return rbtree_get_data_by_key(bmp_cache, size); + return rbtree_get_data_by_key(bmp_cache, size); } PD_INLINE font_family_node_t *select_font_family_cache(const char *family_name) { - return dict_fetch_value(fontlib.font_families, family_name); + return dict_fetch_value(fontlib.font_families, family_name); } #ifdef PANDAGL_HAS_FONTCONFIG @@ -92,354 +100,354 @@ PD_INLINE font_family_node_t *select_font_family_cache(const char *family_name) char *pd_font_library_get_font_path(const char *name) { #ifdef PANDAGL_HAS_FONTCONFIG - char *path = NULL; - size_t path_len; - - FcResult result; - FcPattern *font; - FcChar8 *file = NULL; - FcConfig *config = FcInitLoadConfigAndFonts(); - FcPattern *pat = FcNameParse((const FcChar8 *)name); - - FcConfigSubstitute(config, pat, FcMatchPattern); - FcDefaultSubstitute(pat); - - if ((font = FcFontMatch(config, pat, &result))) { - if (FcPatternGetString(font, FC_FILE, 0, &file) == - FcResultMatch) { - path_len = strlen((char *)file); - path = (char *)malloc(path_len + 1); - strncpy(path, (char *)file, path_len); - path[path_len] = 0; - } - FcPatternDestroy(font); - } - - FcPatternDestroy(pat); - FcConfigDestroy(config); - - return path; + char *path = NULL; + size_t path_len; + + FcResult result; + FcPattern *font; + FcChar8 *file = NULL; + FcConfig *config = FcInitLoadConfigAndFonts(); + FcPattern *pat = FcNameParse((const FcChar8 *)name); + + FcConfigSubstitute(config, pat, FcMatchPattern); + FcDefaultSubstitute(pat); + + if ((font = FcFontMatch(config, pat, &result))) { + if (FcPatternGetString(font, FC_FILE, 0, &file) == + FcResultMatch) { + path_len = strlen((char *)file); + path = (char *)malloc(path_len + 1); + strncpy(path, (char *)file, path_len); + path[path_len] = 0; + } + FcPatternDestroy(font); + } + + FcPatternDestroy(pat); + FcConfigDestroy(config); + + return path; #else - return NULL; + return NULL; #endif } pd_font_t *pd_font_create(const char *family_name, const char *style_name) { - pd_font_t *font; + pd_font_t *font; - font = malloc(sizeof(pd_font_t)); - font->id = 0; - font->data = NULL; - font->engine = NULL; - font->family_name = strdup2(family_name); - font->style_name = strdup2(style_name); - font->weight = pd_font_library_detect_weight(style_name); - font->style = pd_font_library_detect_style(style_name); - return font; + font = malloc(sizeof(pd_font_t)); + font->id = 0; + font->data = NULL; + font->engine = NULL; + font->family_name = strdup2(family_name); + font->style_name = strdup2(style_name); + font->weight = pd_font_library_detect_weight(style_name); + font->style = pd_font_library_detect_style(style_name); + return font; } void pd_font_destroy(pd_font_t *font) { - free(font->family_name); - free(font->style_name); - font->engine->close(font->data); - font->data = NULL; - font->engine = NULL; - free(font); + free(font->family_name); + free(font->style_name); + font->engine->close(font->data); + font->data = NULL; + font->engine = NULL; + free(font); } static void destroy_font_family_node(void *privdata, void *data) { - font_family_node_t *node = data; - if (node->family_name) { - free(node->family_name); - } - node->family_name = NULL; - memset(node->styles, 0, sizeof(node->styles)); - free(node); + font_family_node_t *node = data; + if (node->family_name) { + free(node->family_name); + } + node->family_name = NULL; + memset(node->styles, 0, sizeof(node->styles)); + free(node); } static void destroy_font_bitmap(void *arg) { - pd_font_bitmap_destroy(arg); - free(arg); + pd_font_bitmap_destroy(arg); + free(arg); } static void destroy_tree_node(void *arg) { - rbtree_destroy(arg); - free(arg); + rbtree_destroy(arg); + free(arg); } pd_font_bitmap_t *pd_font_library_add_bitmap(wchar_t ch, int font_id, int size, - const pd_font_bitmap_t *bmp) -{ - pd_font_bitmap_t *bmp_cache; - rbtree_t *tree_font, *tree_bmp; - - if (!fontlib.active) { - return NULL; - } - /* 获取字符的字体信息集 */ - tree_font = select_char_cache(ch); - if (!tree_font) { - tree_font = malloc(sizeof(rbtree_t)); - if (!tree_font) { - return NULL; - } - rbtree_init(tree_font); - rbtree_set_destroy_func(tree_font, destroy_tree_node); - rbtree_insert_by_key(&fontlib.bitmap_cache, ch, tree_font); - } - /* 当字体ID不大于0时,使用内置字体 */ - if (font_id <= 0) { - font_id = fontlib.incore_font->id; - } - /* 获取相应字体样式标识号的字体位图库 */ - tree_bmp = select_font_cache(tree_font, font_id); - if (!tree_bmp) { - tree_bmp = malloc(sizeof(rbtree_t)); - if (!tree_bmp) { - return NULL; - } - rbtree_init(tree_bmp); - rbtree_set_destroy_func(tree_bmp, destroy_font_bitmap); - rbtree_insert_by_key(tree_font, font_id, tree_bmp); - } - /* 在字体位图库中获取指定像素大小的字体位图 */ - bmp_cache = select_bitmap_cache(tree_bmp, size); - if (!bmp_cache) { - bmp_cache = malloc(sizeof(pd_font_bitmap_t)); - if (!bmp_cache) { - return NULL; - } - rbtree_insert_by_key(tree_bmp, size, bmp_cache); - } - /* 拷贝数据至该空间内 */ - memcpy(bmp_cache, bmp, sizeof(pd_font_bitmap_t)); - return bmp_cache; + const pd_font_bitmap_t *bmp) +{ + pd_font_bitmap_t *bmp_cache; + rbtree_t *tree_font, *tree_bmp; + + if (!fontlib.active) { + return NULL; + } + /* 获取字符的字体信息集 */ + tree_font = select_char_cache(ch); + if (!tree_font) { + tree_font = malloc(sizeof(rbtree_t)); + if (!tree_font) { + return NULL; + } + rbtree_init(tree_font); + rbtree_set_destroy_func(tree_font, destroy_tree_node); + rbtree_insert_by_key(&fontlib.bitmap_cache, ch, tree_font); + } + /* 当字体ID不大于0时,使用内置字体 */ + if (font_id <= 0) { + font_id = fontlib.incore_font->id; + } + /* 获取相应字体样式标识号的字体位图库 */ + tree_bmp = select_font_cache(tree_font, font_id); + if (!tree_bmp) { + tree_bmp = malloc(sizeof(rbtree_t)); + if (!tree_bmp) { + return NULL; + } + rbtree_init(tree_bmp); + rbtree_set_destroy_func(tree_bmp, destroy_font_bitmap); + rbtree_insert_by_key(tree_font, font_id, tree_bmp); + } + /* 在字体位图库中获取指定像素大小的字体位图 */ + bmp_cache = select_bitmap_cache(tree_bmp, size); + if (!bmp_cache) { + bmp_cache = malloc(sizeof(pd_font_bitmap_t)); + if (!bmp_cache) { + return NULL; + } + rbtree_insert_by_key(tree_bmp, size, bmp_cache); + } + /* 拷贝数据至该空间内 */ + memcpy(bmp_cache, bmp, sizeof(pd_font_bitmap_t)); + return bmp_cache; } int pd_font_library_get_bitmap(unsigned ch, int font_id, int size, - const pd_font_bitmap_t **bmp) -{ - int ret; - rbtree_t *ctx; - pd_font_bitmap_t bmp_cache; - - *bmp = NULL; - if (!fontlib.active) { - return -2; - } - if (font_id <= 0) { - if (fontlib.default_font) { - font_id = fontlib.default_font->id; - } else { - font_id = fontlib.incore_font->id; - } - } - do { - if (!(ctx = select_char_cache(ch))) { - break; - } - ctx = select_font_cache(ctx, font_id); - if (!ctx) { - break; - } - *bmp = select_bitmap_cache(ctx, size); - if (*bmp) { - return 0; - } - break; - } while (0); - if (ch == 0) { - return -1; - } - pd_font_bitmap_init(&bmp_cache); - ret = pd_font_library_render_bitmap(&bmp_cache, ch, font_id, size); - if (ret == 0) { - *bmp = - pd_font_library_add_bitmap(ch, font_id, size, &bmp_cache); - return 0; - } - ret = pd_font_library_get_bitmap(0, font_id, size, bmp); - if (ret != 0) { - *bmp = pd_font_library_add_bitmap(0, font_id, size, &bmp_cache); - } - return -1; + const pd_font_bitmap_t **bmp) +{ + int ret; + rbtree_t *ctx; + pd_font_bitmap_t bmp_cache; + + *bmp = NULL; + if (!fontlib.active) { + return -2; + } + if (font_id <= 0) { + if (fontlib.default_font) { + font_id = fontlib.default_font->id; + } else { + font_id = fontlib.incore_font->id; + } + } + do { + if (!(ctx = select_char_cache(ch))) { + break; + } + ctx = select_font_cache(ctx, font_id); + if (!ctx) { + break; + } + *bmp = select_bitmap_cache(ctx, size); + if (*bmp) { + return 0; + } + break; + } while (0); + if (ch == 0) { + return -1; + } + pd_font_bitmap_init(&bmp_cache); + ret = pd_font_library_render_bitmap(&bmp_cache, ch, font_id, size); + if (ret == 0) { + *bmp = + pd_font_library_add_bitmap(ch, font_id, size, &bmp_cache); + return 0; + } + ret = pd_font_library_get_bitmap(0, font_id, size, bmp); + if (ret != 0) { + *bmp = pd_font_library_add_bitmap(0, font_id, size, &bmp_cache); + } + return -1; } static font_cache_t *font_cache_create(void) { - font_cache_t *cache; - if (!(cache = malloc(sizeof(font_cache_t)))) { - return NULL; - } - memset(cache->fonts, 0, sizeof(cache->fonts)); - return cache; + font_cache_t *cache; + if (!(cache = malloc(sizeof(font_cache_t)))) { + return NULL; + } + memset(cache->fonts, 0, sizeof(cache->fonts)); + return cache; } static void font_cache_destroy(font_cache_t *cache) { - int i; - for (i = 0; i < FONT_CACHE_SIZE; ++i) { - if (cache->fonts[i]) { - pd_font_destroy(cache->fonts[i]); - } - cache->fonts[i] = NULL; - } - free(cache); + int i; + for (i = 0; i < FONT_CACHE_SIZE; ++i) { + if (cache->fonts[i]) { + pd_font_destroy(cache->fonts[i]); + } + cache->fonts[i] = NULL; + } + free(cache); } static pd_font_t *pd_font_library_get_cached_font(int id) { - if (id > fontlib.font_cache_num * FONT_CACHE_SIZE) { - return NULL; - } - return fontlib.font_cache[id / FONT_CACHE_SIZE] - ->fonts[id % FONT_CACHE_SIZE]; + if (id > fontlib.font_cache_num * FONT_CACHE_SIZE) { + return NULL; + } + return fontlib.font_cache[id / FONT_CACHE_SIZE] + ->fonts[id % FONT_CACHE_SIZE]; } static int pd_font_library_add_cached_font(pd_font_t *font) { - size_t size; - font_cache_t **caches, *cache; - - if (font->id > FONT_CACHE_MAX_SIZE) { - logger_error("[font] font cache size is the max size\n"); - return -1; - } - while (font->id >= fontlib.font_cache_num * FONT_CACHE_SIZE) { - fontlib.font_cache_num += 1; - size = fontlib.font_cache_num * sizeof(font_cache_t); - caches = realloc(fontlib.font_cache, size); - if (!caches) { - fontlib.font_cache_num -= 1; - return -ENOMEM; - } - cache = font_cache_create(); - if (!cache) { - return -ENOMEM; - } - caches[fontlib.font_cache_num - 1] = cache; - fontlib.font_cache = caches; - } - fontlib.font_cache[font->id / FONT_CACHE_SIZE] - ->fonts[font->id % FONT_CACHE_SIZE] = font; - return 0; + size_t size; + font_cache_t **caches, *cache; + + if (font->id > FONT_CACHE_MAX_SIZE) { + logger_error("[font] font cache size is the max size\n"); + return -1; + } + while (font->id >= fontlib.font_cache_num * FONT_CACHE_SIZE) { + fontlib.font_cache_num += 1; + size = fontlib.font_cache_num * sizeof(font_cache_t); + caches = realloc(fontlib.font_cache, size); + if (!caches) { + fontlib.font_cache_num -= 1; + return -ENOMEM; + } + cache = font_cache_create(); + if (!cache) { + return -ENOMEM; + } + caches[fontlib.font_cache_num - 1] = cache; + fontlib.font_cache = caches; + } + fontlib.font_cache[font->id / FONT_CACHE_SIZE] + ->fonts[font->id % FONT_CACHE_SIZE] = font; + return 0; } pd_font_weight_t pd_font_library_detect_weight(const char *str) { - char *buf; - pd_font_weight_t weight = PD_FONT_WEIGHT_NORMAL; - - buf = strdup2(str); - if (!buf) { - return weight; - } - strtolower(buf, str); - if (strstr(buf, "thin")) { - weight = PD_FONT_WEIGHT_THIN; - } else if (strstr(buf, "semilight")) { - weight = PD_FONT_WEIGHT_LIGHT; - } else if (strstr(buf, "light")) { - weight = PD_FONT_WEIGHT_EXTRA_LIGHT; - } else if (strstr(buf, "medium")) { - weight = PD_FONT_WEIGHT_MEDIUM; - } else if (strstr(buf, "semibold")) { - weight = PD_FONT_WEIGHT_SEMI_BOLD; - } else if (strstr(buf, "bold")) { - weight = PD_FONT_WEIGHT_BOLD; - } else if (strstr(buf, "black")) { - weight = PD_FONT_WEIGHT_BLACK; - } - free(buf); - return weight; + char *buf; + pd_font_weight_t weight = PD_FONT_WEIGHT_NORMAL; + + buf = strdup2(str); + if (!buf) { + return weight; + } + strtolower(buf, str); + if (strstr(buf, "thin")) { + weight = PD_FONT_WEIGHT_THIN; + } else if (strstr(buf, "semilight")) { + weight = PD_FONT_WEIGHT_LIGHT; + } else if (strstr(buf, "light")) { + weight = PD_FONT_WEIGHT_EXTRA_LIGHT; + } else if (strstr(buf, "medium")) { + weight = PD_FONT_WEIGHT_MEDIUM; + } else if (strstr(buf, "semibold")) { + weight = PD_FONT_WEIGHT_SEMI_BOLD; + } else if (strstr(buf, "bold")) { + weight = PD_FONT_WEIGHT_BOLD; + } else if (strstr(buf, "black")) { + weight = PD_FONT_WEIGHT_BLACK; + } + free(buf); + return weight; } pd_font_style_t pd_font_library_detect_style(const char *str) { - char *buf; - pd_font_style_t style = PD_FONT_STYLE_NORMAL; + char *buf; + pd_font_style_t style = PD_FONT_STYLE_NORMAL; - buf = strdup2(str); - if (!buf) { - return style; - } - strtolower(buf, str); - if (strstr(buf, "oblique")) { - style = PD_FONT_STYLE_OBLIQUE; - } else if (strstr(buf, "italic")) { - style = PD_FONT_STYLE_ITALIC; - } - free(buf); - return style; + buf = strdup2(str); + if (!buf) { + return style; + } + strtolower(buf, str); + if (strstr(buf, "oblique")) { + style = PD_FONT_STYLE_OBLIQUE; + } else if (strstr(buf, "italic")) { + style = PD_FONT_STYLE_ITALIC; + } + free(buf); + return style; } int pd_font_library_add_font(pd_font_t *font) { - pd_font_t *exists_font; - font_family_node_t *node; - font_style_node_t *style_node; - - node = select_font_family_cache(font->family_name); - if (!node) { - node = malloc(sizeof(font_family_node_t)); - node->family_name = strdup2(font->family_name); - memset(node->styles, 0, sizeof(node->styles)); - dict_add(fontlib.font_families, node->family_name, node); - } - style_node = node->styles + font->style; - exists_font = style_node->weights[font->weight- 1]; - if (exists_font) { - font->id = exists_font->id; - if (fontlib.default_font && - font->id == fontlib.default_font->id) { - fontlib.default_font = font; - } - style_node->weights[font->weight - 1] = NULL; - pd_font_destroy(exists_font); - } else { - font->id = ++fontlib.count; - } - style_node->weights[font->weight - 1] = font; - pd_font_library_add_cached_font(font); - return font->id; + pd_font_t *exists_font; + font_family_node_t *node; + font_style_node_t *style_node; + + node = select_font_family_cache(font->family_name); + if (!node) { + node = malloc(sizeof(font_family_node_t)); + node->family_name = strdup2(font->family_name); + memset(node->styles, 0, sizeof(node->styles)); + dict_add(fontlib.font_families, node->family_name, node); + } + style_node = node->styles + font->style; + exists_font = style_node->weights[font->weight - 1]; + if (exists_font) { + font->id = exists_font->id; + if (fontlib.default_font && + font->id == fontlib.default_font->id) { + fontlib.default_font = font; + } + style_node->weights[font->weight - 1] = NULL; + pd_font_destroy(exists_font); + } else { + font->id = ++fontlib.count; + } + style_node->weights[font->weight - 1] = font; + pd_font_library_add_cached_font(font); + return font->id; } pd_font_t *pd_font_library_get_font(int id) { - if (!fontlib.active) { - return NULL; - } - if (id < 0 || id >= fontlib.font_cache_num * FONT_CACHE_SIZE) { - return NULL; - } - return pd_font_library_get_cached_font(id); + if (!fontlib.active) { + return NULL; + } + if (id < 0 || id >= fontlib.font_cache_num * FONT_CACHE_SIZE) { + return NULL; + } + return pd_font_library_get_cached_font(id); } static pd_font_weight_t find_bolder_weight(font_style_node_t *snode, - pd_font_weight_t weight) + pd_font_weight_t weight) { - for (weight += 1; weight <= PD_FONT_WEIGHT_BLACK; weight += 1) { - if (snode->weights[weight]) { - return weight; - } - } - return PD_FONT_WEIGHT_NONE; + for (weight += 1; weight <= PD_FONT_WEIGHT_BLACK; weight += 1) { + if (snode->weights[weight]) { + return weight; + } + } + return PD_FONT_WEIGHT_NONE; } static pd_font_weight_t find_lighter_weight(font_style_node_t *snode, - pd_font_weight_t weight) + pd_font_weight_t weight) { - for (weight -= 1; weight >= PD_FONT_WEIGHT_THIN; weight -= 1) { - if (snode->weights[weight]) { - return weight; - } - } - return PD_FONT_WEIGHT_NONE; + for (weight -= 1; weight >= PD_FONT_WEIGHT_THIN; weight -= 1) { + if (snode->weights[weight]) { + return weight; + } + } + return PD_FONT_WEIGHT_NONE; } /** @@ -447,309 +455,340 @@ static pd_font_weight_t find_lighter_weight(font_style_node_t *snode, * 回退规则的参考文档:https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#Fallback_weights */ static pd_font_weight_t font_weight_fallback(font_style_node_t *snode, - pd_font_weight_t weight) -{ - if (weight > PD_FONT_WEIGHT_MEDIUM) { - return find_bolder_weight(snode, weight); - } - if (weight < PD_FONT_WEIGHT_NORMAL) { - return find_lighter_weight(snode, weight); - } - if (weight == PD_FONT_WEIGHT_NORMAL) { - if (snode->weights[PD_FONT_WEIGHT_MEDIUM - 1]) { - return PD_FONT_WEIGHT_MEDIUM; - } - } else if (weight == PD_FONT_WEIGHT_MEDIUM) { - if (snode->weights[PD_FONT_WEIGHT_NORMAL - 1]) { - return PD_FONT_WEIGHT_NORMAL; - } - } - weight = find_lighter_weight(snode, weight); - if (weight != PD_FONT_WEIGHT_NONE) { - return weight; - } - return PD_FONT_WEIGHT_NONE; + pd_font_weight_t weight) +{ + if (weight > PD_FONT_WEIGHT_MEDIUM) { + return find_bolder_weight(snode, weight); + } + if (weight < PD_FONT_WEIGHT_NORMAL) { + return find_lighter_weight(snode, weight); + } + if (weight == PD_FONT_WEIGHT_NORMAL) { + if (snode->weights[PD_FONT_WEIGHT_MEDIUM - 1]) { + return PD_FONT_WEIGHT_MEDIUM; + } + } else if (weight == PD_FONT_WEIGHT_MEDIUM) { + if (snode->weights[PD_FONT_WEIGHT_NORMAL - 1]) { + return PD_FONT_WEIGHT_NORMAL; + } + } + weight = find_lighter_weight(snode, weight); + if (weight != PD_FONT_WEIGHT_NONE) { + return weight; + } + return PD_FONT_WEIGHT_NONE; } int pd_font_library_get_font_id(const char *family_name, pd_font_style_t style, - pd_font_weight_t weight) -{ - int style_num; - pd_font_weight_t w; - font_style_node_t *snode; - font_family_node_t *fnode; - - if (!fontlib.active) { - return -1; - } - fnode = select_font_family_cache(family_name); - if (!fnode) { - return -2; - } - if (weight == 0) { - weight = PD_FONT_WEIGHT_NORMAL; - } - for (style_num = style; style_num >= 0; --style_num) { - snode = &fnode->styles[style_num]; - if (snode->weights[weight - 1]) { - return snode->weights[weight - 1]->id; - } - w = font_weight_fallback(snode, weight); - if (w) { - return snode->weights[w - 1]->id; - } - } - return -3; + pd_font_weight_t weight) +{ + int style_num; + const char *name; + pd_font_weight_t w; + font_style_node_t *snode; + font_family_node_t *fnode; + + if (!fontlib.active) { + return -1; + } + name = dict_fetch_value(fontlib.font_family_aliases, family_name); + if (!name) { + name = family_name; + } + fnode = select_font_family_cache(name); + if (!fnode) { + return -2; + } + if (weight == 0) { + weight = PD_FONT_WEIGHT_NORMAL; + } + for (style_num = style; style_num >= 0; --style_num) { + snode = &fnode->styles[style_num]; + if (snode->weights[weight - 1]) { + return snode->weights[weight - 1]->id; + } + w = font_weight_fallback(snode, weight); + if (w) { + return snode->weights[w - 1]->id; + } + } + return -3; } size_t pd_font_library_update_font_weight(const int *font_ids, - pd_font_weight_t weight, - int **new_font_ids) -{ - int id, *ids; - pd_font_t *font; - size_t i, count, len; - - if (!font_ids) { - return 0; - } - for (len = 0; font_ids[len]; ++len) - ; - if (len < 1) { - return 0; - } - ids = malloc((len + 1) * sizeof(int)); - if (!ids) { - return 0; - } - for (i = 0, count = 0; i < len; ++i) { - font = pd_font_library_get_font(font_ids[i]); - id = pd_font_library_get_font_id(font->family_name, font->style, - weight); - if (id > 0) { - ids[count++] = id; - } - } - ids[count] = 0; - if (new_font_ids && count > 0) { - *new_font_ids = ids; - } else { - *new_font_ids = NULL; - free(ids); - } - return count; + pd_font_weight_t weight, + int **new_font_ids) +{ + int id, *ids; + pd_font_t *font; + size_t i, count, len; + + if (!font_ids) { + return 0; + } + for (len = 0; font_ids[len]; ++len); + if (len < 1) { + return 0; + } + ids = malloc((len + 1) * sizeof(int)); + if (!ids) { + return 0; + } + for (i = 0, count = 0; i < len; ++i) { + font = pd_font_library_get_font(font_ids[i]); + id = pd_font_library_get_font_id(font->family_name, font->style, + weight); + if (id > 0) { + ids[count++] = id; + } + } + ids[count] = 0; + if (new_font_ids && count > 0) { + *new_font_ids = ids; + } else { + *new_font_ids = NULL; + free(ids); + } + return count; } size_t pd_font_library_update_font_style(const int *font_ids, - pd_font_style_t style, int **new_font_ids) -{ - int id, *ids; - pd_font_t *font; - size_t i, count, len; - - if (!font_ids) { - return 0; - } - for (len = 0; font_ids[len]; ++len) - ; - if (len < 1) { - return 0; - } - ids = malloc((len + 1) * sizeof(int)); - if (!ids) { - return 0; - } - for (i = 0, count = 0; i < len; ++i) { - font = pd_font_library_get_font(font_ids[i]); - id = pd_font_library_get_font_id(font->family_name, style, - font->weight); - if (id > 0) { - ids[count++] = id; - } - } - ids[count] = 0; - if (new_font_ids && count > 0) { - *new_font_ids = ids; - } else { - *new_font_ids = NULL; - free(ids); - } - return count; + pd_font_style_t style, + int **new_font_ids) +{ + int id, *ids; + pd_font_t *font; + size_t i, count, len; + + if (!font_ids) { + return 0; + } + for (len = 0; font_ids[len]; ++len); + if (len < 1) { + return 0; + } + ids = malloc((len + 1) * sizeof(int)); + if (!ids) { + return 0; + } + for (i = 0, count = 0; i < len; ++i) { + font = pd_font_library_get_font(font_ids[i]); + id = pd_font_library_get_font_id(font->family_name, style, + font->weight); + if (id > 0) { + ids[count++] = id; + } + } + ids[count] = 0; + if (new_font_ids && count > 0) { + *new_font_ids = ids; + } else { + *new_font_ids = NULL; + free(ids); + } + return count; } unsigned pd_font_library_query(int **font_ids, pd_font_style_t style, - pd_font_weight_t weight, const char *const *names) -{ - int *ids; - unsigned i, count, loaded_count; - - *font_ids = NULL; - if (!names) { - return 0; - } - for (count = 0; names[count]; ++count) - ; - if (count < 1) { - return 0; - } - ids = malloc(sizeof(int) * (count + 1)); - if (!ids) { - return 0; - } - for (loaded_count = 0, i = 0; i < count; ++i) { - ids[loaded_count] = - pd_font_library_get_font_id(names[i], style, weight); - if (ids[loaded_count] > 0) { - ++loaded_count; - } - } - ids[loaded_count] = 0; - if (loaded_count < 1) { - free(ids); - ids = NULL; - } - *font_ids = ids; - return loaded_count; + pd_font_weight_t weight, + const char *const *names) +{ + int *ids; + unsigned i, count, loaded_count; + + *font_ids = NULL; + if (!names) { + return 0; + } + for (count = 0; names[count]; ++count); + if (count < 1) { + return 0; + } + ids = malloc(sizeof(int) * (count + 1)); + if (!ids) { + return 0; + } + for (loaded_count = 0, i = 0; i < count; ++i) { + ids[loaded_count] = + pd_font_library_get_font_id(names[i], style, weight); + if (ids[loaded_count] > 0) { + ++loaded_count; + } + } + ids[loaded_count] = 0; + if (loaded_count < 1) { + free(ids); + ids = NULL; + } + *font_ids = ids; + return loaded_count; } int pd_font_library_get_default_font(void) { - if (!fontlib.default_font) { - return -1; - } - return fontlib.default_font->id; + if (!fontlib.default_font) { + return -1; + } + return fontlib.default_font->id; } void pd_font_library_set_default_font(int id) { - pd_font_t *font = pd_font_library_get_font(id); - if (font) { - fontlib.default_font = font; - logger_debug("[font] select: %s\n", font->family_name); - } + pd_font_t *font = pd_font_library_get_font(id); + if (font) { + fontlib.default_font = font; + logger_debug("[font] select: %s\n", font->family_name); + } } int pd_font_library_load_file(const char *filepath) { - pd_font_t **fonts; - int i, num_fonts, id; - - logger_debug("[font] load file: %s\n", filepath); - if (!fontlib.engine) { - return -1; - } - num_fonts = fontlib.engine->open(filepath, &fonts); - if (num_fonts < 1) { - logger_debug("[font] failed to load file: %s\n", filepath); - return -2; - } - for (i = 0; i < num_fonts; ++i) { - fonts[i]->engine = fontlib.engine; - id = pd_font_library_add_font(fonts[i]); - logger_debug("[font] add font: %d, family: %s, style name: %s, " - "weight: %d\n", - id, fonts[i]->family_name, fonts[i]->style_name, - fonts[i]->weight); - } - free(fonts); - return 0; -} - -int pd_font_library_render_bitmap(pd_font_bitmap_t *buff, unsigned ch, int font_id, - int pixel_size) -{ - pd_font_t *font = fontlib.default_font; - do { - if (font_id < 0 || !fontlib.engine) { - break; - } - font = pd_font_library_get_font(font_id); - if (font) { - break; - } - if (fontlib.default_font) { - font = fontlib.default_font; - } else { - font = fontlib.incore_font; - } - break; - } while (0); - if (!font) { - return -1; - } - return font->engine->render(buff, ch, pixel_size, font); + pd_font_t **fonts; + int i, num_fonts, id; + + logger_debug("[font] load file: %s\n", filepath); + if (!fontlib.engine) { + return -1; + } + num_fonts = fontlib.engine->open(filepath, &fonts); + if (num_fonts < 1) { + logger_debug("[font] failed to load file: %s\n", filepath); + return -2; + } + for (i = 0; i < num_fonts; ++i) { + fonts[i]->engine = fontlib.engine; + id = pd_font_library_add_font(fonts[i]); + logger_debug("[font] add font: %d, family: %s, style name: %s, " + "weight: %d\n", + id, fonts[i]->family_name, fonts[i]->style_name, + fonts[i]->weight); + } + free(fonts); + return 0; +} + +int pd_font_library_render_bitmap(pd_font_bitmap_t *buff, unsigned ch, + int font_id, int pixel_size) +{ + pd_font_t *font = fontlib.default_font; + do { + if (font_id < 0 || !fontlib.engine) { + break; + } + font = pd_font_library_get_font(font_id); + if (font) { + break; + } + if (fontlib.default_font) { + font = fontlib.default_font; + } else { + font = fontlib.incore_font; + } + break; + } while (0); + if (!font) { + return -1; + } + return font->engine->render(buff, ch, pixel_size, font); +} + +bool pd_font_library_set_font_family_alias(const char *alias, + const char *family_name) +{ + return dict_add(fontlib.font_family_aliases, (void *)alias, + family_name) == DICT_OK; +} + +static void font_family_dict_val_destructor(void *privdata, void *data) +{ + free(data); +} + +static void *font_family_dict_val_dup(void *privdata, const void *data) +{ + return strdup2(data); } static void pd_font_library_init_base(void) { - fontlib.count = 0; - fontlib.font_cache_num = 1; - fontlib.font_cache = malloc(sizeof(font_cache_t)); - fontlib.font_cache[0] = font_cache_create(); - rbtree_init(&fontlib.bitmap_cache); - dict_init_string_key_type(&fontlib.font_families_type); - fontlib.font_families_type.val_destructor = destroy_font_family_node; - fontlib.font_families = dict_create(&fontlib.font_families_type, NULL); - rbtree_set_destroy_func(&fontlib.bitmap_cache, destroy_tree_node); - fontlib.active = true; + static dict_type_t dict_type; + static dict_type_t alias_dict_type; + + fontlib.count = 0; + fontlib.font_cache_num = 1; + fontlib.font_cache = malloc(sizeof(font_cache_t)); + fontlib.font_cache[0] = font_cache_create(); + rbtree_init(&fontlib.bitmap_cache); + dict_init_string_key_type(&dict_type); + dict_init_string_copy_key_type(&alias_dict_type); + dict_type.val_destructor = destroy_font_family_node; + alias_dict_type.val_destructor = font_family_dict_val_destructor; + alias_dict_type.val_dup = font_family_dict_val_dup; + fontlib.font_families = dict_create(&dict_type, NULL); + fontlib.font_family_aliases = dict_create(&alias_dict_type, NULL); + rbtree_set_destroy_func(&fontlib.bitmap_cache, destroy_tree_node); + fontlib.active = true; } static void pd_font_library_init_engine(void) { - int fid; - /* 先初始化内置的字体引擎 */ - fontlib.engine = &fontlib.engines[0]; - pd_incore_font_create(fontlib.engine); - pd_font_library_load_file("in-core.inconsolata"); - fid = pd_font_library_get_font_id("inconsolata", 0, 0); - fontlib.incore_font = pd_font_library_get_font(fid); - fontlib.default_font = fontlib.incore_font; - /* 然后看情况启用其它字体引擎 */ + int fid; + /* 先初始化内置的字体引擎 */ + fontlib.engine = &fontlib.engines[0]; + pd_incore_font_create(fontlib.engine); + pd_font_library_load_file("in-core.inconsolata"); + fid = pd_font_library_get_font_id("inconsolata", 0, 0); + fontlib.incore_font = pd_font_library_get_font(fid); + fontlib.default_font = fontlib.incore_font; + /* 然后看情况启用其它字体引擎 */ #ifdef PANDAGL_HAS_FREETYPE - if (pd_freetype_engine_init(&fontlib.engines[1]) == 0) { - fontlib.engine = &fontlib.engines[1]; - } + if (pd_freetype_engine_init(&fontlib.engines[1]) == 0) { + fontlib.engine = &fontlib.engines[1]; + } #endif - if (fontlib.engine && fontlib.engine != &fontlib.engines[0]) { - logger_debug("[font] current font engine is: %s\n", - fontlib.engine->name); - } else { - logger_warning("[font] warning: not font engine support!\n"); - } + if (fontlib.engine && fontlib.engine != &fontlib.engines[0]) { + logger_debug("[font] current font engine is: %s\n", + fontlib.engine->name); + } else { + logger_warning("[font] warning: not font engine support!\n"); + } } static void pd_font_library_destroy_base(void) { - if (!fontlib.active) { - return; - } - fontlib.active = false; - while (fontlib.font_cache_num > 0) { - --fontlib.font_cache_num; - font_cache_destroy(fontlib.font_cache[fontlib.font_cache_num]); - } - dict_destroy(fontlib.font_families); - rbtree_destroy(&fontlib.bitmap_cache); - free(fontlib.font_cache); - fontlib.font_cache = NULL; + if (!fontlib.active) { + return; + } + fontlib.active = false; + while (fontlib.font_cache_num > 0) { + --fontlib.font_cache_num; + font_cache_destroy(fontlib.font_cache[fontlib.font_cache_num]); + } + dict_destroy(fontlib.font_family_aliases); + dict_destroy(fontlib.font_families); + rbtree_destroy(&fontlib.bitmap_cache); + free(fontlib.font_cache); + fontlib.font_cache = NULL; + fontlib.font_families = NULL; + fontlib.font_family_aliases = NULL; } static void pd_font_library_destroy_engine(void) { - pd_incore_font_destroy(); + pd_incore_font_destroy(); #ifdef PANDAGL_HAS_FREETYPE - pd_freetype_engine_destroy(); + pd_freetype_engine_destroy(); #endif } void pd_font_library_init(void) { - pd_font_library_init_base(); - pd_font_library_init_engine(); + pd_font_library_init_base(); + pd_font_library_init_engine(); } void pd_font_library_destroy(void) { - pd_font_library_destroy_base(); - pd_font_library_destroy_engine(); + pd_font_library_destroy_base(); + pd_font_library_destroy_engine(); } diff --git a/lib/ui/include/ui/text_style.h b/lib/ui/include/ui/text_style.h index 78aee0764..a0e7e49e2 100644 --- a/lib/ui/include/ui/text_style.h +++ b/lib/ui/include/ui/text_style.h @@ -28,7 +28,6 @@ typedef struct ui_text_style { int font_size; int line_height; int *font_ids; - char *font_family; wchar_t *content; pd_color_t color; uint8_t font_style; diff --git a/src/lcui_fonts.c b/src/lcui_fonts.c index ef814a58d..ed52addd8 100644 --- a/src/lcui_fonts.c +++ b/src/lcui_fonts.c @@ -13,26 +13,39 @@ #include #include +bool lcui_fonts_set_default(const char *family_name) +{ + int id = pd_font_library_get_font_id(family_name, PD_FONT_STYLE_NORMAL, + PD_FONT_WEIGHT_NORMAL); + if (id < 0) { + return false; + } + pd_font_library_set_default_font(id); + pd_font_library_set_font_family_alias("system-ui", family_name); + return true; +} + #ifdef PTK_WIN32 static void lcui_windows_fonts_init(void) { size_t i; - int *ids = NULL; - const char *names[] = { "Consola", "Simsun", "Microsoft YaHei", NULL }; const char *fonts[] = { "C:/Windows/Fonts/consola.ttf", + "C:/Windows/Fonts/consolai.ttf", + "C:/Windows/Fonts/consolab.ttf", + "C:/Windows/Fonts/consolaz.ttf", "C:/Windows/Fonts/simsun.ttc", "C:/Windows/Fonts/msyh.ttf", - "C:/Windows/Fonts/msyh.ttc" }; + "C:/Windows/Fonts/msyh.ttc", + "C:/Windows/Fonts/msyhbd.ttc", + "C:/Windows/Fonts/msyhl.ttc" }; for (i = 0; i < sizeof(fonts) / sizeof(char *); ++i) { pd_font_library_load_file(fonts[i]); } - i = pd_font_library_query(&ids, PD_FONT_STYLE_NORMAL, - PD_FONT_WEIGHT_NORMAL, names); - if (i > 0) { - pd_font_library_set_default_font(ids[i - 1]); - } - free(ids); + lcui_fonts_set_default("Microsoft YaHei"); + pd_font_library_set_font_family_alias("serif", "Simsun"); + pd_font_library_set_font_family_alias("sans-serif", "Microsoft YaHei"); + pd_font_library_set_font_family_alias("monospace", "Consola"); } #else @@ -42,24 +55,20 @@ static void lcui_windows_fonts_init(void) static void lcui_fc_fonts_init(void) { size_t i; + bool has_default = false; char *path; - int *ids = NULL; - const char *names[] = { "Noto Sans CJK", "Ubuntu", - "WenQuanYi Micro Hei", NULL }; const char *fonts[] = { "Ubuntu", "Noto Sans CJK SC", "WenQuanYi Micro Hei" }; for (i = 0; i < sizeof(fonts) / sizeof(char *); ++i) { path = pd_font_library_get_font_path(fonts[i]); - pd_font_library_load_file(path); + id = pd_font_library_load_file(path); free(path); + // TODO: 使用系统已设置的默认字体 + if (!has_default) { + has_default = lcui_fonts_set_default(fonts[i]); + } } - i = pd_font_library_query(&ids, PD_FONT_STYLE_NORMAL, - PD_FONT_WEIGHT_NORMAL, names); - if (i > 0) { - pd_font_library_set_default_font(ids[i - 1]); - } - free(ids); } #else @@ -67,9 +76,6 @@ static void lcui_fc_fonts_init(void) static void lcui_linux_fonts_init(void) { size_t i; - int *ids = NULL; - const char *names[] = { "Noto Sans CJK SC", "Ubuntu", "Ubuntu Mono", - "WenQuanYi Micro Hei", NULL }; const char *fonts[] = { "/usr/share/fonts/truetype/ubuntu/Ubuntu-BI.ttf", "/usr/share/fonts/truetype/ubuntu/Ubuntu-B.ttf", @@ -100,12 +106,12 @@ static void lcui_linux_fonts_init(void) for (i = 0; i < sizeof(fonts) / sizeof(char *); ++i) { pd_font_library_load_file(fonts[i]); } - i = pd_font_library_query(&ids, PD_FONT_STYLE_NORMAL, - PD_FONT_WEIGHT_NORMAL, names); - if (i > 0) { - pd_font_library_set_default_font(ids[i - 1]); + // TODO: 使用系统已设置的默认字体 + if (!lcui_fonts_set_default("Noto Sans CJK SC")) { + lcui_fonts_set_default("Ubuntu"); } - free(ids); + pd_font_library_set_font_family_alias("sans-serif", "Ubuntu"); + pd_font_library_set_font_family_alias("monospace", "Ubuntu Mono"); } #endif