Использование 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 предоставляет расширенные оформления и размещения текста для разработки инновационных веб-решений. Среда может быть использована в Adobe® Flex® или Adobe® Flash® Professional. Разработчики могут пользоваться существующими компонентами или расширять их, а также создавать собственные текстовые компоненты в среде.

TLF предоставляет следующие возможности:
  • Двунаправленный текст, текст по вертикали и более 30 систем письма, включая арабскую, иврит, китайскую, японскую, корейскую, тайскую, лаосскую, вьетнамскую и другие.

  • Выделение, редактирование и расположение текста в нескольких столбцах и связанных контейнерах.

  • Текст по вертикали, элементы Tate-Chu-Yoko (текст по горизонтали и вертикали) и выравнивание для восточноазиатского оформления.

  • Широкий набор функций управления оформлением, включая кернинг, лигатуры, типографский регистр, цифровой регистр, цифровая ширина и возможные переносы.

  • Вырезание, копирование, вставка, отмена и стандартные жесты мышью и комбинации клавиш для редактирования.

  • Многофункциональный API-интерфейс разработчика для манипуляции текстовым содержимым, расположением и разметкой, а также для создания текстовых компонентов.

  • Поддержка списков, включая пользовательские маркеры и форматы нумерации

  • Встроенные изображения и правила позиционирования

TLF — это библиотека ActionScript 3.0, созданная на основе механизма обработки текста Flash Text Engine (FTE), представленного в инструменте Flash Player 10. Можно получить доступ к FTE с помощью пакета flash.text.engine, являющегося компонентом прикладного программного интерфейса (Application Programming Interface, API) Flash Player 10.

Однако доступ к этому механизму обработки текста, предоставляемый API-интерфейсом Flash Player, осуществляется на низком уровне. Это означает, что для выполнения некоторых задач требуется написание большого кода. Среда TLF добавляет код нижнего уровня в более простые API-интерфейсы. TLF также предоставляет концептуальную архитектуру, которая организует базовые структурные блоки, определенные в FTE, в более простую для использования систему.

В отличие от FTE, компонент TLF не встроен в приложение Flash Player. Он представляет собой независимую библиотеку компонентов, полностью созданную на основе кода ActionScript 3.0. Поскольку среда может расширяться, его можно настроить для определенных сред. Инструменты Flash Professional и Flex SDK включают компоненты, созданные на основе среды TLF.

Поддержка сложного письма

TLF предоставляет поддержку сложного письма. Поддержка сложного письма включает возможность отображения и редактирования текста с направлением письма справа налево. TLF также позволяет отображать и редактировать текст с комбинированным направлением письма слева направо и справа налево, например арабский и иврит. Среда не только поддерживает вертикальное размещение текста для китайского, японского и корейского языков, но также поддерживает элементы tate-chu-yoko (TCY). Элементы TCY являются блоками горизонтального текста, встроенного в вертикальные строки текста. Поддерживаются следующие системы письма и языки:

  • латинский (английский, испанский, французский, вьетнамский и так далее);

  • греческий, кириллица, армянский, грузинский и эфиопский;

  • арабский и иврит;

  • иероглифы и кана (китайский, японский и корейский языки), хангыль, джохаб (корейский язык);

  • тайский, лаосский и кхмерский;

  • девангари, бенгальский, гурмухи, малаялам, телугу, тамильский, гуджарати, ория, каннада и тибетский;

  • тифинаг, ий, чероки, канадское слоговое письмо, дезерет, шавиан, ваи, тагальский, хануну, бухид и тагбанва.

Использование Text Layout Framework в среде Flash Professional и Flex

С помощью классов TLF можно создавать пользовательские компоненты непосредственно в среде Flash. Кроме того, в Flash Professional CS5 представлен новый класс fl.text.TLFTextField, добавляющий функциональность TLF. Класс TLFTextField служит для создания текстовых полей в ActionScript, которые используют расширенные возможности отображения TLF. Создайте объект TLFTextField так же, как и текстовое поле класса TextField. Затем с помощью свойства textFlow назначьте расширенное форматирование из классов TLF.

