Suporte a OpenType Variable Fonts no Inkscape

Sobre o meu trabalho com tipografia e software livre

Eu tenho a alegria de trabalhar profissionalmente com desenvolvimento de software livre em tempo integral. E uma das vantagens disso (além de ser uma grande realização pessoal para um ativista como eu) é que eu posso falar abertamente sobre absolutamente todos os detalhes do trabalho que eu desenvolvo. Não há necessidade de sigilo dado que todo o meu código é disponibilizado publicamente na Internet. E é por isso que resolvi abrir essa thread aqui no Fiozeira. A idéia é mostrar um pouquinho do dia-a-dia de um desses meus projetos profissionais e, quem sabe, inspirar mais pessoas a buscarem também a formação de uma carreira em software livre.

Mas e a tipografia ?

Em linhas gerais eu tenho trabalhado no desenvolvimento de um projeto chamado FontBakery, que é uma ferramenta para controle de qualidade de fontes tipográficas. Esse programa é genérico e pode ser utilizado por qualquer pessoa interessada em verificar se uma família tipográfica possui algum problema (que já tenhamos descrito na suite de testes). Mas, em particular, ele é usado pelo time do Google Fonts para avaliar o nível de qualidade das famílias, como parte do processo de publicação de novas fontes em seu acervo público.

Recentemente, entretanto, tive a oportunidade de dedicar parte do meu tempo à implementação de suporte a fontes variáveis no Inkscape. E é com muita alegria que estou trabalhando nessa nova feature, dado que o Inkscape, software livre de desenho vetorial, foi minha porta de entrada ao mundo do desenvolvimento de software livre cerca de 10 anos atrás.

O que são Fontes Variáveis ?

Nesse texto, fontes variáveis refere-se a uma adição recente ao padrão OpenType, em sua versão 1.8 lançada recentemente, que permite aos designers especificarem regras paramétricas definindo as caracteristicas das fontes. Com essa tecnologia, os usuários de fontes tipográficas podem interpolar os estilos das fontes ao longo de múltiplos eixos de configuração. O exemplo clássico disso seria a interpolação do peso de uma face, gradativamente desde seu peso regular, até seu peso Bold (ou Negrito). Ou, no sentido oposto, até o extremo da fonte mais fina/leve possível de uma determinada família.

O mesmo tipo de ajuste pode ser feito ao longo de outros eixos “canônicos” que definem atributos como o espaçamento dos glifos, ou a intensidade da inclinação (itálico), etc. E, por fim, é possível também especificar eixos de interpolação arbitrários que podem alterar qualquer outro aspecto da fonte, ao gosto e livre à criatividade dos desiners de fontes.

Para saber mais detalhes sobre essa tecnologia e suas origens, recomendo a leitura deste artigo (em inglês) sobre o tema:

Próximos posts: o que esperar…

Dada essa introdução geral à tecnologia de fontes variáveis e ao objetivo da tarefa - que é possibilitar que usuários do Inkscape possam selecionar fontes variáveis e ajustar seus parâmetros durante a criação de suas artes vetoriais - gostaria de dar uma pequena pausa pois, em seguida, partirei para uma análise mais detalhada sobre as bibliotecas de software que já temos disponíveis para a implementação desta feature, e muitos outros detalhes técnicos sobre a minha estratégia de implementação.

Vale mencionar também que estou escrevendo essa postagem antes de ter de fato implementado o código. Então é possível, e provável, que os posts dessa thread sejam um pouco tortuosos e construidos gradativamente, conforme eu mesmo for aprendendo mais sobre essa parte do código-fonte do Inkscape e conforme eu for decidindo quais os melhores caminhos a seguir. E, se tudo der certo, teremos em breve uma nova super-feature no Inkscape para os amantes da tipografia :smiley:

Happy Hacking,
Felipe “Juca” Sanches

2 curtidas

Bibliotecas Pango e Harfbuzz

