Uso del Text Layout Framework

Flash Player 10 e versioni successive, Adobe AIR 1.5 e versioni successive

Panoramica del Text Layout Framework

Il Text Layout Framework (TLF) è una libreria ActionScript estensibile creata sul motore del testo in Adobe® Flash® Player 10 e Adobe® AIR® 1.5 e che fornisce funzioni di composizione tipografica e layout del testo avanzate per la composizione tipografica innovativa sul Web. Il framework può essere utilizzato con Adobe® Flex® o Adobe® Flash® Professional. Gli sviluppatori possono utilizzare o estendere componenti esistenti, oppure possono utilizzare il framework per creare i propri componenti di testo.

Il TLF include le funzionalità seguenti:
  • Testo bidirezionale, testo verticale e più di 30 script di scrittura incluso Arabo, Ebraico, Cinese, Giapponese, Coreano, Tailandese, Lao, Vietnamita e altri

  • Selezione, modifica e distribuzione del testo tra più colonne e contenitori collegati

  • Testo verticale, Tate-Chu-Yoko (orizzontale all'interno di testo verticale) e funzione di giustificazione per composizione tipografica dell'est asiatico

  • Controlli tipografici avanzati, inclusi crenatura, legature, maiuscole/minuscole, cifre ascendenti/discendenti, larghezza delle cifre e trattini facoltativi

  • Funzioni di taglia, copia, incolla, annulla, nonché manovre tastiera e mouse standard per la modifica

  • API sviluppatore avanzate per manipolare contenuto, layout e tag del testo, nonché creare componenti di testo personalizzati

  • Supporto elenco versatile che include indicatori personalizzati e formati di numerazione

  • Immagini in linea e regole di posizionamento

Il TLF è una libreria ActionScript 3.0 creata sul motore del testo Flash (FTE) introdotto in Flash Player 10. Potete accedere a FTE tramite il pacchetto flash.text.engine, che fa parte dell'API (Application Programming Interface) di Flash Player 10.

L'API di Flash Player, tuttavia, fornisce un accesso di basso livello al motore del testo. Alcune operazioni possono pertanto richiedere una quantità di codice relativamente elevata. Il TLF incorpora il codice di basso livello in API più semplici e fornisce inoltre un'architettura concettuale che organizza gli elementi di base definiti da FTE in un sistema di più facile da utilizzare.

A differenza di FTE, il TLF non è incorporato in Flash Player. Si tratta infatti di una libreria di componenti indipendente scritta interamente in ActionScript 3.0. Trattandosi di un framework estensibile, è possibile personalizzarlo per ambienti specifici. Flash Professional e Flex SDK includono componenti basati sul framework TLF.

Supporto di script complessi

Il TLF fornisce il supporto per script complessi, inclusa la possibilità di visualizzare e modificare script da destra a sinistra. Il TLF consente anche di visualizzare e modificare una combinazione di script da sinistra a destra e da destra a sinistra, ad esempio l'arabo e l'ebraico. Il framework supporta non solo il layout di testo verticale per cinese, giapponese e coreano, ma anche gli elementi TCY (tate-chu-yoko), ovvero blocchi di testo orizzontale incorporati in sequenze di testo verticali. Sono supportati i seguenti script:

  • Latino (inglese, spagnolo, francese, vietnamita e così via)

  • Greco, cirillico, armeno, georgiano ed etiope

  • Arabo ed ebraico

  • Ideogrammi Han e Kana (cinese, giapponese e coreano) e Hangul Johab (coreano)

  • Tailandese, Lao e Khmer

  • Devanagari, bengali, gurmukhi, malayalam, telugu, tamil, gujarati, oriya, kannada e tibetano

  • Tifinagh, yi, cherokee, canadese sillabico, deseret, shavian, vai, tagalog, hanunoo, buhid e tagbanwa

Utilizzo del Text Layout Framework in Flash Professional e Flex

Potete utilizzare le classi TLF direttamente per creare componenti personalizzati in Flash. Inoltre, Flash Professional CS5 fornisce una nuova classe, fl.text.TLFTextField, che incorpora le funzionalità TLF. Utilizzate la classe TLFTextField per creare campi di testo in ActionScript che utilizzano le funzioni avanzate di visualizzazione del testo di TLF. Potete creare un oggetto TLFTextField nello stesso modo con cui create un campo di testo con la classe TextField. Utilizzate quindi la proprietà textFlow per assegnare le opzioni di formattazione avanzate delle classi TLF.

Potete anche utilizzare Flash Professional per creare l'istanza TLFTextField sullo stage utilizzando lo strumento Testo. Quindi potete utilizzare ActionScript per controllare la formattazione e il layout del contenuto del campo di testo utilizzando le classi TLF. Per ulteriori informazioni, vedete TLFTextField nella Guida di riferimento di Adobe ActionScript 3.0 per la piattaforma Adobe Flash.

Se state lavorando in Flex, utilizzate le classi TLF. Per ulteriori informazioni, vedete Uso del Text Layout Framework.

Uso del Text Layout Framework

Se state lavorando in Flex o state creando componenti di testo personalizzati, utilizzate le classi TLF. Il TLF è un libreria di ActionScript 3.0 contenuta interamente all'interno della libreria textLayout.swc. La libreria TLF contiene circa 100 classi e interfacce ActionScript 3.0 organizzate in dieci pacchetti. Questi pacchetti sono sottopacchetti del pacchetto flashx.textLayout.

Classi Text Layout Framework

Le classi TLF possono essere raggruppate in tre categorie:
  • Strutture di dati e classi di formattazione

  • Classi di rendering

  • Classi interazione utente

Strutture di dati e classi di formattazione

I pacchetti seguenti contengono le strutture di dati e le classi di formattazione per TLF:

La struttura dati principale di TLF è la gerarchia del flusso di testo, definita nel pacchetto elements. All'interno di questa struttura potete assegnare stili e attributi alle sequenze di testo con il pacchetto formats. Potete anche controllare la modalità di importazione ed esportazione del testo dalla struttura di dati con il pacchetto conversion.

Classi di rendering

I pacchetti seguenti contengono le classi di rendering per il TLF: Le classi in questo pacchetto semplificano il rendering del testo per la visualizzazione tramite Flash Player. Il pacchetto factory fornisce un metodo semplice per la visualizzazione del testo statico. Il pacchetto container comprende le classi e le interfacce che definiscono i contenitori di visualizzazione per il testo dinamico. Il pacchetto compose definisce le tecniche di posizionamento e visualizzazione del testo dinamico nei contenitori.

Classi di interazione utente

I pacchetti seguenti contengono le classi di interazione utente per il TLF: I pacchetti edit e operations definiscono le classi che potete utilizzare per consentire la modifica del testo memorizzato nelle strutture di dati. Il pacchetto events contiene classi di gestione degli eventi.

Operazioni generali per la creazione di testo con il Text Layout Framework

I passaggi seguenti descrivono il processo generale di creazione di testo con il Text Layout Format:

  1. Importare testo formattato nelle strutture di dati di TLF. Per ulteriori informazioni, vedete Creazione di strutture di testo con TLF e Formattazione di testo con TLF.

  2. Creare uno o più contenitori di oggetti di visualizzazione collegati per il testo. Per ulteriori informazioni, vedete Gestione di contenitori di testo con TLF.

  3. Associare il testo nelle strutture dati con i contenitori e impostare le opzioni di modifica e scorrimento. Per ulteriori informazioni, vedete Abilitazione di selezione, modifica e annullamento del testo con TLF.

  4. Creare un gestore eventi per ridisporre il testo in risposta a eventi resize (o altri). Per ulteriori informazioni, vedete Gestione degli eventi con TLF.

Esempio Text Layout Framework: layout con stile quotidiano

L'esempio seguente dimostra l'utilizzo di TLF per disporre una semplice pagina di giornale. La pagina include un titolo di grandi dimensioni, un sottotitolo e una sezione del corpo dell'articolo su più colonne:

package 
{ 
    import flash.display.Sprite; 
    import flash.display.StageAlign; 
    import flash.display.StageScaleMode; 
    import flash.events.Event; 
    import flash.geom.Rectangle; 
     
    import flashx.textLayout.compose.StandardFlowComposer; 
    import flashx.textLayout.container.ContainerController; 
    import flashx.textLayout.container.ScrollPolicy; 
    import flashx.textLayout.conversion.TextConverter; 
    import flashx.textLayout.elements.TextFlow; 
    import flashx.textLayout.formats.TextLayoutFormat; 
     
    public class TLFNewsLayout extends Sprite 
    { 
        private var hTextFlow:TextFlow; 
        private var headContainer:Sprite; 
        private var headlineController:ContainerController; 
        private var hContainerFormat:TextLayoutFormat; 
         
        private var bTextFlow:TextFlow; 
        private var bodyTextContainer:Sprite; 
        private var bodyController:ContainerController; 
        private var bodyTextContainerFormat:TextLayoutFormat; 
         
        private const headlineMarkup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008'><flow:p textAlign='center'><flow:span fontFamily='Helvetica' fontSize='18'>TLF News Layout Example</flow:span><flow:br/><flow:span fontFamily='Helvetica' fontSize='14'>This example formats text like a newspaper page with a headline, a subtitle, and multiple columns</flow:span></flow:p></flow:TextFlow>"; 
         
        private const bodyMarkup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='12' textIndent='10' marginBottom='15' paddingTop='4' paddingLeft='4'><flow:p marginBottom='inherit'><flow:span>There are many </flow:span><flow:span fontStyle='italic'>such</flow:span><flow:span> lime-kilns in that tract of country, for the purpose of burning the white marble which composes a large part of the substance of the hills. Some of them, built years ago, and long deserted, with weeds growing in the vacant round of the interior, which is open to the sky, and grass and wild-flowers rooting themselves into the chinks of the stones, look already like relics of antiquity, and may yet be overspread with the lichens of centuries to come. Others, where the lime-burner still feeds his daily and nightlong fire, afford points of interest to the wanderer among the hills, who seats himself on a log of wood or a fragment of marble, to hold a chat with the solitary man. It is a lonesome, and, when the character is inclined to thought, may be an intensely thoughtful occupation; as it proved in the case of Ethan Brand, who had mused to such strange purpose, in days gone by, while the fire in this very kiln was burning.</flow:span></flow:p><flow:p marginBottom='inherit'><flow:span>The man who now watched the fire was of a different order, and troubled himself with no thoughts save the very few that were requisite to his business. At frequent intervals, he flung back the clashing weight of the iron door, and, turning his face from the insufferable glare, thrust in huge logs of oak, or stirred the immense brands with a long pole. Within the furnace were seen the curling and riotous flames, and the burning marble, almost molten with the intensity of heat; while without, the reflection of the fire quivered on the dark intricacy of the surrounding forest, and showed in the foreground a bright and ruddy little picture of the hut, the spring beside its door, the athletic and coal-begrimed figure of the lime-burner, and the half-frightened child, shrinking into the protection of his father's shadow. And when again the iron door was closed, then reappeared the tender light of the half-full moon, which vainly strove to trace out the indistinct shapes of the neighboring mountains; and, in the upper sky, there was a flitting congregation of clouds, still faintly tinged with the rosy sunset, though thus far down into the valley the sunshine had vanished long and long ago.</flow:span></flow:p></flow:TextFlow>"; 
         
        public function TLFNewsLayout() 
        {      
            //wait for stage to exist 
            addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);     
        } 
         
        private function onAddedToStage(evtObj:Event):void 
        { 
            removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 
            stage.scaleMode = StageScaleMode.NO_SCALE; 
            stage.align = StageAlign.TOP_LEFT; 
             
            // Headline text flow and flow composer 
            hTextFlow = TextConverter.importToFlow(headlineMarkup, TextConverter.TEXT_LAYOUT_FORMAT); 
             
            // initialize the headline container and controller objects 
            headContainer = new Sprite(); 
            headlineController = new ContainerController(headContainer); 
            headlineController.verticalScrollPolicy = ScrollPolicy.OFF; 
            hContainerFormat = new TextLayoutFormat(); 
            hContainerFormat.paddingTop = 4; 
            hContainerFormat.paddingRight = 4; 
            hContainerFormat.paddingBottom = 4; 
            hContainerFormat.paddingLeft = 4; 
             
            headlineController.format = hContainerFormat; 
            hTextFlow.flowComposer.addController(headlineController); 
            addChild(headContainer); 
            stage.addEventListener(flash.events.Event.RESIZE, resizeHandler); 
             
            // Body text TextFlow and flow composer 
            bTextFlow = TextConverter.importToFlow(bodyMarkup, TextConverter.TEXT_LAYOUT_FORMAT); 
             
            // The body text container is below, and has three columns 
            bodyTextContainer = new Sprite(); 
            bodyController = new ContainerController(bodyTextContainer); 
            bodyTextContainerFormat = new TextLayoutFormat(); 
            bodyTextContainerFormat.columnCount = 3; 
            bodyTextContainerFormat.columnGap = 30; 
             
            bodyController.format = bodyTextContainerFormat; 
            bTextFlow.flowComposer.addController(bodyController); 
            addChild(bodyTextContainer); 
            resizeHandler(null); 
        } 
         
        private function resizeHandler(event:Event):void 
        { 
            const verticalGap:Number = 25; 
            const stagePadding:Number = 16; 
            var stageWidth:Number = stage.stageWidth - stagePadding; 
            var stageHeight:Number = stage.stageHeight - stagePadding; 
            var headlineWidth:Number = stageWidth; 
            var headlineContainerHeight:Number = stageHeight; 
             
            // Initial compose to get height of headline after resize 
            headlineController.setCompositionSize(headlineWidth, 
headlineContainerHeight); 
            hTextFlow.flowComposer.compose(); 
            var rect:Rectangle = headlineController.getContentBounds(); 
            headlineContainerHeight = rect.height; 
             
            // Resize and place headline text container 
            // Call setCompositionSize() again with updated headline height 
            headlineController.setCompositionSize(headlineWidth, headlineContainerHeight ); 
            headlineController.container.x = stagePadding / 2; 
            headlineController.container.y = stagePadding / 2; 
            hTextFlow.flowComposer.updateAllControllers(); 
             
            // Resize and place body text container 
            var bodyContainerHeight:Number = (stageHeight - verticalGap - headlineContainerHeight); 
            bodyController.format = bodyTextContainerFormat; 
            bodyController.setCompositionSize(stageWidth, bodyContainerHeight ); 
            bodyController.container.x = (stagePadding/2); 
            bodyController.container.y = (stagePadding/2) + headlineContainerHeight + verticalGap; 
            bTextFlow.flowComposer.updateAllControllers(); 
        } 
    } 
} 

