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}
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
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.