使用 Text Layout Framework

Flash Player 10 和更高版本,Adobe AIR 1.5 和更高版本

Text Layout Framework 概述

Text Layout Framework (TLF) 是一种可扩展的 ActionScript 库。TLF 是在 Adobe® Flash® Player 10 和 Adobe® AIR® 1.5 中的文本引擎基础上构建而成的。TLF 提供的高级排版和文本布局功能可以实现新颖的 Web 排版创意。该框架可与 Adobe® Flex® 或 Adobe® Flash® Professional 一起使用。开发人员可以使用或扩展现有组件,也可以使用该框架创建自己的文本组件。

TLF 包含以下功能:
  • 双向文本、垂直文本以及 30 多种写作文种,包括阿拉伯文、希伯来文、中文、日文、韩文、泰文、老挝文、越南文和其他文种

  • 跨多个列和链接容器选择、编辑和流动文本

  • 垂直文本、直排内横排(在垂直文本内显示水平文本)以及在东亚排版规则中对齐文本

  • 丰富的排版控件,包括字距微调、连字、印刷大小写、数字大小写、数字宽度和自由连字符

  • 剪切、复制、粘贴、撤消以及标准的键盘和鼠标编辑手势

  • 丰富的开发人员 API,用于操纵文本内容、布局、和标记以及创建自定文本组件

  • 强大的列表支持,包括自定义标记和编号格式

  • 内嵌图像和定位规则

TLF 是在 Flash Player 10 中引入的 Flash 文本引擎 (FTE) 基础上构建的一种 ActionScript 3.0 库。可以通过 flash.text.engine 包访问 FTE,该包是 Flash Player 10 应用程序编程接口 (API) 的一部分。

但是,Flash Player API 提供了对文本引擎的低级别访问,这意味着为了执行某些任务可能需要使用的代码相对比较多。TLF 将底层代码封装到更简单的 API 中。TLF 还提供了一种概念体系结构,可以将 FTE 定义的基础构建块组织成易于使用的系统。

与 FTE 不同,TLF 并未内置在 Flash Player 中,而是完全用 ActionScript 3.0 编写的一个独立组件库。由于此框架可扩展,因此可针对特定环境对其进行自定义。Flash Professional 和 Flex SDK 都包括基于 TLF 框架的组件。

复杂文种支持

TLF 提供了复杂文种支持。复杂文种支持包括显示和编辑从右至左文种的功能。TLF 还提供了显示和编辑从左至右和从右至左混合文种(如阿拉伯文和希伯来文)的功能。此框架不仅支持适用于中文、日文和韩文的垂直文本布局,而且还支持直排内横排(TCY 元素)。TCY 元素是嵌入到垂直文本串的水平文本块。支持以下文种:

  • 拉丁文(英文、西班牙文、法文、越南文等)

  • 希腊文、西里尔文、亚美尼亚文、格鲁吉亚文和埃塞俄比亚文

  • 阿拉伯文和希伯来文

  • 汉字象形和假名(中文、日文和韩文)及 Hangul Johab(韩文)

  • 泰文、老挝文和高棉文

  • 梵文、孟加拉文、果鲁穆奇文、马拉雅拉姆文、泰卢固文、泰米尔文、古吉特拉文、奥里雅文、卡纳达文和藏文

  • 提非纳文、彝文、切罗基文、加拿大音节、德塞莱特文、萧伯纳字母、瓦伊文、塔加路文、哈努诺文、布迪文和塔格巴努亚文

在 Flash Professional 和 Flex 中使用 Text Layout Framework

在 Flash 中,您可以直接使用 TLF 类创建自定义组件。此外,Flash Professional CS5 还提供了一个新的 fl.text.TLFTextField 类,该类封装了 TLF 功能。使用 TLFTextField 类可在 ActionScript 中创建使用 TLF 的高级文本显示功能的文本字段。以与使用 TextField 类创建文本字段相同的方式创建 TLFTextField 对象。然后,使用 textFlow 属性从 TLF 类分配高级格式设置。

