#!/usr/bin/env python3
"""Largura de cada letra das fontes do modelo, medida no próprio arquivo da fonte e no peso que vai para a tela.

O build.py usa esta tabela (assets/fontes/larguras.json) para encaixar o lettering antes de montar a página: quebra
por sentido, dois momentos e, só por último, letra menor. A Montserrat do modelo é variável e, sem escolher o peso,
é medida no 100 (bem mais fina que a 900 da tela); aqui cada peso é medido de verdade.

Rode com o Python da skill (tem o Pillow) quando trocar ou acrescentar uma fonte em assets/fontes:
  uv run --directory '<SKILL>' python '<PROJETO>/ferramentas/medir_fontes.py'

Saída: {"fontes": {"Montserrat": {"arquivo": "...", "pesos": {"900": {"A": 780, ...}}}}, "em": 1000}: a largura de
cada caractere com a letra de 1000 px (sem kerning; a página com kerning fica igual ou um pouco mais estreita).
"""
import json
import os
import sys

AQUI = os.path.dirname(os.path.abspath(__file__))
FONTES = os.path.join(os.path.dirname(AQUI), 'assets', 'fontes')
EM = 1000
# arquivo, pesos medidos (o que o modelo usa na tela)
MEDIR = {'Montserrat': ('Montserrat.ttf', (700, 800, 900)), 'Caveat': ('Caveat.ttf', (700,)), 'Inter': ('Inter.ttf', (800,))}
EXTRAS = '–—‘’“”…•€✓→×'


def caracteres():
    cs = [chr(c) for c in range(32, 127)] + [chr(c) for c in range(160, 256)]
    return cs + list(EXTRAS)


def main():
    if any(a in ('-h', '--help') for a in sys.argv[1:]):
        print(__doc__)
        return 0
    try:
        from PIL import ImageFont
    except ImportError:
        print('erro: falta o Pillow. Rode com o Python da skill: uv run --directory <SKILL> python ...', file=sys.stderr)
        return 2
    saida = {'em': EM, 'fontes': {}}
    for nome, (arq, pesos) in MEDIR.items():
        caminho = os.path.join(FONTES, arq)
        if not os.path.exists(caminho):
            print(f'aviso: não achei {caminho}', file=sys.stderr)
            continue
        por_peso = {}
        for peso in pesos:
            f = ImageFont.truetype(caminho, EM)
            try:
                eixos = f.get_variation_axes()
            except OSError:
                eixos = []
            if eixos:
                f.set_variation_by_axes([max(eixos[0]['minimum'], min(eixos[0]['maximum'], peso))])
            por_peso[str(peso)] = {c: round(f.getlength(c)) for c in caracteres()}
        saida['fontes'][nome] = {'arquivo': f'assets/fontes/{arq}', 'pesos': por_peso}
    destino = os.path.join(FONTES, 'larguras.json')
    with open(destino, 'w', encoding='utf-8') as fh:
        json.dump(saida, fh, ensure_ascii=False, separators=(',', ':'))
    print(f'ok: {destino}')
    return 0


if __name__ == '__main__':
    sys.exit(main())
