在使用GDI方式处理文本时,往往会用到StringFormat。里面的某些点有点反直觉,不够直观,所以本篇就通过图文的方式去讲解一下。
本篇内容仅涉及到文本方向、对齐的相关内容。
如有错误、不妥之处,欢迎大家指正。
一、相关属性
与文本方向、对齐相关的属性,主要与三个属性有关:
Alignment、LineAlignment、FormatFlags。
Alignment与LineAlignment的属性值都是StringAlignment枚举。StringAlignment枚举有三个成员:Near、Center、Far。其MSDN解释如下:
FormatFlags的属性值是StringFormatFlags枚举。主要与其枚举的两个成员——DirectionRightToLeft、DirectionVertical——有关。其MSDN解释如下:
二、使用搭配
1,现代文的阅读顺序:水平方向上从左到右、从上到下。
此时,FormatFlags不包含成员DirectionRightToLeft、DirectionVertical。
1.1,对于Alignment,其示意图如下:
此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:
Near:左对齐
Center:居中对齐
Far:右对齐
1.2,对于LineAlignment,其示意图如下:
此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:
Near:文本段落处于显示区域顶部
Center:文本段落处于显示区域中部
Far:文本段落处理显示区域底部
1.3,Alignment和LineAlignment的组合共有9种,如下所示:
2,古文的阅读顺序:垂直方向上从上到下、从右到左。
此时,FormatFlags同时包含成员DirectionRightToLeft、DirectionVertical。
2.1,对于Alignment,其示意图如下:
此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:
Near:顶部对齐
Center:居中对齐
Far:底部对齐
2.2,对于LineAlignment,其示意图如下:
此时,StringAlignment枚举的三个成员——Near、Center、Far——可以理解为:
Near:文本段落处于显示区域右侧
Center:文本段落处于显示区域中侧
Far:文本段落处理显示区域左侧
2.3,Alignment和LineAlignment的组合共有9种,如下所示:
3,其他
除上文两种搭配方式之外,还有两种搭配方式,即分别使用DirectionRightToLeft和DirectionVertical,这两种搭配方式共有18种样式,不过日常几乎用不到。具体想查看可以通过文末提供的示例源代码自行查看。
示例程序截图:
三、重点说明
仅搭配使用而言,并没有什么可多说的,直接使用即可,但是如果想在某个具体的区域内显示文本段落的话——比如上面的示例截图,其坐标的计算是个难点。
这里的“坐标”并不是人眼看上去的坐标,而是使用Graphics.DrawString时所使用的坐标——绘制文本的左上角。
下面进行举例说明。
例1,现代文方式、右对齐、居中显示。
示意图如下所示(这个示意图是用GDI画的,其中绿框是后期为了方便讲解而手动加的):
其中:
显示区域(上图的蓝色方框):宽=高=200
文本区域:即字符串所占的矩形区域(上图中绿色方框):宽:165,高:43
此时,在使用DrawString时,其point(绘制文本的左上角)的坐标并不是绿色方框的左上角:X:200-165=35,Y:(200-43)/2=78(此处取整数)
其坐标应该是:X:200,Y:200/2=100,即下图中红点所在的坐标(其中黄线是中线):
是不是很反直觉?
不过当接受了这种坐标计算思路之后,一切就迎刃而解了。
下面再举一个例子:
例2:古文方式、底部对齐、左侧显示
示意图如下所示(这个示意图是用GDI画的,其中绿框是后期为了方便讲解而手动加的):
其中:
显示区域(上图的蓝色方框):宽=高=200
文本区域:即字符串所占的矩形区域(上图中绿色方框):宽:43,高:165
此时,在使用DrawString时,其point(绘制文本的左上角)的坐标并不是绿色方框的左上角:X:0,Y:200-165=35
其坐标应该是:X:0,Y:200,即下图中红点所在的坐标:
四、坐标计算核心代码
完整代码见下方提供的源工程。
1 //…… 2 3 Bitmap bmpStr = new Bitmap(200,200); 4 PointF stringStart = new PointF(0, 0); 5 6 if (!DirectionRightToLeft) 7 { 8 if (!DirectionVertical) 9 { 10 if (alignment == StringAlignment.Near) 11 { 12 stringStart.X = 0; 13 } 14 else if (alignment == StringAlignment.Center) 15 { 16 stringStart.X = bmpStr.Width / 2; 17 } 18 else if (alignment == StringAlignment.Far) 19 { 20 stringStart.X = bmpStr.Width; 21 } 22 23 if (lineAlignment == StringAlignment.Near) 24 { 25 stringStart.Y = 0; 26 } 27 else if (lineAlignment == StringAlignment.Center) 28 { 29 stringStart.Y = bmpStr.Height / 2; 30 } 31 else if (lineAlignment == StringAlignment.Far) 32 { 33 stringStart.Y = bmpStr.Height; 34 } 35 } 36 else 37 { 38 if (alignment == StringAlignment.Near) 39 { 40 stringStart.Y = 0; 41 } 42 else if (alignment == StringAlignment.Center) 43 { 44 stringStart.Y = bmpStr.Height / 2; 45 } 46 else if (alignment == StringAlignment.Far) 47 { 48 stringStart.Y = bmpStr.Height; 49 } 50 51 if (lineAlignment == StringAlignment.Near) 52 { 53 stringStart.X = 0; 54 } 55 else if (lineAlignment == StringAlignment.Center) 56 { 57 stringStart.X = bmpStr.Width / 2; 58 } 59 else if (lineAlignment == StringAlignment.Far) 60 { 61 stringStart.X = bmpStr.Width; 62 } 63 } 64 } 65 else 66 { 67 if (!DirectionVertical) 68 { 69 if (alignment == StringAlignment.Near) 70 { 71 stringStart.X = bmpStr.Width; 72 } 73 else if (alignment == StringAlignment.Center) 74 { 75 stringStart.X = bmpStr.Width / 2; 76 } 77 else if (alignment == StringAlignment.Far) 78 { 79 stringStart.X = 0; 80 } 81 82 if (lineAlignment == StringAlignment.Near) 83 { 84 stringStart.Y = 0; 85 } 86 else if (lineAlignment == StringAlignment.Center) 87 { 88 stringStart.Y = bmpStr.Height / 2; 89 } 90 else if (lineAlignment == StringAlignment.Far) 91 { 92 stringStart.Y = bmpStr.Height; 93 } 94 } 95 else 96 { 97 if (alignment == StringAlignment.Near) 98 { 99 stringStart.Y = 0; 100 } 101 else if (alignment == StringAlignment.Center) 102 { 103 stringStart.Y = bmpStr.Height / 2; 104 } 105 else if (alignment == StringAlignment.Far) 106 { 107 stringStart.Y = bmpStr.Height; 108 } 109 110 if (lineAlignment == StringAlignment.Near) 111 { 112 stringStart.X = bmpStr.Width; 113 } 114 else if (lineAlignment == StringAlignment.Center) 115 { 116 stringStart.X = bmpStr.Width / 2; 117 } 118 else if (lineAlignment == StringAlignment.Far) 119 { 120 stringStart.X = 0; 121 } 122 } 123 } 124 125 //…… 126 127 g.DrawString(str, font, new SolidBrush(Color.Red), stringStart, stringFormat); 128 129 //……
五、示例程序源代码下载
源工程文件:
https://files.cnblogs.com/files/lesliexin/StringFormat.7z