Также можно использовать Flash Professional, чтобы создать экземпляр the TLFTextField в рабочей области с помощью текстового инструмента. Затем ActionScript можно использовать для управления форматированием и размещением содержимого текстовых полей с помощью классов TLF. Дополнительные сведения см. в описании класса TLFTextField в справочнике ActionScript 3.0 для платформы Adobe Flash Platform.

Если вы работаете в среде Flex, используйте классы TLF. Дополнительные сведения см. в разделе «Использование Text Layout Framework».

Использование Text Layout Framework

Если вы работаете в среде Flex или создаете пользовательские текстовые компоненты, используйте классы TLF. TLF — это библиотека ActionScript 3.0, включенная в библиотеку textLayout.swc. Библиотека TLF включает около 100 классов и интерфейсов ActionScript 3.0, сгруппированных в десять пакетов. Эти пакеты являются подпакетами пакета flashx.textLayout.

Классы Text Layout Framework

Классы TLF могут быть сгруппированы в три категории:
  • Структуры данных и классы форматирования

  • классы визуализации;

  • классы взаимодействия с пользователем.

Структуры данных и классы форматирования

Структуры данных и классы форматирования TLF включены в следующие пакеты:

Основная структура данных TLF — это иерархия потока текста, которая определена в пакете элементов. Внутри данной структуры можно присваивать стили и атрибуты последовательностям текста с пакетом форматов. С помощью пакета преобразования можно также управлять импортом текста в структуру данных и экспортом из нее.

Классы визуализации

Классы визуализации TLF включены в следующие пакеты: Классы из этих пакетов упрощают визуализацию текста при его отображении в проигрывателе Flash Player. Пакет фабрики предоставляет простой способ отображения статического текста. Пакет контейнера включает классы и интерфейсы, определяющие отображение для динамического текста. Пакет компоновки определяет способы размещения и отображения динамического текста в контейнерах.

Классы взаимодействия с пользователем

Классы TLF для взаимодействия с пользователем включены в следующие пакеты: Пакеты редактирования и операций определяют классы, которые можно использовать, чтобы разрешить редактирование текстов, сохраненных в структуры данных. Пакет событий содержит обрабатывающие события классы.

Общая процедура создания текста с помощью Text Layout Framework

Ниже предоставлено описание общей процедуры создания текста с использованием Text Layout Format.

  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 Markup см. разделе «Структурирование текста с использованием 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 Markup

Понимание структуры TLF также необходимо при работе с разметкой TLF Markup. Разметка TLF Markup является представлением XML текста, сохраненного в компоненте TLF. Несмотря на то, что среда поддерживает также другие форматы XML, уникальность разметки TLF Markup заключается в том, что она особым образом основана на структуре иерархии TextFlow. При экспорте XML из TextFlow с помощью этого формата разметки XML экспортируется с помощью данной иерархии в неизменном виде.

TLF Markup обеспечивает максимально точное представление текста в иерархии 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>
Для указания типа маркера в списке используйте свойство listStyleType класса ListElement. Это свойство может принимать любое значение, определяемое классом 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.

Внешний вид маркеров в списках можно дополнительно настроить с помощью свойств afterContent и beforeContent класса ListMarkerFormat. Эти свойства применяются к контенту, который отображается до и после маркера.

В примере ниже перед маркером добавляется строка «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 можно определить дополнительные параметры для формата маркера. В примере ниже отображается маркер в виде римской цифры в верхнем регистре.
<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-контента в поток, заключите её в HTML-кавычки &quote; вместо простых кавычек ("<строка >").

Использование отступов в TLF

Каждый FlowElement имеет свойства отступов, в помощью которых можно управлять положением каждой области контента элемента и пространством между областями контента.

Общая ширина элемента складывается из ширины его контента и значений свойств paddingLeft и paddingRight. Общая высота элемента складывается из высоты его контента и значений свойств paddingTop и paddingBottom.

Отступ — это пространство между границей и контентом. Свойства отступов: paddingBottom, paddingTop, paddingLeft и paddingRight. Заполнение может применяться к объекту TextFlow, а также к следующим дочерним элементам:
  • div

  • img

  • li

  • list

  • p

Свойства отступов нельзя применять к элементам «span».

В примере ниже устанавливаются свойства отступов для объекта 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";

Назначение форматов объекту FlowElement с помощью класса TextLayoutFormat

