Files
AskaEth c0396e40ce sync(SDK): 增量同步主仓 M6.37–M6.39 至公开 SDK 仓
sdk/:
- 同步 meow_ui_widget/input/gfx/lazygrid/audio/media/img 等源码与头
  (SDK 默认列表/容器控件默认 MD3 — meow_list_set_container 可回退;
   全局 App 内底部上滑回桌面 — meow_ui_input_is_home_swipe 系统保留手势;
   LazyGrid/LazyColumn/LazyRow MD3 化;叠加让位自抑改 app_id 判定;
   DSD 音频格式等)
- 新增独立模块源码 meow_img_color / meow_lyric / meow_lyric_view 及对应宿主 test_*.c
- 保留公开仓自包含适配:vendored meow_font.c/meow_font.h/meow_notif.h 不动;
  build_sdk.sh 自包含版本不动;meow_ui_gfx.c 仅改 meow_font.h include 路径;
  meow_ui_internal.h 去除 FreeType 内部声明
- meow_ipc.h 同步到主仓 launcher 版本(含 AUDIO_FMT_DOP/媒体歌词/蓝牙输出协议)
- 不含 FreeType 矢量字 meow_ft_*(需 freetype vendor,公开仓以位图 meow_font
  自包含);不含 mipsel 二进制 / .o / .a / 固件 / 密钥 / devdocs

examples/hello/:
- 新增 ui/demo/sdk2/sdk2.c;build_hello.sh 纳入该文件(保持自包含)

docs / README / .gitignore:
- docs/MEOW_APP_SDK.md 补 §12.5(默认 MD3 容器 + 底部上滑回桌面 + 两个新 API)
- README 能力清单补「默认 MD3 容器」与「底部上滑回桌面」
- .gitignore 补新增宿主测试二进制

验证:sdk/meow_ui.a 与 examples/hello/hello 交叉编译均 0 warning;工作区无生成物。
2026-09-04 18:05:36 +08:00

