1 pontos por GN⁺ 2024-08-11 | 1 comentários | Compartilhar no WhatsApp
  • Lançado em dezembro de 2023, o 175 Pixel Font Megapack é um projeto de fontes pixeladas que usa uma toolchain própria em Rust para gerar fontes, testar a qualidade e fazer a distribuição
  • Os pacotes anteriores tinham 12 fontes em 2016 e 40 em 2018; o novo pacote começou com a meta de elevar de uma vez só qualidade, estilo, suporte a idiomas e automação de distribuição
  • As novas fontes superam a limitação de suportar apenas ASCII e passam a incluir 176 caracteres latinos estendidos para EFIGS, mas caracteres asiáticos e não latinos foram excluídos por questões de qualidade e tempo de produção
  • A ferramenta em Rust pifo gera contornos de glifos, kerning automático, TTF, tilesheets e atlas de textura empacotados a partir de tilesheets PNG e configuração TOML, processando até 175 fontes em poucos segundos
  • Imagens de amostra grandes, kerning automático e scripts de distribuição com butler para o itch.io reduziram o trabalho manual de revisão, correção e upload, permitindo melhorar rapidamente a qualidade de quase 200 fontes

Do pacote anterior de fontes pixeladas ao Megapack

  • O primeiro pacote de fontes, em 2016, era um conjunto de 12 fontes criado quando o trabalho em Ikenfell estava começando
    • As fontes feitas para o jogo foram refinadas e algumas extras foram adicionadas para venda no itch.io
    • Foram usadas em vários jogos indie e tiveram boa recepção
  • O segundo pacote, em 2018, cresceu para 40 fontes e também trouxe um grande salto de qualidade
    • Foram criadas tabelas de kerning para melhorar a renderização de frases
    • Também foram oferecidos formatos pré-compilados, fáceis de usar em vários motores de jogo
    • A divulgação foi feita mostrando suas fontes aplicadas em capturas de tela de jogos de desenvolvedores indie
  • Os pacotes anteriores foram usados em centenas de jogos indie e também em Cadence of Hyrule, da Nintendo
    • Várias fontes também foram usadas em Get in the Car, Loser, da Love Conquers All Games
  • Depois do lançamento de Ikenfell, mesmo durante um longo período de burnout, o autor continuou desenvolvendo suas habilidades com Rust e trabalhando com fontes, com a ideia de um dia criar um novo pacote de fontes pixeladas

Objetivos do Megapack

  • A meta inicial do novo pacote era 100 fontes, mas o resultado final foi de 175 fontes pixeladas
    • Os pacotes anteriores tinham 12 e 40 fontes, respectivamente
    • O novo pacote buscava fontes para vários gêneros, como sci-fi, fantasia, terror, fazenda e jogos aconchegantes
  • O maior pedido e também a maior reclamação sobre os pacotes anteriores era o fato de suportarem apenas caracteres ASCII
    • Para oferecer suporte a EFIGS, sigla para English, French, Italian, German e Spanish, o novo pacote adotou um conjunto de caracteres latinos estendidos
    • O conjunto final tem 176 caracteres
    • Idiomas asiáticos ou baseados em alfabetos não latinos foram excluídos porque seria difícil atingir a qualidade desejada com conjuntos de caracteres menos familiares, além de exigir muito mais tempo de produção
  • Como interfaces de jogos precisam de hierarquia visual, a ideia foi criar cada fonte não como um único estilo, mas como uma família tipográfica
    • Por exemplo, a família Virtue inclui 20 estilos
    • Assim, desenvolvedores podem variar tamanho e peso sem precisar misturar fontes com atmosferas diferentes
  • O kerning foi um dos grandes fatores de consumo de tempo na produção dos pacotes anteriores
    • Com 176 caracteres suportados, o número de pares possíveis de kerning pode chegar a 176²
    • Para evitar inserir manualmente todos os pares, a maior parte passou a ser calculada automaticamente, deixando para ajuste manual apenas o que o algoritmo não resolvesse bem
  • Controle de qualidade e distribuição também entraram na automação
    • Antes, era preciso corrigir erros de pixel ou bugs de kerning, exportar novamente, testar e fazer upload manual no itch.io
    • A nova toolchain foi pensada para gerar textos de amostra e visualizações de kerning, ajudando a encontrar problemas rapidamente e verificar imediatamente o resultado das correções

