5

I need Help Improving and optimizing a Script.

I'm fairly new to java and scripting in general and I've been Trying to do a script that would increase the font Size of a text until it fully fills it's box Limits , and this is what I've come up with so far.

 function textResize(v,n){
    var myComp = v;
    var myTextLayer = myComp.layer(n);
    var myText = myTextLayer.sourceText.value;
    var orgText = myText.text;
    var textBoxSurface = myText.boxTextSize[0]*myText.boxTextSize[1];
    var textPixel = myTextLayer.sourceRectAtTime(0,false);
    var textPixelSurface = textPixel.height*textPixel.width;

    myText.text = "W";
    myText.fontSize = 20;
    myTextLayer.sourceText.setValue(myText);
    textPixel = myTextLayer.sourceRectAtTime(0,false);
    textPixelSurface = textPixel.height*textPixel.width;
    while ((  Math.round((textBoxSurface/textPixelSurface))  >=  Math.round(orgText.length)  ) ){
        myText.fontSize = myText.fontSize +1;
        myTextLayer.sourceText.setValue(myText);
        textPixel = myTextLayer.sourceRectAtTime(0,false);
        textPixelSurface = textPixel.height*textPixel.width;
        }

    myText.text = orgText;
    myTextLayer.sourceText.setValue(myText);

}

it's still inaccurate and even the font size reaches it's limit (1296)!

1
  • Good question, I'm examining the DOM via the Data Browser in the ESTK, there appear to be no readily-available overset text indicator properties. I see a "baselineLocs" array, which I'm not quite sure what that means yet. If there was a way to detect the height of text by itself and compare to the area-text box height, it would be the way.
    – Silly-V
    Commented Apr 26, 2017 at 14:49

2 Answers 2

0

Thats at spot on suggestion Silly-V. I was looking for a similar solution and tried to use baselineLocs. Basically, an array means, as per documentation

line0.start_x, line0.start_y, line0.end_x,
line0.end_y, line1.start_x, line1.start_y, line1.end_x, line1.end_y ...
lineN-1.start_x, lineN-1.start_y, lineN-1.end_x, lineN-1.end_y

With that said, each 4 array numbers declare a single line.

Accordingly, what I did:

During while cycle, reduced font size by X. Checked for the change in baselinesLoc array size.

According whether there is a change or not, set temp status variable. Which controls the while cycle. As long as baselineLocs increases, cycle spins. If it starts decreasing, it stops.

I am not yet finished with the execution, but this is my initial logic behind this. If there are a lot of text and it is not filled in the box, by introducing new lines (while reducing font size), we make sure all text gets filled. On the other hand, if after some point number of lines start decrease, it means we changed the fontSize too much and it needs to be added back.

Of course, later anchor point and position needs to be adjusted, but thats another topic.

0

I have a need to be able to autosize text in a paragraph box to fit a specific height, and have been pulling my hair out trying to figure out how to do this. Using expressions and the scale property to fit the text is not a good solution for me. It would be really nice if Adobe had a way to easily tell if text in a paragraph text box was overflowing the box.

I managed to finally get something working via script. If someone else has a better solution to do this please let me know!

Below is my first pass at the working code. I needs some cleanup, but its working fine. For this to work you need to have a paragraph text field/box, and also a mask (set to none) on the text box. The mask is used as the bounds that you want the text to fit into. Only the height of the mask is used as the text will automatically fit the width of the paragraph text box.

function getActualTextSize(layer) {
    var textProp = layer.property('Source Text')
    var textDocument = textProp.value
    var baselineArray = textDocument.baselineLocs

    var boxTextPos = textDocument.boxTextPos
    var textBoxInvisibleAnchorY = Math.abs(boxTextPos[1])
    var lastBaselineIndex = baselineArray[baselineArray.length - 3]

    // we add 10 at the end to adjust for descenders
    return Math.floor(baselineArray[lastBaselineIndex] + textBoxInvisibleAnchorY + 10)
}

function autosizeText(textLayer) {
    var textProp = textLayer.property('Source Text')
    var textDocument = textProp.value

    //  GET THE BASELINE LOCATIONS OF THE TEXT
    var baselineArray = textDocument.baselineLocs

    // GET BOXTEXPOS
    var boxTextPos = textDocument.boxTextPos
    var textBoxInvisibleAnchorX = Math.abs(boxTextPos[0])
    var textBoxInvisibleAnchorY = Math.abs(boxTextPos[1])

    var boxTextSize = textDocument.boxTextSize

    // GET THE MASK DIMENSIONS
    var theMaskPath = selection[0].property('Masks').property('Mask1').maskPath
    var theMaskShape = theMaskPath.value
    var theMaskVertices = theMaskShape.vertices
    var maskHeight = theMaskVertices[2][1] - theMaskVertices[1][1] // bottom left Y - top left y

    // NOW WE GET THE ACTUAL HEIGHT OF THE TEXT IN THE TEXTBOX.
    var lastBaselineIndex = baselineArray[baselineArray.length - 3]
    var actualTextHeight = Math.floor(baselineArray[lastBaselineIndex] + textBoxInvisibleAnchorY)
    if (actualTextHeight > maskHeight) {
        while (actualTextHeight > maskHeight) {
            textDocument.fontSize -= 1
            textProp.setValue(textDocument)
            actualTextHeight = getActualTextSize(selectedLayer)
        }
    }
}

var selection = app.project.activeItem.selectedLayers
var selectedLayer = selection[0]
autosizeText(selectedLayer)

Not the answer you're looking for? Browse other questions tagged or ask your own question.