<html> <body> <textarea id="result" cols="200" rows="32"></textarea> <canvas id="canvas" width="320" height="200"></canvas> <script> var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var r = "static readonly double[] CharacterProportions = {\n "; var head = ""; let size = 24; ctx.font = "bold " + size + "px \"Helvetica Neue\""; var mmm = ctx.measureText("MM"); let sp = 0; let np = 0; let mw = 0; let tx = 0; let ty = size; let widths = {}; for (let i = 0; i < 128; i++) { if (i > 0 && i % 8 == 0) { head = ",\n "; } else if (i > 0) { head = ", "; } let c = String.fromCharCode(i); let s = "M" + c + "M"; let m = ctx.measureText(s); let w = m.width - mmm.width; if (tx + w > 320) { tx = 0; ty += size; } ctx.fillText(c, tx, ty); ctx.strokeRect(tx, ty - size, w, size); tx += w; let p = w / size; if (p > 1e-4) { sp += p; np++; } if (c == "M") { mw = w; } r += head + p; widths[c] = w; console.log (c + " = " + w); } let test = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; let testLen = 0; for (const i in test) { const w = widths[test[i]]; testLen += w; } console.log("TEST COMP LEN = " + testLen); console.log("TEST REAL LEN = " + ctx.measureText(test).width); let ap = sp / np; let padding = (mmm.width - mw*2)/size; r += "\n};\nconst double AverageCharProportion = " + ap + ";"; r += "\nconst double StringWidthPaddingProportion = " + padding + ";"; console.log(r); document.getElementById("result").innerText = r; </script> </body> </html>