MeasureCharacterRanges not even exact?
문제
Of course, the Graphics.MeasureString method is well-known to have padding problems, and so you use Graphics.MeasureCharacterRanges instead, but as you can see here:
It's not measuring quite correctly. Is this a problem with MeasureCharacterRanges or is it my code? How can I fix it?
Here's my code:
'Draw the selection cursor
If Me.Focused Then
Dim cX As Integer = 1, cY As Integer = 5, c As Char
For i As Integer = 0 To Me.SelectionStart - 1
c = Me.Text(i)
If c = ControlChars.CrLf Then
cY += Me.Font.Height
Else
Dim w As Integer = MeasureCharacter(g, c, Me.Font).Width
g.DrawRectangle(Pens.Black, cX, cY, w, Me.Font.Height) 'Draw a rectangle for debugging
cX += w
End If
Next
g.DrawLine(Pens.Black, cX, cY, cX, cY + Me.Font.Height)
End If
End Sub
Protected Function MeasureCharacter(ByVal g As Graphics, ByVal c As Char, ByVal f As Font) As Size
Dim cr() As CharacterRange = {New CharacterRange(0, 1)}
Dim sfmt As New StringFormat()
sfmt.FormatFlags = StringFormatFlags.MeasureTrailingSpaces
sfmt.SetMeasurableCharacterRanges(cr)
Return g.MeasureCharacterRanges(c.ToString(), f, Me.ClientRectangle, sfmt)(0).GetBounds(g).Size.ToSize()
End Function
해결책
Measuring the length of indiviual characters doesn't take into account the kerning that occurs between groups of characters, so the sum of the lengths of the characters will not equal the length of the string.
If you look at your example text, you can see the kerning between the "t" at the end of "Sprint" and the "T" at the start of "Textbox", the characters are moved closer together than you would expect given their individual lengths.