/* * meow_ui_font.h — SDK 字体:应用可读 TF 卡字体列表(§5.7)+ 字体分层/大字库(§10)。 * * 原 meow_ui.h 拆分的一部分(font 模块)。字库权威列表 = launcher 扫描落盘的持久文件 * MeowOS/config/fonts/index(CSV);App 只经本接口读该列表。字体「档位」由 launcher 按 * app.json 声明的 "fonts:<档>" 注入 MEOW_FONT_TIER;SDK 据档选库(meow_font_reload_tier)。 */ #ifndef MEOW_UI_FONT_H #define MEOW_UI_FONT_H #include /* uint32_t(meow_ft_text color)—— 子头自洽、可单独 include */ #ifdef __cplusplus extern "C" { #endif /* ============================================================ */ /* §5.7 应用可读 TF 卡字体列表(M2.58:字体索引 / 查列表 / 丢失降级默认) */ /* ============================================================ */ /* 系统字体管理器的面向应用接口(规格 §5.7.1/§5.7.2): * - 权威列表 = launcher 扫描 MeowOS/fonts/// 后落盘的持久文件 * MeowOS/config/fonts/index(CSV:family,weight,path,label,tier,glyph_count)。 * app 只经本接口读该列表(不直接拼路径、不依赖 launcher 内存数组)。 * - 渲染仍走 env MEOW_FONT_PNG/MEOW_FONT_IDX(launcher 注入的「当前生效字体」, * 选中字体那一套);本节的 get_available_count/enumerate 只负责「列有哪些库」, * select_by_id 负责「app 会话内固定用哪套」。两路明确。 * - 无卡 / 无 index → 仅 1 项板载默认(family=default)。 */ #ifndef MEOW_FONT_INFO_DEFINED #define MEOW_FONT_INFO_DEFINED typedef struct meow_font_info { char family[64]; /* family slug = MeowOS/fonts// 一级目录名 */ char name[64]; /* 显示名(index 无单列 → 回退 family) */ char weight[32]; /* weight slug(regular|bold|…,缺省 regular) */ char tier[8]; /* 档位 common|gbk|full(info 用) */ int glyph_count; /* font.json glyph_count(info 用) */ char label[128]; /* index 显示名(含字重 + 尺寸标记) */ int size_list[16]; /* 原生字号表(index 无 → 空) */ int size_count; /* 有效字号数 */ int bit_depth; /* 4|8(index 无 → 0) */ char path_png[320]; /* 卡根相对 MeowOS/fonts///font.png */ } meow_font_info; #endif /* 可用字库数(含默认;无卡 → 1)。 */ int meow_font_get_available_count(void); /* 按序号取:idx=0=默认行(family=default);越界返回 0。 */ int meow_font_enumerate(int idx, meow_font_info *out); /* 选该套为 app 会话默认字体:id=0 跟随系统默认(font.file,经 env);id>0 固定用该套。 * 该套字库缺失 → 降级默认(不丢请求)+ WARN(meow_log→app 日志)。成功 0,越界负值。 */ int meow_font_select_by_id(int id); /* ============================================================ */ /* §10 字体分层 / 大字库(M2.5x:基座声明 + font 域已实现按档装载) */ /* ============================================================ */ /* 字体「档位」概念:launcher 按 app.json 声明的字库档("fonts":<档>)向 app 注入 * MEOW_FONT_TIER=<0|1|2>;SDK(meow_ui_gfx / meow_font 大字库加载)据档选库: * MEOW_FONT_TIER_COMMON=0 默认 4K 常用字库; * MEOW_FONT_TIER_GBK =1 大字库 GBK; * MEOW_FONT_TIER_FULL =2 Full(全字符集)。 * 大字库生成由 font/gen/gen_font.py --charset 按档产出;按档装载由 meow_font_reload_tier() * 实现(先 unload 旧再 load 新,释放旧 atlas 防大字库双驻留)。launcher 经 * meow_font_effective_paths_tiered() 按档解析大字库绝对路径并注入 MEOW_FONT_PNG/IDX。 * 既有 meow_font_* 符号(class_of/has_glyph/load_slot/config_multifont…)保留不动。 * 判缺字:meow_font_has_glyph(cp) 预判当前字库是否含该码位。 */ #define MEOW_FONT_TIER_COMMON 0 #define MEOW_FONT_TIER_GBK 1 #define MEOW_FONT_TIER_FULL 2 /* 设当前字体档(0/1/2,越界 clamp 到合法值),返回生效档。 * meow_ui_gfx.c 定义并触发 meow_font_reload_tier() 真重载(大字库切换释放旧 atlas)。 */ int meow_font_set_tier(int tier); /* 当前字体档(初始 = MEOW_FONT_TIER_COMMON;meow_ui_init 时读 MEOW_FONT_TIER env 对齐)。 */ int meow_font_tier(void); /* ============================================================ */ /* §10.1 矢量字(FreeType,2026-09-02 追加)—— 上收阅读器管线到 SDK */ /* ============================================================ */ /* 背景:SDK 位图字库只有离散字号档位(meow_font);阅读器 R1/R2 的 FreeType 管线已在真机 * 验证(MiSans OTF 渲染)。本组 API 把矢量字能力上收 SDK,任何 App 可用:**无级字号 + CJK * 全字形**——这是解决大字库豆腐类问题的根(位图全字形 atlas 稳态 17.3MiB 装不下,矢量按需 * 读文件 + LRU 缓存字形)。与位图字库**并存**:App **显式**调用 meow_ft_* 才走矢量;既有 * meow_ui_text 路径零改动(默认仍是 meow_font)。 */ /* 内存纪律(对齐 READER_ENGINE_NOTES §5.1/§5.4): * - FT_New_Face(path) 按需读文件(不整载 → 零大块 anon;文件 disk-backed 可回收重读)。 * - glyph LRU 512(默认,~0.46MB:28px CJK 约 900B/字),可配 256 省内存 / 1024 提命中。 * - 目标单 App 增量 ≤1.5MB(FreeType 本体按需拉入,App 不调 meow_ft_* 则零增量)。 */ /* 载入矢量字体文件(TTF/OTF 绝对路径)。0=成功;重载会先释放旧面 + 清空 glyph 缓存。 * 失败(路径无效/损坏/无 FreeType)返回负值,meow_ft_loaded()==0,后续 text/width 自动降级 * 位图字库(meow_font),绝不豆腐不崩。 */ int meow_ft_load(const char *path); /* 释放矢量字体(保留 FreeType 运行时可再载;再调 meow_ft_load 即可)。 */ void meow_ft_unload(void); /* 当前是否已载入矢量字体(0=无 → text/width 走位图字库降级)。 */ int meow_ft_loaded(void); /* 矢量渲染文本:(x,y)=行首升线顶(同 meow_ui_text;baseline = y + meow_ft_ascender(px)); * 颜色为 24-bit RGB(内部按当前 back_buf 底色逐像素 blend565 反锯齿);px=字号(无级)。 * 返回 0=矢量渲染成功;-1=无矢量字体 → 已自动降级 meow_ui_text(位图字库,不出豆腐); * -2=未初始化/空串。 */ int meow_ft_text(int x, int y, const char *utf8, int px, uint32_t color); /* 矢量文本宽度(px;advance 累加,不栅格化、不占 LRU 槽);无矢量字体 → 降级 meow_ui_text_width。 */ int meow_ft_width(const char *utf8, int px); /* 行高 / 上伸 / 下伸(px;无矢量字体时 line_height 返回近似、ascender=px、descender=0)。 */ int meow_ft_line_height(int px); int meow_ft_ascender(int px); int meow_ft_descender(int px); /* glyph LRU 容量:默认 512;设 256 省内存 / 1024 提命中(越界 clamp 1..4096,实际生效)。 */ int meow_ft_cache_set_slots(int slots); int meow_ft_cache_slots(void); /* 当前 LRU 占用条目数(宿主单测 / 诊断用)。 */ int meow_ft_cache_used(void); #ifdef __cplusplus } #endif #endif /* MEOW_UI_FONT_H */