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的要求也不是很高。

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

  • 相关阅读:
    pyftpdlib 搭建FTP服务器
    numpy 解一道简单数学题
    python 实现词云
    个人的毕业长足---- 暴走北京
    Tensorflow of GPU, hello fish by version 0.8.
    图像识别
    用一个Inception v3 架构模型实现简单的迁移学习(译:../tensorflow/tensorflow/examples/image_retraining/retrain.py)
    19.液晶屏的原理
    18.DMA-6410
    17.DMA-2440
  • 原文地址:https://www.cnblogs.com/grenet/p/1717775.html
Copyright © 2011-2022 走看看