83 lines
5.1 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* meow_lyric.h — MeowOS SDK 通用歌词组件(LRC 时间轴解析 / 存取 / 查询 + 折行辅助)。
*
* 定位:把网易云 ncm_app 的歌词解析/查询能力(app/logic/lyric.c 的 parse/clear/count/
* line_at/line_text/line_tl + copy_lrc_text 的「字面 \n 当换行」语义 + player.c 的
* lyr_wrap_lines 折行)**通用化上收到 SDK**,供 launcher / ncm 等任意 App 复用。
* 本头为**独立公共头**(仿 meow_ui_view.h 模式:不随 meow_ui.h 伞头发布,App 按需
* `#include "meow_lyric.h"`),命名与 SDK 规范一致:API 一律 `meow_lyric_*`。
*
* 输入:标准 LRC 行 `[mm:ss.xx]正文`。lrc=原文,tlrc=翻译。解析把带时间戳的行按时间升序
* 排序存 timestamp(ms)/text;翻译按相同 timestamp 合并到对应原文行(存 tl),无匹配的翻译行
* 忽略。流式、有界:行数上限默认 MEOW_LYRIC_LINES_MAX(600),运行时可经
* meow_lyric_set_max_lines 下调;单行文本上限 MEOW_LYRIC_TEXT_MAX(192)字节。
*
* 服务器字面序列:网易云服务器把多行文本用字面 `\n`/`\r` 塞进一行(渲染成豆腐块/凌乱),
* 解析时按空格替换(`\r\n`/`\n\r` 折成单空格),语义与 ncm copy_lrc_text 一致。
*
* 线程安全(单写多读,机制与 ncm lyric.c 相同的交错安全):数据由后台线程写
* (meow_lyric_parse / meow_lyric_clear / meow_lyric_set_max_lines),UI 线程读
* (meow_lyric_count / line_at / line_text / line_tl / line_time)。全部函数内部持同一把
* pthread 互斥锁,函数级粒度,写侧整段持锁、读侧每次访问持锁,无嵌套(清空/解析用 nolock
* 私有版,避免二次取锁自锁死)。**读接口返回的指针指向静态存储,在下次 meow_lyric_parse /
* meow_lyric_clear 之前有效**;调用方不得跨重建持有。这是与 ncm 完全相同的「指针在下次写前
* 有效」契约。
*
* 依赖:纯 libc(stdlib/string/stdio)+ pthread,不依赖其它 SDK 对象(不含 meow_log,便于
* launcher 等非 meow_ui.a 使用方独立链入)。宿主 gcc 可直接编译单测。
*
* 时间戳小数位自适应:1 位=0.1s(×100)、2 位=0.01s(×10,标准 LRC 厘秒)、3 位=0.001s(×1,
* 网易云 LRC 毫秒)、>3 位截断到毫秒 —— 避免把网易云 3 位毫秒当 2 位厘秒解析导致时间放大。
*/
#ifndef MEOW_LYRIC_H
#define MEOW_LYRIC_H
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ---- 容量 / 静态存储 ---- */
#define MEOW_LYRIC_LINES_MAX 600 /* 静态行数组硬上限(对齐 ncm NCM_LYRIC_LINES) */
#define MEOW_LYRIC_TEXT_MAX 192 /* 单行文本(原文/翻译)字节上限(对齐 ncm LRC_MAX_TEXT) */
#define MEOW_LYRIC_SEG_SZ 256 /* 折行单段缓冲字节上限(对齐 ncm LYR_SEG_SZ) */
/* ---- 折行宽测量回调 ----
* 由使用方注入(歌词视图传 meow_ui_text_width 的包装;宿主测传自己的测量函数)。
* 返回 utf8 段在字号 size 下的宽度(px)。NULL 时回退为「字节数近似」(非像素精确,仅兜底)。 */
typedef int (*meow_lyric_width_fn)(const char *utf8, int size, void *ctx);
/* ---- 解析 / 清空 ----
* meow_lyric_parse:重置并解析 lrc(原文)+ tlrc(翻译),按时间升序排序后返回歌词行数
* (=meow_lyric_count 的值;<- 解析失败/空输入返回 0)。翻译按相同时间戳合并到对应原文行。
* meow_lyric_clear:清空全部数据(下次 read 返回空)。 */
void meow_lyric_clear(void);
int meow_lyric_parse(const char *lrc, const char *tlrc);
/* ---- 查询(全部线程安全;line_text/tl 返回静态串,越界返回 "")---- */
int meow_lyric_count(void);
int meow_lyric_line_at(int64_t ms); /* 当前行下标:last timestamp<=ms;首戳前=0;末戳后=n-1 */
const char *meow_lyric_line_text(int i); /* 第 i 行原文;越界 "" */
const char *meow_lyric_line_tl(int i); /* 第 i 行翻译;越界/无翻译 "" */
int64_t meow_lyric_line_time(int i); /* 第 i 行时间戳(ms);越界 -1(供「点行跳转」seek) */
/* ---- 行上限配置 ----
* 缺省 MEOW_LYRIC_LINES_MAX(600)。可下调至 [1, MEOW_LYRIC_LINES_MAX];下一次 parse 起生效
* (解析行数超过上限时超出的行被截断丢弃)。 */
void meow_lyric_set_max_lines(int max);
/* ---- 折行辅助(上收 ncm lyr_wrap_lines,非线程相关、纯函数)----
* 把 txt 按「词/字符」折成 ≤max_rows 段,每段宽度 ≤maxw px(宽测由 width 回调给出;中文按字符、
* 英文按词断行)。段写入调用方 seg[][MEOW_LYRIC_SEG_SZ](seg 须能容纳 max_rows 个段),
* 返回段数(≥1;txt 空/超短返回 1 段空串)。单字符超宽时强制容纳该字符,防止死循环。 */
int meow_lyric_wrap(const char *txt, int size, int maxw,
char seg[][MEOW_LYRIC_SEG_SZ], int max_rows,
meow_lyric_width_fn width, void *ctx);
#ifdef __cplusplus
}
#endif
#endif /* MEOW_LYRIC_H */