Introdução à antialias

Introdução

O anti-aliasing é algo muito importante nos gráficos da Web. É por isso que temos texto nítido e formas vetoriais suaves nas nossas telas. Na verdade, existem algumas abordagens para antialiasing usadas em navegadores atuais que são mais óbvias quando se trata de renderização de texto. Quando o algoritmo usado para antialização de interruptores pode levar a resultados visuais inesperados. Neste artigo, vamos conhecer as abordagens de anti-aliasing e ver como os pixels são desenhados.

Todas as nossas telas são compostas, como todos sabemos, de pixels. É uma grade gigante de blocos, e cada um contém componentes vermelhos, verdes e azuis (RGB). À distância, vemos imagens, textos e ícones, mas de perto podemos ver a grade dos componentes RGB e como tudo é feito.

Pixels de uma tela de perto. Cada pixel tem componentes vermelhos, verdes e azuis
Figura 1: pixels de uma tela de perto. Cada pixel tem componentes vermelhos, verdes e azuis.

Suavização

O que acontece quando estamos desenhando uma forma vetorial e ela passa por "parte" de um pixel? Vamos supor que a forma que estamos desenhando seja preta e o fundo seja branco. Devemos colorir esse pixel? Se for colorido, qual deve ser a cor? Preto, cinza ou outra coisa?

O processo de suavização determina qual cor devemos usar ao preencher pixels. A versão mais simples é chamada de anti-aliasing em escala de cinza, que trata os três componentes dos pixels da mesma forma. Se o pixel estivesse metade coberto, e vamos supor que o texto em preto sobre branco por um segundo para simplificar, você pensaria que cada componente seria definido como metade do brilho (eu sei que certamente sim), mas na verdade é mais complexo do que isso: você precisa considerar a gama, o que significa que você provavelmente nunca o definirá para esse valor exato. Isso deixa as coisas um pouco mais complicadas, mas como esta é uma introdução ao tópico, não vou mergulhar nela aqui. O importante é saber que o antialiasing em escala de cinza é tratado no nível do pixel e podemos, de fato, fazer muito melhor.

Figura 2 - Antialias em comparação a bordas rígidas
Figura 2: cantos com antialias x cantos rígidos

Na Figura 2, você pode ver o mesmo triângulo sendo desenhado, mas, à esquerda, o anti-aliasing está ativado e, à direita, está desativado. Quando o anti-aliasing está ativado, os pixels ficam em tons de cinza quando o triângulo passa apenas por uma parte do pixel. Quando desativada, no entanto, o pixel é preenchido como preto sólido ou branco sólido e a forma parece irregular.

Renderização de texto

Sempre que um navegador estiver renderizando texto, que é essencialmente uma forma vetorial, encontraremos o mesmo problema: os caracteres do texto só preencherão parcialmente alguns pixels. Queremos ter uma estratégia de como preencher esses pixels. O ideal é que o texto seja suavizado, porque isso tornará a leitura mais fácil e agradável.

No entanto, acontece que a abordagem em escala de cinza para o antialias é apenas uma maneira de lidar com isso. Uma abordagem frequentemente adotada é ser um pouco mais seletiva com a forma como ativamos os componentes RGB dos pixels. O processo é chamado de antialiasing de subpixels e, ao longo dos anos, a equipe da ClearType da Microsoft investiu muito tempo e esforço para progredir nesse processo. Hoje ele é muito mais amplamente utilizado e todos os principais navegadores o utilizam, em maior ou menor grau.

Em primeiro lugar, como sabemos que cada pixel é, na verdade, composto por componentes vermelhos, verdes e azuis, detectamos quanto de cada um desses componentes deve ser "ativado" para o pixel em questão. Portanto, se um pixel estiver “meio coberto” do lado esquerdo, poderemos alternar o componente vermelho totalmente, o componente verde para a metade e manter o azul desligado. Esse processo é geralmente descrito como “triplicar a resolução horizontal da tela” e depende do fato de que cada pixel é, na verdade, os três componentes separados lado a lado, em vez de uma única unidade.

Figura 3 - Antialiasing usando escala de cinza x subpixel
Figura 3: antialiasing usando escala de cinza x subpixel

Na figura 3 acima, podemos ver que, à esquerda, tratamos cada componente igualmente e cada um é ligado ou desligado da mesma forma (escala de cinza). No entanto, no lado direito, usamos a abordagem de subpixel, permitindo que cada componente (vermelho, verde e azul) seja diferente, dependendo do quanto ele se sobrepõe à forma desenhada.

Com tudo isso dito, no entanto, a visão humana não pesa igualmente luz vermelha, verde e azul. Somos muito mais sensíveis ao verde do que o vermelho ou o azul, e isso significa que, embora haja um benefício definido em relação ao antialiasing em escala de cinza, como observa Darel Rex Finley, ativar cada componente separadamente não vai produzir uma melhoria de 3 vezes na clareza. No entanto, o antialiasing de subpixel é definitivamente útil e significa que vemos o texto com mais clareza do que se o antialiasing em escala de cinza for usado.

