Rendering di oggetti di testo

Utilizzate la funzione di caching bitmap e la proprietà opaqueBackground per migliorare le prestazioni di rendering del testo.

Flash Text Engine offre alcune interessanti ottimizzazioni. Tuttavia, per visualizzare una singola riga di testo sono necessarie diverse classi. Per questo motivo, la creazione di un campo di testo modificabile con la classe TextLine richiede una notevole quantità di memoria e molte righe di codice ActionScript. La classe TextLine è indicata soprattutto per il testo statico e non modificabile, poiché per tale tipo di testo garantisce un rendering veloce e consuma meno memoria.

La funzione di caching bitmap consente di memorizzare nella cache il contenuto vettoriale sotto forma di bitmap per migliorare le prestazioni di rendering. Questa funzione risulta utile per il contenuto vettoriale complesso così come per il contenuto testuale il cui rendering richiede una certa quantità di elaborazione.

L'esempio seguente illustra come utilizzare la funzione di caching bitmap e la proprietà opaqueBackground per migliorare le prestazioni di rendering. La figura seguente mostra una tipica schermata di attesa che può essere visualizzata quando un utente sta aspettando che qualcosa venga caricato:

La figura seguente illustra l'andamento che viene applicato programmaticamente all'oggetto TextField. L'andamento del testo procede lentamente dall'alto della scena fino al centro:

Il codice seguente crea l'andamento. La variabile preloader memorizza l'oggetto target corrente per ridurre al minimo le verifiche delle proprietà, che possono pregiudicare le prestazioni:

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 ); 
}

La funzione Math.abs() in questo caso potrebbe essere spostata inline per ridurre il numero di chiamate di funzione e ottenere un miglioramento delle proprietà. È buona norma utilizzare il tipo int per le proprietà destX e destY , in modo da ottenere valori a virgola fissa. Utilizzando il tipo int si ottiene un aggancio ai pixel perfetto e non occorre arrotondare manualmente i valori mediante metodi lenti come Math.ceil() o Math.round() . Questo codice non arrotonda le coordinate a un numero intero, poiché un arrotondamento costante dei valori non permetterebbe all'oggetto di muoversi in maniera fluida. L'oggetto potrebbe muoversi in modo irregolare perché le coordinate verrebbero adattate ai numeri interi più vicini per ciascun fotogramma. Tuttavia, questa tecnica può essere utile quando si imposta una posizione finale per un oggetto di visualizzazione. Non utilizzate il codice seguente:

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

Il codice seguente è molto più veloce:

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

Il codice precedente può essere ottimizzato ulteriormente utilizzando operatori di spostamento bit a bit per dividere i valori:

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

La funzione di caching bitmap facilita il rendering degli oggetti tramite il runtime utilizzando le bitmap dinamiche. Nell'esempio corrente, il clip filmato che contiene l'oggetto TextField viene memorizzato nella cache:

wait_mc.cacheAsBitmap = true;

Un ulteriore modo per migliorare le prestazioni è quello di rimuovere la trasparenza alfa. La trasparenza alfa comporta un carico di lavoro aggiuntivo per il runtime quando devono essere disegnate immagini bitmap trasparenti, come nel codice precedente. Potete utilizzare la proprietà opaqueBackground per aggirare il problema, specificando un colore per lo sfondo.

Quando si usa la proprietà opaqueBackground , la superficie bitmap creata in memoria utilizza comunque 32 bit, ma l'offset alfa è impostato su 255 e la trasparenza non viene utilizzata. Di conseguenza, la proprietà opaqueBackground non riduce l'utilizzo della memoria ma migliora le prestazioni di rendering quando si usa la funzione di caching bitmap. Il codice seguente contiene tutte le ottimizzazioni:

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 ); 
}

L'animazione è ora ottimizzata e il caching bitmap è stato ottimizzato rimuovendo la trasparenza. Sui dispositivi mobili, valutate anche la possibilità di commutare la qualità dello stage tra LOW e HIGH durante i diversi stati dell'animazione utilizzando la funzione di caching bitmap:

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 ); 
    } 
}

Tuttavia, in questo caso, la modifica della qualità dello stage obbliga il runtime a rigenerare la superficie bitmap dell'oggetto TextField per farla corrispondere alla qualità corrente dello stage. Per questo motivo, è meglio non cambiare la qualità dello stage quando si usa la funzione di caching bitmap.

In questo caso si potrebbe adottare una soluzione di caching bitmap manuale. Per simulare la proprietà opaqueBackground , il clip filmato può essere disegnato su un oggetto BitmapData non trasparente, così da non obbligare il runtime a rigenerare la superficie bitmap.

Questa tecnica funziona bene per i contenuti non soggetti a variazioni nel corso del tempo. Se invece è possibile che il contenuto del campo di testo subisca dei cambiamenti, valutate una strategia differente. Ad esempio, considerate un campo di testo che viene continuamente aggiornato con una percentuale che indica il grado di caricamento dell'applicazione. Se il campo di testo, o l'oggetto di visualizzazione che lo contiene, è stato memorizzato nella cache come bitmap, la sua superficie deve essere generata dopo ogni cambiamento del contenuto. Non potete usare il caching bitmap manuale in questo caso, perché l'oggetto di visualizzazione utilizzato come contenitore è soggetto a continui cambiamenti. Questo cambiamento costante vi obbligherebbe a chiamare manualmente il metodo BitmapData.draw() per aggiornare la bitmap memorizzata nella cache.

Tenete presente che a partire da Flash Player 8 (e AIR 1.0), indipendentemente dal valore di qualità dello stage, un campo di testo con il rendering impostato su Antialiasing per leggibilità mantiene un perfetto antialiasing. Questa soluzione consuma meno memoria, ma richiede più risorse della CPU e determina un rendering più lento rispetto alla funzione di caching bitmap.

Il codice seguente usa questo tipo di soluzione:

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 ); 
    } 
}

L'uso di questa opzione (Antialiasing per leggibilità) non è consigliato per il testo in movimento. Quando si ridimensiona il testo, l'opzione tenta di mantenere allineato il testo, causando un effetto di spostamento. Se tuttavia il contenuto dell'oggetto di visualizzazione cambia in continuazione ed è necessario ridimensionare il testo, potete migliorare le prestazioni nelle applicazioni mobili impostando la qualità su LOW . Quando il movimento finisce, riportate la qualità a HIGH .