Uso de Text Layout Framework

Flash Player 10 y posterior, Adobe AIR 1.5 y posterior

Información general sobre Text Layout Framework

Text Layout Framework (TLF) es una biblioteca ampliable de ActionScript. TLF está incorporada en el motor de texto de Adobe® Flash® Player 10 y Adobe® AIR® 1.5. TLF proporciona funciones de diseño de texto y tipográficas avanzadas para una tipografía innovadora en la web. La arquitectura se puede utilizar con Adobe® Flex® o Adobe® Flash® Professional. Los desarrolladores pueden utilizar o ampliar los componentes existentes, o bien, pueden utilizar la arquitectura para crear sus propios componentes de texto.

TLF incluye las siguientes capacidades:
  • Texto bidireccional, texto vertical y unos 30 scripts de escritura, incluyendo árabe, hebreo, chino, japonés, coreano, tailandés, lao y vietnamita, entre otros.

  • Selección, edición y flujo de texto en varias columnas y contenedores vinculados.

  • Texto vertical, Tate-Chu-Yoko (texto vertical con horizontal) y justificador para la tipografía del este asiático.

  • Controles tipográficos entre los que se incluyen ajuste entre caracteres, ligaduras, formato tipográfico de mayúsculas y minúsculas, caja de dígitos, anchura de dígitos y guiones discrecionales.

  • Cortar, copiar, pegar, deshacer y gestos de ratón y teclado estándar para edición.

  • APIs para el desarrollador para manipular contenido de texto, diseño y marcado y crear componentes de texto personalizados.

  • Compatibilidad sólida con la lista, incluyendo marcadores personalizados y formatos de numeración.

  • Imágenes en línea y reglas de posicionamiento.

TLF es una biblioteca de ActionScript 3.0 incorporada en Flash Text Engine (FTE) introducido en Flash Player 10. A FTE se puede acceder mediante el paquete flash.text.engine , que forma parte de la Interfaz de programación de aplicaciones (API) de Flash Player 10.

Sin embargo, la API de Flash Player ofrece un acceso de muy bajo nivel al motor de texto, lo que significa que algunas tareas pueden requerir una enorme cantidad de código. TLF encapsula el código de bajo nivel en APIs más sencillas. TLF también ofrece una arquitectura conceptual que organiza los bloques de creación básicos definidos por FTE en un sistema que sea más fácil de utilizar.

A diferencia de FTE, TLF no se basa en Flash Player. Se trata de una biblioteca de componentes independiente escrita en ActionScript 3.0 en su totalidad. Debido a que la arquitectura se puede ampliar, también se puede personalizar para entorno específicos. Tanto Flash Professional como el SDK de Flex incluyen componentes que se basan en el marco TLF.

Compatibilidad con scripts complejos

TLF proporciona compatibilidad con scripts complejos. La compatibilidad con scripts complejos incluye la capacidad para mostrar y editar scripts de derecha a izquierda. TLF también proporciona la capacidad para mostrar y editar una mezcla de scripts de izquierda a derecha y de derecha a izquierda como, por ejemplo, árabe y hebreo. La arquitectura no solo admite diseño de texto vertical para chino, japonés y coreano, sino que también es compatible con tate-chu-yoko (elementos TCY). Los elementos TCY son bloques de texto horizontal incorporados en extensiones de texto vertical. Se admiten los siguientes scripts:

  • Latinos (inglés, español, francés, vietnamita, etc)

  • Griego, cirílico, armenio, georgiano y etíope

  • Árabe y hebreo

  • Ideogramas de Han y Kana (chino, japonés y coreano) y Hangul Johab (coreano)

  • Thai, Lao y Khmer

  • Devanagari, Bengali, Gurmukhi, Malayalam, Telugu, Tamil, Gujarati, Oriya, Kannada y tibetano

  • Tifinagh, Yi, Cherokee, alfabeto silábico canadiense, Deseret, Shavian, Vai, Tagalog, Hanunoo, Buhid y Tagbanwa

Uso de Text Layout Framework en Flash Professional y Flex

