Adjust font size to fit string in gap

Cags

Well-known member
Joined
Feb 19, 2004
Messages
690
Location
Melton Mowbray, England
Im creating what is essentially a custom control which consists of a grid with text values being included in the cells. The entire control is being drawn using DrawLine, DrawString etc. What I am trying todo is have it so that if a cell is resized, the control automatically selects (or at least tries to select) a font size that will still allow the entire string to stay within the sections.

I know there is a MeasureString function, but Im not sure how much help it would be in this instance, I might come up with an idea after some sleep, but if anyone has anyone can point me in the right direction, itd be much appreciated?
 
Why not find the width of the string, and if it is greater than the size available, do some simple division and multiplication to find the size needed.
[Vb]
Limit how small the font can be
Const MinSize As Single = 8.0F

Dim MeasuredWidth, AvailableWidth, FontSize As Single

Get some values
FontSize = Me.Font.Size()
AvailableWidth = Me.Width minus border width?
MeasuredWidth = e.Graphics.MeasureString(Me.Text, Me.Font).Width

Take either the current font size, or the sized-to-fit size, whichever
is appropriate
FontSize = Math.Max(FontSize, FontSize * AvailableWidth / MeasuredWidth)
Make sure that we are at least the minimum size
FontSize = Math.Max(FontSize, MinSize)

Create The Font
MyFont = New Font(Me.Font, FontSize, Me.Font.Style, GraphicsUnit.Point)
[/VB]
That might need some tweaking, but I think it is the jist of what you need. It will also probably work better when a user has font anti-aliasing on, which allows for fractional character widths and therefore more percise sizing.
 
Thanks for the idea its a good suggestion however as far as I can tell it wont work in this situation. The string that will be held in the cell uses the overload

DrawString(string, Font, Brush, RectangleF);

Thus the string is automatically wrapped to fit into the rect. Due to the multiline nature measuring the string width wont work in this manner (I dont think :S)

Ive found a solution that ensures the string fits in the box unfortunately it merely ensures its small enough for the entire string to be displayed, not necessarily a good fit.

C#:
			SizeF stringSize = gTemp.MeasureString(sString , fOptions, iSquareSize );
			double aspect = 0.0;

			if( iSquareSize / stringSize.Width < iSquareSize / stringSize.Height )
				aspect = iSquareSize / stringSize.Width;
			else
				aspect = iSquareSize / stringSize.Height;

			float new_size = ( float )( fOptions.Size * aspect );

			fOptions = new Font(fOptions.FontFamily, new_size);
 
Found a better solution...

C#:
	int iMeasuredHeight = (int)e.Graphics.MeasureString( sString, fOptions, iSquareSize).Height;

	while(iSquareSize < iMeasuredHeight)
	{
		iFontSize --;
		fOptions = new Font(fOptions.FontFamily, iFontSize);
		iMeasuredHeight = (int)e.Graphics.MeasureString( sString, fOptions,  iSquareSize).Height;			
	}

NB: iFontSize starts at the maximum size you wish the text to be. Due to the nature of the control my grid cells are always square.
 
Back
Top