AS3: Inline graphics using Text Layout Framework

A little bit of history
Few days ago I was working on something which required graphics and text in same line. The text and graphics were fully dynamic. At first I thought it’s a 15 minutes work, as TextField supports HTML img tag. So It should be a simple one line code.

textField.htmlText = "before img <img src='img.png'> after img";

The output was horrible.


As shown in the screenshot, the image was moved on the next line. This is really not inline graphics what I was looking for. Then I checked the manual of TextField again and found that img tag is not fully supported, the image will be placed on the line following the img tag. Well well well, I am not going to write here how I solved the problem, as that was a little bit of dirty solution.

As a result, I was looking for a better solution, Googled and asked a question on StackOverflow. Someone suggested to use Text Layout Framework from Adobe Labs. After checking, I found that this is a very powerful framework and supports many things. And now I am going to write how to show inline graphics using TLF.

Text Layout Framework
So what is Text Layout Framework anyway? It is a AS3 library built on the new text engine of Adobe Flash Player 10 and Adobe AIR 1.5 with lots of features like bidirectional text, vertical text, inline graphics, advanced styling capabilities, selection and editing of text and many more. It requires Flash Player 10 or Adobe AIR 1.5. The library is open source now and it is included in Flex 4 SDK.

Organization of Text in TLF
TLF uses a tree to represent text. Every node in the tree is an instance of a class defined in flashx.textLayout.elements package. The root node is always an instance of TextFlow class. It can have two types of children, instance of DivElement and instance of ParagraphElement which are similar to HTML div and p tag respectively. Similarly DivElement can have two types of children, DivElement instance and ParagraphElement instance. And ParagraphElement can have four types of children, instances of SpanElement, InlineGraphicElement, LinkElement and TCYElement. These four types contain primitive text and graphics. SpanElement represents the text with a common formatting, InlineGraphicElement represents inline graphic elements which are treated as a single character, LinkElement represents a hyper link and TCYElement represents text which can be perpendicular with the rest of the line (interesting?). All these elements are structured hierarchically to represent the entire text in TLF.

Inline graphics using TLF

  1. First I want to embed the test image for simplicity. Don’t want to load dynamically just for this demo.
    [Embed(source='img.png')]
    private static var Img:Class;
    
  2. Create a TextFlow instance which is the root node of the tree.
    var textFlow:TextFlow = new TextFlow();
    
  3. Create a ParagraphElement and add this as a child to the root TextFlow.
    var para:ParagraphElement = new ParagraphElement();
    textFlow.addChild(para);
    
  4. Create the SpanElement to represent the text before the image and add this as a child to the ParagraphElement. I am using the default styling here.
    var spanBefore:SpanElement = new SpanElement();
    spanBefore.text = "before img ";
    para.addChild(spanBefore);
    
  5. Create the InlineGraphicElement to represent the image and add this as a child to the ParagraphElement.
    var inlineImg:InlineGraphicElement = new InlineGraphicElement();
    var img:Bitmap = new Img();
    inlineImg.source = img;
    para.addChild(inlineImg);
    
  6. Create the second SpanElement to represent the text after the image and add this as a child to the ParagraphElement.
    var spanAfter:SpanElement = new SpanElement();
    spanAfter.text = " after img with TLF";
    para.addChild(spanAfter);
    
  7. Now we have our text with inline graphics ready. We need to render this. For rendering simple TextFlowTextLineFactory is used here. There is another sophisticated method for rendering which I am not discussing. TextFlowTextLineFactory is sufficient when user don’t need much control over the text like editing the text. TextFlowTextLineFactory instance has a method createTextLines which takes a callback function and a TextFlow instance as parameters. Naturally TextFlow parameter is the root node of the tree that we are trying to render. The callback is fired when rendering is complete and the DisplayObject is passed to the callback. Then we simply need to add this display object in the display list.
    var factory:TextFlowTextLineFactory = new TextFlowTextLineFactory();
    factory.compositionBounds = new Rectangle(30, 100, 500, 100);
    factory.createTextLines(addTextLineCallback, textFlow);
    
    // callback
    private function addTextLineCallback(textLine:DisplayObject):void {
        addChild(textLine);
    }
    

And here is the result

Conclusion
Full code for this demo can be downloaded from here. Here I have shown only a tiny portion of the power of TLF. It is capable of much more things. Please follow the links in the reference section for the details of TLF.

And as usual, any feedback is welcome.

References

About these ads
This entry was posted in AS3 and tagged . Bookmark the permalink.

8 Responses to AS3: Inline graphics using Text Layout Framework

  1. i want that: test ,
    i want set verticalAlign to middle , but not success , why?

  2. Jagan says:

    Need Help about Vertical Align in TLF…

    I have added an InlineGraphicsElement in TextFlow which has some text in it. and i want to align the text verticalAlign.MIDDLE. ie. the text to be vertically aligned middle to the InlineGraphicsElement. rite now its bottom aligned. how can i make it to middle alligned.. please help me..?

  3. Nemi says:

    Great! Thank you!

  4. Kenny says:

    Hey, just wondering how it would be possible to do this with dynamically loaded images from a server. I know this is a relatively old post, but any help would be appreciated.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s