• 全新单提交:清除含敏感信息的旧历史(sudo 口令、内网 IP、SSH 密钥路径、热点 SSID、设备 MAC) • 本地开发文档/测试记录/构建脚本全部移入 gitignored 的 devdocs/ 与 scripts/build/(不入库) • 保留:MeowOS 源码(launcher/watchdog/bootmenu/meow_svcd/SDK)、项目规范文档、mips-repo 增补组件:SDK 统一日志+通知 API、meow_svcd 服务管理器、mips-repo 软件仓库
124 lines
4.3 KiB
C
124 lines
4.3 KiB
C
/*
|
|
* meow_font_demo.c — MeowOS 字体子系统主机/真机验证 demo。
|
|
*
|
|
* 用法:
|
|
* host(主机侧验证):meow_font_demo --sim demo.raw
|
|
* 渲染中文串到内存 480x720 RGB565 缓冲并写入 demo.raw,主机再用 raw2png.py 转 PNG。
|
|
* 真机:meow_font_demo --to-fb (写 /dev/fb0,默认走非显示后备缓冲并暂存,谨慎用 --sim)
|
|
*
|
|
* 通过 meow_font.h 的公开 API 绘制,验证字形/字号/advance/描边;把 width_text 打印到 stdout。
|
|
*/
|
|
#include "meow_font.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define FB_W 480
|
|
#define FB_H 720
|
|
|
|
static uint16_t *g_fb;
|
|
|
|
static inline uint16_t rgb565(int r, int g, int b) {
|
|
return (uint16_t)(((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3));
|
|
}
|
|
|
|
static void fill_bg(uint16_t c) {
|
|
for (size_t i = 0; i < (size_t)FB_W * FB_H; i++) g_fb[i] = c;
|
|
}
|
|
|
|
static void fill_rect(int x, int y, int w, int h, uint16_t c) {
|
|
for (int yy = y; yy < y + h; yy++) {
|
|
for (int xx = x; xx < x + w; xx++) {
|
|
if (xx >= 0 && xx < FB_W && yy >= 0 && yy < FB_H) g_fb[(size_t)yy * FB_W + xx] = c;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 设备侧写文件 */
|
|
static int write_raw(const char *path) {
|
|
FILE *f = fopen(path, "wb");
|
|
if (!f) { fprintf(stderr, "cannot open %s\n", path); return -1; }
|
|
size_t n = fwrite(g_fb, 2, (size_t)FB_W * FB_H, f);
|
|
fclose(f);
|
|
return (n == (size_t)FB_W * FB_H) ? 0 : -1;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
int to_fb = 0;
|
|
const char *rawpath = "font/demo/meow_demo.raw";
|
|
for (int i = 1; i < argc; i++) {
|
|
if (!strcmp(argv[i], "--to-fb")) to_fb = 1;
|
|
else if (!strcmp(argv[i], "--sim")) rawpath = (i + 1 < argc) ? argv[++i] : rawpath;
|
|
else { fprintf(stderr, "usage: %s [--sim out.raw | --to-fb]\n", argv[0]); return 2; }
|
|
}
|
|
|
|
g_fb = (uint16_t *)calloc((size_t)FB_W * FB_H, 2);
|
|
if (!g_fb) return 3;
|
|
|
|
meow_font_set_fb(FB_W, FB_H, FB_W * 2);
|
|
|
|
const char *png = "font/atlas/font.png";
|
|
const char *idx = "font/atlas/font.idx";
|
|
int rc = meow_font_load(png, idx);
|
|
if (rc != 0) {
|
|
fprintf(stderr, "meow_font_load failed rc=%d\n", rc);
|
|
return 4;
|
|
}
|
|
printf("loaded %s + %s : has_size(28)=%d has_size(20)=%d\n",
|
|
png, idx, meow_font_has_size(28), meow_font_has_size(20));
|
|
|
|
/* ---- 度量核对 ---- */
|
|
printf("width_text('MeowOS 主屏',28)=%d line_h28=%d asc28=%d\n",
|
|
meow_font_width_text("MeowOS 主屏", 28), meow_font_line_height(28), meow_font_ascent(28));
|
|
printf("width_text('返回播放器需重启',20)=%d line_h20=%d\n",
|
|
meow_font_width_text("返回播放器需重启", 20), meow_font_line_height(20));
|
|
|
|
/* ---- 布局 --- */
|
|
uint16_t cbg = rgb565(0x0c, 0x0e, 0x12);
|
|
uint16_t ctit = rgb565(0xff, 0xb0, 0x30); /* 主题橙 */
|
|
uint16_t ctext = rgb565(0xf2, 0xf2, 0xf2); /* 近白 */
|
|
uint16_t c_dim = rgb565(0x7a, 0x82, 0x8c); /* 灰 */
|
|
uint16_t cselbg = rgb565(0x1e, 0x2a, 0x3a); /* 选中背景 */
|
|
|
|
fill_bg(cbg);
|
|
|
|
/* 顶栏:标题 + 状态(版本) */
|
|
meow_font_drawtext(g_fb, 16, 10, "MeowOS 主屏", ctit, 28);
|
|
meow_font_drawtext(g_fb, 400, 16, "0.6.9", c_dim, 20);
|
|
|
|
/* 分隔线 */
|
|
fill_rect(16, 56, FB_W - 32, 1, rgb565(0x2a, 0x30, 0x38));
|
|
|
|
/* 应用/功能列表(正文 20px) */
|
|
struct item { const char *s; int sel; } items[] = {
|
|
{"本地音乐", 0}, {"在线电台", 0}, {"返回播放器需重启", 1},
|
|
{"设置", 0}, {"关闭背光", 0}, {"关机", 0},
|
|
};
|
|
int y = 78;
|
|
for (unsigned i = 0; i < sizeof(items) / sizeof(items[0]); i++) {
|
|
int lh = meow_font_line_height(20);
|
|
if (items[i].sel) {
|
|
fill_rect(12, y - 4, FB_W - 24, lh + 6, cselbg);
|
|
meow_font_drawtext_outline(g_fb, 24, y, items[i].s, ctext, ctit, 1, 20);
|
|
} else {
|
|
meow_font_drawtext(g_fb, 24, y, items[i].s, items[i].sel ? ctit : ctext, 20);
|
|
}
|
|
y += lh + 16;
|
|
}
|
|
|
|
/* 底栏提示 */
|
|
meow_font_drawtext(g_fb, 16, FB_H - 46, "按住电源键 3 秒返回", c_dim, 20);
|
|
|
|
if (to_fb) {
|
|
fprintf(stderr, "--to-fb 暂未在本机关联(真机用);先用 --sim 验证\n");
|
|
}
|
|
if (write_raw(rawpath) != 0) {
|
|
fprintf(stderr, "write_raw failed\n");
|
|
return 5;
|
|
}
|
|
printf("wrote %s\n", rawpath);
|
|
meow_font_unload();
|
|
free(g_fb);
|
|
return 0;
|
|
}
|