Exibindo texto com Uniscribe
Seus aplicativos podem usar as funções da API Uniscribe para suportar tipografia e a exibição e edição de texto internacional. Uniscribe usa o parágrafo como a unidade para exibição de texto, e a funcionalidade Uniscribe deve ser usada para o parágrafo inteiro.
Ao usar Uniscribe para exibição de texto, um aplicativo deve passar por um processo de formatação ("layout"), normalmente usando Uniscribe. A aplicação divide um parágrafo de texto em cadeias de caracteres com o mesmo estilo, chamadas "segmentos". O estilo é determinado pela implementação específica, mas normalmente inclui atributos como fonte, tamanho e cor. Ao definir execuções, o aplicativo também pode aplicar outras informações, como dados de idioma e localidade mantidos para uso com ferramentas lexicais. Por exemplo, um aplicativo pode tratar como uma execução separada uma passagem em um texto principalmente em inglês que é processado em francês.
Depois de determinar as execuções para todos os parágrafos, o aplicativo divide cada parágrafo em cadeias de caracteres que têm o mesmo script e direção ("itens"). O aplicativo aplica as informações do item para produzir execuções que são exclusivas em script e direção e se enquadram inteiramente dentro de um único item ("intervalos").
A divisão de um item em intervalos é um pouco arbitrária, embora um intervalo deva consistir em um ou mais agrupamentos de caracteres indivisíveis definidos por script consecutivos, chamados "clusters". Para idiomas europeus, um cluster normalmente corresponde a um único caractere de página de código ou ponto de código Unicode e consiste em um único glifo . No entanto, em idiomas como o tailandês, um cluster é um agrupamento de glifos e corresponde a vários caracteres consecutivos ou pontos de código. Por exemplo, um agrupamento tailandês pode conter uma consoante, uma vogal e uma marca de tom. Para que não quebre clusters, a aplicação geralmente deve usar os intervalos mais longos possíveis ou recorrer às suas próprias informações lexicais para fazer a quebra entre intervalos em locais que não estejam no meio de um cluster.
Quando tiver identificado os clusters em cada intervalo, o aplicativo deve determinar o tamanho de cada cluster. Ele usa Uniscribe para somar os clusters para determinar o tamanho de cada intervalo. Em seguida, o aplicativo soma os tamanhos dos intervalos até que eles transbordem uma linha, ou seja, atinjam a margem. O intervalo que transborda a linha é dividido entre a linha atual e a linha seguinte. Para cada linha, o aplicativo constrói um mapa da posição visual para a posição lógica para cada intervalo. Em seguida, o aplicativo molda os pontos de código para cada intervalo em glifos, que podem posteriormente posicionar e renderizar.
Um aplicativo faz layout de texto apenas uma vez. Depois, ele salva os glifos e posições para fins de exibição ou os gera cada vez que exibe o texto, com a compensação sendo velocidade versus memória. Um aplicativo típico implementa o processo de layout uma vez e, em seguida, gera os glifos e posições cada vez que exibe o texto.
Uma aplicação que usa scripts complexos tem os seguintes problemas com uma abordagem simples de layout e apresentação.
- A largura de um caractere de script complexo depende de seu contexto. Não é possível salvar as larguras em tabelas simples.
- A quebra entre palavras em escritas como a tailandesa requer suporte baseado em dicionários. Por exemplo, nenhum caractere separador é usado entre palavras tailandesas.
- Árabe, hebraico, persa, urdu e outras linguagens de texto bidirecional exigem reordenação antes da exibição.
- Alguma forma de associação de fontes é frequentemente necessária para usar facilmente scripts complexos.
O fato de Uniscribe usar o parágrafo como unidade de exibição ajuda o aplicativo a lidar adequadamente com esses problemas de script complexos.
Observação
Uniscribe deve ser usado para um parágrafo inteiro, mesmo que as seções do parágrafo não sejam scripts complexos.
Como mostrado na tabela a seguir, o Uniscribe versão 1.6 ou superior suporta várias funções que aproveitam as tags OpenType. Eles podem ser substituídos pelas funções regulares correspondentes do Uniscribe. Geralmente, seus aplicativos devem trabalhar inteiramente com funções de um conjunto ou outro e não devem tentar "misturar e combinar" funções.
Função Uniscribe regular | Função OpenType equivalente |
---|---|
ScriptItemize | ScriptItemizeOpenType |
ScriptShape | ScriptShapeOpenType |
ScriptPlace | ScriptPlaceOpenType |
Dispor texto usando Uniscribe
Seu aplicativo pode usar as etapas a seguir para estabelecer um parágrafo de texto com Uniscribe. Este procedimento pressupõe que a aplicação já tenha dividido o parágrafo em troços de texto.
Chame ScriptRecordDigitSubstitution somente ao iniciar ou ao receber uma mensagem WM_SETTINGCHANGE.
(Opcional) Chame ScriptIsComplex para determinar se o parágrafo requer processamento complexo.
(Opcional) Se estiver usando Uniscribe para manipular texto bidirecional e/ou substituição de dígitos, chame ScriptApplyDigitSubstitution para preparar as estruturas SCRIPT_CONTROL e SCRIPT_STATE como entradas para ScriptItemize. Se ignorar esta etapa, mas ainda exigir a substituição de dígitos, substitua os dígitos nacionais por Unicode U+0030 a U+0039 (dígitos europeus). Para obter informações sobre substituição de dígitos, consulte Formas de dígitos.
Chame ScriptItemize para dividir o parágrafo em itens. Se não estiver usando Uniscribe para substituição de dígitos e a ordem bidirecional for conhecida, por exemplo, devido ao layout do teclado usado para inserir o caractere, chame ScriptItemize. Na chamada, forneça ponteiros nulos para as estruturas SCRIPT_CONTROL e SCRIPT_STATE. Esta técnica gera itens usando apenas o mecanismo de modelagem, e os itens podem ser reordenados usando as informações do mecanismo.
Observação
Normalmente, os aplicativos que trabalham apenas com scripts da esquerda para a direita e sem qualquer substituição de dígitos devem passar ponteiros nulos para as estruturas SCRIPT_CONTROL e SCRIPT_STATE.
Mescle as informações do item com as informações de execução para produzir intervalos.
Chame ScriptShape para identificar clusters e gerar glifos.
Se ScriptShape retornar o código USP_E_SCRIPT_NOT_IN_FONT ou S_OK com a saída contendo glifos ausentes, selecione caracteres de uma fonte diferente. Substitua outra fonte ou desative a modelagem definindo o eScript membro da estrutura SCRIPT_ANALYSIS passada para ScriptShape como SCRIPT_UNDEFINED. Para obter mais informações, consulte Usando o fallback de fonte.
Chame ScriptPlace para gerar larguras de avanço do e posições x e y para os glifos em cada faixa sucessiva. Este é o primeiro passo para o qual o tamanho do texto se torna uma consideração.
Somar os tamanhos do intervalo até que a linha transborde.
Parta o intervalo num limite de palavra, usando os membros fSoftBreak e fWhiteSpace dos atributos lógicos. Para interromper a execução de um único cluster de caracteres, use as informações retornadas chamando ScriptBreak.
Observação
Determine se o primeiro ponto de código de um intervalo deve ser um ponto de quebra de palavra devido à necessidade imposta pelo último caractere do intervalo anterior. Por exemplo, se um intervalo terminar em uma vírgula, considere o primeiro caractere do próximo intervalo como um ponto de interrupção de palavra.
Repita as etapas 6 a 10 para cada linha do parágrafo. No entanto, se quebrar a última execução na linha, chame ScriptShape para remodelar a parte restante da execução como a primeira execução na próxima linha.
Exibir texto usando Uniscribe
Seu aplicativo pode usar as etapas a seguir para exibir um parágrafo de texto. Este procedimento pressupõe que o aplicativo já tenha estabelecido o texto e não tenha salvo os glifos e posições do processo de layout. Se a velocidade for uma preocupação, o aplicativo pode salvar os glifos e posições do procedimento de layout e iniciar na etapa 2 no procedimento de exibição.
Observação
O aplicativo pode omitir a etapa 2 se o texto não contiver caracteres de scripts da direita para a esquerda, não contiver caracteres de controle bidirecionais e usar um nível de incorporação de base da esquerda para a direita.
Para cada corrida, faça o seguinte:
- Se o estilo tiver sido alterado desde a última execução, atualize o identificador para o contexto do dispositivo liberando-o e obtendo-o novamente.
- Chame ScriptShape para gerar glifos para a execução.
- Chame ScriptPlace para gerar uma largura avançada e um deslocamento x,y para cada glifo.
Faça o seguinte para estabelecer a ordem visual correta para as execuções na linha:
- Extraia uma matriz de níveis de embebimento , bidirecional,, um por intervalo. O nível de incorporação é dado por (SCRIPT_ITEM) si. (SCRIPT_ANALYSIS) a. (SCRIPT_STATE) s.uBidiLevel.
- Passe essa matriz para ScriptLayout para gerar um mapa de posições visuais para posições lógicas.
(Opcional) Para justificar o texto, chame ScriptJustify ou use conhecimento especializado do texto.
Use o mapa visual-para-lógico para exibir as sequências por ordem visual. Começando na extremidade esquerda da linha, chame ScriptTextOut para exibir a execução dada pela primeira entrada no mapa. Para cada entrada subsequente no mapa, chame ScriptTextOut para exibir a execução indicada à direita da execução exibida anteriormente.
Se omitir a etapa 2, comece na extremidade esquerda da linha e chame ScriptTextOut para exibir a primeira execução lógica e, em seguida, para exibir cada execução lógica à direita da execução anterior.
Repita as etapas acima para todas as linhas do parágrafo.
Tópicos relacionados