La classe TLFNewsLayout utilizza due contenitori di testo. Un contenitore visualizza un titolo e un sottotitolo, mentre l'altro visualizza un corpo del testo a tre colonne. Per semplicità, il testo è codificato nell'esempio come testo di marcatura TLF. La variabile headlineMarkup contiene un titolo e un sottotitolo, mentre la variabile bodyMarkup contiene il testo principale. Per ulteriori informazioni sul codice TLF, vedete Creazione di strutture di testo con TLF.

Dopo alcune operazioni di inizializzazione, la funzione onAddedToStage() importa il testo del titolo in un oggetto TextFlow, che è la struttura di dati principale di TLF:
hTextFlow = TextConverter.importToFlow(headlineMarkup, TextConverter.TEXT_LAYOUT_FORMAT); 
Di seguito, viene creato un oggetto Sprite per il contenitore, nonché un controller associato al contenitore stesso:
headContainer = new Sprite(); 
headlineController = new ContainerController(headContainer);
Il controller viene inizializzato per impostare formattazione, scorrimento e altre opzioni. Inoltre contiene la geometria che definisce i limiti del contenitore in cui fluisce il testo. Un oggetto TextLayoutFormat contiene le opzioni di formattazione:
hContainerFormat = new TextLayoutFormat();

Il controller viene assegnato al compositore di flusso e la funzione aggiunge il contenitore all'elenco di visualizzazione. La composizione e la visualizzazione effettiva dei contenitori è differita al metodo resizeHandler(). La stessa sequenza di operazioni viene eseguita per inizializzare l'oggetto TextFlow del corpo.

