/** * AutoCAD Color Index (ACI) → hex RGB integer. * Returns null for BYBLOCK (0) and BYLAYER (256) — caller uses layer/default color. */ function hsl2hex(h, s, l) { const c = (1 - Math.abs(2 * l - 1)) * s; const x = c * (1 - Math.abs(((h / 60) % 2) - 1)); const m = l - c / 2; let r, g, b; if (h < 60) { r = c; g = x; b = 0; } else if (h < 120) { r = x; g = c; b = 0; } else if (h < 180) { r = 0; g = c; b = x; } else if (h < 240) { r = 0; g = x; b = c; } else if (h < 300) { r = x; g = 0; b = c; } else { r = c; g = 0; b = x; } return Math.round((r + m) * 255) * 65536 + Math.round((g + m) * 255) * 256 + Math.round((b + m) * 255); } // ACI 0-9: exact fixed colors const FIXED = [ null, // 0: BYBLOCK 0xFF0000, // 1: red 0xFFFF00, // 2: yellow 0x00FF00, // 3: green 0x00FFFF, // 4: cyan 0x0000FF, // 5: blue 0xFF00FF, // 6: magenta 0xFFFFFF, // 7: white 0x414141, // 8: dark gray 0x808080, // 9: gray ]; // ACI 10-249: 24 hue groups × 10 saturation/lightness variants const VARIANTS_SL = [ [1.00, 0.50], // 0: full [1.00, 0.28], // 1: dark [0.65, 0.65], // 2: light pastel [0.65, 0.38], // 3: pastel dark [0.35, 0.80], // 4: pale [0.35, 0.48], // 5: pale mid [0.18, 0.68], // 6: faint light [0.18, 0.38], // 7: faint dark [0.00, 0.55], // 8: light gray [0.00, 0.30], // 9: dark gray ]; export function aciToHex(aci, isDark = true) { if (aci == null || aci === 0 || aci === 256) return null; if (aci === 7) return isDark ? 0xFFFFFF : 0x000000; if (aci <= 9) return FIXED[aci] ?? null; if (aci >= 250 && aci <= 255) { const v = Math.round(40 + (aci - 250) * 43); return v * 65536 + v * 256 + v; } if (aci >= 10 && aci <= 249) { const idx = aci - 10; const [s, l] = VARIANTS_SL[idx % 10]; return hsl2hex(Math.floor(idx / 10) * 15, s, l); } return 0xC9D1D9; }