Skip to main content
Sébastien Périer17107209
Community Manager
Community Manager
July 31, 2023
Question

New Text Scripting Hooks starting After Effects Beta 24.0x14

  • July 31, 2023
  • 5 replies
  • 6096 views
Hello everyone,

We’re very happy to announce that starting in today’s build (24.0x14), we have added 42 new scripting hooks for text and font manipulation. Our goal with these new hooks is to match in scripting what is available in the UI.
 
In addition to extending the TextDocument object, we’ve also added two brand-new objects:
  • Fonts Object: The Fonts object provides information about the current font environment on your device. It will allow you to retrieve all the available fonts and iterate them.
  • Font Object: The Font object provides information about a specific font and the font technology used, helping disambiguate when multiple fonts sharing the same Postscript name are installed on the system.

 

You can see the full list right here, along with documentation for the new hooks and objects: https://ae-scripting.docsforadobe.dev/introduction/changelog.html. Remember, these scripting hooks are currently in Beta and are subject to change.
 
We’ve also attached a demo script panel to this post that exercises all of the new hooks. You will need to rename the file's extension from .jsx.txt to .jsx to run it inside AE.
 
We're excited to see what you'll be able to do with these new scripting capabilities!
This topic has been closed for replies.

5 replies

Inspiring
February 8, 2024

Hi there,
Is there a way to know if a character is selected so we can run a script on that selected portion of a text layer?




Adobe Employee
February 8, 2024

Nope, not at this time.

 

Good idea, though.

 

Douglas Waterfall

After Effects Engineering

Inspiring
February 8, 2024

Thanks for replying!
If you can add it, it would be wonderful. Have a think about it.

Cheers

Inspiring
August 13, 2023

I've been playing with this new functionality the last few hours. Really impressed by how thorough it seems to be. There's lots of new stuff in TextDocument too which will take a long time to digest. I have no idea what half of it even does yet from just the basic descriptions on docsforadobe.dev. FontObject.writingScripts is interesting. Seems like it could be another way to help a user narrow down relevant fonts. How many fonts do support Klingon I wonder!

 

I've got a basic font family dropdown going, that then populates a style dropdown onChange. I guess if our own dropdowns have the full font family list we can query the allFonts entry for styles by the selection.index, otherwise we can loop through allFonts to find the family to then query the styles, which seems fast enough. And likewise use getFontsByFamilyNameAndStyleName to retrieve the postScriptName from the pulldown selection.text to apply to a textDoc.font, and getFontsByPostScriptName to turn textDoc.font back into the UI style family and style naming.

 

Is there any possibility of tapping into a Character panel font favorites flag (or method for getting/setting it) for font family? I always figured I'd need a favorites manager of my own, but requiring a user to create another set of favorites if they already have them in the Character panel isn't ideal. If the favorites flag could be read/write then even better as we could offer a manager that could affect the Character panel font list too. You could even do things like let users create multiple different favorite profiles for different jobs.

Adobe Employee
August 14, 2023

Hi Paul:

 

I implemented scripting access to both favorites and the mru for my own testing, but it remains internal at this point. Let me think about exposing that.

 

Your strategy for building your font dropdown is...flawed. The reason of course is that PostScript names or Family/Style names are not guaranteed to be unique. So all this translation is going to fail in mysterious ways.

 

You might instead simply keep around a reference to the Font Objects which you get from app.fonts.allFonts in our dropdown. Then when you pick you'll know which font it was without any translation.

 

The new api at TextDocument.fontObject returns an actual Font Object, rather than simply the PostScript name which is returned from TextDocument.font. You might give that a try to see if that works better for you.

 

One thing I suspect you have not yet realized is what happens when fonts are added or removed from the font environment. A FontObject does not have a strong enough reference to keep a font from disappearing and consequently any Font Object can become invalid at any time...which I have found annoying as well while doing automated testing around font environment changes.

 

To fully do what you want you'll need even more properties exposed.

 

Douglas Waterfall

After Effects Engineering

Inspiring
August 20, 2023

