HOWTO: Dynamically Change the Font Size of a Text Annotation Upon Resize


For WinForms projects, DotImage will automatically word wrap the text in a TextAnnotation when it is resized. However, if you want to dynamically changed the font size itself, you can do the following in the AnnotateViewer's AnnotationResized event:

C# Sample:

-----

private void annotateViewer1_AnnotationResized(object sender, AnnotationEventArgs e)
{
    ResizeFont(e.Annotation);
}

private void ResizeFont(AnnotationUI baseAnno)
{
   TextAnnotation tAnno = baseAnno as TextAnnotation;
   if (tAnno != null)
   {
      Size annoSize = tAnno.Size.ToSize();
      System.Drawing.Font annoFont = new Font(tAnno.Font.Name, tAnno.Font.Size);
      SizeF size;
      System.Drawing.Font newFont = AppropriateFont(annotateViewer1.CreateGraphics(), 12f, 72f, annoSize, tAnno.Text, annoFont, out size);
      tAnno.Font = new AnnotationFont(newFont.Name, newFont.Size);
   }
}

public static Font AppropriateFont(Graphics g, float minFontSize, float maxFontSize, Size layoutSize, string s, Font f, out SizeF extent)
{
   if (maxFontSize == minFontSize)
   {
      f = new Font(f.FontFamily, minFontSize, f.Style);
   }

   extent = g.MeasureString(s, f);

   if (maxFontSize <= minFontSize)
   {
      return f;
   }

   float hRatio = layoutSize.Height / extent.Height;
   float wRatio = layoutSize.Width / extent.Width;
   float ratio = (hRatio < wRatio) ? hRatio : wRatio;
   float newSize = f.Size * ratio;

   if (newSize < minFontSize)
   {
      newSize = minFontSize;
   }
   else if (newSize > maxFontSize)
   {
      newSize = maxFontSize;
   }

   f = new Font(f.FontFamily, newSize, f.Style);
   extent = g.MeasureString(s, f);
   return f;
}

VB.Net Sample:

-----

Private Sub annotateViewer1_AnnotationResized(ByVal sender As Object, ByVal e As AnnotationEventArgs)
    ResizeFont(e.Annotation)
End Sub

Private Sub ResizeFont(ByVal baseAnno As AnnotationUI)
    Dim tAnno As TextAnnotation = TryCast(baseAnno, TextAnnotation)
    If tAnno IsNot Nothing Then
       
Dim annoSize As Size = tAnno.Size.ToSize()
        Dim annoFont As System.Drawing.Font = New Font(tAnno.Font.Name, tAnno.Font.Size)
        Dim size As SizeF
        Dim newFont As System.Drawing.Font = AppropriateFont(annotateViewer1.CreateGraphics(), 12.0F, 72.0F, annoSize, tAnno.Text, annoFont, size)
        tAnno.Font = New AnnotationFont(newFont.Name, newFont.Size)
    End If
End Sub

Public Shared Function AppropriateFont(ByVal g As Graphics, ByVal minFontSize As Single, ByVal maxFontSize As Single, ByVal layoutSize As Size, ByVal s As String, ByVal f As Font, ByRef extent As SizeF) As Font
    If maxFontSize = minFontSize Then
       
f = New Font(f.FontFamily, minFontSize, f.Style)
    End If

    extent = g.MeasureString(s, f)

    If maxFontSize <= minFontSize Then
       
Return f
    End If

    Dim hRatio As Single = layoutSize.Height / extent.Height
    Dim wRatio As Single = layoutSize.Width / extent.Width
    Dim ratio As Single = If((hRatio < wRatio), hRatio, wRatio)
    Dim newSize As Single = f.Size * ratio

    If newSize < minFontSize Then
        newSize = minFontSize
    ElseIf newSize > maxFontSize Then
       
newSize = maxFontSize
    End If

    f = New Font(f.FontFamily, newSize, f.Style)
    extent = g.MeasureString(s, f)
    Return f
End Function

Original Article:
Q10307 - HOWTO: Dynamically Change the Font Size of a Text Annotation Upon Resize