Il metodo resizeHandler() misura lo spazio disponibile per il rendering dei contenitori e misura le dimensioni dei contenitori di conseguenza. Una chiamata iniziale al metodo compose() consente il calcolo dell'altezza corretta del contenitore del titolo. Il metodo resizeHandler() può quindi collocare e visualizzare il contenitore del titolo con il metodo updateAllControllers(). Infine, il metodo resizeHandler() utilizza la dimensione del contenitore del titolo per determinare la posizione del contenitore del testo principale.

Creazione di strutture di testo con TLF

TLF utilizza una struttura ad albero gerarchica per rappresentare il testo. Ogni nodo della struttura ad albero è un'istanza di una classe definita nel pacchetto elements. Ad esempio, il nodo radice della struttura ad albero è sempre un'istanza della classe TextFlow. La classe TextFlow rappresenta un brano di testo completo. Un brano è una raccolta di testo e altri elementi gestiti come un'unica unità o flusso. Un brano singolo potrebbe richiedere più colonne o contenitori di testo per essere visualizzato.

A parte il nodo radice, tutti gli altri elementi sono genericamente basati su elementi XHTML. Il seguente diagramma mostra la gerarchia del framework:

Gerarchia TextFlow

Formato di codifica Text Layout Framework Markup

La conoscenza della struttura di TLF è utile anche per gestire il formato di codifica TLF Markup, ovvero una rappresentazione XML del testo che fa parte del TLF. Il framework supporta anche altri formati XML, ma l'unicità del formato di codifica TLF Markup risiede nel fatto che è basato specificamente sulla struttura della gerarchia TextFlow. Se esportate codice XML da un'istanza TextFlow utilizzando questo formato di codifica, il codice XML verrà esportato mantenendo intatta la gerarchia.

