Text Layout Framework 간단한 안내
HTML 과 Flash 로 동시에 파싱되는 위키 언어 만든답시고 삽질 하고, 컴포넌트 만든다고 삽질하고 하다보니 어느새 TLF 도 적당히 손에 익어가는 중입니다.
자세한 내용들을 쓰기엔 내용이 너무 방대하기 때문에 나중에 시간이 남으면 써보기로 하고... 작업 동안 경험했던 간단한 팁들을 안내해볼까 합니다.
1 . Font, Embed Font 의 표현
매우 필요했지만, 한글 폰트 자체의 용량 덕분에 쓰는 것이 주저되었던 Embed Font 의 사용환경이 TLF 에 들어서는 매우 좋아진 편입니다.
일단, Embed Font 의 용량자체가 상당히 줄었기 때문에 (이전에 약 7MB 짜리 폰트가 TLF 에서는 2MB 정도로 압축가능 하기 때문에) 독립적인 swf 로 분리해서 사이트 전체적으로 런타임 공유를 통해 사용한다면 크게 부담되지 않는 수준입니다.
다만, 여러개의 폰트들을 그룹으로 지정해서 1순위 폰트에 필드가 없을 경우, 다음 순위의 폰트에서 글자를 찾는 fontFamily 의 존재에도 불구하고 fontLookup 의 일방성 덕분인지 embedFont 에 없는 한자나 특수문자의 표현에는 무리가 있는 편이네요... embed font 에 없는 필드를 device font 로 대체할 수도 있지 않을까 싶긴 한데... 아직 방법은 찾지 못했습니다. (아니면, 테스트에 사용한 나눔고딕에 한자 필드가 아예 없는게 아니라, 공백으로 넣어뒀을 가능성도 있겠군요...)
2 . ITextLayoutFormat, TextLayoutFormat
TLF 에서 사용하는 TextLyaoutFormat 은 크게 paragraph (문단) 의 모양을 조절하는 기능과 font 의 모양을 조절하는 기능 (FTE 에서 FontDescription) 과 글의 모양을 조절하는 기능 (FTE 에서 ElementFormat) 과 그 외, 몇가지 추가적인 기능들이 짬뽕되어 있는 포맷 형식 입니다.
이전에 사용하던 TextFormat 보다는 상당히 디테일한 지원을 해줍니다. 딱히 정리해서 설명하긴 어렵고, TLF 를 사용할때 모든 모양에 대한 조절을 원한다면 이 flashx.textLayout.formats.ITextLayoutFormat 을 살펴보면 됩니다.
다만, 링크에 대한 서식설정은 FlowElement 에 존재하는 linkNormalFormat, linkHoverFormat, linkActiveFormat 을 사용해야 합니다.
3 . 마법의 InlineGraphicsElement
TextFlow 상에 여러 그래픽스 오브젝트를 넣는데는 InlineGraphicsElement 가 사용되어질 수 있습니다. 이게 단순히 그림만을 지원하는 것이 아니기 때문에 원한다면 DisplayObject 를 상속받은 모든 그래픽스 오브젝트들을 TextFlow 상에 집어넣을 수 있다는 이야기가 됩니다.
제 경우에는 TLF 에 없는 html 의 <hr> 기능이나 <ol>, <ul> 등의 기능을 이 InlineGraphicsElement 를 통해 구현시켰죠. 원한다면 <table> 과 같은 고급 서식 기능을 만드는 것도 불가능하지 않다는 이야기가 됩니다. 그리고, <video> 기능을 문서 흐름속에 포함시킬 수도 있다는 이야기가 되겠죠...
InlineGraphicsElement.source 는 크게 세가지 정도를 줄 수 있는데, "image.png" 와 같은 String 형태의 uri 와 DisplayObject 로 인스턴스가 생성되는 class, 마지막으로 아싸리 DisplayObject 자체를 집어넣을 수 있습니다.
이 기능은 아직 저차원적인 수준의 지원만을 해주는 TLF 를 보다 강력한 문서표현이 가능하도록 확장시킬 수 있는 기반이 되어줍니다. 사용하기에 따라서 여러가지 것을 만들 수 있을 것 같네요.
이미지 uri 의 경우, ContainerController 에 문서 구현을 시켜주면 자동으로 로드처리를 해주는데 이때, StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE 이벤트를 감지해서 container update 를 시켜줘야 합니다.
그리고, InlineGraphicElement 에는 좀 특이한 버그(인지 아닌건지 잘 모를 에러)가 있는데, InlineGraphicElement 중에서 source 가 uri 로 지정된 녀석이 하나라도 있으면 Selection 시에 문제가 없는데, 아예 자체적으로 생성된 DisplayObject 나 Class 로만 source 가 구성된 녀석들만 있으면 Selelction focus 가 들어가는 순간 모든 그래픽스들이 removeChild 되어서 사라져버립니다... (ㅡ ㄴ ㅡ;;;) 이건 버그인건지 뭔지 잘 모르겠는데... 그런 문제들이 지속적으로 발생한다면 더미로 uri 로드를 하는 녀석을 하나 박아넣으면 해결이 됩니다.
4 . TLFTextField, ContainerController, TextLineFactory 의 선택
TLF 의 텍스트 표현에는 크게 세가지 정도의 선택이 있습니다.
일단, Interaction 이 전혀 되지 않는 순수하게 그림을 그리는 용도로 사용할 수 있는 TextLineFactory 기반의 기능들이 있습니다. 글자마다 서식이 다른 복잡한 녀석이라면 TextFlowTextLineFactory 를 사용할 수 있고, 서식이 하나로 통일된 단순한 녀석이라면 StringTextLineFactory 를 사용할 수 있습니다. 이 Factory 방식은 인터렉션이 필요하지 않은 아주 디스플레이용 글을 표현할 경우에 매우 유용합니다. 그리고, 무엇보다 이 Factory 방식에서는 truncation 기능 (긴 글의 마지막을 ... 으로 줄여주는 기능) 을 사용할 수 있기 때문에 굉장히 유용합니다. 주의할 점으론 TextLine 을 사용하고 난 뒤에는 수동으로 TextLineRecycler 를 통해 풀에 다시 집어넣어줘야 한다는 점 정도가 있겠네요.
그리고, ContainerController 나 좀 더 단순화된 TextContainerManager 는 좀 더 디테일한 기능의 조절이 가능합니다. 말 그대로 TextFlow 를 컨트롤하는 원천이기 때문에 Interaction 이 가능한 글을 만들려 할때는 가장 베이스가 되는 녀석입니다. 다만... 원천인 녀석답게 단순하게 쓰는데는 매우 편리하고 가볍지만, 복잡한 "쓰기", "스크롤" 기능들을 만들때는 매우 해야할게 많습니다. 특히나 쓰기에서 displayAsPassword 나 restrict 기능들이 하나도 구현되지 않은 정말 저수준의 녀석이기 때문에 시간이 넘쳐 흐르지 않는 이상 이 것으로 "쓰기" 기능을 구현하지 않는 것이 정신건강에 좋습니다.
마지막으로 Flash 에 포함되어 있는 TLFTextField 나 Flex SDK 에 포함된 input component 들이 있는데 쓰기 기능들을 구현하는데는 그냥 만들어져 있는 이 기능들을 사용하는게 좋습니다. TLFTextField 의 경우엔 좀 Class 가 정체를 알 수 없는 느낌으로 TextField 적인 api 와 TLF 의 api 가 짬뽕된 녀석이라 좀 거시기하지만... 정신의 평온을 위해선 이걸 쓰는 것을 추천합니다.
결론을 이야기 하자면
걍 디스플레이 용도의 간단한 텍스트 = TextLineFactory 계열
자유롭게 커스텀 할 수 있는 간단한 용도 = Controller 계열
쓰기 등 복잡한 처리가 필요한 폼 형식 = TLFTextField 등의 컴포넌트 계열
을 사용하면 될 것 같습니다.
사용법이 각각 계열마다 상당히 큰 차이가 나므로 익혀야 하는 api 수가 TextField 보다 많지만, 이래저래 성능 고려하거나 합리적으로 만들려고 할때는 도움이 많이 됩니다.
5 . TextFlow 의 후가공 처리
TextFlow 에는 getElementByID 와 getElementsByStyleName 이라는 두가지 메서드를 통해서 각 Element 를 불러오는 것이 가능합니다. 이 기능은 CSS 라는 일괄 서식지정 기능이 없는 TLF 에 도움이 많이 되고, 특히나 위에서 이야기한 InlineGraphicsElement 등을 사용하는데 도움이 많이 되는 편입니다.
getElementByStyleName 을 통해서 같은 스타일의 Element 들을 일괄적으로 모은 뒤에 서식지정을 한다거나 하는데 도움이 많이 됩니다.
6 . TextConverter, ITextExporter, ITextImporter
TLF 가 기존 TextField 보다 좋아진 점 대표적으로 꼽을 만한 것은 XML 형태의 전용 마크업 언어가 있다는 것인데요... 이를 통해서 서식이 지정된 텍스트를 저장하거나 읽어들이는 작업이 가능합니다.
다만, 마크업 언어 자체가 아직까지는 단순 서식 문서 정도만 지원하기 때문에 복잡한 처리를 위해서는 필연적으로 위에서 언급한 InlineGraphicElement 를 통해 확장시킬 필요가 있습니다.
제 경우에는 복잡한 쓰기 기능은 그냥 TLFTextField 를 사용하기로 했기 때문에 주로 flashx.textLayout.container 와 flashx.textLayout.conversion, flashx.textLayout.elements, flashx.textLayout.factory, flashx.textLayout.formats 만 보고 있습니다. flashx.textLayout.operations 나 flashx.textLayout.edit, flashx.textLayout.undo 의 경우엔 만지기 시작하니깐 사람 상당히 피곤하게 만드는 경향이 있어서 작업하다가 아예 포기해버렸습니다. 뭐... 혹시나 플래시로 위지윅 에디터 만들려는 사람들 아니라면 딱히 만질일이 별로 없는 부분이기도 합니다. 쓰기 부분을 피해서 알아보면 의외로 분량이 그다지 많지 않은 편입니다. 텍스트 엔진을 TLF 베이스로 바꾸고 싶으신 분들에겐 조금 참고가 되지 않을까 하네요...
그럼 이만~ 앙뇽~
2010년07월14일 10:10
깔끔한 정리.. 좋은내용 감사합니다.