给自己单位开发的应用程序,里面有个功能是使用C#中的GDI+功能开发的在固定区域显示指定内容。 最初实现起来很简单,因为显示内容的区域大小是固定的,要显示的内容的字体和字号也是固定的,直接使用Graphics类中的DrawString方法就可以搞定。效果如下图所示: 用户使用这个模块已经有一段时间了。最近突然提出来在这个区域中显示的内容要加长,这样的话再使用固定的字体绘制要显示的内容就显示不下了,效果图如下,本来要显示九个字,结果只显示了四个字出来。 因此需要找方法能够在固定区域内显示所有的内容。
字体太大就把字体变小,字体小了,固定区域里面显示的内容自然而然就多了。这是我一开始的想法。但是如何能够把字体调整的比较合适的? Graphics类中有个MeasureString函数,其中有一个重载函数的形式如下:
public SizeF MeasureString( string text, Font font )该函数输入指定的字体大小已经要绘制的内容,然后返回绘制该内容所需的最小区域尺寸。因此可以通过不断微调字体的大小,通过不断测量用调整后的字体绘制内容所需的宽度是否小于等于固定区域的宽度,判断调整后的字体是否合适,示例代码如下:
float fontSize = ORIGINAL_FONT_SIZE; Font f = new Font(FONT_NAME, ORIGINAL_FONT_SIZE); float contentWidth = g.MeasureString(content, f).Width; while ((contentWidth > m_rect.Width)) { f.Dispose(); fontSize-=FONT_SIZE_CHANGE_STEP;//每次减0.5 f = new Font(FONT_NAME, fontSize); contentWidth = g.MeasureString(content, f).Width; } g.DrawString(content, f, Brushes.Blue, m_rect); f.Dispose();该段代码的效果图如下: 这种方法的缺点就是字体变窄的同时,字体高度也跟着变小了,如果绘制的内容特别多,那字体会别的特别小,虽然画是能够画下了,但是根本看不清楚内容。
用户提的意见是最好字体高度不变,宽度变窄,这样就可以在固定区域内装下更多的内容了。但是C#里面没有什么字体是可以只变宽度不变高度(搜了一顿没有搜到),后来还是通过百度,看到有人提的将字体内容变成图片后进行缩放的做法,这种应该能够满足我的需要。 实现该方式的第一步是将文本内容变成图片,还是使用MeasureString获取使用指定字体绘制指定内容的最小区域,然后创建一个同样大小的图片,代码如下:
using (Graphics g = pnlBoard.CreateGraphics()) { using (Font f = new Font(FONT_NAME, ORIGINAL_FONT_SIZE)) { SizeF contentSize = g.MeasureString(m_content, f); if (m_image != null) { m_image.Dispose(); } m_image = new Bitmap(Convert.ToInt32(contentSize.Width + 1), Convert.ToInt32(contentSize.Height + 1)); using (Graphics gImage = Graphics.FromImage(m_image)) { gImage.DrawString(m_content, f, Brushes.Blue, new Rectangle(0, 0, m_image.Width, m_image.Height)); } } }创建好图片后,使用Graphics类中的DrawImage函数直接将图片绘制到固定区域中即可。程序的效果图如下:
这种方法我没有试通,只是在这里提一下,该函数可以创建指定高度和宽度的字体,按理说应该是可以在C#中使用的。CreateFont的具体介绍可以参考百度百科
示例代码地址:https://github.com/guochao2299/TextAutoSize