Il formato di codifica TLF Markup fornisce la rappresentazione più fedele del testo in una gerarchia TextFlow. Il linguaggio di markup fornisce tag per ciascuno degli elementi di base della gerarchia TextFlow, nonché attributi per tutte le proprietà di formattazione disponibili nella classe TextLayoutFormat.

La tabella seguente contiene i tag che è possibile utilizzare nel formato di codifica TLF Markup.

Elemento

Descrizione

Elemento secondario

Classe

textflow

L'elemento principale del markup.

div, p

TextFlow

div

Una divisione all'interno di un TextFlow. Può contenere un gruppo di paragrafi.

div, list, p

DivElement

p

Un paragrafo.

a, tcy, span, img, tab, br, g

ParagraphElement

a

Un collegamento.

tcy, span, img, tab, br, g

LinkElement

tcy

Una sequenza di testo orizzontale (utilizzata in un oggetto TextFlow verticale).

a, span, img, tab, br, g

TCYElement

span

Una sequenza di testo all'interno di un paragrafo.

 

SpanElement

img

Un'immagine in un paragrafo.

 

InlineGraphicElement

tab

Un carattere di tabulazione.

 

TabElement

br

Un carattere di interruzione. Utilizzato per terminare una riga all'interno di un paragrafo; il testo continua sulla riga successiva ma rimane nello stesso paragrafo.

 

BreakElement

linkNormalFormat

Definisce gli attributi di formattazione utilizzati per i collegamenti nello stato normal.

TextLayoutFormat

TextLayoutFormat

linkActiveFormat

Definisce gli attributi di formattazione utilizzati per i collegamenti nello stato attivo, quando il pulsante del mouse è premuto su un collegamento.

TextLayoutFormat

TextLayoutFormat

linkHoverFormat

Definisce gli attributi di formattazione utilizzati per i collegamenti nello stato hover, quando il mouse è all'interno dei limiti di un collegamento (rollover).

TextLayoutFormat

TextLayoutFormat

li

Un elemento voce di elenco. Deve essere interno a un elemento elenco.

