Renderização de objetos de texto

Use o recurso de armazenamento de bitmap no cache e a propriedade opaqueBackground para aprimorar o desempenho da renderização de texto.

O Flash Text Engine oferece algumas excelentes otimizações. No entanto, várias classes são necessárias para mostrar uma única linha de texto. Por isso, criar um campo de texto editável com a classe TextLine requer uma grande quantidade de memória e muitas linhas de código ActionScript. A classe TextLine é melhor aproveitada para texto estático não editável, que ela renderiza mais rapidamente, com menor exigência de memória.

O recurso de armazenamento de bitmap no cache permite armazenar conteúdo de vetor em cache como bitmaps para aumentar o desempenho da renderização. Esse recurso é útil para conteúdo de vetor complexo e, também, quando usado com conteúdo de texto que requer processamento para ser renderizado.

O exemplo a seguir mostra como o recurso de armazenamento de bitmap em cache e a propriedade opaqueBackground podem ser usados para aumentar o desempenho da renderização. A figura a seguir ilustra uma tela típica de boas-vindas que pode ser exibida enquanto um usuário aguarda o carregamento de alguma coisa:

A figura a seguir ilustra o easing aplicado programaticamente ao objeto TextField. O texto se aproxima/afasta lentamente desde a parte superior da cena até seu centro:

O código a seguir cria o easing. A variável preloader armazena o objeto alvo atual para minimizar consultas de propriedade, o que pode afetar o desempenho:

wait_mc.addEventListener( Event.ENTER_FRAME, movePosition ); 
  
var destX:Number=stage.stageWidth/2; 
var destY:Number=stage.stageHeight/2; 
var preloader:DisplayObject; 
  
function movePosition( e:Event ):void 
{ 
    preloader = e.currentTarget as DisplayObject; 
     
    preloader.x -= ( preloader.x - destX ) * .1; 
    preloader.y -= ( preloader.y - destY ) * .1; 
     
    if (Math.abs(preloader.y-destY)<1) 
        preloader.removeEventListener( Event.ENTER_FRAME, movePosition ); 
}

A função Math.abs() pode ser movida em linha aqui para reduzir o número de chamados de função e conseguir mais aumento de desempenho. Uma melhor prática é usar o tipo int para as propriedades destX e destY para obter valores de ponto fixo. O uso do tipo int permite obter o encaixe perfeito dos pixels sem a necessidade de arredondar os valores manualmente por meio de métodos lentos como Math.ceil() ou Math.round() . Este código não arredonda as coordenadas para int, porque ao arredondar os valores constantemente, o objeto não se move de forma suave. O objeto pode ter movimentos instáveis, porque as coordenadas são encaixadas para o inteiro arredondado mais próximo em cada quadro. No entanto, esta técnica pode ser útil quando for definir uma posição final para um objeto de exibição. Não utilize o seguinte código:

// Do not use this code 
var destX:Number = Math.round ( stage.stageWidth / 2 );  
var destY:Number = Math.round ( stage.stageHeight / 2); 

O seguinte código é muito mais rápido:

var destX:int = stage.stageWidth / 2;  
var destY:int = stage.stageHeight / 2; 

O código anterior pode ser otimizado ainda mais por meio do uso de operadores de deslocamento bit a bit para dividir os valores:

var destX:int = stage.stageWidth >> 1;  
var destY:int = stage.stageHeight >> 1;

O recurso de armazenamento de bitmap em cache torna mais fácil para o tempo de execução renderizar objetos usando bitmaps dinâmicos. No exemplo atual, o clipe de filme que contém o objeto TextField é armazenado em cache:

wait_mc.cacheAsBitmap = true;

Outra maneira de aumentar o desempenho é remover a transparência alfa. A transparência alfa sobrecarrega o tempo de execução por desenhar imagens de bitmap transparentes, como no código anterior. Você pode usar a propriedade opaqueBackground para se desviar disso, especificando uma cor como fundo.

Quando a propriedade opaqueBackground é usada, a superfície do bitmap criado na memória ainda usa 32 bits. No entanto, o deslocamento alfa é definido como 255 e não é utilizada nenhuma transparência. Como resultado, a propriedade opaqueBackground não reduz o uso da memória, mas aumenta o desempenho da renderização quando o recurso de armazenamento de bitmap em cache é usado. O código a seguir contém todas as otimizações:

wait_mc.addEventListener( Event.ENTER_FRAME, movePosition ); 
wait_mc.cacheAsBitmap = true; 
  
// Set the background to the color of the scene background 
wait_mc.opaqueBackground = 0x8AD6FD; 
var destX:int = stage.stageWidth >> 1; 
var destY:int = stage.stageHeight >> 1; 
var preloader:DisplayObject; 
  
