c/ui/color_chart.c · 7112 字节 · 下载原文
/* color_chart.c —— 标准颜色**一览表**:名字写在色块上,一眼核对「这个名字 ↔ 这个色」对不对。
* color_chart.c — a **swatch chart** for the standard colors: the name sits on the swatch,
* so "does this name match this color" is checked at a glance.
*
* ## 与 draw_colors.c 的分工
* ## How this splits the work with draw_colors.c
*
* `draw_colors.c` 是**取像素的自动化体检**(同一颜色画满 15 格、逐格读回像素比对)。
* `draw_colors.c` is the **automated, pixel-reading health check** (15 cells of one color, each read back).
* 本程序是**给人眼看的那一张**:22 个 `VML_COLOR_*` 各自画一格、名字压在上面。
* this program is the **one a human looks at**: each of the 22 `VML_COLOR_*` gets a swatch with its name on it.
* 两者不重复 —— 像素判据能抓"通道序写反",但抓不到"RED 这个常量定成了蓝的"
* (the two do not overlap: a pixel check catches a swapped channel order, but not "the constant named RED holds blue")
* —— 后者只有把**名字和颜色摆在一起**才看得出来,这正是本程序存在的理由。
* — only putting **name and color side by side** reveals that, which is why this program exists.
*
* ## 怎么核对
* ## How to check
*
* 数 4 列 × 6 行(22 个颜色 + 2 格留空),逐个看:
* count 4 columns x 6 rows (22 colors + 2 blank cells), and for each cell ask:
* · `RED` 是不是红的、`GREEN` 是不是**暗绿**(`0xFF008000`,HTML/CSS 那个绿,不是纯绿 `00FF00`);
* is RED red, and is GREEN the **dark** green (`0xFF008000`, the HTML/CSS one, not pure `00FF00`);
* · `LIME` 才是**亮绿**,`GREY` 与 `GRAY` 应当**一模一样**;
* LIME is the **bright** green, and GREY must look **exactly like** GRAY;
* · `TRANSPARENT` 那格**没有底色**,靠灰边框才看得出位置(这是对的,不是画错了)。
* the TRANSPARENT cell has **no fill** and is only visible by its grey border (that is correct, not a bug).
*
* ⚠ 颜色值一律走 `VML_COLOR_*` 常量 + `ui_color_rgb()`,**不写字面量**
* ⚠ Every color goes through the `VML_COLOR_*` constants and `ui_color_rgb()`, **no literals** --
* — 这个程序同时就是"常量能不能用、值对不对"的现场证据。
* this program doubles as live evidence that the constants resolve and hold the right values.
*/
#include <vml_ui.h>
#define COLS 4 /* 4 列 */
/* 4 columns */
#define ROWS 6 /* 6 行(22 个颜色,最后两格留空) */
/* 6 rows (22 colors; the last two cells stay empty) */
#define PAD 8 /* 格间距 */
/* cell spacing */
#define TITLE_H 46 /* 顶部标题占的高度 */
/* height taken by the title bar at the top */
/* 一格:**先描边再填色** —— TRANSPARENT 那格没有底色,靠边框才看得出位置。 */
/* One cell: **stroke first, then fill** - the TRANSPARENT cell has no fill and needs the border. */
void cell(int x, int y, int w, int h, int color, char* name) {
int lum;
int ink;
ui_2d_rect(x, y, w, h, ui_color_rgb(90, 96, 110), 0, 2, 6);
ui_2d_rect(x + 3, y + 3, w - 6, h - 6, color, 1, 0, 4);
/* 名字压在色块上:按**亮度**选黑字还是白字,否则浅色块上的白字看不见。 */
/* The name sits on the swatch: pick black or white ink by **luminance**, or white-on-light is unreadable. */
/* ⚠ 亮度算式**自带**,不调 shared 的 `grayscale()`:那个函数在 `shared/color.vml` 里,
* ⚠ The luminance math is **inlined** instead of calling shared's `grayscale()`: that one lives in
而 C 的默认链接集(`vmltool.config.xml` 的 `Libs=`)不含它 ⇒ 调了会「未定义的函数」。
`shared/color.vml`, which is not in C's default link set (`Libs=` in vmltool.config.xml) => calling it would report "undefined function". */
lum = (((color >> 16) & 255) * 299 + ((color >> 8) & 255) * 587 + (color & 255) * 114) / 1000;
if (lum > 140) ink = ui_color_rgb(16, 16, 20);
else ink = ui_color_rgb(240, 240, 245);
ui_2d_text(x + 8, y + h - 26, name, ink, 12, VML_ANCHOR_LEFT);
}
/* 按"第几列第几行"摆一格(列/行由 0 起)。 */
/* Place one cell by (column, row), both 0-based. */
void swatch(int col, int row, int cw, int ch, int color, char* name) {
int x = PAD + col * (cw + PAD);
int y = TITLE_H + PAD + row * (ch + PAD);
cell(x, y, cw, ch, color, name);
}
void main(void) {
int w = 468;
int h = 704;
int cw;
int ch;
ui_win_open_ex("标准颜色 Standard Colors", w, h, VML_WIN_ROTATABLE, VML_WIN_NO_GAMEPAD);
cw = (w - PAD * (COLS + 1)) / COLS;
ch = (h - TITLE_H - PAD * (ROWS + 1)) / ROWS;
while (ui_win_is_closed() == 0) {
ui_2d_clear(ui_color_rgb(24, 26, 32));
ui_2d_text(14, 12, "VML_COLOR_* 标准颜色(名字 ↔ 色块)", ui_color_rgb(230, 232, 240), 15, VML_ANCHOR_LEFT);
ui_2d_text(14, 30, "GREEN 是暗绿 0xFF008000,亮绿是 LIME;GREY 与 GRAY 相同", ui_color_rgb(140, 148, 164), 10, VML_ANCHOR_LEFT);
swatch(0, 0, cw, ch, VML_COLOR_BLACK, "BLACK");
swatch(1, 0, cw, ch, VML_COLOR_WHITE, "WHITE");
swatch(2, 0, cw, ch, VML_COLOR_RED, "RED");
swatch(3, 0, cw, ch, VML_COLOR_GREEN, "GREEN");
swatch(0, 1, cw, ch, VML_COLOR_BLUE, "BLUE");
swatch(1, 1, cw, ch, VML_COLOR_YELLOW, "YELLOW");
swatch(2, 1, cw, ch, VML_COLOR_CYAN, "CYAN");
swatch(3, 1, cw, ch, VML_COLOR_MAGENTA, "MAGENTA");
swatch(0, 2, cw, ch, VML_COLOR_GRAY, "GRAY");
swatch(1, 2, cw, ch, VML_COLOR_GREY, "GREY");
swatch(2, 2, cw, ch, VML_COLOR_ORANGE, "ORANGE");
swatch(3, 2, cw, ch, VML_COLOR_PURPLE, "PURPLE");
swatch(0, 3, cw, ch, VML_COLOR_PINK, "PINK");
swatch(1, 3, cw, ch, VML_COLOR_BROWN, "BROWN");
swatch(2, 3, cw, ch, VML_COLOR_NAVY, "NAVY");
swatch(3, 3, cw, ch, VML_COLOR_TEAL, "TEAL");
swatch(0, 4, cw, ch, VML_COLOR_LIME, "LIME");
swatch(1, 4, cw, ch, VML_COLOR_MAROON, "MAROON");
swatch(2, 4, cw, ch, VML_COLOR_OLIVE, "OLIVE");
swatch(3, 4, cw, ch, VML_COLOR_SILVER, "SILVER");
swatch(0, 5, cw, ch, VML_COLOR_GOLD, "GOLD");
swatch(1, 5, cw, ch, VML_COLOR_TRANSPARENT, "TRANSPARENT");
ui_2d_present();
ui_msg_fetch_wait(40); /* 只是「等输入最多 40ms」(上屏节奏由宿主管,2026-10-04 起);
* just "wait for input at most 40 ms" (the host owns frame pacing since 2026-10-04);
* 静态图也走这条,转屏后自动重排
* the static picture goes through this too, and it re-lays-out after a rotation. */
}
}