Since last week, pretty much the most requested feature has been text flow around inline graphics. Yes, even more than editability. I’ve had cleaning up and adding advanced features to the TextLayout and TextContainer on the tinytlf 1.0 roadmap for a while, but last night I finally got to work on it. These classes are only preliminary, but I hope they demo just how powerful tinytlf’s layout architecture can be.
As always, the source is available here: source for these demos.
Text Layout
Ok, so say we have this wikipedia entry about the fascinating Atrophaneura hector (Crimson Rose) butterfly. It’s a nice article, and tinytlf formats it well (except for the TLMR bug):
Don’t encyclopedia entries come with an image?
Much better!
Put that image where you want it
Alright, now we’re rockin’
Ok, I know this is ugly, but I thought I’d show off a little bit. You aren’t constricted to docking on the left or the right, the new layout algorithm will wrap text around images no matter where they are in the markup.
Features
This shows off some features I’ve never talked about before. Of course there’s flow around the image, but that’s really just some fancy layout math, it’s not too complicated. I’m probably most proud of the fact that tinytlf intelligently renders only the invalid TextLines.
Invalidation
This is a Flash Text Engine feature, but it’s one that I love: when members of the FTE ContentElement model change (text, ElementFormat, etc.), the TextBlock will tag the TextLines which render the content “invalid.” The FTE can’t automatically update the TextLines; whomever renders the TextLines (tinytlf, in this case), is responsible for surgically removing and re-rendering the invalid lines.
It’s a delicate procedure, but tinytlf handles it like a champ. You see the result of this in the examples whenever you roll over an anchor tag and it changes fontPosture or color.
Layout
The second part of this is the little bit of fancy math I did to break and layout the lines in the proper order. If you want to see the algorithm, check out the newest ImageFlowContainer here.
It’s not too difficult. Basically, as I lay out the lines, I calculate the (x, y) position for the next TextLine. Because I can change the x and y independently of each other, I can break TextLines across the plane of the graphic.
Where can it go from here? My next feature will be to respect padding set on the <img/> tag. After that will be allowing a way for the <img/> to specify whether it renders inline, causes line/paragraph breaking, etc. There’s a lot that can be done.
Caveats
I haven’t tested this with more than one image. In theory it should work, but I’ve been awake for longer than 24 hours, so I can’t trust I’m actually thinking as clearly as I think I am o.O.
And yes, there’s a bug with the links. It’s especially prominent here, but basically when you move the mouse very quickly, the FTE TextLineMirrorRegions dispatch a “mouseOver” but never its corresponding “mouseOut.” If anybody on Adobe’s TLF or FTE team can shed some light on this situation, I’d be very grateful.
That’s it, happy coding. Fork it on github!
Tags: Flash Text Engine, text layout, tinytlf