Figura 4 - Texto com suavização de subpixel. Componentes individuais dos pixels são ativados para criar o efeito geral
Figura 4: texto com suavização de subpixel. Componentes individuais dos pixels são ativados para criar o efeito geral.

Direto ao ponto

O que tudo isso significa para nós, desenvolvedores? Bem, do ponto de vista do Chrome, pelo menos há uma mistura de antialiasing em escala de cinza e subpixel usada para renderizar texto, e qual você obterá depende de alguns critérios. Para começar, no entanto, precisamos entender um pouco sobre camadas, pois esse é o principal critério em questão. Se você ainda não conhece as camadas e como elas são usadas internamente pelo Chrome, Tom Wiltzius escreveu uma introdução fantástica sobre o tópico, que você deve ler primeiro.

Supondo que você esteja familiarizado com camadas ou que tenha acabado de ler sobre elas, vamos continuar. Se a composição de hardware estiver ativada para a página e você tiver conteúdo de texto em uma camada que não seja a camada raiz, ela será renderizada com um anti-aliasing em escala de cinza, por padrão. Os desenvolvedores geralmente percebem que, se eles hackearem elementos para colocá-los em camadas próprias (não raiz), como usar TranslateZ, notem que o texto é renderizado de maneira diferente. Muitas vezes, os desenvolvedores aplicam acionadores de "nova camada" rapidamente através de JavaScript ou CSS, fazendo com que a renderização de texto mude de subpixel para escala de cinza. Isso pode ser confuso se você não souber o que acionou a alteração na renderização. No entanto, se o texto estiver na camada raiz, ele será renderizado com anti-aliasing de subpixels e, consequentemente, a leitura será muito mais clara.

Mas, assim como tudo na Web, ela está mudando. O anti-aliasing de subpixels está sendo ativado no Google Chrome para texto em camadas não raiz, desde que a camada satisfaça três critérios. Esses critérios são válidos hoje, mas é provável que eles mudem. Com o tempo, mais casos serão abordados. Atualmente, esses critérios são:

  1. A camada tem uma cor de plano de fundo totalmente opaca. O uso de border-radius ou um valor background-clip não padrão faz com que a camada seja tratada como não opaca e a renderização de texto seja revertida para anti-aliasing em escala de cinza.
  2. A camada só pode ter uma transformação de identidade ou uma tradução integral aplicada a ela. Por integral, queremos dizer valores arredondados. Por exemplo, translate(20.2px, 30px) resultaria em antialiasing em escala de cinza, já que o componente x, 20.2px, não é integral. A transformação de identidade significa simplesmente que não há rotação, translação ou dimensionamento adicionais aplicados além do padrão.
  3. A camada tem uma opacidade de 1,0. Qualquer alteração na opacidade mudará o anti-aliasing de subpixel para escala de cinza.
Figura 5. Antes e depois: escala de cinza x subpixel. Observe as bordas de cores no texto à direita.
Figura 5. Antes e depois: escala de cinza x subpixel. Observe a borda de cor à direita no texto

Outra observação é que a aplicação de uma animação CSS pode fazer com que uma nova camada seja criada, diferentemente do uso de requestAnimationFrame. Para alguns desenvolvedores, as diferenças de renderização de texto que implicam impediram o uso de animações em CSS. Portanto, se você estiver usando JavaScript para animar elementos por causa de diferenças de renderização de texto, verifique se essa atualização corrige o problema para você.

Isso é o Chrome. Com relação aos outros navegadores, o Opera, que é transferido para o Chromium, deve se assemelhar ao comportamento do Chrome. O Internet Explorer parece usar a suavização de subpixels para praticamente todo o texto (se você tiver ativado o ClearType, é claro!), embora aparentemente não esteja no modo Metro do Windows 8. O Safari, dada a proximidade do WebKit com o Blink, comporta-se de maneira muito semelhante ao Chrome, embora sem essas melhorias mais recentes que permitem mais anti-aliasing de subpixels. Em grande parte, o Firefox se comporta da mesma maneira que o Internet Explorer, na medida em que usa anti-aliasing de subpixels para praticamente todo o texto. Claro que esta não é uma lista completa. É provável que haja casos em todos os navegadores em que o antialiasing em escala de cinza é usado em vez de subpixel, mas é bom saber que o antialiasing de subpixel é amplamente usado no conjunto principal de navegadores.

Conclusão

Agora você sabe um pouco sobre como o anti-aliasing funciona e por que pode haver diferenças na renderização de texto nos seus sites e aplicativos atualmente, especialmente em dispositivos com DPI mais baixo. Se você estiver interessado em acompanhar a implementação do Chrome com relação à renderização de texto, marque os seguintes bugs com uma estrela:

Recursos e referências