Se pueden utilizar las clases TLF directamente para crear componentes personalizados en Flash. Asimismo, Flash Professional CS5 proporciona una nueva clase, fl.text.TLFTextField, que encapsula la funcionalidad de TLF. Utilice la clase TLFTextField para crear campos de texto en ActionScript que utilicen las funciones avanzadas de visualización de TLF. Cree un objeto TLFTextField la misma manera que crearía un campo de texto con la clase TextField. Seguidamente, utilice la propiedad textFlow para asignar formato avanzado de las clases TLF.

También se puede utilizar Flash Professional para crear la instancia de TLFTextField en el escenario utilizando la herramienta de texto. Posteriormente ActionScript se puede utilizar para controlar el formato y el diseño del contenido del campo de texto utilizando las clases TLF. Para obtener más información, consulte la clase TLFTextField en la Referencia de ActionScript 3.0 para la plataforma de Adobe Flash.

Si está trabajando en Flex, utilice las clases TLF. Para obtener más información, consulte Uso de Text Layout Framework .

Uso de Text Layout Framework

Si está trabajando en Flex o está creando componentes de texto personalizados, utilice las clases TLF. TLF es una biblioteca de ActionScript 3.0 incluida por completo en la biblioteca textLayout.swc. La biblioteca TLF contiene unas cien interfaces y clases de ActionScript 3.0 organizadas en diez paquetes. Estos paquetes son subpaquetes del paquete flashx.textLayout.

Clases de Text Layout Framework

Las clases TLF se pueden agrupar en tres categorías:
  • Clases de formato y estructuras de datos

  • Clases de representación

  • Clases de interacción con el usuario

Clases de formato y estructuras de datos

Los siguientes paquetes contienen las estructuras de datos y las clases de formato para TLF:

La estructura de datos principal de TLF es la jerarquía de flujo de texto, que se define en el paquete de elementos. Dentro de esta estructura, puede asignar estilos y atributos a extensiones de texto con el paquete de formatos. También es posible controlar el modo en que el texto se exporta e importa en la estructura de datos con el paquete de conversión.

Clases de representación

Los siguientes paquetes contienen las clases de representación para TLF: Las clases de estos paquetes facilitan la representación de texto para su visualización en Flash Player. El paquete factory proporciona una forma sencilla de mostrar texto estático. El paquete container incluye clases e interfaces que definen contenedores de visualización para texto dinámico. El paquete compose define técnicas para situar y visualizar texto dinámico en contenedores.

Clases de interacción con el usuario

Los siguientes paquetes contienen las clases de interacción del usuario para TLF: Los paquetes edit y operations definen clases que se pueden utilizar para permitir la edición de texto almacenado en las estructuras de datos. El paquete de eventos contiene clases de gestión de eventos.

Pasos generales para la creación de texto con Text Layout Framework

Los siguientes pasos describen el proceso general para crear texto con Text Layout Format:

  1. Importe el texto con formato en las estructuras de datos TLF. Para obtener más información, consulte Estructuración del texto con TLF y Formato de texto con TLF .

  2. Cree uno o varios contenedores de objetos de visualización vinculados para el texto. Para obtener más información, consulte Administración de contenedores de texto con TLF .

  3. Asocie el texto en las estructuras de datos con los contenedores y establezca las opciones de edición y desplazamiento. Para obtener más información, consulte Activación de las operaciones para deshacer, editar y selección de texto con TLF .

  4. Cree un controlador de eventos para volver a transmitir el texto como respuesta a los eventos de cambio de tamaño (resize) (u otros). Para obtener más información, consulte Control de eventos con TLF .

Ejemplo de Text Layout Framework: News Layout

En el siguiente ejemplo se muestra el uso de TLF para diseñar una sencilla página de periódico. La página incluye un titular grande, un subtí­tulo y una sección de cuerpo de varias columnas:

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 clase TLFNewsLayout utiliza dos contenedores de texto. Un contenedor muestra un titular y subtítulo y el otro muestra el texto de cuerpo de tres columnas. Para que resulte más fácil, el texto se codifica en el ejemplo como texto de marcado TLF. La variable headlineMarkup contiene el titular y el subtítulo y la variable bodyMarkup incluye el texto principal. Para obtener más información sobre TLF Markup, consulte Estructuración del texto con TLF .