li, Elenco, p

ListItemElement

list

Un elenco. Gli elementi possono essere nidificati o affiancati. Alle voci elenco possono essere applicati schemi di etichettatura e numerazione diversi.

div, li, list, p

ListElement

g

Un elemento di gruppo. Utilizzato per raggruppare elementi in un paragrafo. Consente di nidificare elementi sotto il livello di paragrafo.

a, tcy, span, img, tab, br, g

SubParagraphGroupElement

Utilizzo di elenchi numerati e puntati

Potete utilizzare le classi ListElement e ListItemElement per aggiungere elenchi puntati ai controlli di testo. Gli elenchi puntati possono essere nidificati e personalizzati per utilizzare punti elenco (o indicatori) diversi e la numerazione automatica, nonché numerazione in stile contorno.

Per creare elenchi nel flusso di testo, utilizzate il tag <list>. Utilizzate quindi i tag <li> all'interno del tag <list> per ogni voce nell'elenco. Potete personalizzare l'aspetto dei punti elenco utilizzando la classe ListMarkerFormat.

L'esempio seguente crea semplici elenchi:
<flow:list paddingRight="24" paddingLeft="24"> 
    <flow:li>Item 1</flow:li> 
    <flow:li>Item 2</flow:li> 
    <flow:li>Item 3</flow:li> 
</flow:list>
Potete nidificare elenchi all'interno di altri elenchi, come mostrato nell'esempio seguente:
<flow:list paddingRight="24" paddingLeft="24"> 
    <flow:li>Item 1</flow:li> 
    <flow:list paddingRight="24" paddingLeft="24"> 
        <flow:li>Item 1a</flow:li> 
        <flow:li>Item 1b</flow:li> 
        <flow:li>Item 1c</flow:li> 
    </flow:list> 
    <flow:li>Item 2</flow:li> 
    <flow:li>Item 3</flow:li> 
</flow:list>
Per personalizzare il tipo di indicatore nell'elenco, utilizzate la proprietà listStyleType di ListElement. Il valore di questa proprietà può essere uno tra quelli definiti dalla classe ListStyleType (ad esempio, check, circle, decimal e box). L'esempio seguente crea elenchi con diversi tipi di indicatore e un incremento contatore personalizzato:
<flow:list paddingRight="24" paddingLeft="24" listStyleType="upperAlpha">     <flow:li>upperAlpha item</flow:li>     <flow:li>another</flow:li> </flow:list> <flow:list paddingRight="24" paddingLeft="24" listStyleType="lowerAlpha">     <flow:li>lowerAlpha item</flow:li>     <flow:li>another</flow:li> </flow:list> <flow:list paddingRight="24" paddingLeft="24" listStyleType="upperRoman">     <flow:li>upperRoman item</flow:li>     <flow:li>another</flow:li> </flow:list> <flow:list paddingRight="24" paddingLeft="24" listStyleType="lowerRoman">     <flow:listMarkerFormat>         <!-- Increments the list by 2s rather than 1s. -->         <flow:ListMarkerFormat counterIncrement="ordered 2"/>     </flow:listMarkerFormat>     <flow:li>lowerRoman item</flow:li>     <flow:li>another</flow:li> </flow:list>

Utilizzate la classe ListMarkerFormat per definire il contatore. Oltre alla definizione dell'incremento di un contatore, potete anche personalizzare il contatore ripristinandolo con la proprietà counterReset.

Potete personalizzare ulteriormente l'aspetto degli indicatori negli elenchi utilizzando le proprietà beforeContent e afterContent di ListMarkerFormat. Queste proprietà si applicano al contenuto visualizzato prima e dopo il contenuto dell'indicatore.

L'esempio seguente aggiunge la stringa “XX” prima dell'indicatore e la stringa “YY” dopo l'indicatore:
<flow:list listStyleType="upperRoman" paddingLeft="36" paddingRight="24"> 
    <flow:listMarkerFormat> 
        <flow:ListMarkerFormat fontSize="16" 
            beforeContent="XX" 
            afterContent="YY" 
            counterIncrement="ordered -1"/> 
        </flow:listMarkerFormat> 
    <flow:li>Item 1</flow:li> 
    <flow:li>Item 2</flow:li> 
    <flow:li>Item 3</flow:li> 
</flow:list>
La proprietà content stessa può definire ulteriori personalizzazioni del formato indicatore. L'esempio seguente visualizza un indicatore numero romano maiuscolo, ordinato:
<flow:list listStyleType="disc"  paddingLeft="96" paddingRight="24"> 
    <flow:listMarkerFormat> 
        <flow:ListMarkerFormat fontSize="16" 
            beforeContent="Section " 
            content="counters(ordered,&quot;*&quot;,upperRoman)" 
            afterContent=": "/> 
    </flow:listMarkerFormat> 
    <flow:li>Item 1</li> 
    <flow:li>Item 2</li> 
    <flow:li>Item 3</li> 
</flow:list>

Come mostrato nell'esempio precedente, la proprietà content può anche inserire un suffisso: una stringa visualizzata dopo l'indicatore, ma prima di afterContent. Per inserire questa stringa quando si fornisce contenuto XML al flusso, racchiudete la stringa tra entità HTML &quote; piuttosto che tra virgolette ("<stringa>").

