(icon)
| 2948 | } |
| 2949 | |
| 2950 | async function addIconElement(icon) { |
| 2951 | const inferred = inferSizeFromPath(icon.file); |
| 2952 | const sizeW = inferred?.w || 32; |
| 2953 | const sizeH = inferred?.h || 32; |
| 2954 | const x = Math.max(0, Math.round((dispWidth - sizeW) / 2)); |
| 2955 | const y = Math.max(0, Math.round((dispHeight - sizeH) / 2)); |
| 2956 | |
| 2957 | // Try to convert the PNG to RGB565 so it can be emitted in TFT code output. |
| 2958 | let rgb565 = null; |
| 2959 | let monoBitmap = null; |
| 2960 | let iw = sizeW; |
| 2961 | let ih = sizeH; |
| 2962 | try { |
| 2963 | const converted = await loadPngToRgb565(withCacheBust(icon.url), bgColor, sizeW, sizeH, null); |
| 2964 | iw = converted.w; |
| 2965 | ih = converted.h; |
| 2966 | rgb565 = converted.rgb565; |
| 2967 | monoBitmap = converted.monoBitmap; |
| 2968 | } catch { |
| 2969 | // Keep preview-only if conversion fails (e.g., browser blocks canvas due to file/cors) |
| 2970 | } |
| 2971 | |
| 2972 | const id = makeId(); |
| 2973 | const baseSym = safeSymbolFromPath(icon.file); |
| 2974 | const el = createElementWithDefaults("icon", { |
| 2975 | id, |
| 2976 | x, |
| 2977 | y, |
| 2978 | w: iw, |
| 2979 | h: ih, |
| 2980 | iconFile: icon.file, |
| 2981 | iconSrc: withCacheBust(icon.url), |
| 2982 | imageName: `icon_${baseSym}_${id.replace(/[^a-zA-Z0-9_]/g, "_")}`, |
| 2983 | imageWidth: iw, |
| 2984 | imageHeight: ih, |
| 2985 | rgb565: rgb565 || undefined, |
| 2986 | monoBitmap: monoBitmap || undefined |
| 2987 | }); |
| 2988 | |
| 2989 | // Register asset for project re-use (embed PNG only if toggle is on and we can) |
| 2990 | try { |
| 2991 | const embed = assetsEmbedToggle ? !!assetsEmbedToggle.checked : false; |
| 2992 | const assetId = "asset_" + Math.random().toString(36).slice(2, 10); |
| 2993 | let dataUrl = null; |
| 2994 | if (embed) { |
| 2995 | // Best effort: reuse existing URL as dataUrl only if already a data: URL (otherwise keep null). |
| 2996 | dataUrl = String(el.iconSrc || "").startsWith("data:") ? el.iconSrc : null; |
| 2997 | } |
| 2998 | assets.push({ |
| 2999 | id: assetId, |
| 3000 | name: safeSymbolFromPath(icon.file), |
| 3001 | kind: "icon", |
| 3002 | dataUrl, |
| 3003 | sourceName: icon.file, |
| 3004 | width: iw, |
| 3005 | height: ih, |
| 3006 | rgb565: rgb565 || undefined, |
| 3007 | monoBitmap: monoBitmap || undefined, |
no test coverage detected