Text Resizing with ShapeSheet Formulas
We see quite often in Visio’s newsgroups the question; “how do I get my font size to change with the size of my shape?” We’ll tackle that issue with some nifty ShapeSheet formulas, and a bit of philosophizing. So pull up a chair and a warm cup of coffee…
Philosophy Behind Text/Font Resizing
Okay, the question is often phrased more like; “Why the heck doesn’t Visio resize my font size when I resize my shape?!!” For the user who needs that to happen at a particular time, it seems to make perfect sense, but it’s really a philosophical issue.
If you are making a CAD drawing and have a circle with an “A” in that represents some piece of equipment, you probably want the A to get bigger or smaller along with the symbol.
But if you’re creating a flowchart, and you have a process box that needs a slightly longer description, you’d probably get angry if the font-size grew every time you stretched the shape! In this case, the box defines the limits of the paragraph, and the text inside is not symbolic or graphical.
Basic Text Resizing Formula
Okay, okay, enough theory already! What can we do to get our text to resize with our shapes?(!!!) Well, the easiest way to do this is to craft a ShapeSheet formula that compares the current height of the shape to an original height, and multiplies that by an original font size. In mathematical-formula style (ie: pseudo-ShapeSheet-code), this looks like this:
Char.Size = F0 x Height / Height0
Char.Size is the ShapeSheet cell that holds the font size for the shape. It’s located — aptly — in the Character section of the ShapeSheet. F0 is the original font size at the time of design, and Height0 is the original Height of the shape.
So if we create a shape with 12pt font, that is 0.375 in tall, the formula would look like this:
Char.Size = 12 pt * Height/0.375 in
We can see an example in action here:
The font-size for this shape won’t change with the Width of the shape, only the Height. So our formula won’t help us if some wise user makes the shape really thin. But this is good enough for most purposes, and we now have enough font-sizing knowledge to create more sophisticated behaviors.
Scaled Environment Formula
Warning: more theory…
Our basic formula won’t work in scaled drawings, because Visio doesn’t scale certain parts of a shape! I like to borrow concepts from AutoCAD and talk about certain ShapeSheet units being measured in “paper space” and others being measured in “drawing space”. In Visio, we might better call them “Page Units” and “Drawing Units”, but the idea is this: some quantities are better measured in their printed size (Page Units) and some are better represented in their logical, or scaled size (Drawing Units)
The size of a shape will scale, so Width & Height are in drawing units. If you switch a scale from 1:2 to 1:4, you will fit twice as many shapes on the page. A two-meter table-shape remains two-meters long, it’s just drawn smaller on the page. It’s printed size gets smaller, but its logical size stays the same.
But font-size and line weight don’t scale (imagine how frustrating that would be!), because they are measured in paper space, or Page Units. The philosophy is that we want a 12pt font to take up the same amount of paper, regardless of scale, because we want to be able to read the text. If text scaled, we might end up with lots of 0.25 pt text, or worse! And line weight usually doesn’t represent a physical attribute of an object, but simply shows it’s outline, so we don’t really want that to scale either.
So when we drop our example shape from above onto a 1:4 scaled page, the following happens:
You can see from the ruler that the shape is still 0.375 in tall, but the text is WAY too big for the shape. It is still 12 pt text and it will print at the same size it did in the 1:1 drawing, but 12 pt takes up more logical space in a 1:4 drawing.
So what went wrong? In a weird way, nothing went wrong. The font is still 12 pt, and the shape is still 0.375 in tall. So nothing really happened, but it sure looks funny! But seriously, folks…
The problem is back in our simple formula, where we are forming a ratio between Page Units and Drawing Units, without first converting one to the other. My algebra teacher would have said; “you’re comparing apples to oranges, and you can’t do that!”.
We can compare apples to apples by forming a ratio between two cells stored in every Visio Page’s ShapeSheet: PageScale and DrawingScale. These two cells get set when you choose a scale for your drawing. You can examine them by selecting nothing on a Visio page, then choosing Window > Show ShapeSheet from the menu.
The way to compare them in a shape’s ShapeSheet formula is to create a fraction that uses cross-sheet references:
User.AntiScale = ThePage!PageScale/Thepage!DrawingScale
This is sometimes called the Anti-scale formula or the Anti-scale ratio. You’ll often find it lurking in the User-defined cells section.
Our resulting, more-robust font-resizing formula will then look like this:
User.SomeFontSize = 12 pt*ThePage!PageScale/ThePage!DrawingScale*Height/0.375 in
User.SomeFontSize = 12 pt * User.AntiScale * Height/0.375 in
With this formula, our font-size will behave much more nicely in scaled drawings! Note: the 0.375 in should technically also be multiplied by an “AntiScale0” term — an originally scale ratio. But since our shape was created at 1:1, this ratio is in turn 1, so we can drop it from our formula. If the shape had been created in another scale, we’d have to add the extra fraction to get the font to size correctly.
Multiple Character Section Rows
Before this article gets two long, I’ll try and wrap it up, but not before adding a few more caveats.
The Character section is a strange beast. It can have multiple rows, but you can’t manually add them inside of the ShapeSheet! You get multiple character rows when you have multiple formatting in your shape’s text. That potentially means multiple font-resizing formulas! I’ve modified our first shape by adding some seriously frightening formatting:
If you look in the Character section for this shape, you see that a whole bunch of rows have been added. Each row represents a run where the text formatting is the same. The left-most column denotes the number of characters that have the new formatting. You can see a “3″ that corresponds to “Guy”, which has only been bold formatted.
You’ll also notice that our smart font-size formula has automatically been copied for us. What luck! I didn’t do that by hand, fyi. So we have nothing to worry about, right? Visio’s ShapeSheet has a read-your-mind feature that lets you fire-and-forget, right?
IF we had changed the font-size in our text, this would have changed the value in the Size cell for that character run. We would have to re-enter the formula, and probably modify it, since the font size is different. In the example, I only changed font-color, bold and italics. I never messed with the size.
If you are worried about your users messing up your font-size formulae, then think about setting the LockText and LockFormat cells in the Protection section of the ShapeSheet, or experiment with wrapping GUARD() around your Character.Size formula.
By default, shapes usually have non-zero values in for the text margins. These are also Page Unit values, so they don’t scale, and can throw a monkey-wrench into your font-sizing formulas.
You can examine a shape’s text margins by selecting the shape and choosing: Format > Text > Text Block tab from the menu. Or look in the ShapeSheet under the Text Block Format section, where you’ll find the LeftMargin, BottomMargin, TopMargin and RightMargin cells. Typically, these cells will have a value of 4 pt or 2 pt. As the scale of a drawing grows, those 2 or 4 points will take up more and more of your shape, as it’s printed size diminishes.
I usually opt for setting the margins to zero, wherever possible. If your text is centered, then zero-margins won’t have much of an effect anyway. Otherwise you’ll have to take them into consideration with your smart formula — and there are situations in scaled drawings when, for example, TopMargin + BottomMargin is actually greater than the height of the shape itself!