Introduction
Hello. Today, I will show you how to draw words, more specifically fonts, at an angle. This angle can be any angle we supply.
First, the Basics
I would advise you to first read through this article explaining what fonts are, and what type of fonts you get.
Just a small note, before we start the project: Seeing the fact that you will be dealing with a Font object mostly, I have decided to include some other Font functionalities and properties as well. Otherwise, this article would have been very short…
Our Project
The project you will create today will not only allow you to draw text at an angle (in any direction), but it will also allow you to set various Font properties, such as:
- Bold
- Underline
- Colour
- Size
- Face
- Strikethrough
- Italic
Create a new Visual Basic Windows Forms project and design your form to resemble Figure 1:

Figure 1: Our design
Let’s code!
The Code
As usual, let me start with the objects that will be used throughout this application. These variables are as follows:
Private FontName As String 'Font Family Name
Private FontSize As String 'Font Size
Private FontColor As Color 'Font Colour
Private FontRegular As Boolean 'Regular Font
Private FontBold As Boolean 'Bold Font
Private FontItalic As Boolean 'Italic Font
Private FontUnderline As Boolean 'Underlined Font
Private FontStrikeThrough As Boolean 'Strikethrough Font
Private FontReal As Font 'Actual Font Object
Private FontRotate As Integer 'Font Rotate Angle
The comments make it a bit easier to understand, don’t they? Basically, all these objects will be used for the various font settings.
To load a list of fonts, add the next code:
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
'Load System Fonts Into ComboBox
Dim fFonts As FontFamily
For Each fFonts In System.Drawing.FontFamily.Families
cboFonts.Items.Add(fFonts.Name)
Next
End Sub
Here, I created a FontFamily object. Then, I loop through each font registered on the system and add its name to the cboFonts combobox. If you were to run your application now, you will see the list of fonts inside the Font combobox.
To be able to select a font from the list, you need to add the following code:
Private Sub cboFonts_SelectedIndexChanged(ByVal sender _
As System.Object, _
ByVal e As System.EventArgs) Handles _
cboFonts.SelectedIndexChanged
If cboFonts.SelectedIndex > -1 Then
'Get Selected Font Name
FontName = _
cboFonts.GetItemText(cboFonts.SelectedIndex)
End If
End Sub
This is the classic way of obtaining an item selected from the list. It makes use of the built-in list’s Index. The index number starts at 0, and indicates what item was ultimately selected.
Add the following code to be able to set the Font’s size:
Private Sub cboSize_SelectedIndexChanged(ByVal sender _
As System.Object, ByVal e As System.EventArgs) Handles _
cboSize.SelectedIndexChanged
If cboSize.SelectedIndex > -1 Then
'Get Selected Font Size
FontSize = cboSize.GetItemText(cboSize.SelectedItem)
End If
End Sub
It works with the same principle as the previous combobox. Now we have a font and a size.
Add the following code to set the font object’s color:
Private Sub butColor_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles butColor.Click
clrFont.AllowFullOpen = True 'Show Full Dialog Box
clrFont.AnyColor = True 'Can Select Any Colour
clrFont.SolidColorOnly = False 'All Colours
clrFont.ShowHelp = True 'Show WhatsThis Help
clrFont.FullOpen = True
If clrFont.ShowDialog() = _
System.Windows.Forms.DialogResult.OK Then
FontColor = clrFont.Color 'Set Font Colour
End If
End Sub
I set numerous properties for the Color dialogbox and allow for user selection. Now, FontColor contains the chosen color. Let’s move on.
The next couple of procedures simply set a Boolean flag (on and off/selected or not selected) for whichever formatting option was selected. Add them now:
Private Sub chkBold_CheckedChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles chkBold.CheckedChanged
'If Bold Selected Then FB = True
If chkBold.Checked Then FontBold = True
End Sub
Private Sub chkItalic_CheckedChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles chkItalic.CheckedChanged
If chkItalic.Checked Then FontItalic = True
End Sub
Private Sub chkUnderline_CheckedChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles chkUnderline.CheckedChanged
If chkUnderline.Checked Then FontUnderline = True
End Sub
Private Sub chkStrike_CheckedChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles chkStrike.CheckedChanged
If chkStrike.Checked Then FontStrikeThrough = True
End Sub
Private Sub chkRegular_CheckedChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles chkRegular.CheckedChanged
If chkRegular.Checked Then FontRegular = True
End Sub
Add the following code to set the Font object’s rotation when focus has left the rotation textbox:
Private Sub txtRotate_Leave(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles txtRotate.Leave
'Set Rotation Degree
If IsNumeric(txtRotate.Text) Then FontRotate = _
Integer.Parse(txtRotate.Text)
End Sub
I simply determined whether or not the entered text was numeric, then converted the entered value to a numeric value.
Add the FontStuff sub that will put all the pieces of the puzzle together:
Private Sub FontStuff()
Dim width As Double 'Width Of Font
Dim height As Double 'Height Of Font
'Create New Bitmap Object To "Save" Graphic Image
Dim bmp As New Bitmap(picPreview.Width, _
picPreview.Height)
'Create Graphics Object To Draw To
Dim g As Graphics = Graphics.FromImage(bmp)
If FontRegular Then 'If Regular Font
'Create Font Based On Regular Style
FontReal = New Font(FontName, FontSize, _
FontStyle.Regular, GraphicsUnit.Point)
'Determine Text Width Based On Font
width = g.MeasureString(txtText.Text, FontReal).Width
'Determine Height Of Text Based On Font
height = g.MeasureString(txtText.Text, FontReal).Height
End If
If FontBold Then
FontReal = New Font(FontName, FontSize, _
FontStyle.Bold, GraphicsUnit.Point)
width = g.MeasureString(txtText.Text, FontReal).Width
height = g.MeasureString(txtText.Text, FontReal).Height
End If
If FontItalic Then
FontReal = New Font(FontName, FontSize, _
FontStyle.Italic, GraphicsUnit.Point)
width = g.MeasureString(txtText.Text, FontReal).Width
height = g.MeasureString(txtText.Text, FontReal).Height
End If
If FontUnderline = True Then
FontReal = New Font(FontName, FontSize, _
FontStyle.Underline, GraphicsUnit.Point)
width = g.MeasureString(txtText.Text, FontReal).Width
height = g.MeasureString(txtText.Text, FontReal).Height
End If
If FontStrikeThrough Then
FontReal = New Font(FontName, FontSize, _
FontStyle.Underline, GraphicsUnit.Point)
width = g.MeasureString(txtText.Text, FontReal).Width
height = g.MeasureString(txtText.Text, FontReal).Height
End If
'Angle For Rotating
Dim angleRadian As Double = _
((FontRotate Mod 360) / 180) * Math.PI
'Font Color
Dim b As Brush = New SolidBrush(FontColor)
'Between 0 To 90 And -270 And -360
If (FontRotate >= 0 AndAlso FontRotate < 90) Or _
(FontRotate < -270 AndAlso FontRotate >= -360) Then
g.TranslateTransform(CInt(Math.Sin(angleRadian) * height), 0)
'Between 90 To 180 To -180 To -270
ElseIf (FontRotate >= 90 AndAlso FontRotate < 180) Or _
(FontRotate < -180 AndAlso FontRotate >= -270) Then
g.TranslateTransform(ClientRectangle.Width, CInt(height - _
(Math.Sin(angleRadian) * height)))
'Between 180 To 270 And -90 To -180
ElseIf (FontRotate >= 180 AndAlso FontRotate < 270) Or _
(FontRotate < -90 AndAlso FontRotate >= -180) Then
g.TranslateTransform(0 + CInt(Math.Sin(angleRadian) * height), _
ClientRectangle.Height)
Else
g.TranslateTransform(0, ClientRectangle.Height - _
CInt(Math.Cos(angleRadian) * height))
End If
g.RotateTransform(CInt(FontRotate)) 'Rotate
'Draw The String / Font
g.DrawString(txtText.Text, FontReal, b, 0, 0)
picPreview.Image = bmp 'Display Font "Image"
' g.ResetTransform() 'Reset
End Sub
The first parts of this sub mainly concentrate on what settings were set. After it has determined the specific setting, it resizes the font object to fit in not only the text, but the formatting as well. All this happens with the MeasureString property; here is more information on it.
Lastly, this sub determines the rotation value and, based on the rotation value, uses a bit of math to create the desired writing at the desired angle. Here is more information on RotateTransform and DrawString.
Add the call to the FontStuff sub:
Private Sub butApply_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles butApply.Click
FontStuff() 'Call font Creation Sub
End Sub
When run, your form might look like Figure 2:

Figure 2: Rotation in action
Conclusion
I hope you have enjoyed this article. Until next time, this is me signing off!