Preparação para elevar a qualidade do design das fontes

  • Apesar de já ter bastante experiência com pixel art e fontes pixeladas, o autor nunca havia estudado design tipográfico tradicional de forma aprofundada
  • Durante o trabalho, consultou Design School: Type, de Richard Poulin
    • O livro foi usado como introdução para aprender a terminologia e as convenções do design tipográfico
  • Também foram reunidas fotos de textos vistos no cotidiano como referência
    • Letreiros de pequenas lojas, museus, galerias, festivais, pôsteres de eventos locais e capas de livros serviram como material de apoio
    • O objetivo não era copiar tipografias, mas estudar formas de letras, descendentes e diferenças entre caracteres finos e largos
  • Ao observar fontes decorativas vistas na rua, o autor percebeu que muitas fontes “chamativas” concentram a ornamentação nas maiúsculas, enquanto deixam as minúsculas de forma mais sutil

O papel da ferramenta Rust pifo

  • Para atingir essas metas, foi escrito o programa próprio em Rust pifo
  • O design das fontes em si foi feito com ferramentas comuns de pixel art
    • A entrada consiste em um tilesheet PNG e um arquivo TOML de configuração
    • Um comando de exemplo é pifo --all --output "Faraway" --input "Faraway*"
  • O pifo corta a imagem de entrada em tiles de glifos individuais, gera os contornos dos glifos, calcula pares de kerning automaticamente e exporta arquivos TTF
    • Também gera outros formatos para uso imediato em vários engines
    • O processamento de glifos individuais é paralelizado, então uma única fonte é tratada quase instantaneamente
    • Mesmo processando as 175 fontes uma a uma, tudo leva apenas alguns segundos
  • Os principais crates de Rust usados foram:
    • clap: parsing de argumentos de linha de comando
    • image: decodificação e codificação de imagens
    • rayon: paralelização
    • serde: serialização de dados
    • glyph-names: mapeamento entre caracteres e nomes de glifos
    • ab-glyph: carregamento e rasterização de fontes
    • crunch: empacotamento de retângulos

Processo de geração dos contornos dos glifos

  • Cada folha de fonte é composta por um tilesheet e um arquivo TOML de configuração
    • A configuração inclui version, baseline, line_gap, spacing, metrics, auto_kerning, auto_kerning_min, manual_kerning, skip_kerning_left, skip_kerning_right e outros
    • O tamanho da grade pode variar, mas ela sempre precisa ser uniforme, e os caracteres devem estar em posições definidas
    • A ferramenta processa apenas pixels 100% brancos; o fundo quadriculado e a linha de base servem apenas como guia
  • Glifos TrueType são compostos por um ou mais contornos (contours)
    • Em fontes pixeladas, é preciso criar um contorno para cada grupo de pixels conectados, ou seja, para cada cluster
    • Por exemplo, se a letra minúscula t tiver dois blocos de pixels separados, serão necessários dois contornos
  • A geração dos contornos acontece em várias etapas
    • Os pixels brancos são extraídos de RgbaImage para um HashSet da struct Point
    • A partir de um pixel arbitrário, é feito um flood fill pelos pixels adjacentes, repetindo o processo até não restarem pixels não visitados, para encontrar os clusters
    • Em cada cluster, são coletadas como arestas expostas as faces sem pixel adjacente
    • As extremidades de cada aresta são ligadas para formar caminhos fechados, que são então convertidos em contornos
  • Clusters com buracos podem gerar vários contornos
    • O contorno externo percorre no sentido horário, e os buracos internos, no anti-horário
    • Essa diferença de direção corresponde à forma como o TTF representa buracos
  • Pontos intermediários em linhas retas contínuas são removidos
    • Isso é uma otimização para reduzir o tamanho do arquivo e acelerar a rasterização