Duas das principais bibliotecas envolvidas nessa tarefa são Hafbuzz e Pango. O que segue abaixo é um relato da minha compreensão atual da relação entre essas duas bibliotecas. E, mais uma vez, é preciso alertar que eu posso estar enganado em alguns dos pontos apresentados abaixo! Mas vamos lá.

Uma parte da funcionalidade da biblioteca Pango está gradualmente sendo oferecida com maior qualidade pela biblioteca Harfbuzz, portanto é de se esperar que os projetos de software livre passem a usar Harfbuzz para tal, mas ainda há casos como o do Inkscape onde a bibliteca harfbuzz ainda não é utilizada.

A funcionalidade em questão se chama text-shaping e consiste em computar o posicionamento correto dos glifos em um trecho de texto. Existem scripts complexos como a escrita árabe que utilizam uma grande quantidade de ligaduras e regras de substituição contextual de glifos, por exemplo. Determinar quando e como são aplicadas essas
substituições é função dos algorítmos de shaping que são implementados pela biblioteca Harfbuzz.

Segue abaixo uma ilustração de glifos árabes exibidos separadamente e como eles mudam de forma quando são dispostos juntos em uma palavra:

Outros aspectos do árabe (e notem que eu não sei ler árabe, apenas conheço de forma bem superficial algumas das suas características tipográficas) são o fato de ser escrito da direita para a esquerda (chamamos de script RTL - “Right To Left”) e também a mudança de forma dos glifos para um mesmo caractere dependendo da posição em que se encontra numa palavra. Há diversas formas como a isolada ou as formas assumidas quando o caractere é empregado no início, no meio e no final de palavras, como ilustrado abaixo:

A biblioteca Pango também possui rotinas de shaping (invocadas pelo método pango_shape(…)), mas não são tão avançadas como as oferecidas pela biblioteca Harfbuzz (por meio do método hb_shape(…)).

Primeira estratégia: Migrar de Pango para Harfbuzz

Quando comecei a investigar o tema das fontes variáveis, tomei conhecimento dessas diferenças entre as bibliotecas (que são em grande parte desenvolvidas pelo mesmo programador, Behdad Esfahbod) e concluí que, independentemente da questão das fontes variáveis, havia já razões suficientes para modernizar o código de processamento de texto no Inkscape para usar a engine de shaping avançada da biblioteca Harfbuzz. Some-se a isso o fato da biblioteca Pango ainda não ter (até onde entendi por enquanto) conhecimento sobre as features de fontes variáveis da nova especificação OpenType 1.8.

Então resolvi investigar no código fonte do Inkscape onde exatamente o método pango_shape é invocado e como eu poderia alterá-lo para usar hb_shape em seu lugar. A resposta é que o método pango_shape é invocado em um único ponto, dentro da classe Layout::Calculator em http://bazaar.launchpad.net/~inkscape.dev/inkscape/trunk/view/15739/src/libnrtype/Layout-TNG-Compute.cpp#L1316

O que acontece aqui é relativamente complicado. Conforme explicado pelo próprio Behdad em um artigo de novembro de 2009, o motor de shaping tem como pré-requisito que o texto de entrada seja quebrado em trechos que façam uso de um único estilo de uma determinada fonte tipográfica. Sendo assim, a biblioteca Pango oferece um método chamado pango_itemize(…) que faz esse fatiamento do buffer de texto de entrada para que a aplicação posteriormente invoque o método de shaping para cada um dos trechos (chamados, em inglês, de items).

E a minha primeira surpresa foi descobrir que a biblioteca Harfbuzz não oferece um método “hb_itemize”. Harfbuzz se foca exclusivamente na etapa de shaping do texto e espera que outras bibliotecas ou códigos de aplicação se encarreguem da itemização. Com isso, conclui-se que a meta inicial de substituir por completo o uso da biblioteca Pango pela biblioteca Harfbuzz não é possível. Teremos que manter a Pango para executar a itemização (e provavelmente também algumas outras tarefas de layout de blocos de texto), e delegar apenas a etapa de shaping à Harfbuzz.

