Copy link to clipboard
Copied
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)
Copy link to clipboard
Copied
Opps, the code above is not working. Below is the fixed code
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.length - 3
return Math.floor(baselineArray[lastBaselineIndex] + textBoxInvisibleAnchorY + 10)
}
function autosizeFontToFit(textLayer) {
var textProp = textLayer.property('Source Text')
var textDocument = textProp.value
// GET THE BASELINE LOCATIONS OF THE TEXT
var baselineArray = textDocument.baselineLocs
// GET BOXTEXPOS. THIS GET THE POINT (INVISIBLE ANCHOR POINT THING)
// FOR THE TEXT BOX. THIS POINT IS THE POINT IN THE TEXTBOX THAT
// THE BASELINELOCS ARE CALCULATED FROM
var boxTextPos = textDocument.boxTextPos
var textBoxInvisibleAnchorY = Math.abs(boxTextPos[1])
// 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.
// FIRST WE NEED TO GET THE BASELINE POSITION OF THE LAST LINE OF TEXT. THIS WILL GIVE US
// THE BOTTOM POSITION OF THE LAST LINE OF TEXT. THEN WE NEED TO ADD THE POSITION OF THE
// INVISIBLE ANCHOR POINT WHERE IT WAS MEASURED FROM AND ADD THAT TO IT.
// THIS GIVES US THE TOTAL HEIGHT OF THE TEXT
var lastBaselineIndex = baselineArray.length - 3
var actualTextHeight = Math.floor(baselineArray[lastBaselineIndex] + textBoxInvisibleAnchorY)
if (actualTextHeight > maskHeight) {
while (actualTextHeight > maskHeight) {
textDocument.fontSize -= 1
textProp.setValue(textDocument)
actualTextHeight = getActualTextSize(textLayer)
}
}
}
var selection = app.project.activeItem.selectedLayers
var selectedLayer = selection[0]
autosizeFontToFit(selectedLayer)