Wow, I have had to work really hard at bending TLF to what I need. When this is stable, I will definitely integrate into my project. Really really great work.
Thanks! Any specific feature requests?
I’ve got one! Img tags should be able to use linkage ids, i.e. of embedded symbols.
Interesting, so something along the lines of <img src=”@Embed(‘myFlashLibrarySymbol’”/>?
I have plans to support external SWF embedding (super easy since Loader loads SWFs too), and I have plans to put in embedded components, like Flex lists and whatnot.
Both of these are currently possible without anything else from me, but it would be nice to have an extension IContentElementFactory which does it for you… :)
Very interestting! Are you going to add tables?
Tks.
Yes and no. Yes I have plans to do it, but not for v 1.0.
A table is just a special kind of GraphicElement. The FTE GraphicElement encapsulates any DisplayObject, so it’s possible to embed user interface components into your TextField (yes, even Flex components). When I get more time, I’m going to write a tinytlf Table component (like the TextField component) which builds itself out based on the children of the <table/> tag.
So yes, it’s possible and I have given it some thought :)
This is really neat! Using your TextField has eliminated the spacing problems we’ve been having using HTML text in flash.text.TextFields. However, your TextField doesn’t seem to be able to use embedded fonts unless the font is embedded in the same class the TextField is in. We’re embedding several fonts in class at the root package and all the flash.text.TextFields are able to use the font, but not your TextField. Do you have any idea as to what would be causing this?
Yep, the way you embed fonts changed for the FTE. Fonts that are embedded and can be used by the legacy TextField can’t be used by the Flash Text Engine, and fonts embedded for the FTE can’t be used by the legacy TextField. If you want to use the font in TextFields and the FTE, you’ll have to embed it twice, once with CFF and once without:
For the TextField, use embedAsCFF=”false”, for the FTE use embedAsCFF=”true”.
That *almost* did the trick, but not quite. We are compiling against Flex 4 using the compiler option -managers flash.fonts.AFEFontManager. That allows you to use font embeds without the embedAsCFF option and they will work in legacy TextFields (we didn’t know embedAsCFF existed). Turns out that the manager ignores the embedAsCFF option you specify, so you can’t use AFEFontManager with FTE. The solution was to remove that compiler option and stick embedAsCFF on all our embeds, true for use with FTE TextFields, false for legacy. Good lord, Flash really screws you sometimes.
Truth.
[...] 2010 If you haven’t been following Paul Taylor’s work on TinyTLF, then check out the latest example of his work here. Having wrestled with the Adobe TLF in the past, I’m a big fan of TinyTLF. You will also [...]
Hi, great work.
If you are interested, I already created a full CSS parser in AS that I’m using to style my components.
Check it out at: http://code.google.com/p/efxflashsource/source/browse/trunk/efxflashsource/source/extremefx/modules/css/StyleSheet.as. It has some dependencies on other classes, but it should be really easy to remove the dependencies.
Hope it helps!
Good job on the CSS parser, tinytlf’s extensions lib currently has dependencies on F*CSS, Jesse Freeman’s CSS parser. If you want to benchmark against his 1.1 branch, I’d be very interested to see the results (so would he)!
This is nice, man. I’ve been waiting for TLF-alternatives long ago … TLF is too heavy and troublesome to my point of view…
Thanks.
Many thanks for this great project. I am really exited about it so for.
I’ll be watching it closely and maybe (/hopefully) be able to contribute to it in the future.
My wish list (besides lists and floats you already working on):
- content editing,
- columns that can be (optionally) viewed per page and (optionally) can be balanced,
- straddle heads = all column spanning (sub)heading
Best regards,
Benny
Benny,
Editing is a doozy. I’ll have more of an explanation later, but it’s probably not going to be in 1.0.
Can you elaborate on this? A paginating textfield? Interesting.
This requires a second layout pass, which I’ve been considering adding… basically, before you render the TextLines, you have no idea of how many you’re going to end up with. Once you have them all there you’d have to go back and lay them out differently to auto balance.
This could be accomplished with a TextContainer that spans the length of the columns along the top.
Well my wishes come down to all features required to build something like the Times Reader 2.0 which was build by extending/rewriting parts of TLF 1.0. (https://timesreader.nytimes.com/webapp/wcs/stores/servlet/AppLogin?storeId=10001&catalogId=10001)
The Times Reader shows the pagination I am after. You’ll see that the columns fit the current page height and width and the number of columns or the height of the columns adepts to the new dimensions when the container is resized. I think this is an essential requirement for columns to be the most useful because the user will never ever have to scroll from the bottom of a long column to the top of the next. Instead all columns on a (dynamic sizable) page can be read without scrolling and when the last column is read the reader simply requests the next page.
What plans do you have for editing. Is it on your road map for the 2.0 release? What time frame do you have in mind for that?
The column sizing you’re talking about is less of a requirement on the core framework, and more of a requirement on the component developer. I’ll eventually give more love to the components package once I’m done developing extensions and gestures.
Editing likely won’t ever make it in. Not because it’s impossible, or even particularly difficult, but because it’s tedious and time consuming. I just can’t spend time on it unless someone’s willing to pay for it. Not to say that editing in tinytlf won’t exist, but if it does, it’ll likely be in a commercial component or package of some sort. What can I say, I’ve gotta eat.
There’s nothing stopping you from writing editability into tinytlf yourself. Tinytlf gestures make it really simple to capture all the necessary interactions, then activate the proper editing behaviors. The bulk of the work really that involves manipulating FTE ContentElements and TextBlocks. That’s the tedious part.
Wow, This is pretty good. I wanted to use this in my project. Do you have an Editor for this ? Like the demo editor provided by Adobe ? I am looking for a Rich Text Editor to compose this kind of content.
Nope, editability isn’t a requirement I’ve put on the roadmap. I have plans to release something later, but it’ll likely be a commercial component or exist in an enterprise library of some sort. I’ll have more details at my 360|Flex presentation next week.
[...] This post was mentioned on Twitter by Gilles Guillemin, Simon Bailey. Simon Bailey said: Had shamefully missed Paul Taylor's tinyTLF http://bit.ly/aXS88o http://bit.ly/dDp0Nc and http://bit.ly/bsrTV4 – (via @gillesguillemin) [...]
Source link is broken. Its still in google cache so i doubt its been down long.
This project is great stuff, keep it up.
This looks great. However I have a few questions:
1) Does TinyTLF support RTL/BIDI text? (Hebrew, Arabic etc.)
2) All the examples with links allow the text to be selectable. Is it possible to allow links on a non-selectable text?
3) Can TinyTLF work for Flash-based projects?
4) I haven’t managed to run a single example of the tests you have provided. I am using FlashDevelop and it constantly gives me errors (sometimes missing imports, sometimes the font embedding is missing an attribute etc.). Can you provide a complete working Flash-based download, please?
Thanks in advance!
Hi!
TinyTLF seems to be cool and I would like to use it in some projects. But, I have problems to start using it. I downloaded zip form github, but how I can add it into flex project?
Do I have to somehow build it or what? Is there any tutorial on sample how to get started.
Hope someone can give me little help!
Regards,
th