Tras la inicialización, la función onAddedToStage() importa el texto del titular en un objeto TextFlow, que es la estructura de datos principal de TLF:
hTextFlow = TextConverter.importToFlow(headlineMarkup, TextConverter.TEXT_LAYOUT_FORMAT); 
A continuación, se crea un objeto Sprite para el contenedor y un controlador se crea y se asocia con el contenedor:
headContainer = new Sprite(); 
headlineController = new ContainerController(headContainer);
El controlador se inicializa para establecer el formato, el desplazamiento y otras opciones. El controlador contiene geometría que define los límites del contenedor al que se transmite el texto. Un objeto TextLayoutFormat contiene la opciones de formato:
hContainerFormat = new TextLayoutFormat();

El controlador se asigna al compositor de flujo y la función añade el contenedor a la lista de visualización. La visualización y composición real de los contenedores se difiere al método resizeHandler() . La misma secuencia de pasos se lleva a cabo para inicializar el objeto TextFlow del cuerpo.

El método resizeHandler() mide el espacio disponible para procesar los contenedores y calculan su tamaño en consecuencia. Una llamada inicial al método compose() permite el cálculo de la altura adecuada del contenedor del titular. El método resizeHandler() puede situar y mostrar el contenedor del titular con el método updateAllControllers() . Finalmente, el método resizeHandler() utiliza el amaño del contenedor del titular para determinar la ubicación del contenedor del texto principal.

Estructuración del texto con TLF

TLF utiliza un árbol jerárquico para representar texto. Cada nodo del árbol es una instancia de la clase definida en el paquete de elementos. Por ejemplo, el nodo raíz del árbol siempre es una instancia de la clase TextFlow. La clase TextFlow representa una historia completa del texto. Una historia es una colección de texto y otros elementos que se tratan como una unidad o flujo. Una sola historia puede necesitar varias columnas o contenedores de texto para mostrar.

Aparte del nodo raíz, los elementos restantes se basan en parte en elementos XHTML. El siguiente diagrama muestra la jerarquía del marco:

Jerarquía de TextFlow

Marcado de Text Layout Framework

EL conocimiento de la estructura de TLF también resulta útil a la hora de tratar con el marcado de Text Layout Framework. El marcado de TLF es una representación XML del texto que forma parte de TLF. Aunque la arquitectura también admite otros formatos XML, el marcado es único, ya que se basa específicamente en la estructura de la jerarquía de TextFlow. Si opta por exportar XML desde TextFlow utilizando este formato de marcado, XML se exportará con esta jerarquía intacta.

TLF Markup proporciona la representación de texto de más alta fidelidad en una jerarquía de TextFlow. El lenguaje de marcado proporciona etiquetas para cada uno de los elementos básicos de la jerarquía de TextFlow y también ofrece atributos para todas las propiedades de formato disponibles en la clase TextLayoutFormat.

La siguiente tabla contiene las etiquetas que se pueden utilizar en marcado TLF.

Elemento

Descripción

Elementos secundarios

Clase

textflow

Elemento raíz del marcado.

div, p

TextFlow

div

División en un elemento TextFlow. Puede contener un grupo de párrafos.

div, list, p

DivElement

p

Párrafo.

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

ParagraphElement

a

Vínculo.

tcy, span, img, tab, br, g

LinkElement

tcy

Extensión de texto horizontal (utilizada en un elemento TextFlow vertical).

a, span, img, tab, br, g

TCYElement

span

Extensión de texto en un párrafo.

SpanElement

img

Imagen de un párrafo.

InlineGraphicElement

tab

Carácter de tabulación

TabElement

BR

Carácter de salto. Utilizado para finalizar una línea de un párrafo; el texto continuará en la siguiente línea, pero permanece en el mismo párrafo.

BreakElement

linkNormalFormat

Define los atributos de formato utilizados por los vínculos de estado normal.

