Text Layout Framework 사용

Flash Player 10 이상, Adobe AIR 1.5 이상

Text Layout Framework 개요

TLF(Text Layout Framework)는 확장 가능한 ActionScript 라이브러리입니다. TLF는 Adobe® Flash® Player 10 및 Adobe® AIR® 1.5의 텍스트 엔진에 내장되어 있습니다. TLF는 웹에서 고급 입력 체계와 혁신적인 입력 체계의 텍스트 레이아웃 기능을 제공합니다. 이 프레임워크는 Adobe® Flex® 또는 Adobe® Flash® Professional과 함께 사용할 수 있습니다. 개발자는 기존의 구성 요소를 사용하거나 확장할 수 있을 뿐 아니라 이 프레임워크를 활용하여 자신만의 텍스트 구성 요소를 만들 수 있습니다.

TLF의 기능은 다음과 같습니다.
  • 양방향 텍스트, 세로 방향 텍스트, 30개 이상의 쓰기 스크립트(아랍어, 히브리어, 중국어, 일본어, 한국어, 태국어, 라오스어, 베트남어 등)

  • 여러 열 및 연결된 컨테이너에 걸친 텍스트의 선택, 편집 및 흐름

  • 세로 방향 텍스트, 문자 회전(세로 방향 텍스트 내 가로 방향), 동아시아 언어 입력 체계에 대한 정렬자

  • 커닝, 합자, 입력 체계 대/소문자, 숫자 케이스, 숫자 폭, 임의 하이픈 등의 풍부한 입력 체계 컨트롤

  • 편집을 위한 잘라내기, 복사, 붙여넣기, 실행 취소, 표준 키보드 및 마우스 동작

  • 텍스트 내용, 레이아웃 및 마크업을 조작하고 사용자 정의 텍스트 구성 요소를 만들 수 있는 풍부한 개발자 API

  • 사용자 정의 표시자 및 번호 매기기 형식 등의 강력한 목록 지원

  • 인라인 이미지 및 위치 지정 규칙

TLF는 Flash Player 10에 도입된 FTE(Flash Text Engine)의 내장 ActionScript 3.0 라이브러리입니다. FTE는 Flash Player 10 API(응용 프로그래밍 인터페이스)의 일부인 flash.text.engine 패키지를 통해 액세스할 수 있습니다.

그러나 Flash Player API에서는 텍스트 엔진에 대해 저수준의 액세스만 지원하므로 일부 작업의 경우 상대적으로 매우 많은 양의 코드가 필요할 수 있습니다. TLF는 저수준 코드를 더 간단한 API 안으로 캡슐화합니다. 또한 TLF는 FTE에서 정의된 구성 블록을 사용이 더 간편한 시스템으로 구성하는 개념적 아키텍처를 제공합니다.

FTE와 달리 TLF는 Flash Player에 내장되어 있지 않습니다. 정확히 말해 이 프레임워크는 ActionScript 3.0으로 완전히 작성된 독립적인 구성 요소 라이브러리이며, 확장 가능하기 때문에 특정 환경에 맞게 사용자 정의할 수 있습니다. Flash Professional 및 Flex SDK는 모두 TLF 프레임워크를 기반으로 하는 구성 요소를 포함합니다.

복잡한 스크립트 지원

TLF는 복잡한 스크립트 지원을 제공합니다. 복잡한 스크립트 지원에는 오른쪽에서 왼쪽 방향의 스크립트를 표시 및 편집할 수 있는 기능이 포함됩니다. 또한 TLF는 아랍어나 히브리어와 같이 왼쪽에서 오른쪽 방향 및 오른쪽에서 왼쪽 방향이 혼합된 스크립트를 표시하고 편집할 수 있는 기능을 제공합니다. 이 프레임워크는 중국어, 일본어 및 한국어에 대한 세로 방향 텍스트 레이아웃은 물론 TCY(문자 회전) 요소도 지원합니다. TCY 요소는 세로 방향 텍스트에 포함된 가로 쓰기 텍스트 블록입니다. 다음과 같은 스크립트가 지원됩니다.

  • 라틴(영어, 스페인어, 프랑스어, 베트남어 등)

  • 그리스어, 키릴 자모, 아르메니아어, 그루지야어, 게에즈 문자

  • 아랍어 및 히브리어

  • 한 표의 문자 및 가나(한국어, 중국어 및 일본어) 및 한글 조합(한국어)

  • 태국어, 라오스어, 크메르어

  • 데바나가리 문자, 벵골어, 굴묵키어, 말라얄람어, 텔루구어, 타밀어, 구자라트어, 오리야어, 카나다어, 티베트어

  • 티푸나구어, 이 문자, 체로키어, 캐나다 음절, 데저렛 문자, 샤우 문자, 바이어, 타갈로그어, 하누누어, 부히드어, 타그반와어