Uso del riempimento in TLF

Ogni FlowElement supporta proprietà di riempimento utilizzate per controllare la posizione di ciascuna area di contenuto dell'elemento, nonché lo spazio tra le aree di contenuto.

La larghezza totale di un elemento è la somma della larghezza del suo contenuto più le proprietà paddingLeft e paddingRight. L'altezza totale di un elemento è la somma dell'altezza del suo contenuto più le proprietà paddingTop e paddingBottom.

Il riempimento è lo spazio tra il bordo e il contenuto. Le proprietà di riempimento sono paddingBottom, paddingTop, paddingLeft e paddingRight. Il riempimento può essere applicato all'oggetto TextFlow, nonché agli elementi secondari seguenti:
  • div

  • img

  • li

  • list

  • p

Le proprietà di riempimento non possono essere applicate a elementi intervallo.

L'esempio seguente imposta proprietà di riempimento su TextFlow:
<flow:TextFlow version="2.0.0" xmlns:flow="http://ns.adobe.com/textLayout/2008" fontSize="14" textIndent="15" paddingTop="4" paddingLeft="4" fontFamily="Times New Roman">

Valori validi per le proprietà di riempimento sono un numero (in pixel), “auto” o “inherit”. Il valore predefinito è “auto”, ovvero il riempimento viene calcolato automaticamente è impostato su 0 per tutti gli elementi ad eccezione di ListElement. Per ListElements, “auto” è 0 tranne che sul lato iniziale dell'elenco dove viene utilizzato il valore della proprietà listAutoPadding. Il valore predefinito di listAutoPadding è 40, che fornisce agli elenchi un rientro predefinito.

Per impostazione predefinita, le proprietà di riempimento non prevedono l'ereditarietà. I valori “auto” e “inherit” sono costanti definite dalla classe FormatValue.

Le proprietà di riempimento possono essere valori negativi.

Formattazione di testo con TLF

Il pacchetto flashx.textLayout.formats contiene interfacce e classi che consentono di assegnare formati a qualsiasi oggetto FlowElement della struttura ad albero del flusso di testo. Esistono due modi per applicare la formattazione. Potete assegnare un formato specifico individualmente oppure assegnare un gruppo di formati contemporaneamente con un oggetto di formattazione speciale.

L'interfaccia ITextLayoutFormat contiene tutti i formati che possono essere applicati a un oggetto FlowElement. Alcuni formati vengono applicati a un intero contenitore o paragrafo di testo, ma non si applicano logicamente ai singoli caratteri. Ad esempio, formati quali giustificazione e spazi di tabulazione si applicano a interi paragrafi, ma non a singoli caratteri.

Assegnazione di formati a un oggetto FlowElement con Properties

Potete impostare formati su qualsiasi oggetto FlowElement mediante assegnazione di proprietà. Poiché la classe FlowElement implementa l'interfaccia ITextLayoutFormat, qualsiasi sottoclasse della classe FlowElement deve implementare la stessa interfaccia.

Ad esempio, il codice seguente mostra come assegnare singoli formati a un'istanza di ParagraphElement:

var p:ParagraphElement = new ParagraphElement(); 
p.fontSize = 18; 
p.fontFamily = "Arial";

Assegnazione di formati a un oggetto FlowElement con la classe TextLayoutFormat

Potete applicare formati a un oggetto FlowElement con la classe TextLayoutFormat. Potete utilizzare questa classe per creare un oggetto di formattazione speciale che contiene tutti i valori di formattazione desiderati. Potete quindi assegnare questo oggetto alla proprietà format di qualsiasi oggetto FlowElement. Gli oggetti TextLayoutFormat e FlowElement implementano entrambi l'interfaccia ITextLayoutFormat. Questo approccio garantisce che entrambe le classi contengono le stesse proprietà di formattazione.

Per ulteriori informazioni, vedete TextLayoutFormat nella Guida di riferimento di Adobe ActionScript 3.0 per la piattaforma Adobe Flash.

Ereditarietà dei formati

I formati vengono ereditati tramite la gerarchia del flusso di testo. Se assegnate un'istanza di TextLayoutFormat a un'istanza FlowElement con elementi secondari, il framework avvia un processo a cascata. Durante un processo a cascata, il framework esamina in modo ricorsivo tutti i nodi della gerarchia che ereditano valori dall'istanza FlowElement e determina se i valori ereditati devono essere assegnati alle varie proprietà di formattazione. Durante il processo a cascata vengono applicate le seguenti regole:

  1. I valori delle proprietà vengono ereditati solo da un antenato immediato (definito anche elemento principale).

  2. I valori delle proprietà vengono ereditati solo se una proprietà non dispone già di un valore proprio (ovvero undefined)..

  3. Alcuni attributi non ereditano i valori undefined, a meno che il valore dell'attributo non sia impostato su “inherit” o sulla costante flashx.textLayout.formats.FormatValue.INHERIT.

