GDI图形编程(7)

 

3.2.9  处理像素点

令人惊奇的是,处理窗体中的单个像素非常需要技巧,因为Graphics对象没有提供对像素点进行读取或设置的机制。您可能会认为通过画一条起点坐标与终点坐标相同的线段就可以实现。但是,由于GDI在处理绘制单像素点请求时的奇怪行为,在这种情况下根本不会绘制任何东西,同样的情况也会发生在宽度和高度都为0的矩形与椭圆上,以及所有点坐标都相同的多边形上。

能够实现绘制单像素点的方法是使用FillRectangle方法,将其width参数与height参数都设置为1,这样会在指定的位置上绘制一个只包含了一个像素的矩形。然而,这种方式的效率非常低,应尽量避免使用。

在本章的后文中我们将看到Bitmap类,它提供了更有用的GetPixel与SetPixel方法,它们可以很直接地对单个像素点进行获取和设置。

3.2.10  显示文本

我们还可以使用DrawString方法在窗体上绘制文本。该方法提供了一些重载,允许更好地对文本的呈现进行控制。

所有这些重载的前3个参数都是相同的:用于显示的文本字符串、字体、用于绘制文本的笔刷。

DrawString方法最简单的版本需要指定文本的显示位置,即,使用(x,y)坐标。程序清单3-5展示了在坐标(10,10)上,用窗体默认的字体显示了一些红色的文本。

程序清单3-5  在屏幕上绘制文本

private void MyForm_Paint(object sender, PaintEventArgs e)

{

using (SolidBrush textBrush = new SolidBrush(Color.Red))

{

e.Graphics.DrawString("Hello world!", this.Font, textBrush, 10, 10);

}

}

我们提供的参数中的坐标应是文本打印区域左上角的坐标。如果文本的宽度超过了屏幕,超出屏幕右边界的部分就不会显示。我们可以在文本的任意位置上插入换行符(使用C#中的\n字符序列),将程序清单3-5中要打印的文本修改为"Hello\nworld!",这样,Hello就会出现在world!的上方。换行符会使文本在下方重新打印一行,但还是以DrawString方法所指定的x坐标为起点。

如果需要更好地控制文本的布局,那么可以利用该方法提供的一些其他重载。可以提供一个Rectangle对象,令文本绘制在该矩形区域中。下面的代码在坐标(10,10)上创建了一个宽和高都为100的矩形。最终结果是文本被换行后才能放置在这个定义好的区域中。GDI会自动在距离最近的完整单词的后面进行断行,所以您不必担心在单词中会发生换行(查看程序清单3-6),如果文本太长,已经达到了矩形的底端,那么多出来的文本将会被剪裁掉。

程序清单3-6  在矩形区域中进行换行测试

private void MyForm_Paint(object sender, PaintEventArgs e)

{

using (SolidBrush textBrush = new SolidBrush(Color.Red))

{

// Print the text into a square

e.Graphics.DrawString("The quick brown fox jumps over the lazy dog",

this.Font, textBrush, new Rectangle(10, 10, 100, 100));

// Print the text into a rectangle with insufficient height

e.Graphics.DrawString("The quick brown fox jumps over the lazy dog",

this.Font, textBrush, new Rectangle(130, 10, 100, 35));

}

}

这段代码的运行结果如图3-7所示。注意,右边的文本已经超出了宿主它的矩形的范围,所以看不到底部的文本。

我们还可以通过StringFormat对象进一步提供一个参数,来控制在矩形中如何显示文本。该对象有两个标志:

● NoClip  如果指定NoClip,那么文本可以显示在定义好的矩形边框之外。在矩形区域中,文本还是换行的,但超出预定义区域高度的部分还是连续的。

● NoWrap  此标志禁止文本在矩形中换行。任何位于矩形区域之外的文本都会被剪裁掉。

这两个标志可以通过C#中的二进制OR操作符(使用符号“|”)来一同使用。不过,它的结果相当于只为DrawString函数指定了一个坐标点,而没有指定一个矩形区域。

注:以上内容图略,图片内容请参考原图书

读书导航