"Filip" wanted to know the best way to resize a font in VB.NET. Basicially, he wanted something that would make a font about three-quarters of the original size. He suggested ScaleTransform as one way to do the job with this code:
Private Sub Form1_Paint(
ByVal sender As Object,
ByVal e As System.Windows.Forms.PaintEventArgs
) Handles Me.Paint
Dim f As Font = New Font(
"Arial", 16, FontStyle.Regular)
e.Graphics.DrawString(
"01234567", f, Brushes.Black, 20, 20)
e.Graphics.ScaleTransform(0.75F, 1.0F)
e.Graphics.DrawString(
"01234567", f, Brushes.Black, 20, 40)
End Sub
This does resize the font, but there are some problems. For one thing, he's not resizing the font, he's resizing the GDI+ graphics context that the font is drawn in. Anything that is drawn with the same graphics context will be resized too. This illustration shows a rectangle being resized because it's also drawn using the same graphics object. (Note that only the X dimension is being resized in this case.)
--------
Click this link to view the example.
--------
For another, Scaling text as graphics is not the same as changing the font size. Font sizes are carefully calculated independently of each other in order to provide the best resolution at different sizes. Scaling just creates a mathematical proportion of the original font. Changing the Size property of the Font is the right way to go. I'll discuss this later.
GDI+ graphics requires the use of a "graphics object". A GDI+ graphics object is passed as e in this case whenever the form is painted (refreshed by Windows). If you add a Label or Button to the form, it's won't be resized. If you don't use an event that passes a graphics object, then gaining access to one to use the ScaleTransform method isn't always easy. In fact, the correct use of a graphics object, especially for text, has been a stumbling block for programmers since GDI+ was introduced back in VB6 days. For example, notice also that the when the text is resized, it's also shifted to the left.
About Visual Basic has a whole series of articles showing how to use GDI+. (Use the search box to find them!)
Making it easier and more flexible to do things like this is one reason Microsoft is introducing WPF as a replacement for Windows Forms. WPF also has a ScaleTransform method, but it's completely different. Here's the XAML code in a WPF project showing how ScaleTransform does the job with more flexibility.
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock FontFamily="Arial"
FontSize="16"
Text="UnScaled Text" Margin="42,12,320,0"
Height="39" VerticalAlignment="Top">
</TextBlock>
<TextBlock FontFamily="Arial"
FontSize="16"
Text="Scaled Text" Margin="42,42,320,0"
Height="39" VerticalAlignment="Top">
<TextBlock.RenderTransform>
<ScaleTransform ScaleX=".75" ScaleY="1.0" />
</TextBlock.RenderTransform>
</TextBlock>
<Label HorizontalAlignment="Left" Margin="42,72,0,0"
Name="Label1" VerticalAlignment="Top"
Width="280" Height="70">
<TextBlock FontFamily="Arial"
FontSize="16"
Text="Scaled Text in a Label"
VerticalAlignment="Top">
<TextBlock.RenderTransform>
<ScaleTransform ScaleX="1.5" ScaleY="3.0" />
</TextBlock.RenderTransform>
</TextBlock>
</Label>
</Grid>
</Window>
--------
Click this link to view the example.
--------
(Remember that WPF can be coded using either XAML or Visual Basic. If you haven't tried WPF yet, then try my introductory tutorial: A First Introduction to WPF and XAML for Visual Basic.)
Font Size
Most Windows Forms controls provide a Size property that you can change. But to do it, you have to create a new Font object for the control. For example, suppose you have a Label control with the default properties. Just for information, this code tells you what they are:
Console.WriteLine("Default Font Size: " &
Label1.Font.Size)
Console.WriteLine("Default Font Unit: " &
Label1.Font.Unit & " (" &
Label1.Font.Unit.ToString & ")")
---------------------
Default Font Size: 8
Default Font Unit: 3 (Point)
The font used by a control, such as a Label, is an object so a new one has to be constructed if you change the size (or any other property of the font such as the FontStyle to Bold or Italic).
This code will reduce the size of the font in a Label to 75 percent of what it was:
Dim theSize As Single = Label1.Font.Size
theSize = theSize * 0.75
Label1.Font = New System.Drawing.Font(
Label1.Font.FontFamily, theSize)
One interesting fact to keep in mind is that the Font properties of a Form are inherited. That means that you can change the font of the parent Form and all of the controls in the Form will change along with it, unless you have set the size of the control at design time.
--------
Click this link to view the example.
--------
When you set the size of a control at design time, VB.NET adds a line like this to the generated hidden file Form1.Designer.vb:
Me.Label1.Font = New System.Drawing.Font(
"Microsoft Sans Serif", 8.0!,
System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point,
CType(0, Byte))
You have to delete the Font property of the control to restore the ability of the control to inherit the Font properties of the Form.

