← 都来码 / Dolaima← 例程索引c/ui/color_chart.c原文

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. */
    }
}