MeasureString and DrawString difference

Graphics.MeasureString, TextRenderer.MeasureText and Graphics.MeasureCharacterRanges all return a size that includes blank pixels around the glyph to accomodate ascenders and descenders.

In other words, they return the height of "a" as the same as the height of "d" (ascender) or "y" (descender). If you need the true size of the glyph, the only way is to draw the string and count the pixels:

Public Shared Function MeasureStringSize(ByVal graphics As Graphics, ByVal text As String, ByVal font As Font) As SizeF

    ' Get initial estimate with MeasureText
    Dim flags As TextFormatFlags = TextFormatFlags.Left + TextFormatFlags.NoClipping
    Dim proposedSize As Size = New Size(Integer.MaxValue, Integer.MaxValue)
    Dim size As Size = TextRenderer.MeasureText(graphics, text, font, proposedSize, flags)

    ' Create a bitmap
    Dim image As New Bitmap(size.Width, size.Height)
    image.SetResolution(graphics.DpiX, graphics.DpiY)

    Dim strFormat As New StringFormat
    strFormat.Alignment = StringAlignment.Near
    strFormat.LineAlignment = StringAlignment.Near

    ' Draw the actual text
    Dim g As Graphics = graphics.FromImage(image)
    g.SmoothingMode = SmoothingMode.HighQuality
    g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit
    g.Clear(Color.White)
    g.DrawString(text, font, Brushes.Black, New PointF(0, 0), strFormat)

    ' Find the true boundaries of the glyph
    Dim xs As Integer = 0
    Dim xf As Integer = size.Width - 1
    Dim ys As Integer = 0
    Dim yf As Integer = size.Height - 1

    ' Find left margin
    Do While xs < xf
        For y As Integer = ys To yf
            If image.GetPixel(xs, y).ToArgb <> Color.White.ToArgb Then
                Exit Do
            End If
        Next
        xs += 1
    Loop
    ' Find right margin
    Do While xf > xs
        For y As Integer = ys To yf
            If image.GetPixel(xf, y).ToArgb <> Color.White.ToArgb Then
                Exit Do
            End If
        Next
        xf -= 1
    Loop
    ' Find top margin
    Do While ys < yf
        For x As Integer = xs To xf
            If image.GetPixel(x, ys).ToArgb <> Color.White.ToArgb Then
                Exit Do
            End If
        Next
        ys += 1
    Loop
    ' Find bottom margin
    Do While yf > ys
        For x As Integer = xs To xf
            If image.GetPixel(x, yf).ToArgb <> Color.White.ToArgb Then
                Exit Do
            End If
        Next
        yf -= 1
    Loop

    Return New SizeF(xf - xs + 1, yf - ys + 1)

End Function

MeasureString() method had some issues, especially when drawing non-ASCII characters. Please try TextRenderer.MeasureText() instead.