Форматы можно применить к объекту FlowElement с помощью класса TextLayoutFormat. Этот класс используется для создания специального объекта форматирования, содержащего все необходимые значения форматирования. Затем можно назначить этот объект свойству format объекта FlowElement. Классы TextLayoutFormat и FlowElement реализуют интерфейс ITextLayoutFormat. Такое упорядочение обеспечивает то, что оба класса содержат одинаковые свойства формата.

Дополнительные сведения см. в описании класса TextLayoutFormat в справочнике ActionScript 3.0 для платформы Adobe Flash Platform.

Наследование форматов

Форматы наследуются через иерархию потока текста. При назначении экземпляра TextLayoutFormat экземпляру FlowElement с дочерними элементами инфраструктура начинает процесс, называемый каскадом. В каскадном списке среда рекурсивно исследует каждый узел в иерархии, который наследуется от объекта FlowElement. Затем она определяет необходимость назначения унаследованных значений каждому свойству форматирования. В процессе каскада применяются следующие правила:

  1. Значения свойств наследуются только из непосредственного родительского элемента (иногда называемого родителем).

  2. Значения свойств наследуются только в том случае, если для свойства еще не задано значение (т. е. значением является undefined).

  3. Некоторые атрибуты не наследуют значения при статусе undefined, если для значения атрибута не задан параметр наследования или константа flashx.textLayout.formats.FormatValue.INHERIT.

Например, при установке значения fontSize на уровне TextFlow настройка применяется ко всем элементам в TextFlow. Другими словами, значения располагаются каскадом в иерархии потока текста. Однако можно переопределить значение в указанном элементе путем прямого назначения нового значения элементу. В качестве контрпримера: если задано значение backgroundColor на уровне TextFlow, дочерний элемент TextFlow не наследует это значение. Свойство backgroundColor является свойством, которое не наследуется от родительского элемента в каскадном представлении. Это поведение можно переопределить, установив для свойства backgroundColor каждого дочернего элемента значение flashx.textLayout.formats.FormatValue.INHERIT.

Дополнительные сведения см. в описании класса TextLayoutFormat в справочнике ActionScript 3.0 для платформы Adobe Flash Platform.

Импорт и экспорт текста с использованием TLF

Класс TextConverter в flashx.textLayout.conversion.* пакет позволяет импортировать и экспортировать текст в TLF. Воспользуйтесь этим классом, если планируете загрузить текст в среду выполнения вместо того, чтобы скомпилировать текст в SWF-файле. Этот класс можно также использовать для экспорта текста, хранящегося в экземпляре TextFlow, в объект String или XML.

Импорт и экспорт являются простыми процедурами. Можно вызвать метод export() или метод importToFlow(). Эти методы являются частью класса TextConverter. Оба метода являются статическими. Это означает, что предпочтительнее вызывать методы в классе TextConverter, а не в экземпляре класса TextConverter.

Классы в пакете flashx.textLayout.conversion позволяют свободно выбирать, где будет храниться текст. Например, при сохранении текста в базе данных можно импортировать текст в инфраструктуру для отображения. Затем с помощью классов в пакете flashx.textLayout.edit можно изменить текст и экспортировать измененный текст в базу данных.

Дополнительные сведения см. в описании класса flashx.textLayout.conversion в справочнике ActionScript 3.0 для платформы Adobe Flash Platform.

Управление контейнерами текста с использованием TLF

После того как текст будет сохранен в структуре данных TLF, проигрыватель Flash Player сможет отобразить его. Текст, сохраненный в иерархи потока, следует преобразовать в формат, отображаемый Flash Player. Среда TLF предоставляет два способа создания экранных объектов из потока. Первый более простой подход подходит для отображения статического текста. Второй более сложный подход позволяет создавать динамический текст, который можно выделять и редактировать. В обоих случаях в итоге текст преобразуется в экземпляры класса TextLine, являющегося компонентом пакета flash.text.engine.* в приложении Flash Player 10.

Создание статического текста

Для простого способа используется класс TextFlowTextLineFactory, который находится в пакете flashx.textLayout.factory. Преимущество этого способа по сравнению со способом FlowComposer, кроме его простоты, заключается также в меньшем влиянии на память. Этот способ рекомендуется использовать для статического текста, который не должен редактироваться, выбираться или прокручиваться пользователем.