Ad esempio, se impostate il valore fontSize a livello di TextFlow, l'impostazione viene applicata a tutti i contenitori dell'istanza TextFlow. In altre parole, i valori vengono applicati a cascata agli elementi di livello inferiore della gerarchia del flusso di testo. Potete tuttavia sostituire il valore di un elemento specifico assegnando un nuovo valore direttamente all'elemento. Viceversa, se impostate il valore backgroundColor per il livello TextFlow, l'elemento secondario di TextFlow non eredita tale valore. La proprietà backgroundColor non prevede l'ereditarietà dall'elemento principale durante un processo a cascata. Potete sostituire questo comportamento impostando la proprietà backgroundColor di ciascun elemento secondario su flashx.textLayout.formats.FormatValue.INHERIT.

Per ulteriori informazioni, vedete TextLayoutFormat nella Guida di riferimento di Adobe ActionScript 3.0 per la piattaforma Adobe Flash.

Importazione ed esportazione di testo con TLF

La classe TextConverter nel pacchetto flashx.textLayout.conversion.* consente di importare testo in, ed esportare testo da, TLF. Utilizzate questa classe se prevedete di caricare testo in fase di esecuzione anziché compilarlo nel file SWF. Potete anche utilizzare questa classe per esportare il testo memorizzato in un'istanza TextFlow in un oggetto String o XML.

Sia l'importazione che l'esportazione sono procedure semplici. Chiamate il metodo export() o il metodo importToFlow(), entrambi appartenenti alla classe TextConverter. Poiché si tratta di metodi statici, la chiamata viene effettuata sulla classe TextConverter anziché su un'istanza della classe.

Le classi nel pacchetto flashx.textLayout.conversion offrono una notevole flessibilità nella scelta della posizione di memorizzazione del testo. Ad esempio, se memorizzate il testo in un database, potete importarlo nel framework per la visualizzazione. Potete quindi utilizzare le classi nel pacchetto flashx.textLayout.edit per modificare il testo, nonché esportare nuovamente il testo modificato nel database.

Per ulteriori informazioni, vedete flashx.textLayout.conversion nella Guida di riferimento di Adobe ActionScript 3.0 per la piattaforma Adobe Flash.

Gestione di contenitori di testo con TLF

Il testo memorizzato nelle strutture di dati TLF può essere visualizzato tramite Flash Player. Il testo memorizzato nella gerarchia del flusso deve essere convertito in un formato che possa essere visualizzato da Flash Player. In TLF sono disponibili due modi per creare oggetti di visualizzazione da un flusso. Il primo approccio, più semplice, è adatto per la visualizzazione di testo statico. Il secondo approccio, più complesso, consente di creare testo dinamico che può essere selezionato e modificato. In entrambi i casi il testo viene convertito in istanze della classe TextLine, che fa parte del pacchetto flash.text.engine.* di Flash Player 10.

Creazione di testo statico

L'approccio semplice utilizza la classe TextLFlowTextLineFactory, che fa parte del pacchetto flashx.textLayout.factory. Il vantaggio di questo approccio, oltre alla sua semplicità, è che utilizza una quantità di memoria inferiore rispetto a un compositore di flusso. Questo approccio è indicato per il testo statico che non deve essere modificato, selezionato e che non richiede operazioni di scorrimento.

Per ulteriori informazioni, vedete TextFlowTextLineFactory nella Guida di riferimento di Adobe ActionScript 3.0 per la piattaforma Adobe Flash.

Creazione di testo dinamico e contenitori

Utilizzate un compositore di flusso se desiderate un maggior controllo sulla visualizzazione del testo rispetto a quello fornito da TextFlowTextLineFactory. Ad esempio, gli utenti possono utilizzare un compositore di flusso per selezionare e modificare il testo. Per ulteriori informazioni, vedete Abilitazione di selezione, modifica e annullamento del testo con TLF.

Un compositore di flusso è un'istanza della classe StandardFlowComposer nel pacchetto flashx.textLayout.compose. Gestisce la conversione di TextFlow in istanze TextLine, nonché il posizionamento di queste istanze TextLine in uno o più contenitori.

Visualizzazione dell’elemento grafico a dimensioni intere
Un oggetto IFlowComposer può avere zero o più oggetti ContainerController

A ogni istanza TextFlow corrisponde un oggetto che implementa l'interfaccia IFlowComposer. L'oggetto IFlowComposer è accessibile tramite la proprietà TextFlow.flowComposer, che consente anche di chiamare metodi definiti dall'interfaccia IFlowComposer. Questi metodi consentono di associare il testo a uno o più contenitori, nonché preparare il testo per la visualizzazione all'interno di un contenitore.

Un contenitore è un'istanza della classe Sprite, ovvero una sottoclasse della classe DisplayObjectContainer. Entrambe queste classi fanno parte dell'API dell'elenco di visualizzazione di Flash Player. Un contenitore è una forma più avanzata del rettangolo di delimitazione utilizzato con la classe TextLineFactory. Analogamente al rettangolo di delimitazione, un contenitore definisce l'area in cui verranno visualizzate le istanze TextLine. A differenza del rettangolo di delimitazione, un contenitore dispone di un oggetto “controller” corrispondente. Il controller gestisce lo scorrimento, la composizione, il collegamento, la formattazione e la gestione eventi per un contenitore o insieme di contenitori. Ogni contenitore dispone di un oggetto controller corrispondente che è un'istanza della classe ContainerController nel pacchetto flashx.textLayout.container.