利用文本工具,还可以使用 Flash Professional 在舞台上创建 TLFTextField 实例。然后,可以使用 ActionScript 通过 TLF 类控制文本字段内容的格式和布局。有关更多信息,请参阅《用于 Adobe Flash Platform 的 ActionScript 3.0 参考》中的 TLFTextField

在 Flex 中工作时,请使用 TLF 类。有关更多信息,请参阅 使用 Text Layout Framework

使用 Text Layout Framework

在 Flex 中工作时或在构建自定义文本组件时,请使用 TLF 类。TLF 是一种 ActionScript 3.0 库,它完全包含在 textLayout.swc 库中。TLF 库包含约 100 个 ActionScript 3.0 类和接口,这些类和接口被组织到 10 个包中。这些包是 flashx.textLayout 包的子包。

Text Layout Framework 类

TLF 类划分为三种类别:
  • 数据结构和格式设置类

  • 呈现类

  • 用户交互类

数据结构和格式设置类

TLF 的主要数据结构为文本流层次结构,在元素包中定义。在该结构中,可以使用格式包为文本串指定样式和属性,也可以使用转换包控制在数据结构中如何导入和导出文本。

呈现类

下列包包含 TLF 的呈现类: 利用这些包中的类,可以方便地呈现文本以便在 Flash Player 中显示。工厂包提供显示静态文本的简便方式。容器包中的类和接口用于定义动态文本的显示容器。组合包定义在容器中放置和显示动态文本的技术。

用户交互类

下列包包含 TLF 的用户交互类: 编辑包和操作包定义了一些类,使用这些类可编辑在数据结构中存储的文本。事件包中包含事件处理类。

使用 Text Layout Framework 创建文本的常规步骤

下列步骤介绍了创建带有文本布局格式的文本的常规过程:

  1. 将带格式文本导入到 TLF 数据结构中。有关更多信息,请参阅 使用 TLF 构建文本结构 使用 TLF 设置文本格式

  2. 为文本创建一个或多个链接的显示对象容器。有关更多信息,请参阅 使用 TLF 管理文本容器

  3. 将数据结构中的文本与容器关联并设置编辑和滚动选项。有关更多信息,请参阅 使用 TLF 启用文本选择、编辑和撤消

  4. 在响应 resize(或其他)事件时,创建事件处理函数以重排文本。有关更多信息,请参阅 使用 TLF 处理事件

Text Layout Framework 示例:新闻版面布局

以下示例演示了如何使用 TLF 设置简单的新闻页面的布局。该页包含大标题、副标题和包含多列的正文部分:

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

TLFNewsLayout 类使用两个文本容器。一个容器显示大标题和副标题,另一个容器显示包含三列的正文文本。为简洁起见,文本作为 TLF 标记文本硬编码到示例中。 headlineMarkup 变量包含标题和副标题, bodyMarkup 变量包含正文文本。有关 TLF 标记的更多信息,请参阅 使用 TLF 构建文本结构

在完成一些初始化操作之后, onAddedToStage() 函数将大标题文本导入到 TextFlow 对象中,该对象是 TLF 的主要数据结构:
hTextFlow = TextConverter.importToFlow(headlineMarkup, TextConverter.TEXT_LAYOUT_FORMAT); 
接下来,为容器创建 Sprite 对象,然后为容器创建控制器并将该控制器与容器相关联:
headContainer = new Sprite(); 
headlineController = new ContainerController(headContainer);
初始化控制器以设置格式、滚动和其他选项。控制器包含相关的几何尺寸设置,用于定义文本流入的容器的边界。TextLayoutFormat 对象包含格式选项:
hContainerFormat = new TextLayoutFormat();

控制器分配给了流合成器,该函数将容器添加到显示列表。容器的实际构成和显示会延迟到 resizeHandler() 方法。按相同顺序执行相关步骤以初始化正文的 TextFlow 对象。

resizeHandler() 方法测量可供呈现容器用的空间并相应地设置容器大小。首先,调用 compose() 方法,以便计算标题容器的合适高度。随后, resizeHandler() 方法可以使用 updateAllControllers() 方法添加和显示标题容器。最后, resizeHandler() 方法使用标题容器的大小确定正文文本容器的位置。

使用 TLF 构建文本结构

TLF 使用层次树来表示文本。树中的每个节点都是元素包中定义的类的实例。例如,树的根节点始终是 TextFlow 类的实例。TextFlow 类表示整个文本素材。文章是文本和其他元素的集合,可将其视为一个单元或流。一篇文章可能需要使用多个列或文本容器进行显示。

除了根节点,其余元素大致基于 XHTML 元素。下图显示了该框架的层次结构:

TextFlow 层次结构

Text Layout Framework 标记

了解 TLF 的结构在处理 TLF 标记时也很有用。TLF 标记是文本的 XML 表示形式,作为 TLF 一部分包含在其中。虽然该框架也支持其他 XML 格式,但 TLF 标记是唯一专门基于 TextFlow 层次结构的一种格式。如果您使用此标记格式从 TextFlow 导出 XML,则导出 XML 时会保持此层次结构的完整性。

TLF 标记为 TextFlow 层次结构中的文本提供了最高保真度的表示形式。标记语言为 TextFlow 层次结构的每个基本元素提供标签,并为 TextLayoutFormat 类中的所有可用格式设置属性提供特性。

下表包含可以在 TLF 标记中使用的标签。

元素

说明

子代

textflow

标记的根元素。

div、p

TextFlow

div

TextFlow 内的分割块。可以包含一组段落。

div、list、p

DivElement

p

段落。

a、tcy、span、img、tab、br、g

ParagraphElement

a

链接。

tcy、span、img、tab、br、g

LinkElement

tcy

水平文本串(用于垂直 TextFlow 中)。

a、span、img、tab、br、g

TCYElement

span

段落内的文本串。

SpanElement

img

段落中的图像。

InlineGraphicElement

tab

制表符字符。

TabElement

br

分隔符。用于在段落内结束一行;文本在下一行中继续,仍位于同一段落中。

BreakElement

linkNormalFormat

定义用于处于正常状态的链接的格式属性。

TextLayoutFormat

TextLayoutFormat

linkActiveFormat

在链接上按下鼠标时,定义用于处于活动状态的链接的格式属性。

TextLayoutFormat

TextLayoutFormat

linkHoverFormat

当鼠标位于链接边界内时(滚过),定义用于处于悬停状态的链接的格式属性。

TextLayoutFormat

TextLayoutFormat

li

一个列表项目元素。必须位于一个列表元素内。

div、li、list、p

ListItemElement

list

一个列表。列表可以嵌套,或者放置得距离彼此很近。列表项目可以应用不同的标签或编号方案。

div、li、list、p

ListElement

g

组元素。用于对段落中的元素进行分组。允许您在段落级别以下嵌套元素。

a、tcy、span、img、tab、br、g

SubParagraphGroupElement

使用编号列表和项目列表

可以使用 ListElement ListItemElement 类将项目列表添加到文本控件。可以嵌套项目列表,也可以对其进行自定义以使用不同的项目符号(或标记)和自动编号以及轮廓样式编号。

若要在文本流中创建列表,请使用 <list> 标签。然后,对于列表中的每个列表项,您可以在 <list> 标签内使用 <li> 标签。可以使用 ListMarkerFormat 类自定义项目符号的外观。

下面的示例会创建简单的列表:
<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>
您可以在其他列表中嵌套列表,如下面的示例所示:
<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>
若要自定义列表中标记的类型,请使用 ListElement 的 listStyleType 属性。此属性可以是 ListStyleType 类定义的任意值(如 check circle decimal box )。下面的示例使用多种标记类型和一个自定义计数器增量创建列表:
<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>

使用 ListMarkerFormat 类可以定义计数器。除了定义计数器的增量,您还可以利用 counterReset 属性重新设置计数器,从而对其进行自定义。

可以使用 ListMarkerFormat 的 beforeContent afterContent 属性对列表中标记的外观进行进一步自定义。这些属性会应用到显示在标记内容之前和之后的内容。

下面的示例会在标记之前添加字符串“XX”,在标记之后添加字符串“YY”:
<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>
content 属性本身可以定义标记格式的更多自定义内容。下面的示例会显示一个有序的、大写 Roman 数字标记:
<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>

如上个示例所示, content 属性还可以插入一个后缀:一个在标记后、但在 afterContent 之前显示的字符串。若要在向流提供 XML 内容时插入此字符串,请使用 &quote; HTML 实体而不是引号 ( "< string >" ) 来包括此字符串。

在 TLF 中使用填充

每个 FlowElement 支持您使用的填充属性,来控制每个元素的内容区域的位置以及内容区域之间的间距。

某个元素的总宽度是其内容宽度的总和加上 paddingLeft paddingRight 属性。某个元素的总高度是其内容高度的总和加上 paddingTop paddingBottom 属性。

填充是指边框和内容之间的间距。填充属性包括有 paddingBottom paddingTop paddingLeft paddingRight 。可以将填充应用于 TextFlow 对象和以下子元素:
  • div

  • img

  • li

  • list

  • p

填充属性不能应用到范围元素。

下面的示例将设置 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">

填充属性的有效值包括数值(以像素为单位)、“auto”或“inherit”。默认值为“auto”,表示该值是自动计算得出,对所有元素均设置为 0,ListElement 除外。对于 ListElements,“auto”为 0,使用 listAutoPadding 属性的值所在列表的起始侧除外。 listAutoPadding 的默认值为 40,这是为列表指定的默认缩进。

默认情况下,填充属性不会继承。“auto”和“inherit”值是由 FormatValue 类定义的常数。

填充属性可以为负值。

使用 TLF 设置文本格式

flashx.textLayout.formats 包中包含一些接口和类,使用这些接口和类,您可以为文本流层次树中的任何 FlowElement 指定格式。可通过两种方式应用格式设置。您可以分别指定某特定格式,也可以利用特殊格式设置对象同时指定一组格式。

ITextLayoutFormat 接口包含可以应用于 FlowElement 的所有格式。有些格式应用于文本的某一完整容器或段落,但不会在逻辑上应用于各个字符。例如,字距调整和制表符这样的格式应用于全部段落,但不应用于各个字符。

使用属性为 FlowElement 指定格式

您可以通过属性分配对任何 FlowElement 设置格式。FlowElement 类实现 ITextLayoutFormat 接口,因此 FlowElement 类的任一子类也必须实现该接口。

例如,以下代码显示如何为 ParagraphElement 实例指定单种格式:

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

使用 TextLayoutFormat 类为 FlowElement 指定格式

您可以使用 TextLayoutFormat 类向 FlowElement 应用格式。可使用此类创建包含所需的所有格式设置值的特定格式设置对象。然后,将该对象指定给任何 FlowElement 对象的 format 属性。TextLayoutFormat 和 FlowElement 都实现 ITextLayoutFormat 接口。这种安排确保两个类都包含同样的格式属性。

有关更多信息,请参阅《用于 Adobe Flash Platform 的 ActionScript 3.0 参考》中的 TextLayoutFormat

格式继承

通过文本流层次结构继承格式。如果将 TextLayoutFormat 的实例指定给带有子代的 FlowElement 实例,框架将启动一个称为 级联 的过程。在级联过程中,框架递归检查从您的 FlowElement 继承的层次中的每个节点。然后,它确定是否将继承的值指定给各格式设置属性。在级联过程中应用下列规则:

  1. 属性值只从直接祖先(有时称为父代)继承。

  2. 仅当属性尚未设置值(即该值为 undefined )时,才继承属性值。

  3. 一些属性在未定义时不继承值,除非将属性的值设置为“继承”或常量 flashx.textLayout.formats.FormatValue.INHERIT

例如,如果在 TextFlow 级别设置 fontSize 值,则该设置将应用于 TextFlow 中的所有元素。换句话说,这些值按照文本流层次向下级联。不过,您可以通过直接对给定元素指定新值来覆盖该元素中的值。举个反例,如果您在 TextFlow 级别设置 backgroundColor 值,TextFlow 的子项不继承该值。 backgroundColor 属性不是级联期间从其父项继承的。通过将每一子项中的 backgroundColor 属性设置为 flashx.textLayout.formats.FormatValue.INHERIT ,可以覆盖此行为.

有关更多信息,请参阅《用于 Adobe Flash Platform 的 ActionScript 3.0 参考》中的 TextLayoutFormat

使用 TLF 导入和导出文本

flashx.textLayout.conversion 中的 TextConverter 类。* 包允许您将文本导入到 TLF 以及从 TLF 导出文本。如果打算在运行时加载文本,而不是将文本编译到 SWF 文件中,请使用此类。您也可以使用此类将存储在 TextFlow 实例中的文本导出到一个字符串或 XML 对象。

导入和导出过程都直接完成。可以调用 export() 方法或 importToFlow() 方法,这两个方法都属于 TextConverter 类。这两个方法都是静态方法,意味着您对 TextConverter 类调用这两个方法,而非对 TextConverter 类的实例调用它们。

flashx.textLayout.conversion 包中的类在选择文本存储位置方面提供了极大的灵活性。例如,如果将文本存储在数据库中,您可以将文本导入该框架中以供显示。然后,可以使用 flashx.textLayout.edit 包中的类更改文本,并将更改后的文本导回到数据库中。

有关更多信息,请参阅《用于 Adobe Flash Platform 的 ActionScript 3.0 参考》中的 flashx.textLayout.conversion

使用 TLF 管理文本容器

将文本存储在 TLF 数据结构中后,Flash Player 可以显示这些文本。必须将流层次结构中存储的文本转换为 Flash Player 可以显示的格式。TLF 提供了两种从流中创建显示对象的方法。第一种方法较为简单,适用于显示静态文本。第二种方法较为复杂,允许您创建可进行选择和编辑的动态文本。使用这两种方法,文本最终都会转换为 TextLine 类的实例,TextLine 类保存在 Flash Player 10 中的 flash.text.engine.* 包中。

创建静态文本

此简单方法使用 TextFlowTextLineFactory 类,该类位于 flashx.textLayout.factory 包中。此方法不仅简单,比 FlowComposer 方法占用的内存也少。建议对不需要用户编辑、选择或滚动的静态文本使用此方法。

有关更多信息,请参阅《用于 Adobe Flash Platform 的 ActionScript 3.0 参考》中的 TextFlowTextLineFactory

创建动态文本和容器

如果您要加大对文本显示的控制程度(而不是由 TextFlowTextLineFactory 提供的控制程度),请使用流合成器。例如,使用流合成器,用户可以选择和编辑文本。有关更多信息,请参阅 使用 TLF 启用文本选择、编辑和撤消

流合成器是 flashx.textLayout.compose 包中的 StandardFlowComposer 类的实例。流合成器管理 TextFlow 到 TextLine 实例的转换,并负责将这些 TextLine 实例放置到一个或多个容器中。

查看完全大小图形
IFlowComposer 包含零个或更多 ContainerController

每个 TextFlow 实例都有一个可实现 IFlowComposer 接口的相应对象。可以通过 TextFlow.flowComposer 属性访问此 IFlowComposer 对象。可以通过此属性调用 IFlowComposer 接口定义的方法。使用这些方法,可以将文本与一个或多个容器关联并准备好要在容器中显示的文本。

容器是 Sprite 类(该类是 DisplayObjectContainer 类的子类)的实例。这两个类都包含在 Flash Player 显示列表 API 中。容器是定界矩形的更高级形式,与 TextLineFactory 类一起使用。与定界矩形类似,容器定义显示 TextLine 实例的区域。与定界矩形不同,容器具有对应的“控制器”对象。控制器管理一个容器或一组容器的滚动、合成、格式设置和事件处理。每个容器有一个对应的控制器对象,该对象是 flashx.textLayout.container 包中 ContainerController 类的实例。

若要显示文本,请创建一个控制器对象来管理该容器,并将其与流合成器关联。关联容器之后,编写文本以使文本能显示出来。相应地,容器有两种状态:编写和显示。编写是将文本流层次中的文本转换为 TextLine 实例并计算这些实例是否适合容器的过程。显示是更新 Flash Player 显示列表的过程。

有关更多信息,请参阅《用于 Adobe Flash Platform 的 ActionScript 3.0 参考》中的 IFlowComposer StandardFlowComposer ContainerController

使用 TLF 启用文本选择、编辑和撤消

在文本流级别控制选择或编辑文本的能力。TextFlow 类的每个实例都有一个关联的交互管理器。可通过对象的 TextFlow.interactionManager 属性访问 TextFlow 对象的交互管理器。要启用文本选择功能,可将 SelectionManager 类的实例指定给 interactionManager 属性。要启用文本选择和编辑功能,可指定 EditManager 类的实例,而不是指定 SelectionManager 类的实例。要启用撤消操作,可创建 UndoManager 类的一个实例,并将其纳为调用 EditManager 的构造函数时的参数。UndoManager 类维护用户最新编辑活动的历史记录,并允许用户撤消或重做特定的编辑操作。上述所有三个类都包含在编辑包中。

有关更多信息,请参阅《用于 Adobe Flash Platform 的 ActionScript 3.0 参考》中的 SelectionManager EditManager UndoManager

使用 TLF 处理事件

在许多情况下,TextFlow 对象都会调度事件,包括:
  • 当文本或布局发生更改时

  • 在操作开始之前或操作完成之后

  • 当 FlowElement 对象的状态发生更改时

  • 当合成操作完成时

有关更多信息,请参阅《用于 Adobe Flash Platform 的 ActionScript 3.0 参考》中的 flashx.textLayout.events

在文本内定位图像

若要在文本内定位 InlineGraphicElement ,您可以使用以下属性:
  • InlineGraphicElement 类的 float 属性

  • FlowElement clearFloats 属性

float 属性控制着图形及其周围文本的放置。 clearFloats 属性控制着段落元素相对于 float 的放置。

要控制文本元素内某个图像的位置,可以使用 float 属性。下面的示例向段落中添加一个图像,并将其与左侧对齐,从而使文本在右侧自动换行:
<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>

float 属性的有效值包括:“left”、“right”、“start”、“end”和“none”。Float 类定义了这些常数。默认值为“none”。

要为那些通常环绕在图像周围的后续段落调整起始位置, clearFloats 属性很有用。例如,假设您有一个图像,其尺寸大于第一个段落。要确保第二个段落起始于该图像 后面 ,请设置 clearFloats 属性。

下面的示例使用的图像高于第一个段落中的文本。为使第二个段落起始于文本区块中的图像之后,此示例将第二个段落的 clearFloats 属性设置为“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>

clearFloats 属性的有效值包括:“left”、“right”、“end”、“start”、“none”和“both”。 ClearFloats 类定义这些常数。您还可以将 clearFloats 属性设置为“inherit”,这是一个由 FormatValue 类定义的常数。默认值为“none”。