A outra descoberta que tive ao mesmo tempo foi ver que o código de renderização de texto do Inkscape é bastante extenso. Ele se concentra no subdiretório src/libnrtype/ e não sofreu grandes alterações ao longo da ultima década. Me lembro de ter lidado de leve com esse código por volta de 2008, quando fiz uma bolsa do programa Google Summer of Code em que minha meta era adicionar suporte a SVG Fonts no Inkscape. Meu mentor naquela época, Howard Hughes, também conhecido pelo nome de usuário cyreve, é autor de grande parte desse código. Talvez ele não tenha sido muito alterado na última década justamente pela sua complexidade, e também pelo receio de quebrar a compatibilidade com o padrão SVG. Eu acredito que o código como está hoje é muito sucetível a efeitos colaterais desastrosos se for alterado, pois é muito extenso e um pouco confuso de se ler. Julgo que um refactoring geral dessa base de código focada em legibilidade e corretude em relação ao padrão SVG seria extremamente benéfica.

Apenas o código do arquivo src/libnrtype/Layout-TNG-Compute.cpp sozinho tem um total de cerca de 2 mil linhas. Como eu me senti um pouco perdido (e exausto) lendo esse código todo na tela do computador, eu tomei a iniciativa de imprimí-lo em papel. Ter as 25 páginas de código fonte em mãos foi um pouco inibidor inicialmente, mas depois me deu muito mais coragem para ler e interpretar tudo e absorver o significado e o propósito de cada classe em uso.

Uma elemento central nessa discussão é a classe font_instance declarada em src/libnrtype/font-instance.h

Usando o comando git grep -l podemos ver em quais arquivos instancias dessa classe são usadas:

Bem… Essa postagem aqui esta bem desatualizada. :stuck_out_tongue: Nos últimos 2 meses eu participei de dois encontros de desenvolvedores do Inkscape.

Inkscape Boston Hackfest 2018

Em março o encontro aconteceu durante 5 dias no escritório da Red Hat em Boston.

No penúltimo dia do encontro em Boston eu consegui fazer funcionar um protótipo de interface gráfica para ajuste dos eixos de variação de uma fonte variavel no Inkscape. Para isso funcionar, foi muito importante a participação do Tavmjong Bah, que foi quem fez as adaptações no código para aplicar os ajustes na renderização das fontes no canvas do Inkscape.

Uma pequena demo dessa feature pode ser vista no finalzinho de um vídeo que foi feito lá no quarto dia do evento:

LibrePlanet 2018

Foi muito legal or organizadores do Inkscape Boston Hackfest 2018 terei escolhido a data desse encontro para ser logo depois do final de semana em que aconteceu a LibrePlanet, conferência anual organizada, em um dos prédios do MIT, pela Free Software Foundation.

Lá encontrei também alguns amigos brasileiros :slight_smile:

Libre Graphics Meeting 2018

E agora no mês de abril, voltei a me encontrar com Tav e outros desenvolvedores do Inkscape em Sevilha, na Espanha, durante a converência Libre Grahics Meeting, que reune anualmente (cada no em um país diferente, em 2017 foi no Rio de Janeiro) os times de desenvolvimento dos principais softwares livres gráficos, como Inkscape, GIMP, Blender, Krita, Scribus, etc.

Impulsionado por este novo encontro, o Tav voltou a implementar melhorias no suporte a fontes variáveis e chegamos, inclusive, a fazer uma breve demonstração durante a palestra de Dave Crossland.

Ainda há diversos pequenos detalhes a serem acertados, mas está claro que estamos próximos do amadurecimento dessa nova feature no Inkscape.

Abaixo uma foto com todos os participantes da LGM2018: