Peter Duniho said:
As I mentioned, it will always get you close. But you have no guarantee
that the resulting value will be exactly the largest size that would fit,
nor even that it will fit (a few pixels may be truncated, or the text
might wrap if you've selected that formatting option).
One more follow-up...
In the interest of quantifying the statement I made, I wrote a small program
that tests all of the fonts on the computer for all calculated widths and
font sizes from the smallest to largest.
The basic algorithm:
For every font family installed:
Find the width of the font at 128 points
For every possible width between 1/128th of the max width and the
max width:
Calculate a new font size based on the ratio of the target width
to the max width
Find the actual width of the font for that calculated font size
Note: where I write "font size" what I actually mean is the width of a
sample string, arbitrarily chosen, at a given font size.
I divided the results into three categories:
* calculated font size definitely fit
* calculated font size might not fit
* calculated font size definitely does not fit
The "might not" comes about because for fractional widths, I don't know what
the defined Windows behavior is, and there may not in fact be a defined
behavior when the necessary width for a string is some fractional amount
larger than the desired size. For the sake of discussion, I assumed that
half of the "might nots" actually do result in display truncation or
unwanted wrapping, adding that half to the "definitely does not" for the
purpose of calculating error rates.
I tried a variety of methods, each variation involving truncating one or
more parts of the calculation (there were three places that the supporting
calculations could be truncated: the max width of the string, the calculated
font size, and the end result of the width for the string at the calculated
size).
Interestingly, the *best* results occurred when I truncated all of the
results of the calculations, including the target font size. One of the
worst outcomes was when the widths were truncated, but the font size was
not. This isn't entirely unexpected, since truncation of the font size and
the final width makes the string more likely to fit by making it slightly
smaller.
Generally speaking, the string fails to fit into the target width roughly
somewhere between 5% and 35% of the time, depending on how the calculations
are done (yes, I realize that's a huge variance).
For extra credit, I also added a histogram display to show me roughly what
range of scaling causes the most error. Not surprisingly, the results are
heavily weighted toward the larger scales (that is, a target font size
closer to the maximum). I say "not surprisingly", because it stands to
reason that when the absolute sizes are larger, small variations in
percentage are more likely going to result in multi-pixel errors.
Interestingly, the outcome here wasn't perfectly smooth, and in fact had
peaks and valleys for some calculation variations (for example, truncating
everything resulted in the bin for 88-91% scaling having more occurences
than either of the two higher bins).
Note that this weighting towards the sizes closer to the maximum means that
the error rate may be significantly higher than the stated "5% to 35%" when
considering scenarios in which the font size needs to be reduced only a
small amount.
Finally, I also tried calculating the target font size based on the Pixels
unit rather than Point unit. This did result in a significant improvement
in speed, but otherwise the basic results were very similar (slightly
"smoother" as far as the histogram goes, but otherwise basically the same).
Anyway, I hope that this helps illustrate the underlying problem. IMHO, the
main lessons to take away are:
* A straight calculation _can_ result in the incorrect answer
* You are more likely to get the incorrect answer when the string only
has to shrink a little bit and/or when the maximum size is large
I wish that there was a more reliable way to make a string fit in a specific
area, but at some point one really does need to do some trial and error
calculations to ensure that the font size chosen really does result in the
displayed string fitting entirely within the target rectangle. Otherwise,
your code is not assured of working 100% of the time.
Pete