c# - 如何在 .net 中获取字体字距调整对

标签 c# vb.net fonts gdi+ kerning

我正在尝试使用此 P/Invoke 调用来获取字体字距调整对:

Imports System.Runtime.InteropServices

Public Class Kerning

Structure KERNINGPAIR
    Public wFirst As UInt16
    Public wSecond As UInt16
    Public iKernelAmount As UInt32
End Structure

<DllImport("gdi32.dll")> _
Private Shared Function GetKerningPairs(hdc As IntPtr, 
      nNumPairs As UInteger, <Out> lpkrnpair As KERNINGPAIR()) As UInteger
End Function

Sub ExaminePairs()
    Dim f As Font
    For Each myFontFamily In System.Drawing.FontFamily.Families

        f = New Font(myFontFamily, 25)
        Dim pairs As UInteger = 0
        Dim pairsArray() As KERNINGPAIR
        ReDim pairsArray(pairs)
        Dim a = GetKerningPairs(f.ToHfont(), pairs, Nothing)
        If a <> 0 Then
            MsgBox("Found!")
        End If
        f.Dispose()
    Next

End Sub
End Class

每当找到具有定义的字距对的字体时,ExamineParis 函数应该显示一个消息框(根据此: https://msdn.microsoft.com/en-us/library/windows/desktop/dd144895(v=vs.85).aspx ) 但似乎总是返回0。

我需要找到一种方法来获取给定字体的所有字距调整对(有多少个,然后是它们的结构)。

有谁知道怎么做吗?

最佳答案

已接受的答案 here显示如何从 VB.NET 调用 GetKerningPairs。以下是经过修改以适合您的代码:

Imports System.Drawing
Imports System.Runtime.InteropServices

Public Class Kerning

    <StructLayout(LayoutKind.Sequential)>
    Structure KERNINGPAIR
        Public wFirst As Short
        Public wSecond As Short
        Public iKernelAmount As Integer
    End Structure

    <DllImport("gdi32.dll", SetLastError:=True, CallingConvention:=CallingConvention.Winapi)>
    Public Shared Function GetKerningPairs(ByVal hdc As IntPtr, ByVal nPairs As Integer, <MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> <Out()> ByVal pairs() As KERNINGPAIR) As Integer
    End Function

    <DllImport("gdi32.dll")>
    Private Shared Function SelectObject(ByVal hdc As IntPtr, ByVal hObject As IntPtr) As IntPtr
    End Function

    Public Shared Function GetKerningPairs(ByVal font As Font) As IList(Of KERNINGPAIR)
        Dim pairs() As KERNINGPAIR
        Using g As Graphics = Graphics.FromHwnd(IntPtr.Zero)
            g.PageUnit = GraphicsUnit.Pixel
            Dim hdc As IntPtr = g.GetHdc
            Dim hFont As IntPtr = font.ToHfont
            Dim old As IntPtr = SelectObject(hdc, hFont)
            Try
                Dim numPairs As Integer = GetKerningPairs(hdc, 0, Nothing)
                If numPairs > 0 Then
                    pairs = New KERNINGPAIR(numPairs - 1) {}
                    numPairs = GetKerningPairs(hdc, numPairs, pairs)
                    Return pairs
                Else
                    Return Nothing
                End If
            Finally
                old = SelectObject(hdc, old) ' replace whatever object was selected in the dc
            End Try
        End Using
    End Function

    Sub ExaminePairs()
        For Each myFontFamily In FontFamily.Families
            Try
                Using f = New Font(myFontFamily, 25)
                    Dim pairs = GetKerningPairs(f)
                    If pairs IsNot Nothing Then
                        Debug.Print("#Pairs: {0}", pairs.Count)
                    Else
                        Debug.Print("No pairs found")
                    End If
                End Using
            Catch ex As Exception
                Debug.Print("Error: {0} for: {1}", ex.Message, myFontFamily.Name)
            End Try
        Next
    End Sub

End Class

关于c# - 如何在 .net 中获取字体字距调整对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31327174/

相关文章:

java - 是否可以在 JTextField 上为文本加下划线?如果可以,怎么做?

c# - 当第一个数据流 block 的输入完成所有链接 block 时报告

c# - 有没有从 Java netbeans 项目调用 .net 类的好方法?

c# - 使用 Windows 服务和 Vb.Net 检测 USB 驱动器的插入和移除

asp.net - 在 ASP.NET 中动态添加/删除菜单项?

python - 更改 Matplotlib 图表上的标签(例如 Muli)

c# - 在 C# 中部署 SQL 存储过程

C# 如何序列化 system.linq.expressions?

vb.net - 在 vb.net 中运行批处理文件?

iOS - 下载动态字体