Thanks for all that info. Been playing with this some more. I can see how sticking with textDocument.fontObject over textDocument.font (which pretty much becomes obsolete?) keeps things more certain. Having duplicate fonts feels something of an edge case though, as does the specific case where a user uninstalls a font while AE is running.

 

What I've struggled with is resolving textDocument.fontObject back to the entry/index in allFonts. For example if I'm reading a text layer's font, I need to be able to autoselect it in my font menu. Currently I'm looping through allFonts looking for an initial familyName match, then comparing each allFonts[x][y] object to the textDocument.fontObject converted using JSON.stringify.

 

If a font is not installed but found in a project, a new isSubstitute:true entry is added at end of allFonts and to missingOrSubstitutedFonts. Seems pretty straightforward.

 

If a font was installed but has been removed while session is running, I'm still seeing the original entry in allFonts, plus a new one at the end which is what is assigned to TextDocument.fontObject. Strangely I'm getting 2 identical instances in missingOrSubstitutedFonts, both of which match the original entry in allFonts. It seems if I made a reference to the original but now missing allFonts[x][y] fontObject that reference becomes invalid, in a way I can only detect by querying an attribute in a try/catch.

 

A newly added font during a session will automatically insert a new fontObject into allFonts at the expected position. I didn't actually know that was a thing you could do in AE these days.

 

So I'm still trying to wrap my head around exactly the best way to keep track of some list of fonts. Keeping a list of allFonts indices is always a bad idea if new fonts can be added at any time. An array of references to objects in allFonts has potential for those references to become invalid. I suspect JSON would be the way to go for storing a list in prefs at least. And then if allFonts.length ever changes I probably need some routine for re-evaluating the state of the font list. Just going with postScriptName and an ignorance is bliss attitude seems quite tempting still.

 

Is the docsforadobe description for TextDocument.fontObject correct?

"The text layer’s Font object specified by its PostScript name".

Not sure how it relates to postScriptName as it's a FontObject surely?

 

Hope you can expose favorites! What is mru? Something cool and interesting no doubt.

JohnColombo17100380
Community Manager
Community Manager
August 10, 2023

Hi all!

A small update: in response to your feedback, another new read-only attribute has been added in build 24.0x019: TextDocument.composerEngine. This attribute allows you to determine which composer engine was used to create a Text layer, which may prove useful when opening older projects and interacting with those Text layers via scripting. More details are available in the linked documentation.

Known Participant
August 1, 2023

Very exciting! This opens up quite a lot of possibilities!
I noticed the docs saying elements apply only to the first character of a text layer for now quite often. Is there anything you could share around that for now notation already?
But I'm jumping ahead a bit too much now - for now, really excited to start playing with this.

ariel_n
Participating Frequently
July 31, 2023

Hi Sebastian, thanks a lot for these!, really happy to see RTL in there amont all the rest!

 

Any plans for adding TextDocument styles and convert from/to paragrah/point text?
There are already many mantion of these in the forums and would be a huge help to avoid a lot of crazy non-reliable workarounds 😉

Adobe Employee
August 1, 2023

> and convert from/to paragrah/point text?

 

Is this really a common enough workflow?

 

In what circumstances would you use scripting to edit and convert Text Layers in this way?

 

Douglas Waterfall

After Effects Engineering

ariel_n
Participating Frequently
August 1, 2023

Hi Douglas!,

We do that mostly as a workaround for getting the "line height" of the text.
By "line height", I mean, when creating a paragraph text, After Effects places the text's first line baseline some distance from the top of the bounding box,

 

Computing the same "line height" for point text is simply not possible, and we could never figure out a way to do that reliably.  There is the AVLayer.sourceRectAtTime, but that's not the same, fonts can get crazy sometimes and the pixel perfect bounding box is not the same as the "line height". A similar issue was for computing the line left and right bearings for point text, but I don't exatly remember all the details, it's been a while.

 

What we used for years now is creating a box text, and trying to copy the contexts of the point text and then querying the baselineLocs, but it does not always work and when dealing with rich text or multiple languages, it's simlply a nightmare.