主仓 SDK 的图片层原本是 220 行 stb 直通(整幅解码后重采样)。公开仓 MeowOS-SDK 的同一子系统已被真实 App(tuku 阅读器)驱动并做过峰值实测与像素比对,故以公开仓 为权威方向并入主仓 meow_ui.a,两个方向的新功能都保留(逐文件 diff 确认公开仓是 严格超集:无一处「双方互有增减」)。 - 新增 meow_jpeg.c / meow_jpeg.h:DCT 域缩解 1/8、1/4、1/2(N=1/2/4 点 IDCT), 渐进式只解到首个精细化扫描;不支持项(CMYK/YCCK、算术编码、过订阅 DHT、16bit 量化表)返回 0 由调用方回退 stb - 新增 meow_png_stream.c:libz 逐行 inflate + 反滤波,按步长丢行丢列直写目标尺寸; BMP 按目标行 seek + 行内跳列(8/16/24/32bpp) - meow_ui_img.c + include/meow_ui_image.h:新增 meow_img_pick_scale / load_file_step / load_file_step_ex / resample 四个公开入口;_dim 与 _mem_dim 先进后端,失败/不支持才回退 stb(对外语义不变) - include/meow_ui_draw.h + meow_ui_gfx.c:M32 RGB565 页图 5 函数 (meow_gfx_rgb565 / rgba_to_rgb565 / blit_rgb565 / _scaled)。gfx 保留主仓的 `#include "../meow_launcherd/meow_font.h"` 与 <time.h>(公开仓自 vendored meow_font.h 且无 <time.h>,机械覆盖会丢这两行) - meow_jpeg.h 保持内部:不进 meow_ui.h 伞头,include/ 下无任何头暴露 meow_jpeg_* - build_sdk.sh:OBJS 插入 meow_jpeg / meow_png_stream(32→34);成员数 76→78(+meow_font.o +43 freetype),--verify 全为 ELF32 MIPS32 rel2/o32 - 测试:新增 test_meow_img_stream.c(S1-S16),test_meow_img_budget.c 同步公开仓 版(B9 断言收紧为 p_new <= p_old);22 个既有宿主测试的编译注释行补 meow_jpeg.c / meow_png_stream.c / -lz(meow_ui_img.c 现引用后端符号,不加即 undefined reference) 宿主实测:S1-S16 全绿(S7 与 stb 网格像素一致:JPEG mad 4.35-13.69、PNG/BMP mad 0.00;S9 回退矩阵 CMYK/1bpp BMP/Adam7 均拒绝且 stb 仍成功),B1-B9 全绿 (B9 PNG 峰值 25.65→0.61 MiB、BMP 14.65→0.59 MiB)。回归 test_meow_ui_widgets / scroll / ime_fix / test_umbrella 全过。zlib 在应用链接期解析:meow_ui.a 只留 inflate* 未定义符号,四个 App 构建脚本原本就带 $SYSROOT/lib/libz.a,静态 linkcheck(meow_ui.a + libz.a -lpthread)通过。 注:主仓 patch_v2/reader_app 仍自带 vendored stb、不用 meow_img_*,本单不改变 阅读器的内存占用;RGB565 页图接入 reader_app 是另一个任务。
90 lines
3.6 KiB
C
90 lines
3.6 KiB
C
/* demo_box_scroll.c — 宿主离屏 demo:§12.1 meow_box 布局 + §12.3 meow_scroll fling 端到端。
|
||
* 渲染一屏「标题(固定) / 列表(weight 撑满) / 底栏(固定)」的 box 布局(cross 拉伸),
|
||
* 再对列表跑一次 fling(速度跟踪→惯性滑动到停止处),并 dump PPM 供目检。
|
||
*
|
||
* 编译(宿主 gcc,链真实 SDK 源 + 打桩 font/global):
|
||
* gcc -o demo_box_scroll demo_box_scroll.c test_host_stub.c \
|
||
* meow_ui_gfx.c meow_ui_sys.c meow_ui_theme.c meow_ui_vol.c meow_ui_log.c \
|
||
* meow_ui_widget.c meow_ui_input.c meow_ui_activity.c meow_ui_dialog.c meow_ui_ime.c \
|
||
* meow_pinyin.c meow_ui_draw.c meow_ui_view.c meow_ui_box.c meow_ui_anim.c meow_ui_scroll.c \
|
||
* meow_ui_img.c meow_ui_media.c meow_notify_ipc.c stb_image.c meow_jpeg.c meow_png_stream.c \
|
||
* -I. -I../meow_launcherd -DMEOW_UI_HOST_TEST -pthread -lm -lz
|
||
* 运行:MEOW_UI_DUMP=/tmp/demo_box.ppm ./demo_box_scroll
|
||
*/
|
||
#include "meow_ui.h"
|
||
#include "meow_ui_internal.h"
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <unistd.h>
|
||
|
||
#define NROW 60
|
||
#define ITEM 44
|
||
static int src(int idx, char *label, int len, void *ctx)
|
||
{
|
||
(void)ctx;
|
||
if (idx < 0 || idx >= NROW) return 0;
|
||
snprintf(label, (size_t)len, "item %d", idx);
|
||
return 1;
|
||
}
|
||
|
||
int main(void)
|
||
{
|
||
/* 离屏 dump */
|
||
setenv("MEOW_UI_DUMP", "/tmp/demo_box.ppm", 1);
|
||
meow_ui_opts o = { 480, 720 };
|
||
if (meow_ui_init(&o) != 0) { printf("DEMO FAIL: init\n"); return 1; }
|
||
const meow_theme *th = meow_theme_get();
|
||
meow_ui_clear(th->bg);
|
||
|
||
/* ---- box 布局:标题(固定) / 列表(weight) / 底栏(固定),交叉轴拉伸 ---- */
|
||
meow_box *bx = meow_box_new(MEOW_BOX_V);
|
||
meow_box_set_rect(bx, 0, 0, 480, 720);
|
||
meow_box_set_padding(bx, 12, 12, 12, 12);
|
||
meow_box_set_gap(bx, 8);
|
||
meow_box_set_align(bx, MEOW_BOX_ALIGN_START, MEOW_BOX_CROSS_STRETCH);
|
||
|
||
meow_widget *header = meow_btn_create(0, 0, 480, 44, "Header (fixed)");
|
||
meow_widget *list = meow_list_create(0, 0, 480, 100, NROW, src, NULL);
|
||
meow_list_set_item_h(list, ITEM);
|
||
meow_widget *footer = meow_btn_create(0, 0, 480, 52, "Footer (fixed)");
|
||
|
||
meow_box_add(bx, header, MEOW_BOX_FIXED, 0);
|
||
meow_box_add(bx, list, MEOW_BOX_WEIGHT, 1);
|
||
meow_box_add(bx, footer, MEOW_BOX_FIXED, 0);
|
||
meow_box_arrange(bx);
|
||
|
||
int hr[4], lr[4], fr[4];
|
||
meow_widget_rect(header, hr);
|
||
meow_widget_rect(list, lr);
|
||
meow_widget_rect(footer, fr);
|
||
printf("DEMO layout: header(%d,%d,%d,%d) list(%d,%d,%d,%d) footer(%d,%d,%d,%d)\n",
|
||
hr[0], hr[1], hr[2], hr[3], lr[0], lr[1], lr[2], lr[3], fr[0], fr[1], fr[2], fr[3]);
|
||
|
||
meow_widget_draw(header);
|
||
meow_widget_draw(list);
|
||
meow_widget_draw(footer);
|
||
meow_ui_flush(); /* 上屏并 MEOW_UI_DUMP 写 PPM *//* (host 离屏无 fb → 只落盘) */
|
||
|
||
/* ---- fling:对列表做一次惯性下滑(速度跟踪→减速→停)---- */
|
||
meow_scroll *s = meow_scroll_wrap(list, 0);
|
||
int maxs = meow_list_max_scroll(list);
|
||
uint64_t t = meow_ui_time_ms();
|
||
for (int i = 0; i < 14; i++) meow_scroll_track(s, 40, t + (uint64_t)i * 16);
|
||
meow_scroll_fling(s);
|
||
int guard = 0;
|
||
while (meow_scroll_active(s) && guard++ < 300) { meow_anim_tick(); usleep(10000); }
|
||
meow_anim_tick();
|
||
int end = meow_scroll_offset(s);
|
||
printf("DEMO fling: max_scroll=%d final=%d (active=%d)\n", maxs, end, meow_scroll_active(s));
|
||
|
||
meow_scroll_free(s);
|
||
meow_box_free(bx);
|
||
meow_widget_free(list);
|
||
meow_widget_free(header);
|
||
meow_widget_free(footer);
|
||
meow_ui_shutdown();
|
||
printf("DEMO OK\n");
|
||
return 0;
|
||
}
|