Skip to main content
Participating Frequently
October 12, 2021
Question

Autosize font size of paragraph text to fit all text in the textbox

  • October 12, 2021
  • 1 reply
  • 933 views

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)

 

 

 

This topic has been closed for replies.

1 reply

Participating Frequently
October 14, 2021

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)