Find maximum font size where string fits in a box [modified]
-
I need a function to return the maximum font size (for a given font)such that a given string will fit in a predefined box (rectangle). That is, I want to use DrawString(string, font, brush, rectangle) to draw the string in a fixed size box. Note that Drawstring will wrap the string automatically to fit the width. I don't want any of the string to extend beyond the bottom of the box. BTW, this for a windows application using forms. Thanks for any suggestions! Tom
modified on Saturday, January 30, 2010 5:50 PM
-
I need a function to return the maximum font size (for a given font)such that a given string will fit in a predefined box (rectangle). That is, I want to use DrawString(string, font, brush, rectangle) to draw the string in a fixed size box. Note that Drawstring will wrap the string automatically to fit the width. I don't want any of the string to extend beyond the bottom of the box. BTW, this for a windows application using forms. Thanks for any suggestions! Tom
modified on Saturday, January 30, 2010 5:50 PM
Hi, there is
Graphics.MeasureString()
which calculates the required width (for single-line) or required height (for multi-line and given a fixed width); it works pretty well provided you give it the exact same parameters (font, style, etc) you are going to give DrawString later. So you would need a little iteration: 1. choose some rather large fontsize; 2. calculate required height; 3. reduce fontsize by available_size/required_size; 4. repeat 2+3 two or three times. Warning: there are some minor deviations; I once saw a CP article on the very subject. The solution then is to use TextRenderer class; I never felt a need to do that though. :)Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.
[The QA section does it automatically now, I hope we soon get it on regular forums as well]
-
Hi, there is
Graphics.MeasureString()
which calculates the required width (for single-line) or required height (for multi-line and given a fixed width); it works pretty well provided you give it the exact same parameters (font, style, etc) you are going to give DrawString later. So you would need a little iteration: 1. choose some rather large fontsize; 2. calculate required height; 3. reduce fontsize by available_size/required_size; 4. repeat 2+3 two or three times. Warning: there are some minor deviations; I once saw a CP article on the very subject. The solution then is to use TextRenderer class; I never felt a need to do that though. :)Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.
[The QA section does it automatically now, I hope we soon get it on regular forums as well]
Hi Luc :) I came across this myself a little while ago when I discovered some inaccuracies in
MeasureString
when I used it in a custom control. In my particular situation it was more of an annoyance than a requirement so I decided to live with it, but if accurate measurement is required thenMeasureString
doesn't quite cut it. ApparentlyMeasureCharacterRanges
can help too (according to the notes I made at the time).Dave
Tip: Passing values between objects using events (C#) BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
Why are you using VB6? Do you hate yourself? (Christian Graus) -
Hi Luc :) I came across this myself a little while ago when I discovered some inaccuracies in
MeasureString
when I used it in a custom control. In my particular situation it was more of an annoyance than a requirement so I decided to live with it, but if accurate measurement is required thenMeasureString
doesn't quite cut it. ApparentlyMeasureCharacterRanges
can help too (according to the notes I made at the time).Dave
Tip: Passing values between objects using events (C#) BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
Why are you using VB6? Do you hate yourself? (Christian Graus)Thanks Dave, so there are three ways now. I still wonder why they can't do it right the first time and leave it there, it's not that MeasureString and DrawString are doing very different things... :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.
[The QA section does it automatically now, I hope we soon get it on regular forums as well]
-
Thanks Dave, so there are three ways now. I still wonder why they can't do it right the first time and leave it there, it's not that MeasureString and DrawString are doing very different things... :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.
[The QA section does it automatically now, I hope we soon get it on regular forums as well]
I agree. It's something to do with aliasing in GDI IIRC but it seems a pretty poor excuse. It should be able to calculate it's own size if DrawString were to be called.
Dave
Tip: Passing values between objects using events (C#) BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
Why are you using VB6? Do you hate yourself? (Christian Graus) -
I need a function to return the maximum font size (for a given font)such that a given string will fit in a predefined box (rectangle). That is, I want to use DrawString(string, font, brush, rectangle) to draw the string in a fixed size box. Note that Drawstring will wrap the string automatically to fit the width. I don't want any of the string to extend beyond the bottom of the box. BTW, this for a windows application using forms. Thanks for any suggestions! Tom
modified on Saturday, January 30, 2010 5:50 PM
I did something similar a few years ago. I found the MeasureString wasn't accurate at times and the constant measuring I was forced to do came with a steep performance penalty. I solved the problem by creating a background bitmap image, big enough to fit my text in the format I required, and at 96 point size and them drew the image to a custom control to display the text, scaled down or up to the desired size. I only needed to calculate the text size once per string needed, instead of every time I had to rescale the display.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008
But no longer in 2009... -
I need a function to return the maximum font size (for a given font)such that a given string will fit in a predefined box (rectangle). That is, I want to use DrawString(string, font, brush, rectangle) to draw the string in a fixed size box. Note that Drawstring will wrap the string automatically to fit the width. I don't want any of the string to extend beyond the bottom of the box. BTW, this for a windows application using forms. Thanks for any suggestions! Tom
modified on Saturday, January 30, 2010 5:50 PM
- Get the pixel width of the container box. 1) Divide the box width by the number of characters in your string. This will give you your "desired average character width. 2) Get the average character width of the font that you want to use, and starting at the current font size, get the average character width. Depending on whether the average character width is less than or greater than the desired character width, loop up or down in font size until you find one that matches, or is a little smaller. 3) Once you get to a candidate font size, measure the width of your string using that font, and see if it fits. If it doesn't bump the font size up or down as appropriate.
.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001 -
Hi, there is
Graphics.MeasureString()
which calculates the required width (for single-line) or required height (for multi-line and given a fixed width); it works pretty well provided you give it the exact same parameters (font, style, etc) you are going to give DrawString later. So you would need a little iteration: 1. choose some rather large fontsize; 2. calculate required height; 3. reduce fontsize by available_size/required_size; 4. repeat 2+3 two or three times. Warning: there are some minor deviations; I once saw a CP article on the very subject. The solution then is to use TextRenderer class; I never felt a need to do that though. :)Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.
[The QA section does it automatically now, I hope we soon get it on regular forums as well]