// mkwgticon.c -- Generate 24x24 BMP widget icons for the DVX BASIC toolbox // // Usage: mkwgticon // Types: button, label, textbox, checkbox, radio, dropdown, combobox, // listbox, listview, treeview, image, imgbtn, canvas, slider, // spinner, progress, timer, frame, hbox, vbox, splitter, // scrollpane, tabctrl, toolbar, statusbar, separator, spacer, // terminal #include #include #include #define W 24 #define H 24 static uint8_t pixels[H][W][3]; // BGR static void clear(uint8_t r, uint8_t g, uint8_t b) { for (int y = 0; y < H; y++) { for (int x = 0; x < W; x++) { pixels[y][x][0] = b; pixels[y][x][1] = g; pixels[y][x][2] = r; } } } static void px(int x, int y, uint8_t r, uint8_t g, uint8_t b) { if (x >= 0 && x < W && y >= 0 && y < H) { pixels[y][x][0] = b; pixels[y][x][1] = g; pixels[y][x][2] = r; } } static void rect(int x0, int y0, int w, int h, uint8_t r, uint8_t g, uint8_t b) { for (int y = y0; y < y0 + h && y < H; y++) { for (int x = x0; x < x0 + w && x < W; x++) { px(x, y, r, g, b); } } } static void hline(int x, int y, int len, uint8_t r, uint8_t g, uint8_t b) { for (int i = 0; i < len; i++) { px(x + i, y, r, g, b); } } static void vline(int x, int y, int len, uint8_t r, uint8_t g, uint8_t b) { for (int i = 0; i < len; i++) { px(x, y + i, r, g, b); } } static void box(int x0, int y0, int w, int h, uint8_t r, uint8_t g, uint8_t b) { hline(x0, y0, w, r, g, b); hline(x0, y0 + h - 1, w, r, g, b); vline(x0, y0, h, r, g, b); vline(x0 + w - 1, y0, h, r, g, b); } // 3x5 mini font for labeling icons static void miniChar(int x, int y, char ch, uint8_t r, uint8_t g, uint8_t b) { // Simplified: just draw recognizable glyphs for A-Z, 0-9 static const uint16_t font[128] = { ['A'] = 0x7D6F, ['B'] = 0xFD7F, ['C'] = 0x7C9F, ['D'] = 0xF56F, ['E'] = 0xFC9F, ['F'] = 0xFC90, ['G'] = 0x7CBF, ['H'] = 0xB7ED, ['I'] = 0xE92E, ['K'] = 0xB6AD, ['L'] = 0x924F, ['M'] = 0xBFED, ['N'] = 0xBDED, ['O'] = 0x756E, ['P'] = 0xFD20, ['R'] = 0xFD6D, ['S'] = 0x7C1F, ['T'] = 0xE924, ['U'] = 0xB6DE, ['V'] = 0xB6A4, ['W'] = 0xB7FA, ['X'] = 0xB52D, ['Y'] = 0xB524, ['Z'] = 0xE54F, }; uint16_t bits = (ch >= 'A' && ch <= 'Z') ? font[(int)ch] : 0; for (int row = 0; row < 5; row++) { for (int col = 0; col < 3; col++) { if (bits & (1 << (14 - row * 3 - col))) { px(x + col, y + row, r, g, b); } } } } static void miniText(int x, int y, const char *text, uint8_t r, uint8_t g, uint8_t b) { while (*text) { char ch = *text; if (ch >= 'a' && ch <= 'z') { ch -= 32; } miniChar(x, y, ch, r, g, b); x += 4; text++; } } static void bevel(int x0, int y0, int w, int h, int bw) { // Raised bevel: white top-left, dark bottom-right for (int i = 0; i < bw; i++) { hline(x0 + i, y0 + i, w - i * 2, 255, 255, 255); vline(x0 + i, y0 + i, h - i * 2, 255, 255, 255); hline(x0 + i, y0 + h - 1 - i, w - i * 2, 128, 128, 128); vline(x0 + w - 1 - i, y0 + i, h - i * 2, 128, 128, 128); } } static void drawButton(void) { clear(192, 192, 192); rect(3, 5, 18, 14, 192, 192, 192); bevel(3, 5, 18, 14, 2); miniText(7, 9, "OK", 0, 0, 0); } static void drawLabel(void) { clear(192, 192, 192); miniText(3, 9, "LABEL", 0, 0, 128); } static void drawTextbox(void) { clear(192, 192, 192); rect(2, 6, 20, 12, 255, 255, 255); box(2, 6, 20, 12, 128, 128, 128); miniText(4, 9, "TEXT", 0, 0, 0); } static void drawCheckbox(void) { clear(192, 192, 192); rect(4, 7, 10, 10, 255, 255, 255); box(4, 7, 10, 10, 128, 128, 128); // Checkmark px(6, 12, 0, 0, 0); px(7, 13, 0, 0, 0); px(8, 14, 0, 0, 0); px(9, 13, 0, 0, 0); px(10, 12, 0, 0, 0); px(11, 11, 0, 0, 0); px(12, 10, 0, 0, 0); miniText(16, 9, "AB", 0, 0, 0); } static void drawRadio(void) { clear(192, 192, 192); // Circle outline for (int i = 5; i <= 9; i++) { px(i, 6, 128, 128, 128); px(i, 16, 128, 128, 128); } for (int i = 7; i <= 15; i++) { px(4, i, 128, 128, 128); px(10, i, 128, 128, 128); } // Filled dot rect(6, 9, 3, 3, 0, 0, 0); miniText(14, 9, "AB", 0, 0, 0); } static void drawDropdown(void) { clear(192, 192, 192); rect(2, 7, 20, 11, 255, 255, 255); box(2, 7, 20, 11, 128, 128, 128); // Down arrow button rect(16, 8, 5, 9, 192, 192, 192); bevel(16, 8, 5, 9, 1); px(17, 11, 0, 0, 0); px(18, 12, 0, 0, 0); px(19, 11, 0, 0, 0); } static void drawCombobox(void) { clear(192, 192, 192); drawDropdown(); // Add text to distinguish from dropdown miniText(4, 9, "AB", 0, 0, 0); } static void drawListbox(void) { clear(192, 192, 192); rect(3, 3, 18, 18, 255, 255, 255); box(3, 3, 18, 18, 128, 128, 128); // List items hline(5, 6, 10, 0, 0, 0); rect(5, 9, 14, 3, 0, 0, 128); // selected hline(5, 10, 10, 255, 255, 255); hline(5, 14, 10, 0, 0, 0); hline(5, 17, 10, 0, 0, 0); } static void drawListview(void) { clear(192, 192, 192); rect(2, 2, 20, 20, 255, 255, 255); box(2, 2, 20, 20, 128, 128, 128); // Column headers rect(3, 3, 18, 4, 192, 192, 192); hline(3, 6, 18, 128, 128, 128); vline(10, 3, 18, 128, 128, 128); // Grid lines hline(3, 10, 18, 192, 192, 192); hline(3, 14, 18, 192, 192, 192); } static void drawTreeview(void) { clear(192, 192, 192); rect(2, 2, 20, 20, 255, 255, 255); box(2, 2, 20, 20, 128, 128, 128); // Tree lines vline(6, 5, 14, 128, 128, 128); hline(6, 7, 5, 128, 128, 128); hline(6, 12, 5, 128, 128, 128); vline(10, 12, 5, 128, 128, 128); hline(10, 16, 5, 128, 128, 128); // Expand box rect(4, 4, 5, 5, 255, 255, 255); box(4, 4, 5, 5, 0, 0, 0); hline(5, 6, 3, 0, 0, 0); // minus px(6, 5, 0, 0, 0); // plus vertical px(6, 7, 0, 0, 0); } static void drawImage(void) { clear(192, 192, 192); rect(3, 3, 18, 18, 255, 255, 255); box(3, 3, 18, 18, 128, 128, 128); // Mountain landscape px(8, 8, 255, 255, 0); // sun px(9, 8, 255, 255, 0); px(8, 7, 255, 255, 0); px(9, 7, 255, 255, 0); // Mountain for (int i = 0; i < 7; i++) { hline(10 - i, 17 - i, 1 + i * 2, 0, 128, 0); } } static void drawImgbtn(void) { clear(192, 192, 192); bevel(2, 3, 20, 18, 2); // Small image inside rect(7, 7, 10, 10, 200, 200, 255); box(7, 7, 10, 10, 0, 0, 128); } static void drawCanvas(void) { clear(192, 192, 192); rect(3, 3, 18, 18, 255, 255, 255); box(3, 3, 18, 18, 128, 128, 128); // Diagonal line for (int i = 0; i < 14; i++) { px(4 + i, 4 + i, 255, 0, 0); } // Circle for (int i = 0; i < 8; i++) { px(14 + i/2, 6, 0, 0, 255); px(14 + i/2, 12, 0, 0, 255); } } static void drawSlider(void) { clear(192, 192, 192); // Track hline(3, 12, 18, 128, 128, 128); hline(3, 13, 18, 255, 255, 255); // Thumb rect(10, 8, 4, 8, 192, 192, 192); bevel(10, 8, 4, 8, 1); } static void drawSpinner(void) { clear(192, 192, 192); rect(3, 6, 14, 12, 255, 255, 255); box(3, 6, 14, 12, 128, 128, 128); miniText(5, 9, "42", 0, 0, 0); // Up/down buttons rect(17, 6, 5, 6, 192, 192, 192); bevel(17, 6, 5, 6, 1); rect(17, 12, 5, 6, 192, 192, 192); bevel(17, 12, 5, 6, 1); // Arrows px(19, 8, 0, 0, 0); px(18, 9, 0, 0, 0); px(20, 9, 0, 0, 0); px(18, 14, 0, 0, 0); px(20, 14, 0, 0, 0); px(19, 15, 0, 0, 0); } static void drawProgress(void) { clear(192, 192, 192); rect(2, 8, 20, 8, 255, 255, 255); box(2, 8, 20, 8, 128, 128, 128); // Fill rect(3, 9, 12, 6, 0, 0, 128); } static void drawTimer(void) { clear(192, 192, 192); // Clock face for (int a = 0; a < 12; a++) { int cx = 12, cy = 12; // Approximate circle points static const int dx[] = {0, 4, 7, 8, 7, 4, 0, -4, -7, -8, -7, -4}; static const int dy[] = {-8, -7, -4, 0, 4, 7, 8, 7, 4, 0, -4, -7}; px(cx + dx[a], cy + dy[a], 0, 0, 0); } // Hands vline(12, 5, 7, 0, 0, 0); hline(12, 12, 5, 0, 0, 0); } static void drawFrame(void) { clear(192, 192, 192); box(3, 6, 18, 15, 128, 128, 128); rect(5, 4, 14, 5, 192, 192, 192); miniText(6, 4, "GRP", 0, 0, 0); } static void drawHbox(void) { clear(192, 192, 192); box(2, 4, 20, 16, 0, 0, 128); vline(8, 4, 16, 0, 0, 128); vline(15, 4, 16, 0, 0, 128); // Arrow hline(4, 12, 16, 0, 0, 128); px(18, 11, 0, 0, 128); px(18, 13, 0, 0, 128); } static void drawVbox(void) { clear(192, 192, 192); box(2, 2, 20, 20, 0, 128, 0); hline(2, 8, 20, 0, 128, 0); hline(2, 15, 20, 0, 128, 0); // Arrow vline(12, 4, 16, 0, 128, 0); px(11, 18, 0, 128, 0); px(13, 18, 0, 128, 0); } static void drawSplitter(void) { clear(192, 192, 192); rect(2, 2, 9, 20, 200, 200, 200); box(2, 2, 9, 20, 128, 128, 128); rect(13, 2, 9, 20, 200, 200, 200); box(13, 2, 9, 20, 128, 128, 128); // Grip dots for (int i = 0; i < 3; i++) { px(11, 9 + i * 3, 128, 128, 128); px(12, 9 + i * 3, 255, 255, 255); } } static void drawScrollpane(void) { clear(192, 192, 192); rect(2, 2, 18, 18, 255, 255, 255); box(2, 2, 20, 20, 128, 128, 128); // Scrollbar rect(19, 2, 3, 20, 192, 192, 192); rect(19, 5, 3, 6, 160, 160, 160); bevel(19, 5, 3, 6, 1); } static void drawTabctrl(void) { clear(192, 192, 192); // Tab buttons rect(3, 4, 8, 5, 192, 192, 192); hline(3, 4, 8, 255, 255, 255); vline(3, 4, 5, 255, 255, 255); vline(10, 4, 5, 128, 128, 128); rect(11, 5, 8, 4, 180, 180, 180); hline(11, 5, 8, 255, 255, 255); vline(18, 5, 4, 128, 128, 128); // Body rect(2, 9, 20, 13, 192, 192, 192); box(2, 9, 20, 13, 128, 128, 128); } static void drawToolbar(void) { clear(192, 192, 192); rect(1, 7, 22, 10, 192, 192, 192); bevel(1, 7, 22, 10, 1); // Buttons rect(3, 8, 5, 8, 192, 192, 192); bevel(3, 8, 5, 8, 1); rect(9, 8, 5, 8, 192, 192, 192); bevel(9, 8, 5, 8, 1); rect(15, 8, 5, 8, 192, 192, 192); bevel(15, 8, 5, 8, 1); } static void drawStatusbar(void) { clear(192, 192, 192); rect(1, 14, 22, 8, 192, 192, 192); // Sunken panels hline(2, 15, 12, 128, 128, 128); hline(2, 20, 12, 255, 255, 255); vline(2, 15, 6, 128, 128, 128); vline(13, 15, 6, 255, 255, 255); hline(15, 15, 7, 128, 128, 128); hline(15, 20, 7, 255, 255, 255); vline(15, 15, 6, 128, 128, 128); vline(21, 15, 6, 255, 255, 255); } static void drawSeparator(void) { clear(192, 192, 192); // Horizontal separator line hline(3, 11, 18, 128, 128, 128); hline(3, 12, 18, 255, 255, 255); // Vertical separator line vline(12, 3, 18, 128, 128, 128); vline(13, 3, 18, 255, 255, 255); } static void drawSpacer(void) { clear(192, 192, 192); // Dotted rectangle outline for (int i = 0; i < 20; i += 2) { px(2 + i, 4, 128, 128, 128); px(2 + i, 19, 128, 128, 128); } for (int i = 0; i < 16; i += 2) { px(2, 4 + i, 128, 128, 128); px(21, 4 + i, 128, 128, 128); } // Double-headed arrow hline(5, 12, 14, 128, 128, 128); px(6, 11, 128, 128, 128); px(6, 13, 128, 128, 128); px(18, 11, 128, 128, 128); px(18, 13, 128, 128, 128); } static void drawTerminal(void) { clear(192, 192, 192); rect(2, 2, 20, 20, 0, 0, 0); box(2, 2, 20, 20, 128, 128, 128); // Green text on black miniText(4, 5, "C", 0, 255, 0); hline(4, 11, 4, 0, 255, 0); miniText(4, 14, "A", 0, 255, 0); // Cursor rect(8, 14, 2, 5, 0, 255, 0); } static void writeBmp(const char *path) { // 24-bit BMP, bottom-up int rowBytes = W * 3; int padding = (4 - (rowBytes % 4)) % 4; int stride = rowBytes + padding; int dataSize = stride * H; int fileSize = 54 + dataSize; FILE *f = fopen(path, "wb"); if (!f) { fprintf(stderr, "Cannot open %s\n", path); return; } // BMP header uint8_t hdr[54]; memset(hdr, 0, sizeof(hdr)); hdr[0] = 'B'; hdr[1] = 'M'; hdr[2] = fileSize; hdr[3] = fileSize >> 8; hdr[4] = fileSize >> 16; hdr[5] = fileSize >> 24; hdr[10] = 54; hdr[14] = 40; hdr[18] = W; hdr[19] = W >> 8; hdr[22] = H; hdr[23] = H >> 8; hdr[26] = 1; hdr[28] = 24; fwrite(hdr, 1, 54, f); uint8_t pad[3] = {0, 0, 0}; for (int y = H - 1; y >= 0; y--) { fwrite(pixels[y], 1, rowBytes, f); if (padding) { fwrite(pad, 1, padding, f); } } fclose(f); } static void drawWrapbox(void) { clear(192, 192, 192); box(2, 2, 20, 20, 0, 0, 180); // Row 1: three small boxes rect(4, 4, 5, 4, 200, 200, 255); box(4, 4, 5, 4, 0, 0, 180); rect(10, 4, 5, 4, 200, 200, 255); box(10, 4, 5, 4, 0, 0, 180); rect(16, 4, 5, 4, 200, 200, 255); box(16, 4, 5, 4, 0, 0, 180); // Row 2: two boxes (wrapped) rect(4, 10, 5, 4, 200, 200, 255); box(4, 10, 5, 4, 0, 0, 180); rect(10, 10, 5, 4, 200, 200, 255); box(10, 10, 5, 4, 0, 0, 180); // Row 3: one box rect(4, 16, 5, 4, 200, 200, 255); box(4, 16, 5, 4, 0, 0, 180); } static void drawDatactrl(void) { clear(192, 192, 192); // Navigation bar rect(2, 8, 20, 8, 200, 200, 200); box(2, 8, 20, 8, 128, 128, 128); // |< button vline(5, 10, 4, 0, 0, 0); px(6, 11, 0, 0, 0); px(7, 12, 0, 0, 0); px(6, 13, 0, 0, 0); px(7, 12, 0, 0, 0); // > button px(16, 11, 0, 0, 0); px(17, 12, 0, 0, 0); px(16, 13, 0, 0, 0); // >| button vline(19, 10, 4, 0, 0, 0); px(18, 11, 0, 0, 0); px(18, 13, 0, 0, 0); // Database cylinder icon above rect(7, 2, 10, 4, 255, 255, 200); box(7, 2, 10, 4, 128, 128, 0); hline(7, 3, 10, 128, 128, 0); } static void drawDbgrid(void) { clear(192, 192, 192); // Grid outline box(1, 1, 22, 22, 128, 128, 128); // Header row (darker) rect(2, 2, 20, 5, 160, 160, 200); hline(2, 7, 20, 128, 128, 128); // Column dividers vline(8, 2, 20, 128, 128, 128); vline(15, 2, 20, 128, 128, 128); // Data rows rect(2, 8, 20, 14, 255, 255, 255); hline(2, 14, 20, 200, 200, 200); // Selected row highlight rect(2, 15, 20, 7, 0, 0, 128); } int main(int argc, char **argv) { if (argc != 3) { fprintf(stderr, "Usage: mkwgticon \n"); return 1; } const char *path = argv[1]; const char *type = argv[2]; typedef struct { const char *name; void (*fn)(void); } IconT; IconT icons[] = { {"button", drawButton}, {"label", drawLabel}, {"textbox", drawTextbox}, {"checkbox", drawCheckbox}, {"radio", drawRadio}, {"dropdown", drawDropdown}, {"combobox", drawCombobox}, {"listbox", drawListbox}, {"listview", drawListview}, {"treeview", drawTreeview}, {"image", drawImage}, {"imgbtn", drawImgbtn}, {"canvas", drawCanvas}, {"slider", drawSlider}, {"spinner", drawSpinner}, {"progress", drawProgress}, {"timer", drawTimer}, {"frame", drawFrame}, {"hbox", drawHbox}, {"vbox", drawVbox}, {"splitter", drawSplitter}, {"scrollpane", drawScrollpane}, {"tabctrl", drawTabctrl}, {"toolbar", drawToolbar}, {"statusbar", drawStatusbar}, {"separator", drawSeparator}, {"spacer", drawSpacer}, {"terminal", drawTerminal}, {"wrapbox", drawWrapbox}, {"datactrl", drawDatactrl}, {"dbgrid", drawDbgrid}, {NULL, NULL} }; for (int i = 0; icons[i].name; i++) { if (strcmp(type, icons[i].name) == 0) { icons[i].fn(); writeBmp(path); return 0; } } fprintf(stderr, "Unknown type: %s\nAvailable:", type); for (int i = 0; icons[i].name; i++) { fprintf(stderr, " %s", icons[i].name); } fprintf(stderr, "\n"); return 1; }