Flash Professional 및 Flex에서 Text Layout Framework 사용

TLF 클래스를 직접 사용하여 Flash에서 사용자 정의 구성 요소를 만들 수 있습니다. 또한 Flash Professional CS5에서는 TLF 기능을 캡슐화하는 새 클래스 fl.text.TLFTextField를 제공합니다. 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는 textLayout.swc 라이브러리 내에 완전히 포함된 ActionScript 3.0 라이브러리입니다. TLF 라이브러리에는 약 100개의 ActionScript 3.0 클래스 및 인터페이스가 10개의 패키지로 구성되어 있습니다. 이러한 패키지는 flashx.textLayout 패키지의 하위 패키지입니다.

Text Layout Framework 클래스

TLF 클래스는 다음 세 개의 범주로 그룹화됩니다.
  • 데이터 구조 및 서식 지정 클래스

  • 렌더링 클래스

  • 사용자 상호 작용 클래스

데이터 구조 및 서식 지정 클래스

다음 패키지에는 TLF의 데이터 구조 및 서식 지정 클래스가 포함되어 있습니다.

TLF의 기본 데이터 구조는 텍스트 흐름 계층 구조이며 요소 패키지에서 정의됩니다. 이 구조 내에서 서식 패키지를 사용하여 텍스트 흐름에 스타일 및 특성을 할당할 수 있으며, 변환 패키지를 통해 텍스트를 데이터 구조로 가져오고 데이터 구조에서 내보내는 방식을 제어할 수도 있습니다.

렌더링 클래스

다음 패키지에는 TLF의 렌더링 클래스가 포함되어 있습니다. 이러한 패키지의 클래스를 사용하면 Flash Player에서 표시할 텍스트를 더욱 간편히 렌더링할 수 있습니다. 팩토리 패키지는 정적 텍스트를 표시하는 간단한 방법을 제공합니다. 컨테이너 패키지에는 동적 텍스트의 표시 컨테이너를 정의하는 클래스 및 인터페이스가 포함됩니다. 작성 패키지는 컨테이너에 동적 텍스트를 배치 및 표시하는 기술을 정의합니다.

사용자 상호 작용 클래스

다음 패키지에는 TLF의 사용자 상호 작용 클래스가 포함되어 있습니다. 편집 및 작업 패키지는 데이터 구조에 저장된 텍스트의 편집을 허용하는 데 사용할 수 있는 클래스를 정의합니다. 이벤트 패키지는 이벤트 처리 클래스를 포함합니다.

Text Layout Framework으로 텍스트를 작성하는 일반적인 단계

다음 단계에서는 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 마크업은 TLF에 포함된 텍스트의 XML 표현입니다. TLF에서는 다른 XML 형식도 지원하지만 TLF 마크업은 특히 TextFlow 계층 구조에 기반한다는 점에서 고유합니다. 이 마크업 형식을 사용하여 TextFlow에서 XML을 내보내는 경우 이 계층 구조가 그대로 유지된 상태로 XML이 내보내집니다.

TLF 마크업은 TextFlow 계층 구조를 통해 텍스트의 표현에 있어 최고의 정확도를 보여 줍니다. 이 마크업 언어는 TextFlow 계층 구조의 각 기본 요소에 대해 태그를 제공하며 TextLayoutFormat 클래스에서 사용 가능한 모든 서식 지정 속성에 대한 특성도 제공합니다.

다음 표에는 TLF Markup에서 사용할 수 있는 태그가 나와 있습니다.

요소

설명

하위

클래스

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의 afterContent beforeContent 속성을 사용하면 목록에 있는 표시자의 모양도 사용자 정의할 수 있습니다. 이러한 속성은 표시자의 내용 앞뒤에 나타나는 내용에 적용됩니다.

