Troika: Suporte de layout de texto da direita para a esquerda

Criado em 5 abr. 2021  ·  11Comentários  ·  Fonte: protectwise/troika

Em vez de uma solução de modelagem de texto completa e avançada (por exemplo, harfbuzz.wasm), gostaria de um suporte básico pronto para uso para layout RTL. Typr já inclui algum nível de suporte para substituições de glifos árabes, embora eu não saiba o quão completo isso é.

Eu já adicionei alguma lógica de layout/empacotamento RTL muito básica. Vamos usar esse problema para rastrear bugs com essa e outras lacunas no suporte.

Página de teste temporária: https://troika-examples.netlify.app/#text -rtl

Comentários muito úteis

Empurrei uma implementação mais completa da detecção do tipo de junção; a lógica que eu adaptei do Opentype.js provou estar incompleta. A nova implementação, na verdade, incorpora uma versão altamente compactada das definições de tipo de junção unicode , de modo que agora deve lidar com todos os caracteres juntáveis ​​em árabe e outros. Ele também dá uma lombada decente sobre o código Typr.

@MichaelHazani desde que você se ofereceu para testar hebraico, acho que isso está pronto para você agora. Você pode usar esta página de teste onde adicionei algumas fontes hebraicas ao menu suspenso "fonte" e você pode digitar seu próprio texto. Obrigado!

Todos 11 comentários

Em primeiro lugar, quero agradecer-lhe muito por trabalhar nisso. O suporte a layouts em árabe e RTL será útil para muitas pessoas.
Eu fiz alguns primeiros testes, o texto árabe padrão é principalmente bem suportado nas fontes cairo, Lemonada, Scheherazade (sem Tachkil).

Eu estava testando essas 2 regras para o árabe:

  1. Se as 3 formas de escrita de caracteres estão bem (uma no início, no meio, no final) e conexões (ligadura).
  2. Tachkil que é o conjunto de indicação para pronúncia ُ َ ً ٌ (não usado na maioria dos textos que você encontra na internet, exceto em casos raros)

Em mirza, algumas letras internas não estão conectadas (a forma final da letra é colocada em vez da interna ou de outra forma)
arabicTachkil

Com o tachkil, algumas fontes funcionaram bem, enquanto outras alteraram a forma do caractere ao lado. Alguns trabalharam com um texto que escrevi na caixa enquanto não com um texto copiado.

Se eu usar letras não árabes como parênteses "(", ")" elas são trocadas (precisa ser invertida.).

Este é um teste rápido que fiz, preciso verificar mais e dar mais detalhes onde as coisas ficam estranhas. (Também preciso verificar as fontes, algumas fontes não fornecem os caracteres necessários)

Ótimo, obrigado! Fico feliz em saber que teve um começo decente.

É interessante que o resultado para substituições de posições de palavras varia de acordo com a fonte. A lógica de detecção de posição de palavra em Typr é sempre a mesma, então deve haver algo diferente em como essas fontes codificam suas substituições que Typr não manipula. Vou olhar para Mirza especificamente para ver se consigo determinar uma diferença.

Como não conheço esses caracteres e, portanto, não posso determinar o correto versus o incorreto, seria imensamente útil se você pudesse me fornecer alguns casos de teste direcionados com resultados esperados, talvez apenas palavras simples, algo como:

Texto de entrada: xxx
Deve se parecer com: [imagem]
Parece correto na fonte A: [imagem]
Parece incorreto na fonte B: [imagem]

Quanto aos parênteses, acho que é a parte de parênteses emparelhados do algoritmo Bidi. Ainda não tenho certeza se isso é algo que vou resolver sozinho, mas definitivamente vou investigar.

Eu empurrei o código com algum suporte de layout bidirecional grosseiro. No momento, é puramente manual usando caracteres de controle LRO/RLO/PDF para definir faixas direcionais. O bidi automático completo é muito mais complicado e ainda estou pensando em seu escopo, mas ser capaz de definir os intervalos (com quebra de linha e seleção!) é um começo importante.

image

Sinto muito por não ter postado um feedback ontem. Pensei em fazer um teste completo no fim de semana, mas acho melhor fazer as coisas por etapas.
Vamos começar com fontes que funcionam muito bem (pode haver alguns problemas em algumas fontes) Eu usei a fonte Scheherazade, mas Cairo e Lemonada dão o mesmo resultado.
As fontes Mirza e Amiri sempre mostram letras desconectadas.
As fontes Noto Sans, Roboto não funcionam.

Na imagem abaixo, usei vermelho para significar a forma errada da letra e verde é a forma correta.
O problema aparece apenas quando temos Tachkil (notas vocais) ou um caractere latino ou numérico.

  1. Em vez da forma final, temos uma forma interna.
  2. Dentro da palavra, em vez da forma inicial, temos a forma interna. (dentro da palavra algumas letras não possuem ligadura)
  3. Quando temos um número logo após a palavra, (كم2) mantemos a forma final.
  4. os números estão invertidos.