TextLayoutFormat

TextLayoutFormat

linkActiveFormat

Define los atributos de formato utilizados para los vínculos de estado activo, cuando el ratón está presionado sobre un vínculo.

TextLayoutFormat

TextLayoutFormat

linkHoverFormat

Define los atributos de formato utilizados para los vínculos al pasar por encima con el ratón, cuando este se encuentra dentro de los límites (desplazamiento sobre) un vínculo.

TextLayoutFormat

TextLayoutFormat

li

Elemento de lista. Debe estar dentro de un elemento de lista.

div, li, list, p

ListItemElement

list

Una lista. Las listas se pueden anidar o situar de forma adyacente entre sí. Los distintos esquemas de numeración o etiquetado se pueden aplicar a los elementos de lista.

div, li, list, p

ListElement

v

Elemento de grupo. Se utiliza para agrupar elementos en un párrafo. Permite anidar elementos bajo el nivel de párrafo.

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

SubParagraphGroupElement

Uso de listas numeradas y con viñetas

Las clases ListElement y ListItemElement pueden utilizarse para añadir listas con viñetas a los controles de texto. Las listas con viñetas se pueden anidar y personalizar para que utilicen viñetas distintas (o marcadores) y numeración automática, así como numeración con estilo.

Para crear listas en los flujos de texto, utilice la etiqueta <list> . Posteriormente se utilizan las etiquetas <li> en la etiqueta <list> para cada elemento de la lista. Es posible personalizar la apariencia de las viñetas mediante la clase ListMarkerFormat.

En el siguiente ejemplo se crean listas sencillas:
<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>
Las listas se pueden anidar en otras listas, tal y como se muestra en el ejemplo siguiente:
<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>
Para personalizar el tipo de marcador en la lista, utilice la propiedad listStyleType de ListElement. Esta propiedad puede ser cualquier valor definido por la clase ListStyleType (por ejemplo, check , circle , decimal y box ). En el siguiente ejemplo se crean listas con distintos tipos de marcador y un incremento del contador personalizado:
<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>

La clase ListMarkerFormat se emplea para definir el contador. Además de definir el incremento de un contador, también es posible personalizar el contador, restableciéndolo con la propiedad counterReset .

Se puede personalizar más el aspecto de los marcadores de las listas con el uso de las propiedades beforeContent y afterContent de ListMarkerFormat. Estas propiedades se aplican al contenido que aparece antes y después del contenido del marcador.

En el siguiente ejemplo se añade la cadena “XX” antes del marcador y “YY” después del mismo:
<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 propia propiedad content puede definir más las personalizaciones del formato del marcador En el siguiente ejemplo se muestra un marcador numeral Roman ordenado y en mayúsculas:
<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>

Tal y como se muestra en el ejemplo anterior, la propiedad content también puede insertar un sufijo: una cadena que aparece tras el marcador, pero antes de afterContent . Para insertar esta cadena al proporcionar contenido XML en el flujo, ajuste la cadena en las entradas HTML &quote; en lugar de comillas ( "< string >" ).

Uso del margen en TLF

Todos los objetos FlowElement admiten propiedades de margen que se utilizan para controlar la posición del área de contenido de cada elemento y el espacio entre las áreas de contenido.

La anchura total de un elemento es la suma de la anchura de su contenido, más las propiedades paddingLeft y paddingRight . La altura total de un elemento es la suma de la altura de su contenido, más las propiedades paddingTop y paddingBottom .

El margen es el espacio entre el borde y el contenido. Las propiedades de margen son paddingBottom , paddingTop , paddingLeft y paddingRight . Se puede aplicar margen al objeto TextFlow y a los siguientes elementos secundarios:
  • div

  • img

  • li

  • list

  • p

Las propiedades de margen no se pueden aplicar a los elementos de delimitación.

En el siguiente ejemplo se establecen las propiedades de margen en 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">

