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

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

时间: 2024-12-21 21:49:38

GDI+绘制自定义行距的文本(续)的相关文章

gdi+-C#如何如何开发一个自定义的富文本编辑器组件?使用GDI+来完成么?

问题描述 C#如何如何开发一个自定义的富文本编辑器组件?使用GDI+来完成么? 如题, 1 自定义C#组件 2 富文本编辑器 完成这项东西,需要使用哪些技术来完成?能给个思路就更好了 解决方案 富到什么程度? 可以用RichTextBox或者WebBrowser做编辑界面

C# 数据库系统中使用GDI+绘制柱状图

在C#+SQL Server数据库做系统中,通常需要对数据库中的数据进行绘制图形报表方便经理查看,虽然有很多实用的水晶报表控件和图表控件实现该功能,但我还是想讲讲如何使用GDI绘制简单的柱状图.(推荐大家不要手画,尽量使用已有控件函数绘制) 一.前言 我们在使用C#+SQL Server做的简单应用系统是一个手机销售的系统,所以它有不同手机品牌和不同年份销售手机的利润和数量的柱状图,方便公司经理查看那个月和那种品牌手机销售更好,方便进货增加企业利润.其中它点击"输入年份",查看&quo

用vc++编程,用GDI绘制一个直径为100毫米的圆,高手指教。

问题描述 用vc++编程,用GDI绘制一个在鼠标点击处为圆心直径为100毫米的圆,高手指教.注意直径单位为毫米 解决方案 解决方案二: 解决方案三:哈哈,你在都大家玩阿.1:100毫米转换像素不?这里面涉及到了坐标系和缩放比.2:最好用GDI+来做这个.3:考虑到你对100毫米这个毫米字样很敏感,直接D2DDirectWrite吧,没有毛边.解决方案四:条件不足啊,在什么设备上绘图?设备分辨率?解决方案五:毫米转换像素,然后画圆.

《Java数字图像处理:编程技巧与应用实践》——1.3 用Java Swing绘制自定义的JPanel

1.3 用Java Swing绘制自定义的JPanel Swing的JPanel组件是GUI编程中最重要的面板组件,可以通过重写JPanel中paint-Component方法实现对JPanel面板组件的背景颜色的调整或添加背景图片,进而实现自定义版本的面板(JPanel)组件.只要完成如下几步就可以实现一个简单自定义JPanel面板的绘制. 1)实现对JPanel面板的继承,代码如下: public class CustomJPanel extends JPanel { // 更多代码 } 2

如何用gdi+来指定一行中文本的不同的颜色?

问题描述 如何用gdi+来指定一行中文本的不同的颜色? 如何用gdi+来指定一行中文本的不同的颜色,效果就是输出的一行字符中我指定的几个字符为特定的颜色表示,该如何做呢? 解决方案 指定一行中文本不同颜色Android --- TextView中文本的不同颜色Android:TextView中文本的不同颜色 解决方案二: 使用渐变画刷即可! 例:textRect表示文本显示矩形区,startColor,endColor文本表示开始及结束颜色 protected override void OnP

MFC 用gdi绘制填充多边形区域

MFC 用gdi绘制填充多边形区域 这里的代码是实现一个三角形的绘制,并用刷子填充颜色 在OnPaint()函数里面 运用的是给定的三角形的三个点,很多个点可以绘制多边形 [cpp] view plaincopy   CBrush br(RGB(40,130,170));   CRgn rgn;   CPoint arrpt[3];   arrpt[0].x = m_rcAT.right-8;   arrpt[0].y = m_rcAT.top+m_rcAT.Height()*2/5;   ar

gdi 绘制文字时变宽,变高,加间距功能问题,求助

问题描述 这段代码的功能是在gdi绘制文字时将文字通过m.Scale()方式变宽,变高,并且加间距功能问题,但现在的问题是一旦变换m.Scale()里的参数值,坐标会跟着变,错位,TextRectangle为原始的起点坐标及宽高度,文字是在这个区域内绘制,请大神帮忙,if(!string.IsNullOrEmpty(TextValue))//判断字符串是否为空{char[]fs=TextValue.ToCharArray();SizeFsize=g.MeasureString(fs[0].ToS

Android 自定义TextView实现文本内容自动调整字体大小

最近做通讯录小屏机 联系人姓名显示--长度超过边界字体变小 /** * 自定义TextView,文本内容自动调整字体大小以适应TextView的大小 * @author yzp */ public class AutoFitTextView extends TextView { private Paint mTextPaint; private float mTextSize; public AutoFitTextView(Context context) { super(context); }

VC++ GDI+编程的字体和文本绘制

字体是文字显示和打印的外观形式,它包括了文字的字样.风格和尺寸等多方面的属性.适当地选用不同的字体,可以大大地丰富文字的外在表现力.例如,把文字中某些重要的字句用较粗的字体显示,能够体现出突出.强调的意图.当然,文本输出时还可使用其格式化属性和显示质量来优化文本显示的效果. 字体属性和字体创建 字体的属性有很多,这里主要介绍字样.风格和尺寸三个主要属性. 字样是字符书写和显示时表现出的特定模式,例如,对于汉字,通常有宋体.楷体.仿宋.黑体.隶书以及幼圆等多种字样.GDI+是通过FontFamil