다음 예제에서는 표시자 앞에 문자열 “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 내용을 넣을 때 이 문자열을 삽입하려면 인용 부호가 아닌 &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”로, ListElement를 제외한 모든 요소에서 자동으로 계산되고 0으로 설정됩니다. ListElements의 경우 listAutoPadding 속성 값이 사용되는 목록의 시작 지점을 제외하고 “auto”는 0이 됩니다. 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 객체의 property 속성에 이 객체를 할당할 수 있습니다. TextLayoutFormat 및 FlowElement는 모두 ITextLayoutFormat 인터페이스를 구현합니다. 다음 준비 작업을 통해 두 클래스에 모두 동일한 서식 속성이 포함되도록 합니다.

자세한 내용은 Adobe Flash Platform용 ActionScript 3.0 참조 설명서의 TextLayoutFormat 을 참조하십시오.

서식 상속

서식은 텍스트 흐름 계층 구조를 통해 상속됩니다. TextLayoutFormat 인스턴스를 자식이 있는 FlowElement 인스턴스에 할당하는 경우 프레임워크에서 겹쳐 놓기(cascade) 라는 프로세스를 시작합니다. 겹쳐 놓기 프로세스 동안 프레임워크는 계층 구조에서 FlowElement로부터 상속하는 각 노드를 반복적으로 검사합니다. 그런 다음 상속된 값을 각 서식 속성에 할당할지 여부를 결정합니다. 겹쳐 놓기 프로세스가 수행되는 동안 다음과 같은 규칙이 적용됩니다.

  1. 바로 위 요소(부모)의 속성 값만 상속됩니다.

  2. 아직 속성의 값이 없는 경우, 즉 값이 undefined 인 경우에만 속성 값이 상속됩니다.

  3. 일부 특성의 경우에는 특성의 값이 "inherit" 설정되었거나 상수 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 인스턴스에 저장된 텍스트를 String 또는 XML 객체로 내보낼 수 있습니다.

가져오기와 내보내기의 절차는 모두 간단합니다. TextConverter 클래스의 일부인 export() 메서드 또는 importToFlow() 메서드를 호출하면 됩니다. 두 가지 모두 정적 메서드이므로 TextConverter 클래스의 인스턴스가 아니라 TextConverter 클래스에서 메서드를 호출합니다.

flashx.textLayout.conversion 패키지의 클래스를 사용하면 텍스트의 저장 위치를 매우 유연하게 선택할 수 있습니다. 예를 들어 텍스트를 데이터베이스에 저장할 경우 표시를 위해 텍스트를 프레임워크로 가져올 수 있습니다. 그런 다음 flashx.textLayout.edit 패키지의 클래스를 사용하여 텍스트를 변경하고 변경된 텍스트를 데이터베이스로 다시 내보낼 수 있습니다.

자세한 내용은 Adobe Flash Platform용 ActionScript 3.0 참조 설명서의 flashx.textLayout.conversion 을 참조하십시오.

TLF를 사용한 텍스트 컨테이너 관리

텍스트가 TLF 데이터 구조에 저장된 후에는 Flash Player에서 해당 텍스트를 표시할 수 있습니다. 흐름 계층 구조에 저장된 텍스트는 Flash Player에서 표시할 수 있는 형식으로 변환되어야 합니다. TLF에서는 흐름으로부터 표시 객체를 만들 수 있는 두 가지 방식을 제공합니다. 첫 번째는 더욱 간편한 방법으로, 정적 텍스트를 표시하는 데 적합합니다. 더 복잡한 두 번째 방법을 사용하면 선택 및 편집이 가능한 동적 텍스트를 만들 수 있습니다. 두 가지 방법 중 어떤 것을 사용하든 텍스트는 결국 Flash Player 10에 포함된 flash.text.engine.* 패키지의 일부인 TextLine 클래스의 인스턴스로 변환됩니다.

정적 텍스트 만들기

단순한 방법에서는 flashx.textLayout.factory 패키지에 포함된 TextFlowTextLineFactory 클래스를 사용합니다. 이 방법은 간단할 뿐 아니라 FlowComposer 방법에 비해 메모리를 적게 사용한다는 장점이 있습니다. 사용자가 편집, 선택 또는 스크롤할 필요가 없는 정적 텍스트에 이 방법을 사용하는 것이 좋습니다.