Per visualizzare testo, creare un oggetto controller per gestire il contenitore e associarlo al compositore di flusso. Dopo aver associato il contenitore, componete il testo per poterlo visualizzare. Di conseguenza, i contenitori hanno due stati: composizione e visualizzazione. La composizione è il processo che consente di convertire il testo della gerarchia del flusso di testo in istanze TextLine e definire la disposizione di queste istanze nel contenitore. La visualizzazione è il processo di aggiornamento dell'elenco di visualizzazione di Flash Player.

Per ulteriori informazioni, vedete IFlowComposer, StandardFlowComposer e ContainerController nella Guida di riferimento di Adobe ActionScript 3.0 per la piattaforma Adobe Flash.

Abilitazione di selezione, modifica e annullamento del testo con TLF

La possibilità di selezionare o modificare il testo è controllata a livello di flusso di testo. A ogni istanza della classe TextFlow è associato un gestore di interazione. Potete accedere al gestore interazione di un oggetto TextFlow mediante la proprietà TextFlow.interactionManager dell'oggetto. Per abilitare la selezione testo, assegnate un'istanza della classe SelectionManager alla proprietà interactionManager. Per abilitare sia la selezione che la modifica del testo, assegnate un'istanza della classe EditManager anziché un'istanza della classe SelectionManager. Per abilitare operazioni di annullamento, create un'istanza della classe UndoManager e includetela come un argomento quando chiamate il costruttore per EditManager. La classe UndoManager mantiene una cronologia delle attività di modifica più recenti e consente di annullare o ripetere modifiche specifiche. Tutte e tre queste classi sono parte del pacchetto edit.

Per ulteriori informazioni, vedete SelectionManager, EditManager e UndoManager nella Guida di riferimento di Adobe ActionScript 3.0 per la piattaforma Adobe Flash.

Gestione degli eventi con TLF

Gli oggetti TextFlow inviano eventi in numerose circostanze, incluso:
  • Quando il testo o il layout cambia

  • Prima dell'inizio di un'operazione e al termine di un'operazione

  • Quando lo stato di un oggetto FlowElement cambia

  • Al termine di un'operazione di composizione

Per ulteriori informazioni, vedete flashx.textLayout.events nella Guida di riferimento di Adobe ActionScript 3.0 per la piattaforma Adobe Flash.

Posizionamento di immagini all'interno del testo

Per posizionare InlineGraphicElement all'interno del testo, utilizzate le proprietà seguenti:
  • proprietà float della classe InlineGraphicElement

  • proprietà clearFloats della classe FlowElement

La proprietà float controlla il posizionamento della grafica e del testo circostante. La proprietà clearFloats controlla il posizionamento degli elementi del paragrafo rispetto alla proprietà float.

Per controllare la posizione di un'immagine all'interno di un elemento di testo, utilizzate la proprietà float. L'esempio seguente aggiunge un'immagine a un paragrafo e la allinea a sinistra in modo che il testo si disponga a destra:
<flow:p paragraphSpaceAfter="15" >Images in a flow are a good thing. For example, here is a float. It should show on the left: <flow:img float="left" height="50" width="19" source="../assets/bulldog.jpg"></flow:img> Don't you agree? Another sentence here. Another sentence here. Another sentence here. Another sentence here. Another sentence here. Another sentence here. Another sentence here. Another sentence here.</flow:p>

Valori validi per la proprietà float sono “left”, “right”, “start”, “end” e “none”. La classe Float definisce queste costanti. Il valore predefinito è "none”.

La proprietà clearFloats è utile nei casi in cui si desidera regolare la posizione iniziale dei paragrafi successivi che si dispongono normalmente intorno all'immagine. Ad esempio, ipotizzate di avere un'immagine più larga del primo paragrafo. Accertatevi che il secondo paragrafo inizi dopo l'immagine, impostate la proprietà clearFloats.

L'esempio seguente utilizza un'immagine più alta del testo nel primo paragrafo. Per fare in modo che il secondo paragrafo inizi dopo l'immagine nel blocco di testo, questo esempio imposta la proprietà clearFloats sul secondo paragrafo su “end”.
<flow:p paragraphSpaceAfter="15" >Here is another float, it should show up on the right: <flow:img float="right" height="50" elementHeight="200" width="19" source="../assets/bulldog.jpg"></flow:img>We'll add another paragraph that should clear past it.</flow:p><flow:p clearFloats="end" >This should appear after the previous float on the right.</flow:p>

Valori validi per la proprietà clearFloats sono “left”, “right”, “end”, “start”, “none” e “both”. La classe ClearFloats definisce queste costanti. Potete anche impostare la proprietà clearFloats su “inherit”, che è una costante definita dalla classe FormatValue. Il valore predefinito è "none”.