Los valores válidos para las propiedades de margen son un número (en píxeles), “auto” o “inherit”. El valor predeterminado es “auto”, lo que significa que se calcula automáticamente y se establece en 0, para todos los elementos excepto ListElement. Para ListElements, “auto” es 0 excepto en la parte de inicio de la lista donde se utiliza el valor de la propiedad listAutoPadding . El valor predeterminado de listAutoPadding es 40, lo que proporciona a las listas una sangría predeterminada.

Las propiedades de margen no se heredan de forma predeterminada. Los valores “auto” e “inherit” son constantes definidas por la clase FormatValue .

Las propiedades de margen pueden ser valores negativos.

Formato de texto con TLF

El paquete flashx.textLayout.formats contiene interfaces y clases que permiten asignar formatos a cualquier elemento FlowElement en el árbol de la jerarquía del flujo de texto. Existen dos formas de aplicar el formato de contenedor. Se puede asignar un formato específico de forma individual o asignar un grupo de formatos simultáneamente con un objeto de formato especial.

La interfaz ITextLayoutForma contiene todos los formatos que se pueden aplicar a FlowElement. Algunos formatos se aplican a todo el párrafo de texto, pero lógicamente no se aplican a caracteres individuales. Por ejemplo, formatos como la justificación y las tabulaciones se aplican a párrafos completos, pero no se aplican a caracteres individuales.

Asignación de formatos a un objeto FlowElement con propiedades

Es posible establecer formatos en cualquier elemento FlowElement mediante asignación de propiedades. La clase FlowElement implementa la interfaz ITextLayoutFormat, por lo que cualquier subclase de la clase FlowElement también debe implementar esta interfaz.

Por ejemplo, el siguiente código muestra cómo asignar formatos individuales a una instancia de ParagraphElement:

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

Asignación de formatos a un objeto FlowElement con la clase TextLayoutFormat

Puede aplicar formatos a un objeto FlowElement con la clase TextLayoutFormat. Puede utilizar esta clase para crear un objeto de formato especial que contenga todos los valores de formato que desee. Puede asignar ese objeto a la propiedad format de cualquier objeto TextFlow, DivElement o ContainerController. TextLayoutFormat y FlowElement implementan la interfaz ITextLayoutFormat. Esta disposición garantiza que ambas clases contengan las mismas propiedades de formato.

Para obtener más información, consulte la clase TextLayoutFormat en la Referencia de ActionScript 3.0 para la plataforma de Adobe Flash.

Herencia de formato

Los formatos se heredan mediante la jerarquía de flujo de texto. Si se asigna una instancia de TextLayoutFormat a una instancia de FlowElement con elementos secundarios, la arquitectura inicia un proceso denominado cascada . Durante una cascada, la arquitectura examina de forma sucesiva cada nodo de la jerarquía que hereda de FlowElement. Posteriormente determina si asignar los valores heredados a cada propiedad de formato. Durante la cascada se aplican las siguientes reglas:

  1. Los valores de propiedad se heredan únicamente de un ascendiente inmediato (denominado a veces elemento principal).

  2. Los valores de propiedad solo se heredan si una propiedad aún no tiene un valor (es decir, el valor es undefined )..

  3. Algunos atributos no heredan valores si son undefined, a no ser que el valor del atributo se establezca específicamente en “inherit” o como constante flashx.textLayout.formats.FormatValue.INHERIT .

Por ejemplo, si el valor fontSize es establece para un contenedor a nivel de TextFlow, la configuración aplica todos los contenedores en TextFlow. Es decir, los valores caen en cascada hacia abajo en la jerarquía del flujo de texto. No obstante, puede sustituir el valor de un contenedor determinado asignando un nuevo valor directamente al contenedor. Como contraejemplo, si se establece el valor backgroundColor en el nivel de TextFlow, los elementos secundarios de TextFlow no heredan ese valor. La propiedad backgroundColor no hereda de su elemento principal durante una cascada. Para omitir este comportamiento, establezca la propiedad marginLeft de cada elemento secundario en flashx.textLayout.formats.FormatValue.INHERIT ..

Para obtener más información, consulte la clase TextLayoutFormat en la Referencia de ActionScript 3.0 para la plataforma de Adobe Flash.

Importación y exportación de texto con TLF