자세한 내용은 Adobe Flash Platform용 ActionScript 3.0 참조 설명서의 TextFlowTextLineFactory 를 참조하십시오.

동적 텍스트 및 컨테이너 만들기

TextFlowTextLineFactory에서 제공하는 것보다 더 높은 수준의 텍스트 표시 제어 기능이 필요한 경우에는 흐름 컴포저를 사용합니다. 예를 들어 흐름 컴포저를 사용하면 텍스트를 선택하고 편집할 수 있습니다. 자세한 내용은 TLF를 사용한 텍스트 선택, 편집 및 실행 취소 활성화 를 참조하십시오.

흐름 컴포저는 flashx.textLayout.compose 패키지에 있는 StandardFlowComposer 클래스의 인스턴스입니다. 흐름 컴포저는 TextFlow를 TextLine 인스턴스로 변환하는 작업 및 변환된 TextLine 인스턴스를 하나 이상의 컨테이너에 배치하는 작업을 관리합니다.

전체 화면으로 그래픽 보기
IFlowComposer에는 0개 이상의 ContainerController가 있습니다.

각 TextFlow 인스턴스에는 IFlowComposer 인터페이스를 구현하는 해당 객체가 있습니다. 이 IFlowComposer 객체는 TextFlow.flowComposer 속성을 통해 액세스할 수 있습니다. 이 속성을 통해 IFlowComposer 인터페이스에 정의된 메서드를 호출할 수 있습니다. 이 메서드를 사용하면 텍스트를 하나 이상의 컨테이너와 연결하고 해당 텍스트를 컨테이너 안에 표시하도록 준비할 수 있습니다.

컨테이너는 DisplayObjectContainer 클래스의 하위 클래스인 Sprite 클래스의 인스턴스입니다. 두 클래스 모두 Flash Player 표시 목록 API의 일부입니다. 컨테이너는 TextLineFactory 클래스에서 사용되는 경계 사각형의 보다 발전된 형태입니다. 경계 사각형과 마찬가지로 컨테이너는 TextLine 인스턴스가 표시되는 영역의 경계를 정의합니다. 경계 사각형과 달리 컨테이너에는 상응하는 "컨트롤러" 객체가 있습니다. 컨트롤러는 컨테이너 또는 컨테이너 집합에 대한 스크롤, 컴포지션, 연결, 서식 지정 및 이벤트 처리 등을 관리합니다. 각 컨테이너는 flashx.textLayout.container 패키지에 있는 ContainerController 클래스의 인스턴스인 해당 컨트롤러 객체를 포함합니다.

텍스트를 표시하려면 컨테이너를 관리할 컨트롤러 객체를 만들어 흐름 컴포저와 연결하십시오. 컨테이너를 연결한 후에는 텍스트를 표시할 수 있도록 컴포지션해야 합니다. 따라서 컨테이너에는 컴포지션 및 표시의 두 가지 상태가 포함됩니다. 컴포지션은 텍스트 흐름 계층 구조의 텍스트를 TextLine 인스턴스로 변환하고 이러한 인스턴스가 컨테이너에 맞게 표시되는지 여부를 계산하는 프로세스입니다. 표시는 Flash Player 표시 목록을 업데이트하는 프로세스입니다.

자세한 내용은 Adobe Flash Platform용 ActionScript 3.0 참조 설명서의 IFlowComposer , StandardFlowComposer ContainerController 를 참조하십시오.

TLF를 사용한 텍스트 선택, 편집 및 실행 취소 활성화

텍스트를 선택 또는 편집할 수 있는 기능은 텍스트 흐름 수준에서 제어됩니다. 모든 TextFlow 클래스 인스턴스에는 연결된 상호 작용 관리자가 있습니다. TextFlow 객체의 TextFlow.interactionManager 속성을 통해 TextFlow 객체의 상호 작용 관리자에 액세스할 수 있습니다. 텍스트 선택을 활성화하려면 SelectionManager 클래스의 인스턴스를 interactionManager 속성에 할당하고, 텍스트 선택과 편집을 모두 활성화하려면 SelectionManager 클래스의 인스턴스 대신에 EditManager 클래스의 인스턴스를 할당합니다. 실행 취소 작업을 활성화하려면 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”입니다.