Files
MeowOS-For-R3P2/patch_v2/meow_launcherd/test_host_icon.c
T

159 lines
7.2 KiB
C
Raw 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.
/* test_host_icon.c — 宿主最小 harness:复现主界面卡片(menu_draw_grid_cell)的
* 「卡底 → 图标 → 名称」绘制序列(与实际菜单同序),断言图标区像素非空。
*
* 背景:真机「应用图标完全不渲染(连首字母占位都无)」。本 harness 用真实 SDK(gfx+img)
* 按实际调用顺序绘制,对「有图(meow_ui_img_cover 不透明 226×226)」与「无图(primary
* 圆角块占位)」两分支各断言图标区含非背景像素;另转 PPM 目检。
*
* 编译(在 patch_v2/meow_launcherd 下):
* gcc -o test_host_icon test_host_icon.c ../sdk/test_host_stub.c \
* ../sdk/meow_ui_gfx.c ../sdk/meow_ui_sys.c ../sdk/meow_ui_theme.c \
* ../sdk/meow_ui_vol.c ../sdk/meow_ui_log.c ../sdk/meow_ui_widget.c \
* ../sdk/meow_ui_input.c ../sdk/meow_ui_activity.c ../sdk/meow_ui_dialog.c \
* ../sdk/meow_ui_ime.c ../sdk/meow_ui_draw.c ../sdk/meow_ui_view.c \
* ../sdk/meow_ui_img.c ../sdk/meow_notify_ipc.c ../sdk/meow_ui_media.c \
* ../sdk/stb_image.c -I../sdk -I. -DMEOW_UI_HOST_TEST -pthread -lm
* 运行:MEOW_UI_DUMP=/tmp/icon.ppm ./test_host_icon
*/
#include "meow_ui.h"
#include "meow_ui_internal.h" /* meow_ui_back_buf/pitch/bpp + meow_gfx_fill_round */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* 与 launcher 主题色(dark)对齐 */
#define TH_SURFACE_CONTAINER 0x263038
#define TH_PRIMARY 0x4A6A9A
/* 不透明图标填充色 */
#define IMG_COLOR 0x336699
/* 与主菜单一致的几何常量(main_menu.c) */
#define MENU_GRID_RADIUS 16
#define MENU_GRID_ICON 44
#define MENU_GRID_CARD_H 112
#define MENU_GRID_COLS 2
#define MENU_GRID_PAD 12
#define MENU_GRID_GAP 10
#define FB_W 480
#define FB_H 720
static void rd_px(int x, int y, int *r, int *g, int *b)
{
unsigned char *bb = meow_ui_back_buf();
int line = meow_ui_back_buf_pitch(), bpp = meow_ui_back_buf_bpp();
if (!bb || x < 0 || y < 0) { *r = *g = *b = 0; return; }
if (bpp == 16) {
uint16_t px = *(uint16_t *)(bb + (size_t)y * line + (size_t)x * 2);
*r = (((px >> 11) & 0x1F) << 3) | ((px >> 11) & 0x1F) >> 2;
*g = (((px >> 5) & 0x3F) << 2) | ((px >> 5) & 0x3F) >> 4;
*b = ((px & 0x1F) << 3) | ((px & 0x1F) >> 2);
} else {
uint32_t px = *(uint32_t *)(bb + (size_t)y * line + (size_t)x * 4);
*r = (px >> 16) & 0xFF; *g = (px >> 8) & 0xFF; *b = px & 0xFF;
}
}
static int near2(int a, int b) { int d = a - b; if (d < 0) d = -d; return d <= 16; }
static int px_near(int x, int y, int r, int g, int b)
{
int rr, gg, bb; rd_px(x, y, &rr, &gg, &bb);
return near2(rr, r) && near2(gg, g) && near2(bb, b);
}
/* 区域内含「接近 target 色」的像素数 */
static int region_has(int x, int y, int w, int h, int r, int g, int b)
{
int cnt = 0;
for (int dy = 0; dy < h; dy++)
for (int dx = 0; dx < w; dx++)
if (px_near(x + dx, y + dy, r, g, b)) cnt++;
return cnt;
}
#define UNPK(c, rr, gg, bb) do { (rr) = ((c) >> 16) & 0xFF; (gg) = ((c) >> 8) & 0xFF; (bb) = (c) & 0xFF; } while (0)
/* 菜单图标绘制(menu_draw_icon):primary 圆角垫块始终垫底(MD3 图标 tile),
* 有图叠加 meow_ui_img_cover;无图叠加首字母。透明显图时垫块仍露出,图标区绝不空白。 */
static void menu_draw_icon_like(meow_img *icon, int x, int y, int sz)
{
meow_gfx_fill_round(x, y, sz, sz, sz * 3 / 10, TH_PRIMARY);
if (icon) { meow_ui_img_cover(x, y, sz, icon); return; }
}
/* 复现 menu_draw_grid_cell 的绘制序列(卡底 → 图标;名称与图标区隔离,无关像素) */
static void draw_grid_cell(int x, int y, int w, int h, meow_img *icon)
{
meow_gfx_fill_round(x, y, w, h, MENU_GRID_RADIUS, TH_SURFACE_CONTAINER);
int sz = (h > MENU_GRID_ICON + 40) ? MENU_GRID_ICON : h - 40;
int icx = x + (w - sz) / 2, icy = y + 12;
menu_draw_icon_like(icon, icx, icy, sz);
}
int main(void)
{
setbuf(stdout, NULL); /* 立即冲刷,abort 前也能看到 printf */
setenv("MEOW_UI_DUMP", "/tmp/icon.ppm", 1);
meow_ui_opts o = { FB_W, FB_H };
assert(meow_ui_init(&o) == 0);
assert(meow_ui_width() == FB_W && meow_ui_height() == FB_H);
int apps_top = 130; /* 模拟主菜单 app 区顶缘 */
int cx = MENU_GRID_PAD, cy = apps_top;
int cw = (FB_W - 2 * MENU_GRID_PAD - (MENU_GRID_COLS - 1) * MENU_GRID_GAP) / MENU_GRID_COLS;
int ch = MENU_GRID_CARD_H;
int sz = (ch > MENU_GRID_ICON + 40) ? MENU_GRID_ICON : ch - 40;
int icx = cx + (cw - sz) / 2, icy = cy + 12;
/* ---------- 分支 A:有图(meow_ui_img_cover,不透明 226×226,meow_img_load_file) ---------- */
{
meow_img *im = meow_img_load_file("/tmp/icon226.png");
assert(im != NULL);
assert(meow_img_w(im) == 226 && meow_img_h(im) == 226);
meow_ui_clear(0x000000);
draw_grid_cell(cx, cy, cw, ch, im);
int tr, tg, tb; UNPK(IMG_COLOR, tr, tg, tb);
int got = region_has(icx, icy, sz, sz, tr, tg, tb);
printf("A(image 226x226 opaque): icon region(%d,%d %dx%d) img-color px = %d\n",
icx, icy, sz, sz, got);
assert(got > 0 && "meow_ui_img_cover 未能把不透明图标画进图标区");
int sr, sg, sb; UNPK(TH_SURFACE_CONTAINER, sr, sg, sb);
int cardpx = region_has(icx, icy, sz, sz, sr, sg, sb);
printf(" card-color px inside icon region = %d\n", cardpx);
assert(cardpx == 0 && "图标区仍被卡底色占据(图标被盖掉/未画出)");
meow_img_free(im);
}
/* ---------- 分支 A':全透明图标(alpha=0)——修复后垫块垫底,图标区非空 ---------- */
{
meow_img *im = meow_img_load_file("/tmp/icon226_trans.png");
assert(im != NULL);
meow_ui_clear(0x000000);
draw_grid_cell(cx, cy, cw, ch, im);
int pr, pg, pb; UNPK(TH_PRIMARY, pr, pg, pb);
int got = region_has(icx, icy, sz, sz, pr, pg, pb);
printf("A'(transparent icon, fixed): icon region primary(tile) px = %d\n", got);
assert(got > 0 && "全透明图标不再被放过:垫块应画出(图标区非空)");
/* 垫块圆角角落会透出卡底色,属几何本性 */
meow_img_free(im);
}
/* ---------- 分支 B:无图(primary 圆角块占位) ---------- */
{
meow_ui_clear(0x000000);
draw_grid_cell(cx, cy, cw, ch, NULL);
int pr, pg, pb; UNPK(TH_PRIMARY, pr, pg, pb);
int got = region_has(icx, icy, sz, sz, pr, pg, pb);
printf("B(placeholder primary round): icon region primary px = %d\n", got);
assert(got > 0 && "占位圆角块未画进图标区");
/* 圆角块角落会透出卡底色——这是几何本性,非 bug;只要求主色像素显著多 */
int sr, sg, sb; UNPK(TH_SURFACE_CONTAINER, sr, sg, sb);
int cardpx = region_has(icx, icy, sz, sz, sr, sg, sb);
printf(" card-color px in icon region (round corners) = %d\n", cardpx);
assert(got > sz * sz * 3 / 4 && "占位圆角块覆盖面积过小(未真正画到图标区)");
}
printf("PASS test_host_icon (A image + B placeholder render in icon region)\n");
return 0;
}