MeasureCharacterRanges 甚至不精确?
当然,众所周知,Graphics.MeasureString 方法存在填充问题,因此您可以使用 Graphics.MeasureCharacterRanges 来代替,但正如您在此处看到的:
它的测量不太正确。这是 MeasureCharacterRanges 的问题还是我的代码?我该如何修复它?
这是我的代码:
'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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
测量单个字符的长度不考虑字符组之间发生的字距调整,因此字符长度的总和将不等于字符串的长度。
如果您查看示例文本,您可以看到“Sprint”末尾的“t”和“Textbox”开头的“T”之间的字距调整,这些字符的移动距离比您预期的要近。个别长度。
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.