arabThree

Texto que usei:
كم2.
2
بِسم اللَّه الرحمن الرحيم
بِسمِ اللَّهِ الرَّحمٰنِ الرَّحيمِ

Esta resposta contém uma imagem de como as letras são desenhadas
https://www.quora.com/How-can-anyone-read-Arabic-as-the-letters-are-all-connected-to-each-other/answer/Hashem-Mohamed-4

Muito obrigado por este testcase marcado, isso é imensamente útil !!! Isso realmente me ajuda a entender as coisas.

A lógica do Typr para detectar a posição da palavra é definitivamente falha; Eu o substituí com lógica adaptada de opentype.js e o resultado agora parece muito melhor:

image

Vou contribuir com a correção do Typr de volta ao upstream após mais testes.

O problema "os números estão invertidos" será tratado com o trabalho BiDi que comecei. Por enquanto, isso pode ser contornado com caracteres LRO/PDF explícitos.

Mantenha esses tipos de casos de teste chegando! 🤩

Isso foi rápido.
Bem, não encontrei algo que precise de mais correção, exceto o que pode ser feito usando o trabalho BiDi que você mencionou (número e parênteses podem ser amplamente usados ​​com texto em árabe).
Você pode mostrar um exemplo de como usar caracteres LRO/PDF? Eu mesmo não consegui reproduzir o exemplo de texto misto.

A última coisa que não está relacionada ao texto em árabe, mas talvez relacionada à renderização SDF, é que alguns caracteres têm preto dentro quando 2 caracteres estão conectados como aqui
image
image
e às vezes dentro do mesmo personagem
image
Isso só é visível com a fonte Lemonda. Scheherazade, Cairo funcionam bem (talvez porque os personagens se conectem no lugar certo).
(Parece uma operação booleana na ferramenta de renderização vetorial.)

E mais uma vez obrigado pelo seu trabalho.

Obrigado! Atualmente, estou trabalhando para adicionar uma implementação completa do algoritmo bidi, que acho que deve esclarecer todos os outros problemas que você descreveu até agora.

O texto "BiDi 1" na lista suspensa do exemplo tem um exemplo de LRO/PDF, mas não se preocupe com isso por enquanto, é apenas um paliativo e não está realmente correto de qualquer maneira. O verdadeiro bidi será melhor.

O problema de preenchimento booleano com essa fonte é o mesmo discutido em # 57, eu acho.

Agora temos suporte completo para bidi!

image

Existem alguns trechos bidi na página de exemplo, mas faça alguns testes com seu próprio texto rtl + ltr misto.

Isso se transformou em um exemplo clássico de mim descendo uma toca de coelho; Eu não encontrei uma implementação JS bidi adequada e não queria trazer fribidi.wasm, então decidi tentar uma nova implementação JS como um projeto de noites e fins de semana. Eis https://github.com/lojjic/bidi-js! Eu preciso adicionar alguns documentos lá, mas é totalmente compatível de acordo com os testes oficiais do bidi, bem pequeno (~ 10kb) e bastante rápido, embora provavelmente possa ser otimizado mais.

Estou me sentindo muito feliz com esta solução e quão pouco ela adiciona ao tamanho do pacote. Acho que estamos muito perto do suporte RTL completo agora. Eu preciso revisitar a lógica dos formulários de junção, porém, percebi que a lógica que adaptei do opentype.js lida apenas com scripts árabes, mas não outros que também fazem junção.

Empurrei uma implementação mais completa da detecção do tipo de junção; a lógica que eu adaptei do Opentype.js provou estar incompleta. A nova implementação, na verdade, incorpora uma versão altamente compactada das definições de tipo de junção unicode , de modo que agora deve lidar com todos os caracteres juntáveis ​​em árabe e outros. Ele também dá uma lombada decente sobre o código Typr.

@MichaelHazani desde que você se ofereceu para testar hebraico, acho que isso está pronto para você agora. Você pode usar esta página de teste onde adicionei algumas fontes hebraicas ao menu suspenso "fonte" e você pode digitar seu próprio texto. Obrigado!

Parece ótimo!
("bem, parece que o teste foi um sucesso. A pontuação está onde deveria estar; o alinhamento à direita parece bom. Ambas as fontes exibem o hebraico da maneira que deveria ser exibida. Mudar para o inglês, ou seja, esta palavra, não quebra o alinhamento. Bem feito!")
image

Eu lancei a v0.41.0 com o trabalho feito aqui até agora. Sem dúvida, existem outros scripts RTL que precisarão de tratamento especializado adicional, mas isso fornece uma base sólida o suficiente para que possamos lidar com eles caso a caso. E há sempre a possibilidade de permitir um plugin Harfbuzz opcional (#91) para alguns dos casos mais avançados/obscuros.

Obrigado novamente @boulabiar e @MichaelHazani por sua ajuda inestimável aqui !!! 🎉

Esta página foi útil?
0 / 5 - 0 avaliações