function movePosition ( e:Event ):void 
{ 
    preloader = e.currentTarget as DisplayObject; 
     
    preloader.x -= ( preloader.x - destX ) * .1; 
    preloader.y -= ( preloader.y - destY ) * .1; 
     
    if ( Math.abs ( preloader.y - destY ) < 1 ) 
        e.currentTarget.removeEventListener ( Event.ENTER_FRAME, movePosition ); 
}

Agora a animação está otimizada e o armazenamento do bitmap em cache foi otimizado por meio da remoção da transparência. Em dispositivos móveis, considere mudar a qualidade do Palco para LOW e HIGH durante os diferente estados da animação enquanto usa o recurso de armazenamento de bitmap em cache:

wait_mc.addEventListener( Event.ENTER_FRAME, movePosition ); 
wait_mc.cacheAsBitmap = true; 
wait_mc.opaqueBackground = 0x8AD6FD; 
  
// Switch to low quality 
stage.quality = StageQuality.LOW; 
var destX:int = stage.stageWidth>>1; 
var destY:int = stage.stageHeight>>1; 
var preloader:DisplayObject; 
  
function movePosition( e:Event ):void 
{ 
    preloader = e.currentTarget as DisplayObject; 
     
    preloader.x -= ( preloader.x - destX ) * .1; 
    preloader.y -= ( preloader.y - destY ) * .1; 
     
    if (Math.abs(e.currentTarget.y-destY)<1) 
    { 
        // Switch back to high quality 
        stage.quality = StageQuality.HIGH; 
        preloader.removeEventListener( Event.ENTER_FRAME, movePosition ); 
    } 
}

No entanto, neste caso, alterar a qualidade do Palco força o tempo de execução a gerar a superfície do objeto TextField novamente de modo a corresponder à qualidade atual do Palco. Por isso, é melhor não alterar a qualidade do Palco ao usar o recurso de armazenamento de bitmap em cache.

Uma abordagem de armazenamento manual de bitmap em cache poderia ter sido usada aqui. Para simular a propriedade opaqueBackground , o clipe de filme pode ser desenhado em um objeto BitmapData que não seja transparente, o que não força o tempo de execução a gerar novamente a superfície do bitmap.

Esta técnica funciona bem para conteúdo que não muda com o tempo. Entretanto, se o conteúdo do campo de texto puder ser alterado, considere usar uma estratégia diferente. Por exemplo, imagine um campo de texto que seja continuamente atualizado com uma porcentagem que representa quanto do aplicativo foi carregado. Se o campo de texto ou o objeto de exibição que o contém tiver sido armazenado em cache, sua superfície precisa ser gerada toda vez que o conteúdo for alterado. Não é possível usar o armazenamento manual de bitmap em cache aqui, porque o conteúdo do objeto de exibição é alterado constantemente. Esta alteração constante pode forçar você a chamar manualmente o método BitmapData.draw() para atualizar o bitmap armazenado.

Lembre-se de que, desde o Flash Player 8 (e o AIR 1.0), independentemente do valor da qualidade do Palco, um campo de texto com renderização definida como Suavização de borda para legibilidade permanece com a suavização perfeita da borda. Esta abordagem consome menos memória, mas requer mais processamento da CPU e sua renderização é um pouco mais lenta do que a do recurso de armazenamento de bitmap em cache.

O código a seguir usa essa abordagem:

wait_mc.addEventListener( Event.ENTER_FRAME, movePosition ); 
  
// Switch to low quality 
stage.quality = StageQuality.LOW; 
var destX:int = stage.stageWidth >> 1; 
var destY:int = stage.stageHeight >> 1; 
var preloader:DisplayObject; 
function movePosition ( e:Event ):void 
{ 
    preloader = e.currentTarget as DisplayObject; 
     
    preloader.x -= ( preloader.x - destX ) * .1; 
    preloader.y -= ( preloader.y - destY ) * .1; 
     
    if ( Math.abs ( preloader.y - destY ) < 1 ) 
    { 
        // Switch back to high quality 
        stage.quality = StageQuality.HIGH; 
        preloader.removeEventListener ( Event.ENTER_FRAME, movePosition ); 
    } 
}

Não recomendamos usar essa opção (Suavização de borda para legibilidade) para texto em movimento. Ao escalar o texto, esta opção faz com que o texto tente ficar alinhado, o que produz um efeito de deslocamento. Entretanto, se o conteúdo do objeto de exibição for alterado constantemente e você precisar de texto com escala, poderá aumentar o desempenho em aplicativos móveis definindo a qualidade como LOW . Quando o movimento for concluído, mude a qualidade de volta para HIGH .