Automação da tabela de kerning

  • Depois dos contornos, o próximo elemento necessário para gerar um TTF é a tabela de kerning
    • Ela aproxima pares específicos de caracteres para que as palavras pareçam mais naturais
    • Por exemplo, puxar os pares Va e lt 1 pixel para a esquerda melhora a aparência
  • O kerning manual é definido em manual_kerning no TOML
    • Em um formato como { left = "V", right = "a", kern = -1 }
    • Para evitar definir individualmente todos os caracteres acentuados, existe a opção alts = true
    • Ela mapeia caracteres alternativos como àáâãäå para a, aplicando o mesmo kerning
  • O kerning automático é calculado movendo o glifo da direita 1 pixel por vez para a esquerda
    • O objetivo é encontrar a posição mais próxima em que ele ainda não toque o glifo da esquerda
    • Contato por canto também conta como toque
    • No exemplo LV, é possível puxar o V em 1 pixel, mas em 2 pixels os pixels encostam, então o valor do kerning fica em -1
  • O cálculo automático respeita valores definidos manualmente e configurações de exclusão
    • skip_kerning_left e skip_kerning_right permitem excluir certos glifos em cada direção
    • Todos os pares de kerning são calculados em paralelo com rayon

Formatos de exportação

  • O PIFO gera não só TTF, mas também tilesheets e atlas de textura empacotados
  • Um arquivo TTF é um binário composto por várias tabelas
    • A ferramenta de exportação preenche as tabelas head, hhea, maxp, OS/2, hmtx, cmap, loca, glyf, kern, name e post
    • Cada tabela precisa registrar posição, comprimento e checksum, usando begin_table() e end_table()
  • O tamanho base das fontes pixeladas foi definido como 16
    • Ao renderizar no tamanho 16, cada pixel corresponde exatamente a 1 px
    • Para ampliar sem tremulação, basta desenhar em múltiplos de 16, como 32, 48 e 64
  • A exportação de tilesheets, diferentemente da folha de entrada, é ordenada por codepoints Unicode
    • O arquivo de dados gerado junto inclui linhas e colunas, tamanho dos tiles, linha de base, espaçamento entre linhas, largura do espaço em branco, métricas dos glifos e tabela de kerning
    • A serialização é feita com serde em formatos como JSON, XML e TOML
  • Também são gerados atlas empacotados
    • Para isso é usado o crate próprio de empacotamento de retângulos crunch
    • Como o empacotamento denso faz perder a informação de posicionamento, dados extras como x, y, w, h, off_x, off_y e adv são incluídos para a renderização

Testes de qualidade e imagens de amostra

  • Para alcançar a qualidade desejada, o PIFO ganhou um recurso de geração de imagens de amostra gigantes
  • As imagens de amostra são compostas por vários blocos de teste
  • Como as imagens de amostra podiam ser geradas imediatamente durante o trabalho, foi possível encontrar e corrigir problemas rapidamente
    • Esse processo elevou a qualidade geral e o acabamento de quase 200 fontes

Automação da distribuição no itch.io

  • O resultado final foi de 175 fontes pixeladas, e a loja online escolhida para download foi o já conhecido itch.io
  • A tarefa mais trabalhosa foi criar um projeto separado no itch para cada fonte
    • Isso só precisou ser feito uma vez por fonte
    • Depois disso, upload e manutenção puderam ser tratados por scripts de linha de comando
  • O script de distribuição é composto por três etapas
    • Compilar o PIFO em modo release
    • Construir os assets das fontes desejadas
    • Atualizar o projeto itch de cada fonte com os novos assets
  • Um padrão de entrada como --input "Faraway*" encontra estilos com o mesmo prefixo, como Faraway - Regular e Faraway - Bold, agrupando-os em um único pacote de família tipográfica
  • No upload final foi usada a ferramenta de distribuição por linha de comando butler, fornecida pelo itch
    • A distribuição é feita em um formato como butler push ../distro/faraway chevyray/pixel-font-faraway:assets
    • Como o Butler rastreia os arquivos alterados e atualiza apenas o necessário, não foi preciso criar hashing de arquivos nem um controle de versão especial

