| 860 | } |
| 861 | |
| 862 | function parsePixelForgeHeaderToRgb565(text) { |
| 863 | if (!text || typeof text !== "string") { |
| 864 | throw new Error("No export text received from PixelForge. Click Convert first."); |
| 865 | } |
| 866 | |
| 867 | const widthMatch = text.match(/const\s+uint16_t\s+([A-Za-z0-9_]+)_width\s*=\s*(\d+)\s*;/); |
| 868 | const heightMatch = text.match(/const\s+uint16_t\s+([A-Za-z0-9_]+)_height\s*=\s*(\d+)\s*;/); |
| 869 | if (!widthMatch || !heightMatch) { |
| 870 | throw new Error("Couldn't find width/height in PixelForge export."); |
| 871 | } |
| 872 | |
| 873 | const baseName = widthMatch[1]; |
| 874 | const w = parseInt(widthMatch[2], 10); |
| 875 | const h = parseInt(heightMatch[2], 10); |
| 876 | if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) { |
| 877 | throw new Error("Invalid width/height in PixelForge export."); |
| 878 | } |
| 879 | |
| 880 | // Prefer the base symbol if present; otherwise take the first uint16_t PROGMEM array. |
| 881 | const preferredRe = new RegExp( |
| 882 | `const\\s+uint16_t\\s+(${baseName}(?:_\\d+)?)\\s*\\[\\]\\s*PROGMEM\\s*=\\s*\\{([\\s\\S]*?)\\};` |
| 883 | ); |
| 884 | let arrayMatch = text.match(preferredRe); |
| 885 | if (!arrayMatch) { |
| 886 | arrayMatch = text.match(/const\s+uint16_t\s+([A-Za-z0-9_]+)\s*\[\]\s*PROGMEM\s*=\s*\{([\s\S]*?)\};/); |
| 887 | } |
| 888 | if (!arrayMatch) { |
| 889 | throw new Error("Couldn't find a uint16_t RGB565 array in PixelForge export (TFT mode only)."); |
| 890 | } |
| 891 | |
| 892 | const symbol = arrayMatch[1]; |
| 893 | const body = arrayMatch[2]; |
| 894 | const hexes = body.match(/0x[0-9A-Fa-f]{1,4}/g) || []; |
| 895 | if (!hexes.length) { |
| 896 | throw new Error("No pixel data found in PixelForge export."); |
| 897 | } |
| 898 | const rgb565 = hexes.map((hx) => parseInt(hx, 16) & 0xffff); |
| 899 | |
| 900 | return { symbol, baseName, w, h, rgb565 }; |
| 901 | } |
| 902 | |
| 903 | function rgb565ToDataUrl(w, h, rgb565) { |
| 904 | const canvas = document.createElement("canvas"); |