| 931 | // Nearest-color lookup with cache |
| 932 | const codeCache = new Map(); |
| 933 | function findCode(r, g, b) { |
| 934 | const key = `${r},${g},${b}`; |
| 935 | if (codeCache.has(key)) return codeCache.get(key); |
| 936 | |
| 937 | let minDist = Infinity; |
| 938 | let bestCode = null; |
| 939 | for (const entry of colorEntries) { |
| 940 | const dr = r - entry.r; |
| 941 | const dg = g - entry.g; |
| 942 | const db = b - entry.b; |
| 943 | const dist = dr * dr + dg * dg + db * db; |
| 944 | if (dist < minDist) { |
| 945 | minDist = dist; |
| 946 | bestCode = entry.fullCode; |
| 947 | } |
| 948 | } |
| 949 | codeCache.set(key, bestCode); |
| 950 | return bestCode; |
| 951 | } |
| 952 | |
| 953 | // Compute optimal font size: each single digit width must not exceed 12px |
| 954 | const MAX_DIGIT_WIDTH = 12; |