Multi Column Text in Flash 9: TextFlowLite

Ever wanted to be able to display multi-column text in Flash? What about text that spans multiple arbitrary text fields? Sure, Adobe’s Text Layout Framework will let you display multi column text, but it’s still in beta, not to mention that it’s a big, robust framework.

TextFlowLite is a simple, light-weight class that works in Flash Player 9 with standard text fields. It takes one line of code to link any number of text fields together so that the overflow of each textfield runs into the next. Likewise, it’s one line of code to change the text, or reflow it if the textfields are resized.

import com.gskinner.text.TextFlowLite;
// set up the TextFlow, by default it will use the text of the first field:
var tfl:TextFlowLite = new TextFlowLite([fld1,fld2,fl3]);
...
// change the text:
tfl.text = "my new text";
...
// change the size of a field, and reflow the text:
fld1.height += 20;
tfl.reflow();

I built this class about a year and a half ago while working on the Spelling Plus Library, and had meant to release it much earlier. It is part of a set including TextFlow (adds support for orphans and widows), and TextFlowPro (which includes support for selection, editing, copy/paste). I will release the other two for free when I have time to retest and clean them up (hopefully later this week).

Here’s a simple demo:


It’s a pretty simple class, but hopefully it’s useful for someone. As I said above, I will be releasing TextFlow and TextFlowPro in the near future. You can download the source code by clicking here. As usual, the code is released under the MIT license.

Grant Skinner

The "g" in gskinner. Also the "skinner".

@gskinner

27 Comments

  1. 404 error on the download link.

  2. Great tool. Very good.

  3. Good work again 😉

  4. Awesome Grant – you’re classes always are though!

  5. Cool work Grant! Only thing maybe i have missed something, but can you elaborate the parameters passed to the TextFlowLite Constructor ?

  6. Hi Subroto,

    The constructor takes two parameters. The first is an array of textfields in the order that you want the text to flow through them (ex. in the example above it will flow from fld1 to fld2 to fld3). The second parameter just specifies the text to flow between the fields. If you omit the second parameter, it will default to use the text from the first field specified in parameter 1.

  7. Torbjørn Caspersen January 6, 2009 at 12:37am

    Looks amazing.

    How’s the performance when using embedded fonts and anti-aliasing? We’ve used and developed various layout engines over the years and flash’s rendering of fonts have always been a performance issue.

  8. Awesome Grant! It would be great to add a vertical scrollbar to this text!

  9. Awesome man, this is great. This is the one thing Flash was always missing. Thanks for all of your hard work. – Chris

  10. Lovely. Using it now.

  11. Very nice, thank you! How about selecting the text from one column into another and htmlText so the tag wouldn’t break?

  12. To use this with htmlText just replace the 2 lines (65+66):

    fld2.text = fld1.text.substr(nextCharIndex).replace(/^\s+/, ”);

    fld1.text = fld1.text.substr(0,nextCharIndex).replace(/\s+$/, ”);

    with:

    var splitChar:String = “ҖҖ”; //any string that is unique in the text

    fld1.replaceText(nextCharIndex, nextCharIndex, splitChar);

    var nextHtmlCharIndex:Number = fld1.htmlText.indexOf(splitChar);

    fld2.htmlText = fld1.htmlText.substr(nextHtmlCharIndex).replace(/^\s+/, ”);

    fld1.htmlText = fld1.htmlText.substr(0, nextHtmlCharIndex).replace(/\s+$/, ”);

    Hope that helps.

    Josh

  13. Awsome but i still didn’t understand how to use htmlText…

    If i have a tag eg:visit the google website what do i have to replace?

    (instead of “var splitChar:String = “ҖҖ”; //any string that is unique in the text”)

    Thank you in advance

  14. I think that he’s implying when you use “ҖҖ” in the text you are flowing across columns, you can split the column at this point… which only works when you know exactly where you want to break columns (i.e. when you are not resizing anything). Are there any better solutions for dynamic html content?

  15. thanks for the class. i have a little addition that would make it even more useful:

    – a boolean property to find out if there is some hidden overflowed text.

    – a number property to find out how much lines or pixelheight of hidden overflowed text there is.

    those properties would offer a dynamic way to add textfields at runtime to show all the text. what do you think about that?

  16. There is a mistake in your example for HtmlText! The split Char in your Example is a know a visible part of the splitted text. To remove the splitChar, you have to remove the splitchar after processing with the following line:

    fld2.htmlText = StringUtil.replaceString(fld2.htmlText, splitChar, ”);

    To use this with htmlText just replace the 2 lines (65+66) with the (corrected) line:

    var nextCharIndex:Number = fld1.getLineOffset(fld1.bottomScrollV);

    var splitChar:String = “ҖҖ”; //any string that is unique in the text

    fld1.replaceText(nextCharIndex, nextCharIndex, splitChar);

    var nextHtmlCharIndex:Number = fld1.htmlText.indexOf(splitChar);

    fld2.htmlText = fld1.htmlText.substr(nextHtmlCharIndex).replace(/^\s+/, ”);

    fld1.htmlText = fld1.htmlText.substr(0, nextHtmlCharIndex).replace(/\s+$/, ”);

    //remove splitChar

    fld2.htmlText = StringUtil.replaceString(fld2.htmlText, splitChar, ”);

    Best regards

    screenworker, Berlin

  17. Thanks! Worked first time.

  18. quite cool, thx alot – with the HTML fix it´s really great stuff. This is my solution:

    ********************

    protected function flowField(fld1:TextField,fld2:TextField):void {

    fld1.scrollV = 1;

    fld2.htmlText = “”;

    if (fld1.maxScrollV

  19. Great!

    Could someone point me in the right direction for implementing this with dynamically added textfields?

    Thanks,

    Chris

  20. Having some troubles here…

    line 62: 1170 Function does not return a value.

    line 68: 1170 Function does not return a value.

  21. The source code download seems to be for the AS3 version. Is there still an AS2 version?

  22. thanx Grant Skinner for this class. I’m sure it helps many people. thanx josh as well for the htmlText implementation. for me it woked weel after few workarounds to implement it in a separate class. (Chris: u need to embed fonts in the .fla and define TextFormat on both TextFields, dont’t forget the fld1.embedFonts = true).

    To Josh : One problem i came across with the splitChar hint is that the first line of the fld2 is loosing all the html tags. ex. i load my htmlText from an xml where i use on each line. even if i replace them with html the result is the same : there is no break on the first line, all others are ok.

    Please any suggestions or more briliant hints.

    soon,
    i.

  23. /Users/tompeak/Desktop/projects/4e7/quadrium/scratch/com/gskinner/text/TextFlowLite.as, Line 62 1170: Function does not return a value.

    ???

Comments are closed.