I’ve been thinking a lot about TLF over the past few months; not just about how to use it, what features I like, or what bugs I’ve encountered, but about the philosophy and underlying model it’s built on. I’m hoping that by sharing these thoughts and getting input from the community, I can provide useful feedback to Adobe both about TLF and their future efforts.
I’m sure I’m oversimplifying in some places, and completely wrong in others. Please excuse any errors.
Background
Flash Player 10 introduced the flash.text.engine.* (FTE) package, which contains classes that provide low-level text handling capabilities. FTE is extended by a set of ActionScript 3 classes in the flashx.textLayout.*, known as the Text Layout Framework (TLF), which is shared between Flex and Flash Pro. These classes provide abstract FTE somewhat, but remain fairly low-level.
Flash Pro exposes TLF through a new TLFTextField component, which provides IDE integration and a high-level AS3 abstraction that closely mirrors the TextField API, but with a broad range of new text and typography features. These include multi-column text, text threads (aka linked fields), right to left and vertical text, and a host of typographical enhancements.
The Flex 4 framework exposes TLF through 3 primitives: Label, RichText, and RichEditableText. These provide increasing levels of capability. Label displays a single line of text with a subset of formatting options. RichText supports multiline text with inline graphics and full formatting. RichEditableText adds links, editing, scrolling, and selection. Flex does not have support for text threads.
Philosophy
TLF illustrates a philosophical shift in API development for Adobe. With TLF Adobe chose to expose only a very low-level player API, then build a “standardized” higher-level AS3 API on top. The reasoning behind this appears to be to reduce player size, and facilitate development of the TLF libraries without a dependency on player updates. This means developers can utilize new TLF features as they are released without having to wait on a new version of player to achieve acceptable penetration.
The intent is good, but I’m not convinced it is the best approach in this case. With virtually no exceptions, text is a core element of every project built on the Flash platform. Making core text capabilities dependent on an ActionScript library introduces a variety of issues that I personally feel outweigh the advantages listed above.
File size
The core TLF library weighs in at about 160kb. This is exported as a signed RSL (.swz) beside your SWF. This means that once a user downloads the .swz for a specific version of TLF once, it should be cached locally and reused whenever the library is subsequently used, including on other domains.
This is nice, but if TLF is the future of text in Flash, and text is core to all experiences, it invalidates any benefit to player size. If all users will need to download the RSL anyway, you’re just distributing the problem. I’m also under the (perhaps mistaken) impression that the functionality would be smaller if implemented natively in the player.
Even with the RSL, using a TLFTextField in Flash Pro introduces an additional 60kb to your SWF. This is a pretty big hit for just putting hello world on the stage, and makes TLF unusable for banners and other experiences with file size restrictions. Exacerbating this, Flash exposes TLF as just another text option, not as a component, which makes its cost unclear.
Performance
Because TLF is implemented in ActionScript, it suffers from the same performance problems and memory issues as other AS3 code. Performance in AS is magnitudes better than it used to be and 10.1 brought significant improvements to memory use. However, AS performance remains *much* slower than native code (10-100x in many cases), and memory use is still much higher.
TLF suffers greatly from this. It uses far more CPU to manipulate and display text than TextField, to the extent that Adobe has recommended not using it for mobile devices, and is considering development of a light-weight implementation of TLF specifically for devices. I find it disappointing, and a little ironic, that two of the most important new initiatives for the Flash platform, developed in parallel, are incompatible.
TLF also consumes much larger amounts of memory than TextField. Beyond the memory cost of the AS framework itself, it has to generate huge AS object models describing text structure and layout. It also generates large numbers of display objects (TextLine) to display the text.
This is made even worse by the fact that in TLF all of these objects are generated and maintained for all text in a scrolling text region, not just the visible text. While only the visible text is rendered to screen, there is still a display cost for every TextLine instance as it has to be iterated and culled from the scroll rect. This means there is a high cost for both memory and performance associated with large amounts of text in a scrolling text area. In TextField, this cost is very low.
Flash performance is already a hot enough topic. TLF’s AS implementation is going to make it worse.
Consistency & Complexity
TLF represents the first major collaboration between the Flash Pro and Flex teams. This collaboration is a *great* thing!! I cannot emphasize this enough. These teams really need to work together to create a unified component framework and integrated authoring platform, and I hope that TLF provided an opportunity to really test these waters. Unfortunately, I don’t think they went far enough.
Right now, Flash Pro has a very decent high level abstraction of TLF with TLFTextField. It exposes an almost identical interface to TextField with a lot of nice additions. It’s easy to work with, and simple to extend.
Flex, regrettably, does not appear to have any similar high-level text control built on TLF. Even TextArea lacks most of the functionality of a TextField. To achieve even very simple tasks like finding the position of a character, you are forced to wade through the TLF library, and dabble in FTE.
At this point, I am concerned it will be difficult to retrofit these capabilities into Flex’s spark architecture. I also wonder if these features are missing because of their performance implications when implemented in AS.
Versioning
I understand the benefit of being able to version TLF separately from the player, but leveraging it introduces another set of problems. Firstly, it reduces the efficacy of the cached RSL – it has to be downloaded and cached for every new version. It also has obvious implications for team development, custom controls, and commercial or OSS libraries / components that target TLF. None of these are huge issues (except perhaps the last one), but they still reduce the overall benefit of the model.
Thoughts
As someone who has messed around pretty deeply with the TextField APIs, trying to force it to do some of the things that are possible with FTE (multi-column, decorations, etc), I appreciate the inclusion of low level text APIs. However, I think text is too integral to interactive media to not make usable and performant APIs a core part of the platform.
What I would really like to have seen, was the same low-level FTE API, extended with a player level API for text layout similar to TLF. This could be built on a set of interfaces (as it already largely is) to make it easy to write alternate AS3 implementations of these classes. Further, I would have liked to see a usable text field implemented at the player level on top of these APIs, with most of the functionality of TLFTextField. It would expose an ITextField interface which TextField would also be retrofitted to support.
Ideally, this would provide greatly enhanced performance and reduced memory footprint, while still enabling developers to dig deeply and create custom implementations. It would guarantee a consistent API and implementation between Flash and Flex and even allow developers to work with many aspects of text without knowing if the container is TLF or a TextField by typing as ITextField. While it would increase player size, it would reduce the overall bandwidth spent on downloading TLF related elements. Adobe could even update some aspects of TLF between player versions by providing AS3 extensions of the built in classes.
It may be too late to do this, but I don’t think so. The current player APIs would not have to be changed, which means current content wouldn’t break. The current TLF APIs and a TLFTextField equivalent could be implemented natively in the flash.* package, without breaking the current AS3 versions. A future version of the Flex framework could migrate to use the native API with minimal disruption. Likewise, Flash Pro’s TLFTextField could be stripped down, and become viable for banners and mobile.
If this can’t be done, I’d like to at least see some engineering time spent fixing and enhancing TextField, so that we can continue using that when TLF simply isn’t the best choice.
Even if it is too late to fix (in my opinion) TLF, I think it’s important to raise discussion around Adobe’s new philosophy to help steer future decisions. I don’t think Adobe should go as far as MS has with Silverlight, where controls/components are embedded in the player, but I do think that elements that are as core as TLF belong in the player.
There’s a lot more I’d like to say, but this is getting long, and I think it covers the most pressing topics. I’d love to hear what you think in the comments.