Korzystanie z architektury Text Layout Framework
Flash Player 10 i nowsze wersje, Adobe AIR 1.5 i nowsze wersje
Omówienie architektury Text Layout Framework
Architektura TLF (Text Layout Framework) jest rozszerzalną biblioteką języka ActionScript. Architektura TLF jest oparta na mechanizmie obsługi tekstu zawartym w programie Adobe® Flash® Player 10 i środowisku Adobe® AIR® 1.5. Architektura TLF oferuje zaawansowane funkcje dotyczące typografii oraz układów tekstu, dzięki czemu pozwala na innowacyjne podejście do tekstu w Internecie. Można z niej korzystać podczas pracy w programie Adobe® Flex® lub Adobe® Flash® Professional. Programiści mogą korzystać z istniejących składników, rozszerzać te składniki lub w ramach platformy opracowywać własne składniki do obsługi tekstu.
Niektóre możliwości architektury TLF:
-
Obsługa tekstu dwukierunkowego, tekstu pionowego i ponad 30 skryptów pisania — dla języków takich jak arabski, hebrajski, chiński, japoński, koreański, tajski, laoski czy wietnamski
-
Zaznaczanie, edytowanie, i układanie tekstu w wielu kolumnach oraz połączonych kontenerach
-
Tekst pionowy, Tate-Chu-Yoko (tekst poziomy w tekście pionowym) oraz wyrównywanie czcionek wschodnioazjatyckich
-
Zaawansowane sterowanie typografią, między innymi kerning, ligatury, wielkość liter, wielkość cyfr, szerokość cyfr i ozdobne dywizy
-
Wycinanie, kopiowanie, wklejanie, cofanie oraz standardowe gesty edycji obsługiwane za pomocą klawiatury i myszy
-
Rozbudowane interfejsy API umożliwiające programistom przekształcanie tekstu, układu i znaczników, a także tworzenie własnych składników do obsługi tekstu
-
Niezawodna obsługa list, w tym własne znaczniki i formaty numerowania
-
Obrazy w wierszu i reguły określania położenia
Architektura TLF jest biblioteką języka ActionScript 3.0 opartą na mechanizmie FTE (Flash Text Engine) wprowadzonym w programie Flash Player 10. Mechanizm FTE jest dostępny za pośrednictwem pakietu
flash.text.engine
wchodzącego w skład interfejsu API programu Flash Player 10.
Jednak interfejs API programu Flash Player zapewnia dostęp do mechanizmu tekstowego na bardzo niskim poziomie, co oznacza że realizacja niektórych zadań wymaga napisania skomplikowanego kodu. Architektura TLF obudowuje kod niskiego poziomu przy użyciu prostszych interfejsów API. Udostępnia także ogólną architekturę, która definiuje organizację podstawowych elementów zdefiniowanych w mechanizmie FTE, ujmując je w łatwiejszy w użytku system.
W przeciwieństwie do mechanizmu FTE architektura TLF nie jest wbudowana w program Flash Player. Stanowi niezależną bibliotekę składników napisaną w całości w języku ActionScript 3.0. Jest to rozszerzalna platforma, dzięki czemu można ją dostosować do konkretnych środowisk. Zarówno program Flash Professional, jak i zestaw SDK środowiska Flex zawierają składniki oparte na architekturze TLF.
Obsługa złożonych skryptów
Architektura TLF oferuje obsługę złożonych skryptów. Oznacza to między innymi możliwość wyświetlania i edytowania skryptów dla języków z zapisem od prawej do lewej. Architektura TLF pozwala również wyświetlać i edytować skrypty zawierające na przemian tekst z zapisem od lewej do prawej i od prawej do lewej, na przykład dla języków arabskiego i hebrajskiego. Platforma obsługuje nie tylko pionowy układ tekstu w językach chińskim, japońskim i koreańskim, lecz również elementy TCY (tate-chu-yoko). Elementy TCY są to bloki tekstu poziomego osadzone w pionowych ciągach tekstu. Obsługiwane są następujące skrypty:
-
Łaciński (angielski, hiszpański, francuski, wietnamski itd.)
-
Grecki, cyrylica, armeński, gruziński i etiopski
-
Arabski i hebrajski
-
Ideograficzny Han i Kana (chiński, japoński i koreański) oraz Hangul Johab (koreański)
-
Tajski, laoski, oraz khmerski
-
Dewanagari, bengalski, gurmukhi, malayalam, telugu, tamilski, gujarati, oriya, kannada, tybetański
-
Tifinagh, yi, cherokee, aborygenów kanadyjskich, deseret, shawa, vai, tagalog, hanunoo, buhid, tagbanwa
Korzystanie z architektury Text Layout Framework w programie Flash Professional i środowisku Flex
Klasy architektury TLF można stosować bezpośrednio do tworzenia własnych składników w programie Flash. Ponadto program Flash Professional CS5 udostępnia nową klasę fl.text.TLFTextField, która obudowuje funkcje architektury TLF. Klasa TLFTextField pozwala tworzyć w kodzie ActionScript pola tekstowe, w których są stosowane zaawansowane funkcje wyświetlania tekstu oferowane przez architekturę TLF. Obiekt TLFTextField tworzy się w taki sam sposób, jak pole tekstowe klasy TextField. Następnie można skorzystać z właściwości
textFlow
w celu przypisania zaawansowanych opcji formatowania udostępnianych przez klasy TLF.
Program Flash Professional pozwala utworzyć wystąpienie klasy TLFTextField na stole montażowym za pomocą narzędzia Tekst. Następnie można użyć kodu ActionScript do sterowania formatowaniem i układem pola tekstowego za pośrednictwem klas architektury TLF. Więcej informacji zawiera strona o klasie
TLFTextField
w dokumentacji języka ActionScript 3.0 dla platformy Adobe Flash.
W przypadku pracy w środowisku Flex należy używać klas architektury TLF. Więcej informacji zawiera sekcja
Korzystanie z architektury Text Layout Framework
.
Korzystanie z architektury Text Layout Framework
W przypadku pracy w środowisku Flex lub tworzenia własnych składników do obsługi tekstu należy stosować klasy architektury TLF. Architektura TLF jest biblioteką języka ActionScript 3.0 zawartą w całości w bibliotece textLayout.swc. Biblioteka TLF zawiera około stu klas i interfejsów języka ActionScript 3.0 pogrupowanych w dziesięć pakietów. Pakiety te są pakietami podrzędnymi pakietu flashx.textLayout.
Klasy w architekturze Text Layout Framework
Klasy architektury TLF można pogrupować w trzy kategorie:
Klasy struktur danych i formatowania
Następujące pakiety zawierają klasy struktur danych i formatowania architektury TLF:
Podstawową strukturą danych architektury TLF jest hierarchia układu tekstu zdefiniowana w pakiecie elements. W ramach tej struktury można przypisywać style i atrybuty do fragmentów tekstu, korzystając z pakietu formats. Korzystając z pakietu conversion, można również sterować importowaniem tekstu do struktury danych i eksportowaniem tekstu ze struktury danych.
Klasy renderowania
Następujące pakiety zawierają klasy renderowania architektury TLF:
Klasy zawarte w tych pakietach ułatwiają renderowanie tekstu na potrzeby wyświetlania w programie Flash Player. Pakiet factory udostępnia prosty sposób wyświetlania tekstu statycznego. Pakiet container zawiera klasy i interfejsy definiujące kontenery wyświetlania dla tekstu dynamicznego. Pakiet compose definiuje techniki pozycjonowania i wyświetlania tekstu dynamicznego w kontenerach.
Klasy interakcji z użytkownikiem
Następujące pakiety zawierają klasy interakcji z użytkownikiem architektury TLF:
Pakiety edit i operations definiują klasy, które umożliwiają edytowanie tekstu przechowywanego w strukturach danych. Pakiet events zawiera klasy służące do obsługi zdarzeń.
Ogólna procedura tworzenia tekstu przy użyciu architektury Text Layout Framework
W następującej procedurze opisano ogólny proces tworzenia tekstu w architekturze TLF:
Przykład użycia architektury Text Layout Framework: układ gazetowy
W poniższym przykładzie zademonstrowano użycie architektury TLF do przygotowania układu prostej strony gazety. Strona zawiera duży nagłówek, nagłówek podrzędny i wielokolumnową sekcję treści.
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();
}
}
}
W klasie TLFNewsLayout użyto dwóch kontenerów tekstu. Jeden kontener wyświetla nagłówek i nagłówek podrzędny, a drugi wyświetla tekst podstawowy w trzech kolumnach. Dla uproszczenia tekst został zakodowany na stałe jako tekst w formacie TLF Markup (formacie znaczników architektury TLF). Zmienna
headlineMarkup
zawiera zarówno nagłówek, jak i nagłówek podrzędny, zaś zmienna
bodyMarkup
zawiera tekst podstawowy. Więcej informacji o formacie TLF Markup zawiera sekcja
Ustalanie struktury tekstu w architekturze Text Layout Framework
.
Po operacjach związanych z inicjowaniem funkcja
onAddedToStage()
importuje tekst nagłówka do obiektu TextFlow, który stanowi podstawową strukturę danych w architekturze TLF.
hTextFlow = TextConverter.importToFlow(headlineMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
W kolejnym kroku jest tworzony obiekt Sprite (służący jako kontener) i następuje utworzenie kontrolera oraz skojarzenie go z kontenerem.
headContainer = new Sprite();
headlineController = new ContainerController(headContainer);
Kontener jest inicjowany — następuje ustawienie opcji dotyczących między innymi formatowania i przewijania. Kontroler zawiera informacje o geometrii określające obwiednię kontenera, w której jest umieszczany tekst. Obiekt TextLayoutFormat zawiera opcje formatowania.
hContainerFormat = new TextLayoutFormat();
Kontroler jest przypisywany do układacza typograficznego, po czym funkcja dodaje kontener do listy wyświetlania. Właściwe tworzenie kompozycji i wyświetlanie kontenerów odbywa się dopiero w metodzie
resizeHandler()
. Te same kroki są wykonywane w celu zainicjowania obiektu TextFlow.
Metoda
resizeHandler()
mierzy obszar dostępny do renderowania kontenerów i odpowiednio ustala ich wymiary. Pierwsze wywołanie metody
compose()
umożliwia obliczenie właściwej wysokości kontenera nagłówka. Metoda
resizeHandler()
może następnie umieścić i wyświetlić kontener nagłówka w ramach metody
updateAllControllers()
. Na koniec metoda
resizeHandler()
na podstawie wielkości kontenera nagłówka określa położenie kontenera tekstu treści.
Ustalanie struktury tekstu w architekturze Text Layout Framework
Tekst w architekturze TLF jest przechowywany w hierarchicznej strukturze drzewa. Każdy węzeł drzewa jest instancją klasy zdefiniowanej w pakiecie elements. Na przykład węzłem głównym drzewa jest zawsze instancja klasy TextFlow. Klasa TextFlow reprezentuje cały wątek tekstu. Historia jest to kolekcja tekstu i innych elementów traktowana jako jednostka (ciągły fragment). Pojedyncza historia może być wyświetlana w więcej niż jednej kolumnie lub w kilku kontenerach tekstu.
Wszystkie elementy z wyjątkiem węzła głównego są częściowo oparte na elementach XHTML. Na poniższym schemacie przedstawiono hierarchię stosowaną w architekturze:
Hierarchia obiektu TextFlow
Znaczniki architektury Text Layout Framework
Znajomość struktury architektury TLF jest pomocna podczas pracy ze znacznikami tej architektury — z formatem TLF Markup. Format TLF Markup to reprezentacja XML tekstu używanego w architekturze Text Layout Framework. Architektura obsługuje także inne formaty XML, jednak standard TFL Markup jest unikatowy, ponieważ jest oparty na strukturze hierarchii obiektu TextFlow. Hierarchia obiektu TextFlow wyeksportowana jako kod XML w tym formacie pozostanie nienaruszona.
Format TLF Markup zapewnia najwyższą dokładność wyświetlania tekstu umieszczonego w hierarchii obiektu TextFlow. Język znaczników udostępnia znaczniki dla każdego z podstawowych elementów hierarchii obiektu TextFlow, a także atrybuty związane ze wszystkimi właściwościami formatowania zawartymi w klasie TextLayoutFormat.
Poniższa tabela zawiera znaczniki, których można używać w kodzie TLF Markup.
Element
|
Opis
|
Elementy podrzędne
|
Klasa
|
textflow
|
Element główny kodu.
|
div, p
|
TextFlow
|
div
|
Podział tekstu w elemencie TextFlow. Może zawierać grupę akapitów
|
div, list, p
|
DivElement
|
p
|
Akapit.
|
a, tcy, span, img, tab, br, g
|
ParagraphElement
|
a
|
Łącze.
|
tcy, span, img, tab, br, g
|
LinkElement
|
tcy
|
Tekst poziomy (opcja stosowana wewnątrz pionowego obiektu TextFlow).
|
a, span, img, tab, br, g
|
TCYElement
|
span
|
Bieg tekstu w akapicie.
|
|
SpanElement
|
img
|
Obraz w akapicie.
|
|
InlineGraphicElement
|
tab
|
Znak tabulacji.
|
|
TabElement
|
br
|
Znak podziału. Służy jako zakończenie wiersza w akapicie. Tekst jest kontynuowany w następnym wierszu, ale w ramach tego samego akapitu.
|
|
BreakElement
|
linkNormalFormat
|
Definiuje atrybuty formatujące używane dla łączy w stanie normalnym.
|
TextLayoutFormat
|
TextLayoutFormat
|
linkActiveFormat
|
Definiuje atrybuty formatujące używane dla łączy w stanie aktywnym, gdy użytkownik trzyma naciśnięty przycisk myszy, a wskaźnik znajduje się nad łączem.
|
TextLayoutFormat
|
TextLayoutFormat
|
linkHoverFormat
|
Definiuje atrybuty formatujące używane dla łączy pod wskaźnikiem, gdy wskaźnik myszy znajduje się w granicach łącza („najazd”).
|
TextLayoutFormat
|
TextLayoutFormat
|
li
|
Element pozycji listy. Musi znajdować się wewnątrz pozycji listy.
|
div, li, list, p
|
ListItemElement
|
list
|
Lista. Listy mogą być zagnieżdżone lub umieszczone obok siebie. Do pozycji na liście można stosować różne schematy nazw lub numeracji.
|
div, li, list, p
|
ListElement
|
g
|
Element grupy. Służy do grupowania elementów w akapicie. Umożliwia zagnieżdżanie elementów poniżej poziomu akapitu.
|
a, tcy, span, img, tab, br, g
|
SubParagraphGroupElement
|
Używanie list numerowanych i punktowanych
Korzystając z klas
ListElement
i
ListItemElement
, można dodawać listy punktowane do tekstowych elementów sterujących. Listy punktowane można zagnieżdżać oraz dostosowywać w celu używania różnych punktorów (znaczników), automatycznego numerowania, a także numerowania w stylu konspektu.
Do tworzenia list w przepływie tekstu służy znacznik
<list>
. Następnie dla wszystkich pozycji listy należy wprowadzić znaczniki
<li>
w obrębie znacznika
<list>
. Wygląd punktorów można dostosować przy użyciu klasy ListMarkerFormat.
W poniższym przykładzie przedstawiono tworzenie prostych list.
<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>
Listy można zagnieżdżać w innych listach, co ilustruje poniższy przykład.
<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>
Właściwość
listStyleType
obiektu ListElement pozwala dostosować typ znacznika na liście. Właściwość ta może mieć dowolną wartość zdefiniowaną w klasie ListStyleType, na przykład
check
(ptaszek),
circle
(kółko),
decimal
(liczba dziesiętna) czy
box
(kwadrat). W poniższym przykładzie są tworzone listy z różnymi typami znaczniku i własnymi krokami liczników.
<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>
Klasa
ListMarkerFormat
pozwala zdefiniować licznik. Oprócz definiowania kroku licznika można dostosowywać licznik, zerując go za pomocą właściwości
counterReset
.
W celu dostosowania wyglądu znaczników na listach można użyć właściwości
beforeContent
i
afterContent
obiektu ListMarkerFormat. Właściwości te są stosowane do zawartości wyświetlanej przez zawartością znacznika i po niej.
W poniższym przykładzie przed znacznikiem jest dodawany ciąg „XX”, a po nim ciąg „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>
Również sama właściwość
content
pozwala dostosowywać formatowanie znacznika. Poniższy przykład ilustruje sposób wyświetlania uporządkowanych znaczników opartych na cyfrach rzymskich.
<flow:list listStyleType="disc" paddingLeft="96" paddingRight="24">
<flow:listMarkerFormat>
<flow:ListMarkerFormat fontSize="16"
beforeContent="Section "
content="counters(ordered,"*",upperRoman)"
afterContent=": "/>
</flow:listMarkerFormat>
<flow:li>Item 1</li>
<flow:li>Item 2</li>
<flow:li>Item 3</li>
</flow:list>
Jak widać na poprzednim przykładzie, właściwość
content
pozwala też dodać przyrostek — ciąg wyświetlany po znaczniku, ale przed elementem
afterContent
. Aby wstawić ten ciąg podczas umieszczania zawartości XML w przepływie, należy umieścić ciąg w elementach HTML
"e;
, a nie w cudzysłowach (
"<
string
>"
).
Stosowanie dopełnienia w architekturze TLF
Każdy obiekt
FlowElement
obsługuje właściwości dopełnienia, za pomocą których można sterować położeniem każdego elementu w obszarze zawartości, a także odstępami między obszarami zawartości.
Całkowita szerokość elementu jest sumą szerokości jego zawartości powiększoną o wartości właściwości
paddingLeft
i
paddingRight
. Całkowita wysokość elementu jest sumą wysokości jego zawartości powiększoną o wartości właściwości
paddingTop
i
paddingBottom
.
Dopełnienie jest to puste miejsce między krawędzią a zawartością. Właściwości dopełnienia to:
paddingBottom
,
paddingTop
,
paddingLeft
,
paddingRight
. Dopełnienie można stosować względem obiektu TextFlow, a także następujących elementów potomnych:
Właściwości dopełnienia nie można stosować do elementów zakresu.
W poniższym przykładzie są ustawiane właściwości dopełnienia obiektu 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">
Poprawne wartości właściwości dopełnienia to liczby (w pikselach) oraz ciągi „auto” (automatycznie) i „inherit” (dziedziczenie). Wartością domyślną jest „auto” (automatycznie). Oznacza ona obliczanie automatyczne i ustawianie na 0 dla wszystkich elementów oprócz obiektów typu ListElement. W przypadku obiektów typu ListElement opcja „auto” (automatycznie) oznacza wartość 0 z wyjątkiem początku listy, gdzie jest stosowana wartość właściwości
listAutoPadding
. Wartość domyślna właściwości
listAutoPadding
to 40 — domyślne wcięcie list.
Właściwości dopełnienia domyślnie nie są dziedziczone. Wartości „auto” (automatycznie) i „inherit” (dziedziczenie) są stałymi zdefiniowanymi w klasie
FormatValue
.
Właściwości dopełnienia nie mogą mieć wartości ujemnych.
Formatowanie tekstu w architekturze Text Layout Framework
Pakiet flashx.textLayout.formats zawiera interfejsy i klasy umożliwiające przypisywanie formatów do dowolnych elementów FlowElement w drzewie hierarchii przepływu tekstu. Istnieją dwa sposoby zastosowania formatowania. Można przypisywać formaty pojedynczo lub przypisać od razu całą grupę formatów, korzystając ze specjalnego obiektu formatowania.
Interfejs ITextLayoutFormat zawiera wszystkie formaty, jakie mogą być stosowane do obiektu FlowElement. Niektóre formaty mają zastosowanie do całego kontenera lub akapitu tekstu, ale logicznie nie mają zastosowania do poszczególnych znaków. Takie formaty, jak justowanie i znaczniki tabulacji, mają zastosowanie do całych akapitów, ale nie do poszczególnych znaków.
Przypisywanie formatów do obiektu FlowElement z właściwościami
Do dowolnego obiektu FlowElement można przypisywać formaty poprzez przypisanie właściwości. Klasa FlowElement implementuje interfejs ITextLayoutFormat, a zatem każda podklasa klasy FlowElement także musi implementować ten interfejs.
Poniższy przykładowy kod ilustruje przypisywanie pojedynczych formatów do wystąpienia klasy ParagraphElement.
var p:ParagraphElement = new ParagraphElement();
p.fontSize = 18;
p.fontFamily = "Arial";
Przypisywanie formatów do obiektu FlowElement za pomocą klasy TextLayoutFormat
Możliwe jest stosowanie formatów względem obiektów FlowElement za pomocą klasy TextLayoutFormat. Ta klasa umożliwia utworzenie specjalnego obiektu formatowania, który zawiera wszystkie pożądane wartości formatowania. Następnie taki obiekt można przypisać do właściwości
format
dowolnego obiektu FlowElement. Klasy TextLayoutFormat i FlowElement implementują interfejs ITextLayoutFormat. Takie rozwiązanie gwarantuje, że obie klasy zawierają te same właściwości formatowania.
Więcej informacji zawiera strona o klasie
TextLayoutFormat
w dokumentacji języka ActionScript 3.0 dla platformy Adobe Flash.
Dziedziczenie formatów
W hierarchii przepływu tekstu formaty są dziedziczone. Przypisanie instancji klasy TextLayoutFormat do instancji klasy FlowElement, która ma elementy podrzędne, inicjuje proces nazywany
kaskadowaniem
. W trakcie kaskadowania następuje rekurencyjne przeglądanie wszystkich węzłów hierarchii dziedziczących z obiektu FlowElement. Następnie architektura określa, czy odziedziczone wartości powinny być przypisane do poszczególnych właściwości formatowania. W trakcie kaskadowania stosowane są następujące reguły:
-
Wartości właściwości są dziedziczone wyłącznie z bezpośredniego przodka (niekiedy nazywanego elementem nadrzędnym).
-
Wartości właściwości są dziedziczone, o ile właściwość nie ma jeszcze wartości (tj. ma wartość
undefined
).
-
Niektóre atrybuty nie dziedziczą wartości, jeśli są niezdefiniowane (undefined) — muszą mieć wartość „inherit” lub równą stałej
flashx.textLayout.formats.FormatValue.INHERIT
.
Na przykład ustawienie wartości
fontSize
na poziomie obiektu TextFlow będzie obowiązywało we wszystkich elementach w obiekcie TextFlow. Innymi słowy, wartości są kaskadowo przenoszone w dół hierarchii przepływu tekstu. Można jednak przesłonić wartość w konkretnym elemencie, przypisując ją do właściwości tego elementu. Dla odmiany, jeśli ustawimy wartość
backgroundColor
na poziomie obiektu TextFlow, elementy podrzędne obiektu TextFlow jej nie odziedziczą. Właściwość
backgroundColor
nie jest dziedziczona z elementów nadrzędnych w trakcie kaskadowania. Można przesłonić to zachowanie, przypisując właściwości
backgroundColor
każdego elementu podrzędnego wartość
flashx.textLayout.formats.FormatValue.INHERIT
.
Więcej informacji zawiera strona o klasie
TextLayoutFormat
w dokumentacji języka ActionScript 3.0 dla platformy Adobe Flash.
Importowanie i eksportowanie tekstu w architekturze Text Layout Framework
Klasa TextConverter w pakiecie flashx.textLayout.conversion.* Pakiet umożliwia importowanie tekstu do plików TLF i eksportowanie tekstu z takich plików. Tej klasy należy używać, gdy tekst ma być wczytywany w czasie wykonywania, a nie skompilowany w pliku SWF. Stosując tę klasę, można wyeksportować tekst przechowywany w wystąpieniu klasy TextFlow do obiektu String lub XML.
Procedury importu i eksportu nie są skomplikowane. Należy wywołać metodę
export()
albo metodę
importToFlow()
, które należą do klasy TextConverter. Obie metody są statyczne, co oznacza, że wywołuje się je z klasy TextConverter, a nie z jej instancji.
Klasy zawarte w pakiecie flashx.textLayout.conversion oferują znaczną elastyczność w zakresie wyboru miejsca przechowywania tekstu. Jeśli na przykład tekst jest przechowywany w bazie danych, można go zaimportować w celu wyświetlenia na platformie. Następnie można za pomocą klas z pakietu flashx.textLayout.edit zmienić tekst i wyeksportować go do bazy danych.
Więcej informacji zawiera strona o pakiecie
flashx.textLayout.conversion
w dokumentacji języka ActionScript 3.0 dla platformy Adobe Flash.
Zarządzanie kontenerami tekstu w architekturze Text Layout Framework
Tekst przechowywany w strukturach danych architektury TLF można wyświetlać w programie Flash Player. Tekst przechowywany w hierarchii przepływu musi zostać przekonwertowany na format odpowiedni do wyświetlania w programie Flash Player. Architektura TLF udostępnia dwa sposoby tworzenia obiektów ekranowych z przepływu. Pierwszy, prostszy z nich, jest przydatny podczas wyświetlania tekstu statycznego. Drugi, bardziej złożony, umożliwia tworzenie tekstu dynamicznego z opcjami zaznaczania i edycji. W obu przypadkach tekst jest ostatecznie konwertowany na wystąpienia klasy TextLine, która wchodzi w skład pakietu flash.text.engine.* w programie Flash Player 10.
Tworzenie tekstu statycznego
W prostej metodzie używana jest klasa TextFlowTextLineFactory, która znajduje się w pakiecie
flashx.textLayout.factory
. Zaletą tej metody, obok jej prostoty, jest mniejsza zajętość pamięci niż w przypadku użycia klasy FlowComposer. Ta strategia jest zalecana w przypadku tekstu statycznego, który nie wymaga edycji, zaznaczania ani przewijania przez użytkownika.
Więcej informacji zawiera strona o klasie
TextFlowTextLineFactory
w dokumentacji języka ActionScript 3.0 dla platformy Adobe Flash.
Tworzenie tekstu dynamicznego i kontenerów
Układacz typograficzny zapewnia większą kontrolę nad wyświetlaniem tekstu niż obiekt TextFlowTextLineFactory. Dzięki zastosowaniu układacza typograficznego użytkownicy mogą na przykład zaznaczać i edytować tekst. Więcej informacji zawiera sekcja
Umożliwianie zaznaczania i edytowania tekstu oraz cofania operacji w architekturze Text Layout Framework
.
Układacz typograficzny jest wystąpieniem klasy StandardFlowComposer zawartej w pakiecie
flashx.textLayout.compose
. Układacz typograficzny zarządza konwersją wystąpienia klasy TextFlow na wystąpienia klasy TextLine oraz rozmieszczeniem tych wystąpień klasy TextLine w kontenerze lub kontenerach.
Powiększ obraz
Z obiektem IFlowComposer skojarzonych jest zero lub więcej obiektów ContainerController
Z każdą instancją TextFlow skojarzony jest obiekt implementujący interfejs IFlowComposer. Ten obiekt IFlowComposer jest dostępny za pośrednictwem właściwości
TextFlow.flowComposer
. Korzystając z tej właściwości, można wywoływać metody zdefiniowane w interfejsie IFlowComposer. Metody te pozwalają skojarzyć tekst z kontenerem lub kontenerami oraz przygotować tekst do wyświetlania w kontenerze.
Kontener jest instancją klasy Sprite, która z kolei jest podklasą klasy DisplayObjectContainer. Obie te klasy wchodzą w skład interfejsu API listy wyświetlania programu Flash Player. Kontener jest bardziej zaawansowaną formą prostokąta ograniczającego używanego w klasie TextLineFactory. Podobnie jak obiekt rectangle, kontener otacza obszar, w którym widoczne są instancje klasy TextLine. W odróżnieniu od prostokątnej obwiedni kontener jest powiązany z obiektem kontrolera. Kontroler zarządza przewijaniem, tworzeniem kompozycji, tworzeniem połączeń, formatowaniem i obsługą zdarzeń. Steruje kontenerem lub zbiorem kontenerów. Każdy kontener ma odpowiadający mu obiekt kontrolera będący wystąpieniem klasy ContainerController z pakietu flashx.textLayout.container.
W celu wyświetlenia tekstu należy utworzyć obiekt kontrolera przeznaczony do zarządzania kontenerem i skojarzyć go z układaczem typograficznym. Po skojarzeniu kontenera należy zdefiniować układ tekstu (dokonać kompozycji), aby można go było wyświetlić. W związku z tym kontenery mają dwa stany: kompozycji i wyświetlania. Kompozycja tekstu to proces przekształcania tekstu z hierarchii przepływu tekstu na instancje klasy TextLine i obliczania, w jaki sposób rozmieścić te instancje w kontenerach. Wyświetlanie to proces aktualizowania listy wyświetlania programu Flash Player.
Więcej informacji zawierają opisy klas
IFlowComposer
,
StandardFlowComposer
i
ContainerController
w dokumentacji języka ActionScript 3.0 dla platformy Adobe Flash.
Umożliwianie zaznaczania i edytowania tekstu oraz cofania operacji w architekturze Text Layout Framework
Sterowanie możliwością zaznaczania i edytowania tekstu odbywa się na poziomie obiektu TextFlow. Z każdą instancją klasy TextFlow jest skojarzony menedżer interakcji. Dostęp do menedżera interakcji obiektu TextFlow można uzyskać za pośrednictwem właściwości
TextFlow.interactionManager
tego obiektu. Aby umożliwić zaznaczanie tekstu, należy przypisać instancję klasy SelectionManager do właściwości
interactionManager
. Aby umożliwić zarówno zaznaczanie tekstu, jak i edytowanie, należy przypisać instancję klasy EditManager zamiast instancji klasy SelectionManager. Aby umożliwić cofanie operacji, należy utworzyć instancję klasy UndoManager i przekazać ją jako argument w wywołaniu konstruktora EditManager. Klasa UndoManager umożliwia zarządzanie historią ostatnich czynności edycyjnych użytkownika oraz cofanie lub ponawianie konkretnych czynności. Wszystkie trzy klasy wchodzą w skład pakietu edit.
Więcej informacji zawierają opisy klas
SelectionManager
,
EditManager
i
UndoManager
w dokumentacji języka ActionScript 3.0 dla platformy Adobe Flash.
Obsługa zdarzeń w architekturze Text Layout Framework
Obiekty TextFlow wywołują zdarzenia w wielu sytuacjach, między innymi:
-
przy zmianach tekstu lub układu,
-
przed rozpoczęciem operacji oraz po zakończeniu operacji,
-
w przypadku zmiany stanu obiektu FlowElement,
-
po zakończeniu operacji tworzenia kompozycji.
Więcej informacji zawiera opis pakietu
flashx.textLayout.events
w dokumentacji języka ActionScript 3.0 dla platformy Adobe Flash.
Określanie położenia obrazów w tekście
Właściwość
float
określa, jak grafika jest umieszczana w sąsiadującym z nią tekście. Właściwość
clearFloats
określa położenie elementów w akapicie względem obiektu o właściwości
float
.
Sterowanie położeniem obrazu w elemencie tekstowym odbywa się przy użyciu właściwości
float
. W poniższym przykładzie obraz jest dodawany do akapitu i wyrównywany do lewej w taki sposób, aby tekst był zawijany na prawo od niego.
<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>
Poprawne wartości właściwości
float
: left (do lewej), right (do prawej), start (na początku), end (na końcu), none (brak). Są to stałe zdefiniowane w klasie Float. Wartością domyślną jest none (brak).
Właściwość
clearFloats
jest przydatna, gdy trzeba dopasować położenie początkowe kolejnych akapitów, które bez tej modyfikacji byłyby zawijane wokół obrazu. Załóżmy na przykład, że istnieje obraz większy niż pierwszy akapit. Aby mieć pewność, że drugi akapit zacznie się
pod
obrazem, należy ustawić właściwość
clearFloats
.
W poniższym przykładzie zastosowano obraz wyższy niż tekst w pierwszym akapicie. Aby drugi akapit zaczynał się w bloku tekstu pod obrazem, w przykładzie ustawiono właściwość
clearFloats
drugiego akapitu na end (na końcu).
<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>
Poprawne wartości właściwości
clearFloats
: left (do lewej), right (do prawej), end (na końcu), start (na początku), none (brak), both (obydwa). Są to stałe zdefiniowane w klasie
ClearFloats
. Dla właściwości
clearFloats
można także ustawić wartość inherit (dziedziczenie). Jest to stała zdefiniowana w klasie
FormatValue
. Wartością domyślną jest none (brak).
|
|
|
|
|