MeasureCharacterRanges 甚至不精确?

发布于 2024-11-07 17:50:13 字数 1327 浏览 0 评论 0原文

当然,众所周知,Graphics.MeasureString 方法存在填充问题,因此您可以使用 Graphics.MeasureCharacterRanges 来代替,但正如您在此处看到的:

MeasureCharacterRanges Problem

它的测量不太正确。这是 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:

MeasureCharacterRanges problem

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倾城泪 2024-11-14 17:50:13

测量单个字符的长度不考虑字符组之间发生的字距调整,因此字符长度的总和将不等于字符串的长度。

如果您查看示例文本,您可以看到“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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文