Files
Deshab-OS/CODE/tools/pe-tools/paint.cpp
T

137 lines
4.7 KiB
C++
Raw Normal View History

/* paint.cpp — Deshab 画板(GUI PE64 工具)
*
* 顶栏:色板(10 色)+ 笔刷(2/6/12px)+ Clear。
* 客户区:左键拖拽画线(独立持久层,UI 每帧叠加)。
* 键盘:C = 清空;Esc 关闭。
* 无文件 IO(shim CreateFileA → PE-E05),本工具为纯画布。
*/
#include "pe_tool.h"
#define TB_H 52
#define SWATCH_N 10
#define SWATCH_S 24
static const u32 g_swatches[SWATCH_N] = {
PTCOL(0x1A, 0x1A, 0x1A), PTCOL(0xFF, 0xFF, 0xFF),
PTCOL(0xC4, 0x2B, 0x1C), PTCOL(0xF7, 0x63, 0x16),
PTCOL(0xFF, 0xB9, 0x00), PTCOL(0x0F, 0x7B, 0x0F),
PTCOL(0x00, 0x67, 0xC0), PTCOL(0x8B, 0x5C, 0xF6),
PTCOL(0xE3, 0x00, 0x8B), PTCOL(0x8A, 0x8A, 0x8A),
};
static u32 *g_layer; /* 持久绘画层(画布区) */
static int g_layer_w, g_layer_h;
static int g_cvw; /* 实际画布宽(窗口可能被 surface 钳位) */
static int g_color = 6; /* 默认 Win11 蓝 */
static int g_brush = 2; /* 笔刷索引:0=2px 1=6px 2=12px */
static const int g_brush_px[3] = { 2, 6, 12 };
static int g_drawing;
static int g_last_x, g_last_y;
static void layer_alloc(int w, int h) {
g_layer_w = w;
g_layer_h = h;
for (long i = 0; i < (long)w * h; i++) g_layer[i] = PTCOL(0xFF, 0xFF, 0xFF);
}
static void stroke_to(int x, int y) {
int px = g_brush_px[g_brush];
/* 持久层画线(构造视图 canvas) */
PT_Canvas cv;
cv.w = g_layer_w; cv.h = g_layer_h; cv.bits = g_layer;
pt_line(&cv, g_last_x, g_last_y, x, y, px, g_swatches[g_color]);
pt_disc(&cv, x, y, px / 2, g_swatches[g_color]);
g_last_x = x; g_last_y = y;
}
static void mouse(int x, int y, int buttons, int edge) {
int cw = g_cvw;
/* 顶栏命中 */
if (edge & 1) { /* 左键按下 */
if (y < TB_H) {
/* 色板 */
for (int i = 0; i < SWATCH_N; i++) {
int sx = 10 + i * (SWATCH_S + 6);
if (x >= sx && x < sx + SWATCH_S &&
y >= (TB_H - SWATCH_S) / 2 && y < (TB_H - SWATCH_S) / 2 + SWATCH_S) {
g_color = i;
return;
}
}
/* 笔刷 */
for (int i = 0; i < 3; i++) {
int bx = 10 + SWATCH_N * (SWATCH_S + 6) + 12 + i * 40;
if (x >= bx && x < bx + 36 && y >= 8 && y < TB_H - 8) {
g_brush = i;
return;
}
}
/* Clear */
int cx = cw - 80;
if (x >= cx && x < cx + 72 && y >= 12 && y < TB_H - 12) {
layer_alloc(g_layer_w, g_layer_h);
return;
}
return;
}
/* 画布起笔 */
g_drawing = 1;
g_last_x = x; g_last_y = y - TB_H;
stroke_to(x, y - TB_H);
return;
}
if (edge & 2) g_drawing = 0;
if (buttons & 1 && g_drawing && y >= TB_H)
stroke_to(x, y - TB_H);
}
static void key(unsigned vk, unsigned ch) {
if (ch == 'c' || ch == 'C') layer_alloc(g_layer_w, g_layer_h);
}
static void frame(PT_Canvas *cv) {
g_cvw = cv->w;
/* 画布层 → DIB */
for (int r = 0; r < g_layer_h && r + TB_H < cv->h; r++)
for (int q = 0; q < g_layer_w && q < cv->w; q++)
cv->bits[(long)(r + TB_H) * cv->w + q] = g_layer[(long)r * g_layer_w + q];
/* 顶栏 */
pt_fill(cv, 0, 0, cv->w, TB_H, PT_BG);
pt_fill(cv, 0, TB_H - 1, cv->w, 1, PT_STROKE);
for (int i = 0; i < SWATCH_N; i++) {
int sx = 10 + i * (SWATCH_S + 6);
int sy = (TB_H - SWATCH_S) / 2;
pt_round_fill(cv, sx, sy, SWATCH_S, SWATCH_S, g_swatches[i], 6);
if (g_color == i)
pt_rect(cv, sx - 2, sy - 2, SWATCH_S + 4, SWATCH_S + 4, PT_ACCENT);
}
for (int i = 0; i < 3; i++) {
int bx = 10 + SWATCH_N * (SWATCH_S + 6) + 12 + i * 40;
int bc = g_brush == i ? PT_ACCENT : PT_TEXT2;
pt_disc(cv, bx + 18, TB_H / 2, g_brush_px[i] / 2 + 1, bc);
if (g_brush == i)
pt_rect(cv, bx, 8, 36, TB_H - 16, PT_ACCENT);
}
pt_round_fill(cv, cv->w - 80, 12, 72, TB_H - 24, PT_CARD, 4);
pt_rect(cv, cv->w - 80, 12, 72, TB_H - 24, PT_STROKE);
pt_text_center(cv, "Clear", cv->w - 44, TB_H / 2 - 9, PT_TEXT);
pt_text(cv, "C = clear Esc = close", 10, cv->h - 24, PT_TEXT_DIM);
}
int main(void) {
static u32 layer_mem[900 * 700]; /* 静态层:msvcrt malloc shim 可用,但静态最稳 */
g_layer = layer_mem;
PT_Desc d;
d.w = 700; d.h = 560;
d.title = L"Paint";
d.frame = frame;
d.key = key;
d.mouse = mouse;
/* 层尺寸按期望值预分配;pt_run 钳位后窗口只会更小(绘制有界) */
layer_alloc(700, 560 - TB_H);
return pt_run(&d);
}