Last week I had to do something that I never thought of, let me present you the case:
First of all we have a multiline, word-wrapped textfield in AS3, the text is picked up from an external XML file and gets styled with a CSS stylesheet, the textfield CAN have one line or multiple lines (depending on the translation and the language used), if the text is only an one-liner, the graphic (a simple small gray arrow) needs to be placed after the text in the middle of the first line, so you are able to visualize this, think about a standard <li> tag where you get the black dot, in my case just at the other side eg. at the end fo the line. have a look at the Example for a visual clarification what I want to achieve.
Basically a simple task, you grab the textlength add the gutter and margin to it and place the small arrow at that position.. but what do you do when the text goes multine and word wraps automatically?
After doing some experiments, I’ve came up with a simple yet appropriate solution for this.
Let’s start with a simple text field, containing some text and setup for multiline and wordwrapping.
var tf:TextField = new TextField(); tf.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry."; tf.width = 100; tf.multiline = true; tf.wordWrap = true; addChild( tf );
This will display a simple textfield without any formatting with 5 lines of content. Why did I set a width value on my textfield? Well without it, the textfield would just be as wide as the text, resulting in a single line text, and that’s not what we want.
Now we create a simple square / dot / arrow whatever you like acting as a marker for the end of line, so you can visualize what’s happening, I’ve created a small rectangle like this:
var rect:Sprite = new Sprite(); rect.graphics.beginFill(0xff0000); rect.graphics.drawRect(0,0,10, 2); rect.graphics.endFill(); addChild( rect );
Simple rectangle, doesn’t need much of an explanation, maybe you asking yourself why I’ve set it at x & y 0? Although I could position the rectangle right at the proper position I always preferred to use the setters of it so I rather create all my shapes/graphs at 0,0 and move them with myShape.x = 100, it makes things more obvious to read and you find it much quicker then doing directly on the drawRect() method.
Next up let’s have a look at our class that returns the requested values.
public class StringUtil { private static var _lastChar :TextLineMetrics; private static var _x :int; private static var _y :int; private static var _gutter :int = 2; public static function getEndOfLine( tf:TextField, line:int ):Point { _lastChar = tf.getLineMetrics(line); _x = tf.x + _lastChar.width + _gutter; _y = _lastChar.height * line + _lastChar.ascent; return new Point( _x, _y ); } }
What we are doing here is rather simple then you think. First we pass the textfield and the desired line to our static function, then using the getLineMetrics() method we return the desired line’s metrics, this can now be used to set an x and y position of the to be returned Point(). as you see at the _x value, I’m just telling it to add the textfields x position to the width of the requested line, at the end we add the gutter value for the textfield.
The vertical position is another story, here we need to get the height of the desired line and multiply with it. this has the reason that there is no method available to get the proper y position of the line, so by multiplying the textheight with the desired line you get the proper y position of it. After that calculation we add the _lastCahr.ascent property of the line, asking what ascent? Take a look at the image below for more information about it but basically it’s just the length of the baseline to the top of the line height in pixels, so exactly the middle of our text.
Have a look at the image below for a nice and clean overview about the gutter of a flash textfield as well about the other properties a textfield has.
Something you should also be aware of is that the width of the text line is relative to the textfield width, but you need to subtract the gutter width of 4 pixels (2 pixels on each side ).
Now that our class is available let’s take a look at how I used it for this example.
var point:Point = StringUtil.getEndOfLine( tf, tf.numLines - 1 ); rect.x = point.x; rect.y = point.y;
What we are doing here is nothing else then creating a new Point based on the position returned by our class, passing the textfield and specially since I want to have the rectangle on the LAST line I just ask for the textfields number of lines – 1.

When running this example above you should see the small red rectangle on the last line of our textfield. yay!!!
You can download the StringUtil class here: StringUtil.as
Hope this serves you as well as it served me last week, and don’t forget to leave a comment if you have any questions about it.

The AS3: Multiline textfields and Line Metrics by Tiago's Weblog, unless otherwise expressly stated, is licensed under a Creative Commons Attribution 2.5 Switzerland License.




This is exactly what I was looking for. Thanks!
Happy that it helped
Let me know if you have any improvement ideas
How would you make if instead of placing the rectangle at the end of the text you would have to put it as a background of a given word (let’s say after “printing” in the text above). How can I do this?
something like this might work:
I’m currently working on a simple easy to use Class to make it work for multiline textfields and much more..
Stay tuned.
Cool! Thanks a lot! This is great!
And here we go using it again!
@arii & Andrei, thanks for the comments, happy you liked it.
Cool!Thanks a lot Tiago
I have some implement.
if you set ” tf.autoSize = TextFieldAutoSize.CENTER ” you have to edit this code
“_x = tf.x + _lastChar.width + _gutter;
” to “_x = tf.x + _lastChar.width + (tf.width – _lastChar.width)/2 + _gutter ;
“.
Thanks! Very usefull and working as it should work.
hey…for my case,i need to add another Multiline text field with word wrap right after the small red rectangle ..is there any solution to make both the text fields appear in the same paragraphs with that red rectangle located between them…
Thanks for the clean and clear tutorial, very useful
I also got a news here that I thought would be so useful for all of us as Flash devs, Now that we are talking about TextField thought to let you know about a class that is so powerful and is extended from the Adobe TextField class itself.
It’s named TextArea which allows you every possible tags even your own custom tag and has much more abilities too.
Check out http://doitflash.com/ for more information.
It not only allows you to load different SWF files by calling different tags in line of your text but also you have much more control over your Text blocks and its contents… such as calling your custom functions right from your text blocks and passing multiple and different arguments through them; loading talking avatars, video players, buttons, slideshows and more… by calling their own tags and having full interaction between all of the loaded SWF modules and your text block. Check out the site for more information, downloading the platform is also free of charge