Title | Draw text stretched to fit a rectangle precisely in Visual Basic .NET |
Description | This example shows how to draw text stretched to fit a rectangle precisely in Visual Basic .NET. |
Keywords | stretch text, Graphics, DrawString, GraphicsPath, draw text, draw string, text, text size, VB.NET |
Categories | VB.NET, Graphics |
|
Thanks to Manfred for his help on this.
The Graphics object's MeasureString method tells you how big a piece of text will be when drawn but it is not very precise and leaves extra room around the text. You can get a more accurate measurement by considering font metrics but even that includes some extra space. This method allows you to measure drawn text much more precisely.
The example program's Paint event handler uses the following code to draw some text stretched to fit a rectangle. It starts by building the target rectangle where it will draw the text. It then makes a font that is roughly the right height for the rectangle. It also makes a StringFormat object that specifies centered text.
Next the code makes a GraphicsPath object and adds the text to it, using the same font characteristics it used to build the font. It passes the AddString method the origin (0, 0) and the StringFormat object so the text is centered at (0, 0).
The program then uses the GraphicsPath's GetBounds method to see how big the text is. It then makes a Matrix to represent a transformation that translates and scales the text's rectangle to the target rectangle and assigns it to the Graphics object's Transform property. Now any graphics drawn by the object is automatically transformed by the Matrix.
Finally the program draws the GraphicsPath. The code finishes by resetting the Graphics object's transformation and drawing the target rectangle so you can see that the text fits tightly inside it.
The program redraws its surface whenever it is resized so you can resize the form to see text stretched in various ways.
|
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles _
MyBase.Paint
' Get the target area.
Dim target As New Rectangle(8, 8, Me.ClientSize.Width - _
16, Me.ClientSize.Height - 16)
' Make the text in a GraphicsPath
' at approximately the desired height.
Dim the_font As New Font("Times New Roman", _
target.Height, FontStyle.Bold, GraphicsUnit.Pixel)
' Make the StringFormat.
Dim sf As New StringFormat
sf.Alignment = StringAlignment.Center
sf.LineAlignment = StringAlignment.Center
' Add the text to the GraphicsPath.
Dim text_path As New GraphicsPath
text_path.AddString("Message", _
the_font.FontFamily, CInt(FontStyle.Bold), _
target.Height, New PointF(0, 0), sf)
' Make a transformation to map
' (xmin, ymin)-(xmax, ymax) onto
' the target area.
Dim text_rectf As RectangleF = text_path.GetBounds()
Dim target_pts() As PointF = { _
New PointF(target.Left, target.Top), _
New PointF(target.Right, target.Top), _
New PointF(target.Left, target.Bottom) _
}
e.Graphics.Transform = New Matrix(text_rectf, _
target_pts)
' Draw the text.
e.Graphics.Clear(Me.BackColor)
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
e.Graphics.FillPath(Brushes.Blue, text_path)
e.Graphics.DrawPath(Pens.Blue, text_path)
' Reset the transform.
e.Graphics.ResetTransform()
' Draw the bounding rectangle.
e.Graphics.DrawRectangle(Pens.Red, target)
' Cleanup.
text_path.Dispose()
sf.Dispose()
the_font.Dispose()
End Sub
|