MeowOS for HiBy R3 Pro II — 公共发布版本(历史已重置)
• 全新单提交:清除含敏感信息的旧历史(sudo 口令、内网 IP、SSH 密钥路径、热点 SSID、设备 MAC) • 本地开发文档/测试记录/构建脚本全部移入 gitignored 的 devdocs/ 与 scripts/build/(不入库) • 保留:MeowOS 源码(launcher/watchdog/bootmenu/meow_svcd/SDK)、项目规范文档、mips-repo 增补组件:SDK 统一日志+通知 API、meow_svcd 服务管理器、mips-repo 软件仓库
This commit is contained in:
commit
245bee2946
136 files changed
+32730
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 8.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""raw2png.py — 将 meow_font_demo 产出的 480x720 RGB565(raw, little-endian uint16) 转成 PNG。
|
||||
|
||||
用法: raw2png.py <in.raw> <out.png>
|
||||
"""
|
||||
import sys
|
||||
from PIL import Image
|
||||
|
||||
W, H = 480, 720
|
||||
|
||||
|
||||
def main():
|
||||
raw = open(sys.argv[1], "rb").read()
|
||||
assert len(raw) == W * H * 2, f"expect {W * H * 2}, got {len(raw)}"
|
||||
out = sys.argv[2]
|
||||
img = Image.new("RGBA", (W, H), (0, 0, 0, 255))
|
||||
px = img.load()
|
||||
for y in range(H):
|
||||
base = y * W * 2
|
||||
for x in range(W):
|
||||
o = base + x * 2
|
||||
v = raw[o] | (raw[o + 1] << 8) # LE uint16
|
||||
r = ((v >> 11) & 31) * 255 // 31
|
||||
g = ((v >> 5) & 63) * 255 // 63
|
||||
b = (v & 31) * 255 // 31
|
||||
px[x, y] = (r, g, b, 255)
|
||||
img.save(out)
|
||||
print(f"saved {out} ({W}x{H})")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user