1 comentários

 
GN⁺ 2024-08-11
Comentários do Hacker News
  • As fontes são ótimas e o texto também é interessante
    Fiquei pensando que seria legal se o jogo falso no canto superior direito https://chevyray.dev/blog/creating-175-fonts/old_previews.pn... fosse um jogo de verdade
    Tem uma vibe de “Wonder Boy in Monster World para GBA” que me agrada bastante
    Só que, olhando a licença, parece que usar o TTF em projetos de software open source não é permitido, então vale prestar atenção
    Não sou advogado, mas a última cláusula me parece proibir isso claramente: https://github.com/ChevyRay/pixel_font_megapack_license/blob...

    • Se você gosta de jogos de plataforma, vale jogar Celeste
      A cena desse mockup foi inspirada na cena de abertura de Celeste
    • Distribuir a própria fonte em formato open source ou CC claramente não pode, mas é discutível interpretar que isso também proíba distribuí-la junto com um software cujas outras partes sejam open source
      A intenção parece ser claramente mais usá-la em jogos no estágio de produto final, onde open source é relativamente raro, do que em engines de jogo ou templates
      Lendo isso, também me lembrei de outro caso de borda em direitos autorais: nos EUA, typefaces não são protegidos por copyright
      Fontes são protegidas como programas de computador, mas typefaces e fontes bitmap simples não são
      Então esse fluxo de trabalho acaba criando um TTF com copyright a partir de um tileset original sem copyright, e depois voltando de novo para um tileset/atlas de saída sem copyright
    • O texto deveria dizer “em projetos de software open source”, não “em software open source”
  • Realmente impressionante
    Fazer um conjunto completo de fontes pode facilmente levar um ano
    É preciso criar todos os glifos, de 'A' a 'Z', maiúsculas e minúsculas, parênteses, e comercial, ponto de exclamação e assim por diante, e se possível também variantes como negrito e itálico
    Sem essas variantes, a utilidade da fonte fica limitada
    Em especial, o que realmente diferencia o nível de habilidade é o kerning, ou seja, o espaçamento entre letras, e dá para ficar obcecado com isso sem fim
    Como o próprio texto diz, com suporte a 176 caracteres é preciso inserir até 176² = 37.976 pares de kerning, então ele decidiu criar ferramentas próprias para semi-automatizar a maior parte e inserir manualmente só o que o algoritmo não resolvesse

    • Isso vale quando você limita a fonte a uso puramente em inglês
      Para dar suporte a outros idiomas, mesmo línguas que usam alfabeto latino como francês, espanhol, italiano e português exigem caracteres adicionais
      Depois disso, você pode querer suportar alfabeto grego, cirílico, japonês e chinês
      Por exemplo, segundo a Wikipedia, “as fontes Noto dão suporte a mais de 77 mil caracteres, cerca de metade dos 149.186 caracteres definidos no Unicode 15.0”
    • Um conjunto completo de fontes pode facilmente levar um ano, mas criar uma família tipográfica pode virar um projeto para a vida toda
    • Sinceramente, não consigo concordar com essa ideia de que “um conjunto completo de fontes facilmente leva um ano”
      Dá para ficar obcecado com qualquer coisa sem fim
      Também parece que áreas como idiomas, escrita, música e caligrafia atraem fortemente pessoas com essa tendência à obsessão
      O ponto é que esse tipo de fala soa como criação de barreira de entrada
      Comentários que desencorajam quem está tentando entrar em uma área nova sempre soam um pouco delicados para mim
  • Muito bom
    Uma coisa que me deixou curioso foi por que escolheram esse subconjunto de caracteres especiais escandinavos
    Em sueco há äöå, e em norueguês/dinamarquês há æøå, mas nessa fonte existe æ e não existe ø
    Nesse caso, mesmo removendo æ o suporte ao sueco continuaria, e adicionando ø já seria possível dar suporte a norueguês e dinamarquês também
    Fico na dúvida se foi só uma omissão ou se existe alguma localidade que usa æ, mas não usa ø
    Só para constar, não confundi æ com a ligatura œ, que é um glifo separado usado em francês

    • O islandês usa ö em vez de ø, mas ao mesmo tempo também precisa de ð e ý, que não estão nesta fonte
      Ainda assim, Æ também aparece em textos antigos em inglês como “encyclopædia” ou em plurais de palavras vindas do latim: https://en.wiktionary.org/wiki/Category:English_plurals_in_-...
    • Foi só uma omissão mesmo
      Na verdade, só bem depois que o projeto já estava bastante avançado eu percebi que ø estava faltando no meu conjunto de caracteres
      Com certeza seria possível adicionar e corrigir isso em todas as fontes, mas eu estava esperando para ver se havia demanda suficiente para justificar esse trabalho
      Ainda assim, poder dar suporte a mais dois idiomas seria bem legal
  • Também gostei de algumas das fontes usadas no site e do styling simples
    Felizmente isso foi publicado em um post separado: https://chevyray.dev/blog/how-this-site-is-made/#catppuccin-...

  • Interessante
    Eu não sabia antes que, ao codificar fontes pixeladas como TTF, elas são convertidas em vetores
    Isso provavelmente permite algum nível de zoom suave para quem as carrega em um renderizador de texto decente
    Claro, o caso de engines de jogo que usam fontes pixeladas quase sempre em proporção 1:1 pode ser uma exceção

    • Fazendo assim, elas também podem ser usadas em editores gráficos tradicionais como Photoshop, InDesign, Affinity e Aseprite
      Essas ferramentas não têm o conceito de fonte pixelada, então usar um TTF com hinting e antialiasing desativados permite aproveitá-las nesses aplicativos
  • Muito legal
    Também é bom saber que esse trabalho ajudou financeiramente quem o fez
    Reconheço o nome Chevy Ray da cena de jogos indie, mas não lembro exatamente o que ele fez
    Algo ali por volta de 2010–2012, acho que era alguma coisa na linha de VVVVVV, Nidhogg ou Canabalt

    • Era Flashpunk
      Beacon também era excelente — deu nostalgia, sinto falta dos jogos indie daquela época
    • Acho que o jogo de que você está falando é Beacon
    • Ikenfell
    • Também me diverti muito com Ikenfell
    • Flashpunk?
  • Excelente
    Ver uma figura tipo Leonardo da Vinci como o autor deste texto faz lembrar uma época em que artista e engenheiro não eram claramente separados, mas uma coisa só

    • Nesse caso, eu recomendaria ler sobre Da Vinci de verdade
      Não textos do tipo “as 10 maiores invenções de Da Vinci”
      Na prática, havia uma distinção bem grande entre as duas coisas
      Eu também consigo modelar no Maya uma nave espacial para ir até Alpha Centauri com uma dinâmica suspeita e não comprovada
      Mas isso está bem longe de realmente construí-la e enviá-la ao espaço interestelar
      As imagens são bonitas e cheias de imaginação
  • Em Rust, é curiosamente fácil fazer esse tipo de trabalho rodar em vários núcleos
    Pode bastar encaixar uma chamada na cadeia de funções

    • Rust foi projetada para ter segurança de memória e segurança entre threads por padrão
      Desde que você siga as regras da linguagem, multithreading fica quase “de graça”
      A lei de Amdahl ainda se aplica, mas pelo menos o app não explode na sua frente
    • Não é uma característica exclusiva de Rust
      Scala e Java também oferecem esse tipo de recurso por padrão
  • Trabalho realmente excelente, e o texto também é muito bom
    Parece que daria para acelerar bastante muitos algoritmos com alguns truques
    Pelo que li, uma pista pode ser trocar hash maps por bitmaps e arrays de índices de bytes no desenho dos caracteres e no mapeamento de variações ASCII
    Claro que, como já está rápido o suficiente, isso não importa tanto neste código

    • Que bom que você mencionou isso, está certíssimo
      O site não mostra o código completo, mas na prática ele faz bastante alocação e cópia de strings e estruturas de dados
      Usei código otimizado onde isso era óbvio, e partes como cópia de bitmap ou tarefas fáceis de paralelizar já terminavam rápido o bastante para eu nem tentar otimizar o resto
      Ainda assim, daria para fazer
      É fácil esquecer o quão rápidas podem ser linguagens mais próximas de baixo nível como Rust, C++ e Go, ainda mais usando as ferramentas básicas de multithreading e filas de tarefas
  • Quem se interessa por fontes talvez também queira conferir https://tomorrow.type.today/
    É um estúdio tipográfico que cria fontes originais e experimentais excelentes
    Uma pessoa da nossa equipe é profundamente apaixonada por tipografia e está montando uma coleção do trabalho deles em https://play.soot.com/tomorrowtypetoday

    • Só para constar, a empresa está registrada na Rússia