zoukankan      html  css  js  c++  java
  • GDI+绘制自定义行距的文本(续)

      在上文“GDI+绘制自定义行距的文本的三种方法。”中,介绍了绘制自定义行间距的多行文本的方法。

      在第三种的方法中,启用了GdipDrawDriverString这个函数。这个函数可以定义每个字符的位置,这是它的优点。不过它的缺点也比较明显。一是它定义的字符位置是以字符的左下角为基准的,和一般的概念是两样的。二是他对Font要求比较高,据说如果采用的是英文字体,在显示中文时会显示成一个个小方块。

      再翻翻GDIP中的其他函数,发现graphics的DrawString的方法都是调用GdipDrawString这个函数。如果我们能跳过graphics直接调用GdipDrawString这个函数,是不是能提高效率呢?我们试试看。

      <DllImport("gdiplus.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)> _

      Friend Shared Function GdipDrawString(ByVal graphics As IntPtr, _

                           ByVal textString As String, _

                           ByVal length As Integer, _

                           ByVal font As IntPtr, _

                           ByRef layoutRect As GPRECTF, _

                           ByVal stringFormat As IntPtr, _

                           ByVal brush As IntPtr) As Integer

      End Function

      <StructLayout(LayoutKind.Sequential)> _

      Friend Structure GPRECTF

        Friend X As Single

        Friend Y As Single

        Friend Width As Single

        Friend Height As Single

        Friend Sub New(ByVal x As Single, ByVal y As Single, ByVal width As Single, ByVal height As Single)

          Me.X = x

          Me.Y = y

          Me.Width = width

          Me.Height = height

        End Sub

        Friend Sub New(ByVal rect As RectangleF)

          Me.X = rect.X

          Me.Y = rect.Y

          Me.Width = rect.Width

          Me.Height = rect.Height

        End Sub

        Friend ReadOnly Property SizeF() As SizeF

          Get

            Return New SizeF(Me.Width, Me.Height)

          End Get

        End Property

        Friend Function ToRectangleF() As RectangleF

          Return New RectangleF(Me.X, Me.Y, Me.Width, Me.Height)

        End Function

      End Structure

      Public Sub Draw4(ByVal Text As String)

        Clear()

        Dim i As Integer, j As Integer, tS() As String

        j = Int(Text.Length / 52)

        ReDim tS(j - 1)

        For i = 0 To j - 1

          tS(i) = Text.Substring(i * 52, 52)

        Next

        If Text.Length - j * 52 <> 0 Then

          ReDim Preserve tS(j+1)

          tS(j+1) = Text.Substring(j * 52)

        End If

        DrawLineText(mG, tS, mFont, New SolidBrush(mForeColor))

      End Sub

      Private Sub DrawLineText(ByVal G As Graphics, ByVal T() As String, ByVal F As Font, ByVal B As Brush)

        If (G Is Nothing) Then Throw New ArgumentNullException("graphics")

        If (T Is Nothing) Then Throw New ArgumentNullException("text")

        If (F Is Nothing) Then Throw New ArgumentNullException("font")

        If (B Is Nothing) Then Throw New ArgumentNullException("brush")

        Dim Field As FieldInfo

        Field = GetType(Graphics).GetField("nativeGraphics", BindingFlags.Instance Or BindingFlags.NonPublic)

        Dim hGraphics As IntPtr = Field.GetValue(G)
        Field = GetType(Font).GetField("nativeFont", BindingFlags.Instance Or BindingFlags.NonPublic)

        Dim hFont As IntPtr = Field.GetValue(F)

        Field = GetType(Brush).GetField("nativeBrush", BindingFlags.Instance Or BindingFlags.NonPublic)

        Dim hBrush As IntPtr = Field.GetValue(B)

        Dim i As Integer, tR As GPRECTF

        tR = New GPRECTF(0, 0, mBmp.Width, mBmp.Height)

        For i = 0 To 17

          tR.X = 3

          tR.Y = 3 + i * mLineHeight

          GdipDrawString(hGraphics, T(i), T(i).Length, hFont, tR, IntPtr.Zero, hBrush)

        Next

      End Sub

      经测试,方法四和方法三的效率不相上下。但是,方法四更接近我们直观的想法,而且对Font的要求也不是很高。

      可能还有更好的方法,欢迎各位网友交流。

  • 相关阅读:
    Golang mysql数据库
    C++ list结构体变量排序
    VS2013 ERROR MSB8020
    error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation
    error C2664: “FILE *fopen(const char *,const char *)”: 无法将参数 1 从“LPCTSTR”转换为“const char *”
    error C4430: missing type specifier
    虚拟地址转物理地址
    vs2013 x64 编译汇编代码
    fs寄存器相关,PEB,TEB
    boost 1.57 vs2013 编译
  • 原文地址:https://www.cnblogs.com/grenet/p/1717775.html
Copyright © 2011-2022 走看看