La clase TextConverter del paquete flashx.textLayout.conversion.* permite importar texto y exportar texto desde TLF. Utilice esta clase si va a cargar texto en tiempo de ejecución en lugar de compilar el texto en el archivo SWF. Esta clase también se puede utilizar para exportar texto almacenado en una instancia de TextFlow en un objeto String o XML.

Tanto la importación como la exportación son procedimientos sencillos. Se llama al método export() o importToFlow() ; ambos forman parte de la clase TextFilter. Los dos métodos son estáticos, lo que significa que se llaman en la clase TextFilter en lugar de en una instancia de la clase TextFilter.

Las clases del paquete flashx.textLayout.conversion proporciona una flexibilidad considerable en la que el usuario opta por almacenar el texto. Por ejemplo, si el texto se almacena en una base de datos, se puede importar en la arquitectura para su visualización. Posteriormente se pueden utilizar las clases del paquete flashx.textLayout.edit para cambiar el texto y exportar de nuevo el texto modificado a la base de datos.

Para obtener más información, consulte la case flashx.textLayout.conversion en la Referencia de ActionScript 3.0 para la plataforma de Adobe Flash.

Administración de contenedores de texto con TLF

Una vez que el texto se almacena en las estructuras de datos de TLF, Flash Player puede mostrarlo. El texto que se almacena en la jerarquía de flujo se debe convertir a un formato que pueda mostrar Flash Player. TLF ofrece dos formas de crear objetos de visualización desde un flujo. El primer enfoque más sencillo resulta adecuado para mostrar texto estático. El segundo enfoque más complejo permite crear texto dinámico que se puede seleccionar y editar. En ambos casos, en última instancia el texto se convierte en instancias de la clase TextLine, que forma parte del nuevo paquete flash.text.engine.* de Flash Player 10.

Creación de texto estático

En el enfoque sencillo se utiliza la clase TextFlowTextLineFactory, que puede encontrarse en el paquete flashx.textLayout.factory . Más allá de su simplicidad, la ventaja de este enfoque radica en que presenta una menor superficie de memoria que el esquema de FlowComposer. Este enfoque se recomienda para texto estático que el usuario no necesita editar, seleccionar ni desplazar.

Para obtener más información, consulte la clase TextFlowTextLineFactory en la Referencia de ActionScript 3.0 para la plataforma de Adobe Flash.

Creación de contenedores y texto dinámico

Utilice un compositor de flujo si desea tener más control sobre la visualización del texto que el que proporciona TextFlowTextLineFactory. Por ejemplo, con un compositor de flujo, los usuarios pueden seleccionar y editar el texto. Para obtener más información, consulte Activación de las operaciones para deshacer, editar y selección de texto con TLF .

Un compositor de flujo es una instancia de la clase StandardFlowComposer en el paquete flashx.textLayout.compose . Un compositor de flujo administra la conversión de TextFlow en instancias de TextLine y también la ubicación de las instancias de TextLine en uno o varios contenedores.

Ver gráfico a tamaño completo
El objeto IFlowComposer dispone de varios ContainerControllers o de ninguno de ellos.

Todas las instancias de TextFlow disponen de un objeto correspondiente que implementa la interfaz IFlowComposer. A este objeto IFlowComposer se puede acceder mediante la propiedad TextFlow.flowComposer . Se puede llamar a métodos definidos mediante la interfaz IFlowComposer a través de esta propiedad. Estos métodos permiten asociar el texto con uno o varios contenedores y preparan el texto para su visualización en un contenedor.

Un contenedor es simplemente una instancia de la clase Sprite, que es una subclase de la clase DisplayObjectContainer. Ambas clases forman parte de la API de la lista de visualización de Flash Player. Un contenedor es una forma más avanzada del rectángulo de delimitación utilizado con la clase TextLineFactory. Al igual que sucede con el rectángulo de delimitación, un contenedor limita el área donde aparecerán las instancias de TextLine. A diferencia de un rectángulo de delimitación, un contenedor dispone de un objeto “controller” correspondiente. El controlador administra el desplazamiento, composición, vinculación, formato y control de eventos para un contenedor o conjunto de contenedores. Cada contenedor cuenta con un objeto controlador correspondiente que es una instancia de la clase ContainerController del paquete flashx.textLayout.container.

