<!doctype html>
<html>
    <head>
        <title>8seg dimension planning</title>
<style>
canvas {
}

body {
    margin-left: auto;
    margin-right: auto;
    width: min-content;
}

#form {
    max-width: 1000px;
    margin-left: auto;
    margin-right: auto;
    display: grid;
    grid-template-columns: max-content auto;
}

#form > label {
    text-align: right;
    padding-right: 0.5em;
}

#form > input[type="number"] {
    max-width: 5em;
}

</style>
    </head>
    <body>
        <canvas id="viz" width="1800px" height="500px">
        </canvas>
        <div id="form">
            <label for="text">Text</label><input type="text" id="text" value="Sphinx of black quartz/judge my vow"/>
            <label for="digit_width">Digit width</label><input type="number" id="digit_width" step="0.01" value="1.0">
            <label for="digit_height">Digit height</label><input type="number" id="digit_height" step="0.01" value="1.6">
            <label for="digit_space">Digit spacing</label><input type="number" id="digit_space" step="0.01" value="0.4">
            <label for="digit_num">Number of digits</label><input type="number" id="digit_num" value="36">
            <label for="line_width">Visualization line width</label><input type="number" id="line_width", value=0.05>
        </div>
<script>

    const seg_map = {
        " ": 0x00,
        "a": 0x2e,
        "b": 0xd6,
        "c": 0xd0,
        "d": 0xc5,
        "e": 0x59,
        "f": 0x98,
        "g": 0xd4,
        "h": 0x8c,
        "i": 0x5c,
        "j": 0x78,
        "k": 0x8e,
        "l": 0xc0,
        "m": 0xa3,
        "n": 0xa5,
        "o": 0xf0,
        "p": 0x93,
        "q": 0xf4,
        "r": 0x9e,
        "s": 0x55,
        "t": 0xc8,
        "u": 0xe0,
        "v": 0x8a,
        "w": 0xac,
        "x": 0x0f,
        "y": 0x0b,
        "z": 0x5a,
        "0": 0x13,
        "1": 0x20,
        "2": 0x16,
        "3": 0x56,
        "4": 0x23,
        "5": 0x1c,
        "6": 0x4e,
        "7": 0x1a,
        "8": 0x5f,
        "9": 0x33,
        "/": 0x0a,
        "\\": 0x05,
    };

    function map_digit(codepoint) {
        if (!seg_map.hasOwnProperty(codepoint)) {
            return seg_map[" "];
        }

        return seg_map[codepoint];
    }

    function draw_digit(ctx, x, y, w, h, seg) {
        for (var i=0; i<2; i++) {
            if (i == 0) {
                ctx.strokeStyle = '#e00000';
            } else {
                ctx.strokeStyle = '#404040';
                seg = ~seg;
            }
            ctx.beginPath();
            if (seg & 0x80) {
                ctx.moveTo(x, y);
                ctx.lineTo(x, y+h);
            }
            if (seg & 0x40) {
                ctx.moveTo(x, y+h);
                ctx.lineTo(x+w, y+h);
            }
            if (seg & 0x20) {
                ctx.moveTo(x+w, y+h);
                ctx.lineTo(x+w, y);
            }
            if (seg & 0x10) {
                ctx.moveTo(x+w, y);
                ctx.lineTo(x, y);
            }
            if (seg & 0x01) {
                ctx.moveTo(x+w/2, y+h/2);
                ctx.lineTo(x, y);
            }
            if (seg & 0x02) {
                ctx.moveTo(x+w/2, y+h/2);
                ctx.lineTo(x+w, y);
            }
            if (seg & 0x08) {
                ctx.moveTo(x+w/2, y+h/2);
                ctx.lineTo(x, y+h);
            }
            if (seg & 0x04) {
                ctx.moveTo(x+w/2, y+h/2);
                ctx.lineTo(x+w, y+h);
            }
            ctx.stroke();
        }
    }

    function update() {
        const canvas = document.querySelector("#viz");
        const ctx = canvas.getContext("2d");
        ctx.fillStyle = '#202020';
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        const digit_num = parseFloat(document.querySelector("#digit_num").value);
        const digit_width = parseFloat(document.querySelector("#digit_width").value);
        const digit_height = parseFloat(document.querySelector("#digit_height").value);
        const digit_space = parseFloat(document.querySelector("#digit_space").value);
        const line_width = parseFloat(document.querySelector("#line_width").value);
        const text = document.querySelector("#text").value.toLowerCase();

        const segs = [];
        for (var codepoint of text) {
            segs.push(map_digit(codepoint));
        }

        for (var i=0; i<digit_num; i++) {
            segs.push(map_digit(" "));
        }

        const total_w = digit_num * digit_width + (digit_num - 1) * digit_space;
        const total_h = digit_height;

        const fill_factor = 0.8;
        const scale = canvas.width * fill_factor / total_w;

        var x = (canvas.width - total_w*scale) / 2;
        var y = (canvas.height - total_h*scale) / 2;

        ctx.lineWidth = scale*line_width*digit_width;

        for (var i=0; i<digit_num; i++) {
            draw_digit(ctx, x, y, digit_width*scale, digit_height*scale, segs[i]);
            x += digit_width*scale + digit_space*scale;
        }
    }

    function handle_change(evt) {
        update();
    }

    document.querySelector("#digit_width").addEventListener('change', handle_change);
    document.querySelector("#digit_height").addEventListener('change', handle_change);
    document.querySelector("#digit_space").addEventListener('change', handle_change);
    document.querySelector("#digit_num").addEventListener('change', handle_change);
    document.querySelector("#line_width").addEventListener('change', handle_change);
    document.querySelector("#text").addEventListener('input', handle_change);

    update();
</script>
    </body>
</html>