Need Help Getting String Width via ASObjC

I know I should be able to figure this out on my own, but I’ve been poking about for a couple hours and haven’t had much success.

Here’s my problem: I need to measure the width of a string, given a specific font/size. I found the following Cocoa code on stackoverflow.com:

UIFont’s font = [UIFont fontWithName:@“Helvetica” size:30];
NSDictionary *userAttributes = @{NSFontAttributeName: font, NSForegroundColorAttributeName: [UIColor blackColor]};
NSString *text = @“hello”;
const CGSize textSize = [text sizeWithAttributes: userAttributes];

The question is how to translate that into ASObjC, so I can incorporate it in a script. (Of course, if there’s a better way, I’m ready to learn.)

Following closely. Is this in a specific app? I’d like to do this with inDesign as well.

Any code that uses UI-prefixed classes is for iOS, not macOS. In this case, there’s not a lot of difference, though:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

set theFont to current application's NSFont's fontWithName:"Helvetica" |size|:30.0
set userAttributes to current application's NSDictionary's dictionaryWithObjects:{theFont, current application's NSColor's blackColor()} forKeys:{current application's NSFontAttributeName, current application's NSForegroundColorAttributeName}
set theText to current application's NSString's stringWithString:"hello"
set textSize to theText's sizeWithAttributes:userAttributes
--> {width:63.36, height:29.0}

No – it’s the OS. Apps like InDesign do their own calculations.

You can calculate it in InDesign using the horizontal offset and either descent/ascent or baseline properties.

Thanks, I’ll try that

@estockly

Text coordinates can be more accurate by using a vectored version of the selection.
Take a look at this code:

tell application id "InDn"
	tell selection
		set textBase to baseline
		set textBottom to end baseline
		set textAscent to ascent
		set textDescent to descent
		
		set textLeft to horizontal offset
		set textRight to end horizontal offset
		
		set countLine to (count of line)
		
		if countLine > 1 then
			set {textBottom, textDescent, textRight} to {0, 0, 0}
			
			repeat with iLine from 1 to countLine
				tell line iLine
					set a1 to end baseline
					if a1 > textBottom then set textBottom to a1
					set a2 to descent
					if a2 > textDescent then set textDescent to a2
					set a3 to end horizontal offset
					if a3 > textRight then set textRight to a3
				end tell
			end repeat
			
		end if
	end tell
	set textAscent to textBase - textAscent
	set textDescent to textBottom + textDescent
	set textMiddle to textAscent + ((textBottom - textAscent) / 2)
	set textCenter to textLeft + ((textRight - textLeft) / 2)
	
	
	tell selection to set newbox to create outlines without delete original
	if (count of newbox) > 1 then tell active document to set newbox to make group with properties {group items:(newbox)}
	
	set {vectTop, vectLeft, vectBottom, vectRight} to geometric bounds of item 1 of (newbox)
	
	set vectHorizontal to vectTop + ((vectBottom - vectTop) / 2)
	set vectVertical to vectLeft + ((vectRight - vectLeft) / 2)
	
	delete newbox
	
	{textAscent, textLeft, textDescent, textRight, textCenter, textMiddle} -- with typo
	{vectTop, vectLeft, vectBottom, vectRight, vectVertical, vectHorizontal} -- with vector
		
end tell

Perfect! Thanks so much. (Hey… I thought you were on vacation!) :wink:

This is all very helpful.

The reason I need this info is I have a table with numerous cells of various widths that get filled with text that has three separate character styles. The goal is to put as much information into the cell as possible without a text overflow. If I can accurately and consistently predict exactly how much Bold/plain/styled text a cell can hold I could completely automate a daily task that takes users about an hour to complete.

Because the text styles are modern and well designed, I can’t just count characters. I’s use much less horizontal space than Ws and Ms, for example, and subtler differences with other letters. So I plan to come up with a formula to predict the length of any string combination of Bold/plain/styled text to determine what will exactly fit in a given cell.