Skip to main content
jn1908
Participant
April 13, 2019
Answered

getting text width of specific lines?

  • April 13, 2019
  • 5 replies
  • 2072 views

hello-

first time posting, be gentle. I'm playing around with good old sourceRectAtTime and while I can get the basics for what I need, I'm wondering if it would be possible to find the width of specific lines of text, between carriage returns? in other words, if I have one text layer that is multiple lines (potentially) but I want to have a shape behind each one that actually corresponds to the width of the specific line it is behind, is that possible? my alternative is of course to utilize multiple text layers but I'd rather be able to automate it so a user can input text with carriage returns and it is all straightforward that way.

any help would be great, thanks!

Correct answer Mylenium

Long and short: Nope. sourceRectAtTime() is exactly that - a layers content bounding box, nothing more. there is no way to derive anything more from it because those values you would need simply don't exist in a form that would be accessibel to expressions. As it stands, your only option would be to do the calculations yourself using string operations and adding known widths of letters up.

Mylenium

5 replies

Dan Ebberts
Community Expert
Community Expert
May 16, 2026

You actually can do it with a single text layer, using the negative time hack. What you do is add an expression to the text layer’s Source Text that changes the text to a single line  for times less than zero. So, for example, if your text has three lines, the full text appears at times zero and greater, only the first line appears at times between zero and -1, the second line at times between -1 and -2, and so on.

The text expression would look like this:

txt = value;
splitTxt = txt.split("\r");
time >= 0 ? txt : splitTxt[Math.min(Math.floor(-time),splitTxt.length-1)]

An expression to read the width of a particular line (first line, in this example) would look like this:

lineNo = 1; // first line
thisComp.layer("Text Layer").sourceRectAtTime(-lineNo + .5).width

 

 

Community Expert
May 4, 2026

It is pretty easy to set up a separate text layer that duplicates each line of a “Master Paragraph”  text layer using an expression like this:

txt = thisComp.layer("Master Paragraph").text.sourceText;
lines = txt.split("\r");
lines[0];

The txt.split(“\r”) will return each line of a paragraph text layer with [0] being the first one. Change the last line of the expression to lines[2] and you would create a text layer that mimics the third line in a Paragraph Text layer.

 

You can then use that text layer to create and position a rectangle that is the size of just the layer you’ve pulled from the “Master Paragraph” layer. If you call that text layer “First Line,” turn off its visibility, and tie its position to the “Master Paragraph” layer, you can then add these two expressions to a Rectangle 1 on a shape layer: 

//Rectangle Path 1;
txt = thisComp.layer("First Line");
w = txt.sourceRectAtTime().width;
h = txt.sourceRectAtTime().height;
[w, h]

// Rectangle Path 1/Position;
ofst = -content("Rectangle Path 1").size[1]/2;
[0, ofst];

Start stacking up text layers you have turned off, add some padding, and it’s pretty easy to end up with a single Shape layer with multiple rectangles for every line of text. This could then be turned into a MOGRT for use in Premiere Pro to automatically create a background rectangle for each line of text that has a different color. 

Another option would be to simply create a separate text layer for each line, keep them turned on, use expressions to line them up and match paragraph styles, alignment, and then create a MOGRT or custom Animation Preset to use in multiple projects. That’s probably the way I would do it.

I have used the

lines = txt.split("\r");
lines[1];

a few times to have an expression drive the font size and style of the second line of text in a title.

MIke45666
Participant
May 3, 2026

Hey, welcome 🙂

Yeah this is a common limitation with sourceRectAtTime. It only gives you the bounding box of the entire text layer, not individual lines. Unfortunately After Effects doesn’t natively expose per-line width info when you’re using a single text layer with line breaks.

One workaround is to split the text by line breaks and use multiple text layers, then apply sourceRectAtTime to each. I know you mentioned avoiding that, but it’s still the most reliable method if you need accurate per-line backgrounds.

If you really want to keep it in one layer, you’d have to get creative. Some people use expressions with text.sourceText.split("\r") and then recreate each line separately using additional layers or a script, but expressions alone won’t let you measure each line’s width directly.

So short answer: not directly possible with a single layer + expressions only. Best approach is either multiple layers or a small script to automate the setup so users can still just paste text once.

Hope that helps 👍

MIke45666
Participant
May 16, 2026

By the way, if you’re into clean UI/home upgrade visuals and modern design ideas, I recently came across EcoTech Windows & Doors — they showcase some pretty sleek modern glass and window concepts.

robertheadrick
Participant
October 26, 2021

I figured this one out by using the Javascript "split" function to divide up the main SourceText property by carriage returns. You do have to use multiple text layers, but they can work in the background and the user can still just be given a single entry field.

Create as many additional text layers as you think you might have lines in an extreme scenario. Add an expression to the source text of each of those layers that's something like this:

textVal=thisComp.layer("Main User-Controlled Text Layer").text.sourceText;
linesVal=textVal.split("\r");
linesVal[0];

The key here is knowing that "\r" signifies a carriage return. With the text divided in that way, just grab a different piece of the resulting array on each layer. Then, wherever you're needing to identify the individual line widths, just reference those helper layers (i.e. "thisComp.layer("Line Width 1").sourceRectAtTime().width;")

Tomas B. aka Tom10
Inspiring
October 28, 2021

This surely works, as long as you know user used only return carriages.

Make sure to check "shift+return" split case as well, which stands for: \x03

 

Other than that, there is also \n next line indicator, but it might be not used in AE's texts. These are three common next-line indicators from text editors.

Mylenium
MyleniumCorrect answer
Legend
April 13, 2019

Long and short: Nope. sourceRectAtTime() is exactly that - a layers content bounding box, nothing more. there is no way to derive anything more from it because those values you would need simply don't exist in a form that would be accessibel to expressions. As it stands, your only option would be to do the calculations yourself using string operations and adding known widths of letters up.

Mylenium

jn1908
jn1908Author
Participant
April 16, 2019

yeah, that's what i sorta figured. thanks for your help!