are not within reach of scripting at the moment (perhaps they have were added to OmniGraffle after the AppleScript interface was built ?)
I don’t know how feasible it looks, but scripting access to these options, particularly Scale Font, would be very useful.
CONTEXT
In nested tree-like, radial or block-like diagrams, I often need a different font size for each level of hierarchy, and the script has to make some attempt at finding the largest font that would not cause text overflow for any of the siblings at a given level.
This is clumsy at the moment, and needs manual intervention. Being able to resize a text-filled auto-text-scaling shape, and read through the scripting interface what its new font size is, would allow more much more powerful automation of peer-group font resizing.
These scaling options aren’t really that smart. It’s only comparing original and resulting width and then multiplying font size or stroke width by the same factor. E.g. make the shape half as wide via the geometry inspector while ‘Scale Font’ is set, and the font size is also halved. You could easily do the same calculation when setting shape geometry, and it’s simple enough that I think exposing it as API would just add complication without much real functionality.
It sounds like what you really want is different, which is a “fit text to shape” operation that’s kind of the opposite of the existing “fit shape to text”. This would theoretically set the font size to whatever it needs to be such that the text either doesn’t soft-wrap or doesn’t overflow. Then in your case you’d see whatever the smallest such resulting font size was, and set all shapes at that level to the smallest size (so they’d all match and still fit).
I bet the OmniJS interface is fast enough that you’d be best off just temporarily changing the solid autosizing property to Full (if you want to avoid soft-wrap) or Vertical (if you want to avoid overflow), and then probe smaller and larger font sizes until the resulting geometry is less than and as close as possible to the original geometry. Any API that we would add on our end would essentially be doing the same. When I get a chance, I’ll see if I can write this up as an example script, because it does seem like it would be generally useful to Graffle users.
(Much faster than the old AppleScript code chugging away in that gif :-)
If we get it to return a value (maximum fontsize found), we can also map it across a set of peer shapes which need to share a font size, and go from the varied first-pass outputs:
and then run a separate kind of test to find the point of width overflow for a string of that length, with wrapping switched off, allowing a margin for the possibility that some words shorter in char count may be longer in points (M vs 1, and all the complexity that fonts are heir to etc)
Perhaps testing with, e.g. ‘Substantiation’ -> 14 -> ‘MMMMMMMMMMMMMM’ ?
Presumably we don’t have access to font metrics from NSMutableAttributedString etc ?
Unfortunately, there’s no way to tell OmniGraffle to only word-wrap and not character-wrap (in the UI or via JS). In general, the text manipulation APIs is a weak point right now. We want to get in at least as much text manipulation support as Outliner’s OmniJS API has, for example.
You could change my function above so that it will produce a result font size that doesn’t soft-wrap at all (only actual newlines in the text cause a wrap) by changing this line to TextAutosizing.Full:
If nothing else, you could check to see if the shape text is only a single word, and if so use the resizing function with no soft-wrapping at all, and if there are multiple words use the original resizing function. In your example images here that seems like it would do most of the job? If you wanted to do even better you could make a temporary shape and give it text that concatenated together all your text at a level but replacing all spaces with newlines. Run a similar function with TextAutosizing.Full to figure out a font size that fits the original width (but NOT height). That would give you the maximum font size that fit the longest word in all the text at that level without wrapping it. Use that as an additional no-larger-than constraint.
With more complicated text, though, it definitely becomes harder to find heuristics to make them all look good until we provide a lot more granular text APIs. Sorry those aren’t there yet!