Para mostrar texto, cree un objeto controlador para administrar y asociarlo con el compositor de flujo. Una vez asociado el contenedor, debe componer el texto antes de que pueda visualizarse. Por lo tanto, los contenedores disponen de dos estados: composición y visualización. La composición del texto es el proceso de conversión del texto desde la jerarquía de flujo de texto en instancias de TextLine y el cálculo de la forma en que esas instancias se ajustan al contenedor. La visualización es el proceso de actualización de la lista de visualización de Flash Player.

Para obtener más información, consulte IFlowComposer , StandardFlowComposer y ContainerController en Referencia de ActionScript 3.0 para la plataforma de Adobe Flash.

Activación de las operaciones para deshacer, editar y selección de texto con TLF

La capacidad de seleccionar o editar texto se controla en el nivel de TextFlow. Todas las instancias de la clase TextFlow disponen de un administrador de interacción asociado. Se puede acceder al administrador de interacción del objeto TextFlow mediante la propiedad TextFlow.interactionManager del objeto. Para activar la selección, asigne una instancia de la clase SelectionManager a la propiedad interactionManager . Para activar tanto la selección como la edición, asigne una instancia de la clase EditManager en lugar de una instancia de la clase SelectionManager. Para habilitar las operaciones de deshacer, cree una instancia de la clase UndoManager e inclúyala como argumento al llamar al constructor para EditManager. La clase UndoManager permite mantener un historial de las actividades de edición más recientes del usuario y permite al usuario deshacer y rehacer ediciones específicas. Estas tres clases forman parte del paquete de edición.

Para obtener más información, consulte SelectionManager , EditManager y UndoManager en Referencia de ActionScript 3.0 para la plataforma de Adobe Flash.

Control de eventos con TLF

Los objetos TextFlow distribuyen eventos en diversas circunstancias, entre las que se incluyen:
  • Cuando el texto o el diseño cambian.

  • Antes de que comience una operación y una vez finalizada una operación.

  • Si cambia el estado de un objeto FlowElement.

  • Cuando se completa una operación de composición.

Para obtener más información, consulte la clase flashx.textLayout.events en la Referencia de ActionScript 3.0 para la plataforma de Adobe Flash.

Posicionamiento de imágenes en el texto

Para posicionar InlineGraphicElement en el texto, se utilizan las siguientes propiedades:
  • Propiedad float de la clase InlineGraphicElement.

  • Propiedad clearFloats de FlowElement .

La propiedad float controla la situación del gráfico y el texto de alrededor. La propiedad clearFloats controla la situación de los elementos del párrafo relativos a float .

Para controlar la ubicación de una imagen en un elemento de texto, se utiliza la propiedad float . En el siguiente ejemplo se añade una imagen a un párrafo y se alinea a la izquierda de modo que el texto se ajuste a la derecha:
<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>

Los valores válidos de la propiedad float son “left”, “right”, “start”, “end” y “none”. La clase Float define estas constantes. El valor predeterminado es “none”.

La propiedad clearFloats resulta útil cuando se desea ajustar la posición de inicio de los siguientes párrafos que normalmente se ajustan alrededor de la imagen. Por ejemplo, supongamos que se dispone de una imagen que es más grande que el primer párrafo. Para garantizar que el segundo párrafo comience tras la imagen, establezca la propiedad clearFloats .

En el siguiente ejemplo se utiliza una imagen que es más alta que el texto en el primer párrafo. Para que el segundo párrafo comience tras la imagen en el bloque de texto, en este ejemplo se establece la propiedad clearFloats en el segundo párrafo hasta “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>

Los valores válidos de la propiedad clearFloats son “left”, “right”, “end”, “start”, “none”, y “both”. La clase ClearFloats define estas constantes. También se puede definir la propiedad clearFloats como “inherit”, que es una constante definida por la clase FormatValue . El valor predeterminado es “none”.