Дополнительные сведения см. в описании класса TextFlowTextLineFactory в справочнике ActionScript 3.0 для платформы Adobe Flash Platform.

Создание динамического текста и контейнеров

Воспользуйтесь компоновщиком потока, если хотите контролировать отображение текста больше, чем с помощью класса TextFlowTextLineFactory. Например, с помощью компоновщика потока пользователи смогут выделять и редактировать текст. Дополнительные сведения см. в разделе «Включение выбора текста, редактирования и отмены с использованием TLF».

Компоновщик потока — это экземпляр класса StandardFlowComposer в пакете flashx.textLayout.compose. Компоновщик пакета управляет преобразованием экземпляров TextFlow в TextLine, а также размещением этих экземпляров TextLine в одном или нескольких контейнерах.

Полноразмерное изображение
IFlowComposer имеет ноль или более ContainerControllers

Каждый экземпляр TextFlow имеет соответствующий объект, реализующий интерфейс IFlowComposer. Доступ к этому объекту IFlowComposer осуществляется с помощью свойства TextFlow.flowComposer. Через это свойство можно вызывать методы, определенные интерфейсом IFlowComposer. Данные методы позволяют связывать текст с одним или несколькими контейнерами и подготавливать текст к отображению в контейнере.

Контейнер является экземпляром класса Sprite, который представляет собой подкласс класса DisplayObjectContainer. Оба эти класса являются компонентами API списка отображения Flash Player. Контейнер является более эффективной формой ограничивающего прямоугольника, используемого в классе TextLineFactory. Подобно ограничивающему прямоугольнику, контейнер задает область, в которой отображаются экземпляры TextLine. В отличие от ограничивающего прямоугольника для контейнера имеется соответствующий объект-контроллер. Контроллер управляет прокруткой, компоновкой, связыванием, форматированием и обработкой событий для контейнера или набора контейнеров. Каждый контейнер имеет соответствующий объект-контроллер, который является экземпляром класса ContainerController в пакете flashx.textLayout.container.

Чтобы отобразить текст, создайте объект-контроллер для управления контейнером и свяжите его с компоновщиком потока. После связывания контейнера скомпонуйте текст для его отображения. Таким образом, контейнеры имеют два состояния: компоновка и отображение. Компоновка — это процесс преобразования текста из иерархии потока текста в экземпляры TextLine и вычисления того, подходят ли эти экземпляры для размещения в контейнере. Отображение — это процесс обновления списка отображения Flash Player.

Дополнительные сведения см. в описании классов IFlowComposer, StandardFlowComposer и ContainerController в справочнике ActionScript 3.0 для платформы Adobe Flash Platform.

Включение выбора текста, редактирования и отмены с использованием TLF

Управление возможностью выбора или редактирования текста осуществляется на уровне потока текста. Каждый экземпляр класса TextFlow имеет соответствующий координатор взаимодействия. Доступ к координатору взаимодействия объекта TextFlow можно получить через свойство TextFlow.interactionManager объекта. Для включения выбора текста следует назначить экземпляр класса SelectionManager свойству interactionManager. Для включения и выбора, и редактирования текста следует назначить экземпляр класса EditManager вместо экземпляра класса SelectionManager. Для включения операций отмены создайте экземпляр класса UndoManager и добавьте его в качестве аргумента в вызов конструктора объекта EditManager. Класс UndoManager сохраняет историю последних действий пользователя по редактированию, а также позволяет отменить или выполнить повторно определенные действия редактирования. Все эти три класса являются компонентами пакета редактирования.

Дополнительные сведения см. в описании классов SelectionManager, EditManager и UndoManager в справочнике ActionScript 3.0 для платформы Adobe Flash Platform.

Обработка событий с использованием TLF

Объекты TextFlow отправляют события в различных ситуациях, включая:
  • изменение текста или макета;

  • перед началом операции и после выполнения операции;

  • при изменении состояния объекта FlowElement;

  • после завершения операции compose.

Дополнительные сведения см. в описании класса flashx.textLayout.events в справочнике ActionScript 3.0 для платформы Adobe Flash Platform.

Размещение изображений в тексте

Чтобы разместить объект InlineGraphicElement внутри текста, используйте следующие свойства:
  • Свойство float класса InlineGraphicElement

  • Свойство clearFloats класса FlowElement

Свойство 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».