RenderEngine.6.Render.cs 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Windows.Forms;
  5. using Microsoft.Drawing;
  6. using Microsoft.Windows.Forms.Layout;
  7. namespace Microsoft.Windows.Forms
  8. {
  9. public static partial class RenderEngine
  10. {
  11. /// <summary>
  12. /// 围绕rect的中心将坐标系顺时针旋转degrees角度,返回新坐标系矩形
  13. /// </summary>
  14. /// <param name="g">绘图对象</param>
  15. /// <param name="rect">要旋转的矩形</param>
  16. /// <param name="degrees">角度</param>
  17. /// <param name="fit">内容旋转,绘图区域不旋转</param>
  18. /// <returns>新坐标系矩形</returns>
  19. public static Rectangle RotateRect(Graphics g, Rectangle rect, float degrees, bool fit)
  20. {
  21. g.RotateTransform(degrees, MatrixOrder.Append);//围绕中心原点旋转
  22. g.TranslateTransform(rect.X + rect.Width / 2, rect.Y + rect.Height / 2, MatrixOrder.Append);//平移原点
  23. if (fit)
  24. {
  25. decimal decLessStraigntAngle = Math.Abs((decimal)degrees) % 180m;//取绝对值后除以180的余数,小于平角的角度
  26. return ((decLessStraigntAngle >= 0 && decLessStraigntAngle <= 45) || (decLessStraigntAngle >= 135 && decLessStraigntAngle <= 180))
  27. ? new Rectangle(-rect.Width / 2, -rect.Height / 2, rect.Width, rect.Height)
  28. : new Rectangle(-rect.Height / 2, -rect.Width / 2, rect.Height, rect.Width);//新坐标系矩形
  29. }
  30. else
  31. {
  32. return new Rectangle(-rect.Width / 2, -rect.Height / 2, rect.Width, rect.Height);
  33. }
  34. }
  35. /// <summary>
  36. /// 开始绘制字符串(画布无限制),并返回路径区域和字符串大小.注意不要修改返回的矩形和字符串大小,在EndDrawString中需要传回.必须与EndDrawString成对出现.
  37. /// </summary>
  38. /// <param name="g">绘图对象</param>
  39. /// <param name="s">字符串</param>
  40. /// <param name="font">字体</param>
  41. /// <param name="strSize">字符串大小</param>
  42. /// <returns>字符串路径区域</returns>
  43. public static Rectangle BeginDrawString(Graphics g, string s, Font font, out Size strSize)
  44. {
  45. using (StringFormat sf = DefaultTheme.StringFormat)
  46. {
  47. strSize = Size.Ceiling(g.MeasureString(s, font, PointF.Empty, sf));
  48. using (GraphicsPath path = new GraphicsPath())
  49. {
  50. path.AddString(s, font.FontFamily, (int)font.Style, g.DpiY * font.SizeInPoints / 72f, Point.Empty, sf);
  51. return Rectangle.Round(path.GetBounds());
  52. }
  53. }
  54. }
  55. /// <summary>
  56. /// 开始绘制字符串(画布有限制),并返回路径区域和字符串大小.注意不要修改返回的矩形和字符串大小,在EndDrawString中需要传回.必须与EndDrawString成对出现.
  57. /// </summary>
  58. /// <param name="g">绘图对象</param>
  59. /// <param name="s">字符串</param>
  60. /// <param name="font">字体</param>
  61. /// <param name="layoutRectangle">限制矩形</param>
  62. /// <param name="strSize">字符串大小</param>
  63. /// <returns>字符串路径区域</returns>
  64. public static Rectangle BeginDrawString(Graphics g, string s, Font font, Rectangle layoutRectangle, out Size strSize)
  65. {
  66. using (StringFormat sf = DefaultTheme.StringFormat)
  67. {
  68. strSize = Size.Ceiling(g.MeasureString(s, font, layoutRectangle.Size, sf));
  69. using (GraphicsPath path = new GraphicsPath())
  70. {
  71. path.AddString(s, font.FontFamily, (int)font.Style, g.DpiY * font.SizeInPoints / 72f, layoutRectangle, sf);
  72. return Rectangle.Round(path.GetBounds());
  73. }
  74. }
  75. }
  76. /// <summary>
  77. /// 正式绘制字符串.与BeginDrawString成对出现
  78. /// </summary>
  79. /// <param name="g">绘图对象</param>
  80. /// <param name="s">字符串</param>
  81. /// <param name="font">字体</param>
  82. /// <param name="brush">画刷</param>
  83. /// <param name="layoutRectangle">画布区域</param>
  84. /// <param name="align">对齐方式</param>
  85. /// <param name="pathBounds">字符串路径区域,BeginDrawString(...)返回值</param>
  86. /// <param name="strSize">字符串大小,BeginDrawString(...)返回值</param>
  87. public static void EndDrawString(Graphics g, string s, Font font, Brush brush, Rectangle layoutRectangle, ContentAlignment align, Rectangle pathBounds, Size strSize)
  88. {
  89. layoutRectangle = LayoutUtils.Align(pathBounds.Size, layoutRectangle, align);
  90. #if DEBUG
  91. g.DrawRectangle(SystemPens.ControlDarkDark, layoutRectangle);
  92. #endif
  93. layoutRectangle.Offset(-pathBounds.X, -pathBounds.Y);
  94. layoutRectangle.Size = strSize;
  95. using (StringFormat sf = DefaultTheme.StringFormat)
  96. {
  97. g.DrawString(s, font, brush, layoutRectangle, sf);
  98. }
  99. }
  100. /// <summary>
  101. /// 精确绘制字符串
  102. /// </summary>
  103. /// <param name="g">绘图对象</param>
  104. /// <param name="s">字符串</param>
  105. /// <param name="font">字体</param>
  106. /// <param name="brush">画刷</param>
  107. /// <param name="layoutRectangle">绘制区域</param>
  108. /// <param name="align">对齐方式</param>
  109. public static void DrawString(Graphics g, string s, Font font, Brush brush, Rectangle layoutRectangle, ContentAlignment align)
  110. {
  111. Size strSize;
  112. Rectangle pathBounds = BeginDrawString(g, s, font, layoutRectangle, out strSize);
  113. EndDrawString(g, s, font, brush, layoutRectangle, align, pathBounds, strSize);
  114. }
  115. /// <summary>
  116. /// 绘制背景图
  117. /// </summary>
  118. /// <param name="g">绘图上下文</param>
  119. /// <param name="image">背景图</param>
  120. /// <param name="rect">绘制区域</param>
  121. /// <param name="layout">背景图布局方式</param>
  122. public static void DrawBackgroundImage(Graphics g, Image image, Rectangle rect, ImageLayout layout)
  123. {
  124. if (image == null)
  125. return;
  126. switch (layout)
  127. {
  128. case ImageLayout.None:
  129. g.DrawImageUnscaled(image, rect.Location);
  130. break;
  131. case ImageLayout.Tile:
  132. using (Brush brush = new TextureBrush(image, WrapMode.Tile))
  133. {
  134. g.FillRectangle(brush, rect);
  135. }
  136. break;
  137. case ImageLayout.Center:
  138. int x = rect.Left + (rect.Width - image.Width) / 2;
  139. int y = rect.Top + (rect.Height - image.Height) / 2;
  140. g.DrawImageUnscaled(image, x, y);
  141. break;
  142. case ImageLayout.Stretch:
  143. g.DrawImage(image, rect);
  144. break;
  145. case ImageLayout.Zoom:
  146. float xscale = (float)rect.Width / (float)image.Width;
  147. float yscale = (float)rect.Height / (float)image.Height;
  148. float scale = Math.Min(xscale, yscale);
  149. int width = (int)(((float)image.Width) * scale);
  150. int height = (int)(((float)image.Height) * scale);
  151. x = rect.Left + (rect.Width - width) / 2;
  152. y = rect.Top + (rect.Height - height) / 2;
  153. g.DrawImage(image, x, y, width, height);
  154. break;
  155. default:
  156. break;
  157. }
  158. }
  159. /// <summary>
  160. /// 绘制九宫格背景图
  161. /// </summary>
  162. /// <param name="g">绘图上下文</param>
  163. /// <param name="image">背景图</param>
  164. /// <param name="rect">目标区域</param>
  165. /// <param name="left">九宫格划分,左</param>
  166. /// <param name="top">九宫格划分,上</param>
  167. /// <param name="right">九宫格划分,右</param>
  168. /// <param name="bottom">九宫格划分,下</param>
  169. /// <param name="layout">九宫格背景图布局方式</param>
  170. public static void DrawBackgroundImage9(Graphics g, Image image, Rectangle rect, int left, int top, int right, int bottom, ImageLayout9 layout)
  171. {
  172. if (image == null || !RectangleEx.IsVisible(rect))
  173. return;
  174. //基本
  175. int nSrcWidth = image.Width;
  176. int nSrcHeight = image.Height;
  177. int nDestWidth = rect.Width;
  178. int nDestHeight = rect.Height;
  179. //左上
  180. Rectangle rcSrcTopLeft = new Rectangle(0, 0, left, top);
  181. Rectangle rcDestTopLeft = new Rectangle(rect.X, rect.Y, left, top);
  182. //上
  183. Rectangle rcSrcTop = new Rectangle(rcSrcTopLeft.Right, rcSrcTopLeft.Y, nSrcWidth - left - right, top);
  184. Rectangle rcDestTop = new Rectangle(rcDestTopLeft.Right, rcDestTopLeft.Y, nDestWidth - left - right, top);
  185. //右上
  186. Rectangle rcSrcTopRight = new Rectangle(rcSrcTop.Right, rcSrcTop.Y, right, top);
  187. Rectangle rcDestTopRight = new Rectangle(rcDestTop.Right, rcDestTop.Y, right, top);
  188. //右
  189. Rectangle rcSrcRight = new Rectangle(rcSrcTopRight.X, rcSrcTopRight.Bottom, right, nSrcHeight - top - bottom);
  190. Rectangle rcDestRight = new Rectangle(rcDestTopRight.X, rcDestTopRight.Bottom, right, nDestHeight - top - bottom);
  191. //右下
  192. Rectangle rcSrcBottomRight = new Rectangle(rcSrcRight.X, rcSrcRight.Bottom, right, bottom);
  193. Rectangle rcDestBottomRight = new Rectangle(rcDestRight.X, rcDestRight.Bottom, right, bottom);
  194. //下
  195. Rectangle rcSrcBottom = new Rectangle(rcSrcTop.X, rcSrcBottomRight.Y, rcSrcTop.Width, bottom);
  196. Rectangle rcDestBottom = new Rectangle(rcDestTop.X, rcDestBottomRight.Y, rcDestTop.Width, bottom);
  197. //左下
  198. Rectangle rcSrcBottomLeft = new Rectangle(rcSrcTopLeft.X, rcSrcBottom.Y, left, bottom);
  199. Rectangle rcDestBottomLeft = new Rectangle(rcDestTopLeft.X, rcDestBottom.Y, left, bottom);
  200. //左
  201. Rectangle rcSrcLeft = new Rectangle(rcSrcBottomLeft.X, rcSrcRight.Y, left, rcSrcRight.Height);
  202. Rectangle rcDestLeft = new Rectangle(rcDestBottomLeft.X, rcDestRight.Y, left, rcDestRight.Height);
  203. //中
  204. Rectangle rcSrcMiddle = new Rectangle(rcSrcTop.X, rcSrcLeft.Y, rcSrcTop.Width, rcSrcLeft.Height);
  205. Rectangle rcDestMiddle = new Rectangle(rcDestTop.X, rcDestLeft.Y, rcDestTop.Width, rcDestLeft.Height);
  206. //左上
  207. if (RectangleEx.IsVisible(rcSrcTopLeft))
  208. {
  209. g.DrawImage(image, rcDestTopLeft, rcSrcTopLeft, GraphicsUnit.Pixel);
  210. }
  211. //上
  212. if (RectangleEx.IsVisible(rcSrcTop) && RectangleEx.IsVisible(rcDestTop))
  213. {
  214. if ((layout & ImageLayout9.TopTile) == 0)//拉伸
  215. {
  216. g.DrawImage(image, rcDestTop, rcSrcTop, GraphicsUnit.Pixel);
  217. }
  218. else//平铺
  219. {
  220. using (TextureBrush brush = new TextureBrush(image, WrapMode.Tile, rcSrcTop))
  221. {
  222. brush.TranslateTransform(rcDestTop.X, rcDestTop.Y);
  223. g.FillRectangle(brush, rcDestTop);
  224. }
  225. }
  226. }
  227. //右上
  228. if (RectangleEx.IsVisible(rcSrcTopRight))
  229. {
  230. g.DrawImage(image, rcDestTopRight, rcSrcTopRight, GraphicsUnit.Pixel);
  231. }
  232. //右
  233. if (RectangleEx.IsVisible(rcSrcRight) && RectangleEx.IsVisible(rcDestRight))
  234. {
  235. if ((layout & ImageLayout9.RightTile) == 0)//拉伸
  236. {
  237. g.DrawImage(image, rcDestRight, rcSrcRight, GraphicsUnit.Pixel);
  238. }
  239. else//平铺
  240. {
  241. using (TextureBrush brush = new TextureBrush(image, WrapMode.Tile, rcSrcRight))
  242. {
  243. brush.TranslateTransform(rcDestRight.X, rcDestRight.Y);
  244. g.FillRectangle(brush, rcDestRight);
  245. }
  246. }
  247. }
  248. //右下
  249. if (RectangleEx.IsVisible(rcSrcBottomRight))
  250. {
  251. g.DrawImage(image, rcDestBottomRight, rcSrcBottomRight, GraphicsUnit.Pixel);
  252. }
  253. //下
  254. if (RectangleEx.IsVisible(rcSrcBottom) && RectangleEx.IsVisible(rcDestBottom))
  255. {
  256. if ((layout & ImageLayout9.BottomTile) == 0)//拉伸
  257. {
  258. g.DrawImage(image, rcDestBottom, rcSrcBottom, GraphicsUnit.Pixel);
  259. }
  260. else//平铺
  261. {
  262. using (TextureBrush brush = new TextureBrush(image, WrapMode.Tile, rcSrcBottom))
  263. {
  264. brush.TranslateTransform(rcDestBottom.X, rcDestBottom.Y);
  265. g.FillRectangle(brush, rcDestBottom);
  266. }
  267. }
  268. }
  269. //左下
  270. if (RectangleEx.IsVisible(rcSrcBottomLeft))
  271. {
  272. g.DrawImage(image, rcDestBottomLeft, rcSrcBottomLeft, GraphicsUnit.Pixel);
  273. }
  274. //左
  275. if (RectangleEx.IsVisible(rcSrcLeft) && RectangleEx.IsVisible(rcDestLeft))
  276. {
  277. if ((layout & ImageLayout9.LeftTile) == 0)//拉伸
  278. {
  279. g.DrawImage(image, rcDestLeft, rcSrcLeft, GraphicsUnit.Pixel);
  280. }
  281. else//平铺
  282. {
  283. using (TextureBrush brush = new TextureBrush(image, WrapMode.Tile, rcSrcLeft))
  284. {
  285. brush.TranslateTransform(rcDestLeft.X, rcDestLeft.Y);
  286. g.FillRectangle(brush, rcDestLeft);
  287. }
  288. }
  289. }
  290. //中间
  291. if (RectangleEx.IsVisible(rcSrcMiddle) && RectangleEx.IsVisible(rcDestMiddle))
  292. {
  293. if ((layout & ImageLayout9.MiddleTile) == 0)//拉伸
  294. {
  295. g.DrawImage(image, rcDestMiddle, rcSrcMiddle, GraphicsUnit.Pixel);
  296. }
  297. else//平铺
  298. {
  299. using (TextureBrush brush = new TextureBrush(image, WrapMode.Tile, rcSrcMiddle))
  300. {
  301. brush.TranslateTransform(rcDestMiddle.X, rcDestMiddle.Y);
  302. g.FillRectangle(brush, rcDestMiddle);
  303. }
  304. }
  305. }
  306. }
  307. /// <summary>
  308. /// 绘制边框
  309. /// </summary>
  310. /// <param name="g">绘图对象</param>
  311. /// <param name="pen">画笔</param>
  312. /// <param name="rect">矩形区域</param>
  313. /// <param name="borderStyle">边框样式</param>
  314. /// <param name="cornerStyle">圆角弯曲样式</param>
  315. /// <param name="roundStyle">圆角样式</param>
  316. /// <param name="radius">圆角半径</param>
  317. /// <param name="correct">是否减小一个像素</param>
  318. public static void DrawBorder(Graphics g, Pen pen, Rectangle rect, BorderVisibleStyle borderStyle, CornerStyle cornerStyle, RoundStyle roundStyle, float radius, bool correct)
  319. {
  320. //-----------------不绘制-----------------
  321. if (borderStyle == BorderVisibleStyle.None)
  322. return;
  323. //-----------------校准-----------------
  324. if (correct)
  325. {
  326. rect.Width--;
  327. rect.Height--;
  328. }
  329. //-----------------特殊情况处理-----------------
  330. if (float.IsNaN(radius) || radius <= 0f)
  331. {
  332. //-----------------全边-----------------
  333. if (borderStyle == BorderVisibleStyle.All)
  334. {
  335. g.DrawRectangle(pen, rect);
  336. return;
  337. }
  338. cornerStyle = CornerStyle.None;
  339. roundStyle = RoundStyle.None;
  340. }
  341. //-----------------临时变量定义-----------------
  342. float diameter = radius * 2;//直径
  343. float halfWidth = rect.Width / 2f;//宽度一半
  344. float halfHeight = rect.Height / 2f;//高度一半
  345. PointF ptMiddleCenter = new PointF(rect.X + halfWidth, rect.Y + halfHeight);//中心点
  346. float lrDegrees = 0f;//半径大于半高,圆心角
  347. float lrOffset = 0f;//半径大于半高,圆弧到边距离
  348. if ((roundStyle & RoundStyle.All) != 0 && radius > halfHeight)
  349. {
  350. double lrRadian = Math.Acos((radius - halfHeight) / radius);//弧度
  351. lrDegrees = (float)MathEx.ToDegrees(lrRadian);//角度
  352. lrOffset = (float)(radius * Math.Sin(lrRadian));
  353. }
  354. float tbDegrees = 0f;//半径大于半宽,圆心角
  355. float tbOffset = 0f;//半径大于办宽,圆弧到边距离
  356. if ((roundStyle & RoundStyle.All) != 0 && radius > halfWidth)
  357. {
  358. double tbRadian = Math.Acos((radius - halfWidth) / radius);//弧度
  359. tbDegrees = (float)MathEx.ToDegrees(tbRadian);//角度
  360. tbOffset = (float)(radius * Math.Sin(tbRadian));
  361. }
  362. //临时变量
  363. PointF ptBeginTopLeft;
  364. PointF ptEndTopLeft;
  365. PointF ptBeginTopRight;
  366. PointF ptEndTopRight;
  367. PointF ptBeginBottomRight;
  368. PointF ptEndBottomRight;
  369. PointF ptBeginBottomLeft;
  370. PointF ptEndBottomLeft;
  371. #region 计算左上端点
  372. if ((roundStyle & RoundStyle.TopLeft) == 0)//直角
  373. {
  374. if ((cornerStyle & CornerStyle.LeftIn) != 0)
  375. {
  376. ptBeginTopLeft = new PointF(rect.X + radius, ptMiddleCenter.Y);
  377. ptEndTopLeft = new PointF(rect.X, rect.Y);
  378. }
  379. else if ((cornerStyle & CornerStyle.LeftOut) != 0)
  380. {
  381. ptBeginTopLeft = new PointF(rect.X, ptMiddleCenter.Y);
  382. ptEndTopLeft = new PointF(rect.X + radius, rect.Y);
  383. }
  384. else if ((cornerStyle & CornerStyle.TopIn) != 0)
  385. {
  386. ptBeginTopLeft = new PointF(rect.X, rect.Y);
  387. ptEndTopLeft = new PointF(ptMiddleCenter.X, rect.Y + radius);
  388. }
  389. else if ((cornerStyle & CornerStyle.TopOut) != 0)
  390. {
  391. ptBeginTopLeft = new PointF(rect.X, rect.Y + radius);
  392. ptEndTopLeft = new PointF(ptMiddleCenter.X, rect.Y);
  393. }
  394. else
  395. {
  396. ptBeginTopLeft = ptEndTopLeft = new PointF(rect.X, rect.Y);
  397. }
  398. }
  399. else//圆角
  400. {
  401. if ((cornerStyle & CornerStyle.LeftIn) != 0)
  402. {
  403. if (radius > halfHeight)
  404. {
  405. ptBeginTopLeft = new PointF(rect.X + lrOffset, ptMiddleCenter.Y);
  406. ptEndTopLeft = new PointF(rect.X, rect.Y);
  407. }
  408. else
  409. {
  410. ptBeginTopLeft = new PointF(rect.X + radius, rect.Y + radius);
  411. ptEndTopLeft = new PointF(rect.X, rect.Y);
  412. }
  413. }
  414. else if ((cornerStyle & CornerStyle.LeftOut) != 0)
  415. {
  416. if (radius > halfHeight)
  417. {
  418. ptBeginTopLeft = new PointF(rect.X, ptMiddleCenter.Y);
  419. ptEndTopLeft = new PointF(rect.X + lrOffset, rect.Y);
  420. }
  421. else
  422. {
  423. ptBeginTopLeft = new PointF(rect.X, rect.Y + radius);//same
  424. ptEndTopLeft = new PointF(rect.X + radius, rect.Y);//same
  425. }
  426. }
  427. else if ((cornerStyle & CornerStyle.TopIn) != 0)
  428. {
  429. if (radius > halfWidth)
  430. {
  431. ptBeginTopLeft = new PointF(rect.X, rect.Y);
  432. ptEndTopLeft = new PointF(ptMiddleCenter.X, rect.Y + tbOffset);
  433. }
  434. else
  435. {
  436. ptBeginTopLeft = new PointF(rect.X, rect.Y);
  437. ptEndTopLeft = new PointF(rect.X + radius, rect.Y + radius);
  438. }
  439. }
  440. else if ((cornerStyle & CornerStyle.TopOut) != 0)
  441. {
  442. if (radius > halfWidth)
  443. {
  444. ptBeginTopLeft = new PointF(rect.X, rect.Y + tbOffset);
  445. ptEndTopLeft = new PointF(ptMiddleCenter.X, rect.Y);
  446. }
  447. else
  448. {
  449. ptBeginTopLeft = new PointF(rect.X, rect.Y + radius);//same
  450. ptEndTopLeft = new PointF(rect.X + radius, rect.Y);//same
  451. }
  452. }
  453. else
  454. {
  455. ptBeginTopLeft = new PointF(rect.X, rect.Y + radius);//same
  456. ptEndTopLeft = new PointF(rect.X + radius, rect.Y);//same
  457. }
  458. }
  459. #endregion
  460. #region 计算右上端点
  461. if ((roundStyle & RoundStyle.TopRight) == 0)
  462. {
  463. if ((cornerStyle & CornerStyle.RightIn) != 0)
  464. {
  465. ptBeginTopRight = new PointF(rect.Right, rect.Y);
  466. ptEndTopRight = new PointF(rect.Right - radius, ptMiddleCenter.Y);
  467. }
  468. else if ((cornerStyle & CornerStyle.RightOut) != 0)
  469. {
  470. ptBeginTopRight = new PointF(rect.Right - radius, rect.Y);
  471. ptEndTopRight = new PointF(rect.Right, ptMiddleCenter.Y);
  472. }
  473. else if ((cornerStyle & CornerStyle.TopIn) != 0)
  474. {
  475. ptBeginTopRight = new PointF(ptMiddleCenter.X, rect.Y + radius);
  476. ptEndTopRight = new PointF(rect.Right, rect.Y);
  477. }
  478. else if ((cornerStyle & CornerStyle.TopOut) != 0)
  479. {
  480. ptBeginTopRight = new PointF(ptMiddleCenter.X, rect.Y);
  481. ptEndTopRight = new PointF(rect.Right, rect.Y + radius);
  482. }
  483. else
  484. {
  485. ptBeginTopRight = ptEndTopRight = new PointF(rect.Right, rect.Y);
  486. }
  487. }
  488. else
  489. {
  490. if ((cornerStyle & CornerStyle.RightIn) != 0)
  491. {
  492. if (radius > halfHeight)
  493. {
  494. ptBeginTopRight = new PointF(rect.Right, rect.Y);
  495. ptEndTopRight = new PointF(rect.Right - lrOffset, ptMiddleCenter.Y);
  496. }
  497. else
  498. {
  499. ptBeginTopRight = new PointF(rect.Right, rect.Y);
  500. ptEndTopRight = new PointF(rect.Right - radius, rect.Y + radius);
  501. }
  502. }
  503. else if ((cornerStyle & CornerStyle.RightOut) != 0)
  504. {
  505. if (radius > halfHeight)
  506. {
  507. ptBeginTopRight = new PointF(rect.Right - lrOffset, rect.Y);
  508. ptEndTopRight = new PointF(rect.Right, ptMiddleCenter.Y);
  509. }
  510. else
  511. {
  512. ptBeginTopRight = new PointF(rect.Right - radius, rect.Y);//same
  513. ptEndTopRight = new PointF(rect.Right, rect.Y + radius);//same
  514. }
  515. }
  516. else if ((cornerStyle & CornerStyle.TopIn) != 0)
  517. {
  518. if (radius > halfWidth)
  519. {
  520. ptBeginTopRight = new PointF(ptMiddleCenter.X, rect.Y + tbOffset);
  521. ptEndTopRight = new PointF(rect.Right, rect.Y);
  522. }
  523. else
  524. {
  525. ptBeginTopRight = new PointF(rect.Right - radius, rect.Y + radius);
  526. ptEndTopRight = new PointF(rect.Right, rect.Y);
  527. }
  528. }
  529. else if ((cornerStyle & CornerStyle.TopOut) != 0)
  530. {
  531. if (radius > halfWidth)
  532. {
  533. ptBeginTopRight = new PointF(ptMiddleCenter.X, rect.Y);
  534. ptEndTopRight = new PointF(rect.Right, rect.Y + tbOffset);
  535. }
  536. else
  537. {
  538. ptBeginTopRight = new PointF(rect.Right - radius, rect.Y);//same
  539. ptEndTopRight = new PointF(rect.Right, rect.Y + radius);//same
  540. }
  541. }
  542. else
  543. {
  544. ptBeginTopRight = new PointF(rect.Right - radius, rect.Y);//same
  545. ptEndTopRight = new PointF(rect.Right, rect.Y + radius);//same
  546. }
  547. }
  548. #endregion
  549. #region 计算右下端点
  550. if ((roundStyle & RoundStyle.BottomRight) == 0)
  551. {
  552. if ((cornerStyle & CornerStyle.RightIn) != 0)
  553. {
  554. ptBeginBottomRight = new PointF(rect.Right - radius, ptMiddleCenter.Y);
  555. ptEndBottomRight = new PointF(rect.Right, rect.Bottom);
  556. }
  557. else if ((cornerStyle & CornerStyle.RightOut) != 0)
  558. {
  559. ptBeginBottomRight = new PointF(rect.Right, ptMiddleCenter.Y);
  560. ptEndBottomRight = new PointF(rect.Right - radius, rect.Bottom);
  561. }
  562. else if ((cornerStyle & CornerStyle.BottomIn) != 0)
  563. {
  564. ptBeginBottomRight = new PointF(rect.Right, rect.Bottom);
  565. ptEndBottomRight = new PointF(ptMiddleCenter.X, rect.Bottom - radius);
  566. }
  567. else if ((cornerStyle & CornerStyle.BottomOut) != 0)
  568. {
  569. ptBeginBottomRight = new PointF(rect.Right, rect.Bottom - radius);
  570. ptEndBottomRight = new PointF(ptMiddleCenter.X, rect.Bottom);
  571. }
  572. else
  573. {
  574. ptBeginBottomRight = ptEndBottomRight = new PointF(rect.Right, rect.Bottom);
  575. }
  576. }
  577. else
  578. {
  579. if ((cornerStyle & CornerStyle.RightIn) != 0)
  580. {
  581. if (radius > halfHeight)
  582. {
  583. ptBeginBottomRight = new PointF(rect.Right - lrOffset, ptMiddleCenter.Y);
  584. ptEndBottomRight = new PointF(rect.Right, rect.Bottom);
  585. }
  586. else
  587. {
  588. ptBeginBottomRight = new PointF(rect.Right - radius, rect.Bottom - radius);
  589. ptEndBottomRight = new PointF(rect.Right, rect.Bottom);
  590. }
  591. }
  592. else if ((cornerStyle & CornerStyle.RightOut) != 0)
  593. {
  594. if (radius > halfHeight)
  595. {
  596. ptBeginBottomRight = new PointF(rect.Right, ptMiddleCenter.Y);
  597. ptEndBottomRight = new PointF(rect.Right - lrOffset, rect.Bottom);
  598. }
  599. else
  600. {
  601. ptBeginBottomRight = new PointF(rect.Right, rect.Bottom - radius);//same
  602. ptEndBottomRight = new PointF(rect.Right - radius, rect.Bottom);//same
  603. }
  604. }
  605. else if ((cornerStyle & CornerStyle.BottomIn) != 0)
  606. {
  607. if (radius > halfWidth)
  608. {
  609. ptBeginBottomRight = new PointF(rect.Right, rect.Bottom);
  610. ptEndBottomRight = new PointF(ptMiddleCenter.X, rect.Bottom - tbOffset);
  611. }
  612. else
  613. {
  614. ptBeginBottomRight = new PointF(rect.Right, rect.Bottom);
  615. ptEndBottomRight = new PointF(rect.Right - radius, rect.Bottom - radius);
  616. }
  617. }
  618. else if ((cornerStyle & CornerStyle.BottomOut) != 0)
  619. {
  620. if (radius > halfWidth)
  621. {
  622. ptBeginBottomRight = new PointF(rect.Right, rect.Bottom - tbOffset);
  623. ptEndBottomRight = new PointF(ptMiddleCenter.X, rect.Bottom);
  624. }
  625. else
  626. {
  627. ptBeginBottomRight = new PointF(rect.Right, rect.Bottom - radius);//same
  628. ptEndBottomRight = new PointF(rect.Right - radius, rect.Bottom);//same
  629. }
  630. }
  631. else
  632. {
  633. ptBeginBottomRight = new PointF(rect.Right, rect.Bottom - radius);//same
  634. ptEndBottomRight = new PointF(rect.Right - radius, rect.Bottom);//same
  635. }
  636. }
  637. #endregion
  638. #region 计算左下端点
  639. if ((roundStyle & RoundStyle.BottomLeft) == 0)
  640. {
  641. if ((cornerStyle & CornerStyle.LeftIn) != 0)
  642. {
  643. ptBeginBottomLeft = new PointF(rect.X, rect.Bottom);
  644. ptEndBottomLeft = new PointF(rect.X + radius, ptMiddleCenter.Y);
  645. }
  646. else if ((cornerStyle & CornerStyle.LeftOut) != 0)
  647. {
  648. ptBeginBottomLeft = new PointF(rect.X + radius, rect.Bottom);
  649. ptEndBottomLeft = new PointF(rect.X, ptMiddleCenter.Y);
  650. }
  651. else if ((cornerStyle & CornerStyle.BottomIn) != 0)
  652. {
  653. ptBeginBottomLeft = new PointF(ptMiddleCenter.X, rect.Bottom - radius);
  654. ptEndBottomLeft = new PointF(rect.X, rect.Bottom);
  655. }
  656. else if ((cornerStyle & CornerStyle.BottomOut) != 0)
  657. {
  658. ptBeginBottomLeft = new PointF(ptMiddleCenter.X, rect.Bottom);
  659. ptEndBottomLeft = new PointF(rect.X, rect.Bottom - radius);
  660. }
  661. else
  662. {
  663. ptBeginBottomLeft = ptEndBottomLeft = new PointF(rect.X, rect.Bottom);
  664. }
  665. }
  666. else
  667. {
  668. if ((cornerStyle & CornerStyle.LeftIn) != 0)
  669. {
  670. if (radius > halfHeight)
  671. {
  672. ptBeginBottomLeft = new PointF(rect.Left, rect.Bottom);
  673. ptEndBottomLeft = new PointF(rect.Left + lrOffset, ptMiddleCenter.Y);
  674. }
  675. else
  676. {
  677. ptBeginBottomLeft = new PointF(rect.Left, rect.Bottom);
  678. ptEndBottomLeft = new PointF(rect.Left + radius, rect.Bottom - radius);
  679. }
  680. }
  681. else if ((cornerStyle & CornerStyle.LeftOut) != 0)
  682. {
  683. if (radius > halfHeight)
  684. {
  685. ptBeginBottomLeft = new PointF(rect.Left + lrOffset, rect.Bottom);
  686. ptEndBottomLeft = new PointF(rect.Left, ptMiddleCenter.Y);
  687. }
  688. else
  689. {
  690. ptBeginBottomLeft = new PointF(rect.Left + radius, rect.Bottom);//same
  691. ptEndBottomLeft = new PointF(rect.Left, rect.Bottom - radius);//same
  692. }
  693. }
  694. else if ((cornerStyle & CornerStyle.BottomIn) != 0)
  695. {
  696. if (radius > halfWidth)
  697. {
  698. ptBeginBottomLeft = new PointF(ptMiddleCenter.X, rect.Bottom - tbOffset);
  699. ptEndBottomLeft = new PointF(rect.Left, rect.Bottom);
  700. }
  701. else
  702. {
  703. ptBeginBottomLeft = new PointF(rect.Left + radius, rect.Bottom - radius);
  704. ptEndBottomLeft = new PointF(rect.Left, rect.Bottom);
  705. }
  706. }
  707. else if ((cornerStyle & CornerStyle.BottomOut) != 0)
  708. {
  709. if (radius > halfWidth)
  710. {
  711. ptBeginBottomLeft = new PointF(ptMiddleCenter.X, rect.Bottom);
  712. ptEndBottomLeft = new PointF(rect.Left, rect.Bottom - tbOffset);
  713. }
  714. else
  715. {
  716. ptBeginBottomLeft = new PointF(rect.Left + radius, rect.Bottom);//same
  717. ptEndBottomLeft = new PointF(rect.Left, rect.Bottom - radius);//same
  718. }
  719. }
  720. else
  721. {
  722. ptBeginBottomLeft = new PointF(rect.Left + radius, rect.Bottom);//same
  723. ptEndBottomLeft = new PointF(rect.Left, rect.Bottom - radius);//same
  724. }
  725. }
  726. #endregion
  727. #region 绘制左边
  728. if ((borderStyle & BorderVisibleStyle.Left) != 0)
  729. {
  730. g.DrawLine(pen, ptEndBottomLeft, ptBeginTopLeft);
  731. }
  732. #endregion
  733. #region 绘制左上角
  734. if ((borderStyle & BorderVisibleStyle.Left) != 0 || (borderStyle & BorderVisibleStyle.Top) != 0)
  735. {
  736. if ((roundStyle & RoundStyle.TopLeft) == 0)
  737. {
  738. g.DrawLine(pen, ptBeginTopLeft, ptEndTopLeft);
  739. }
  740. else
  741. {
  742. if ((cornerStyle & CornerStyle.LeftIn) != 0)
  743. {
  744. if (radius > halfHeight)
  745. g.DrawArc(pen, rect.X - radius, rect.Y, diameter, diameter, 270 + lrDegrees, -lrDegrees);
  746. else
  747. g.DrawArc(pen, rect.X - radius, rect.Y, diameter, diameter, 0, -90);
  748. }
  749. else if ((cornerStyle & CornerStyle.LeftOut) != 0)
  750. {
  751. if (radius > halfHeight)
  752. g.DrawArc(pen, rect.X - (radius - lrOffset), rect.Y, diameter, diameter, 270 - lrDegrees, lrDegrees);
  753. else
  754. g.DrawArc(pen, rect.X, rect.Y, diameter, diameter, 180, 90);//same
  755. }
  756. else if ((cornerStyle & CornerStyle.TopIn) != 0)
  757. {
  758. if (radius > halfWidth)
  759. g.DrawArc(pen, rect.X, rect.Y - radius, diameter, diameter, 180, -tbDegrees);
  760. else
  761. g.DrawArc(pen, rect.X, rect.Y - radius, diameter, diameter, 180, -90);
  762. }
  763. else if ((cornerStyle & CornerStyle.TopOut) != 0)
  764. {
  765. if (radius > halfWidth)
  766. g.DrawArc(pen, rect.X, rect.Y - (radius - tbOffset), diameter, diameter, 180, tbDegrees);
  767. else
  768. g.DrawArc(pen, rect.X, rect.Y, diameter, diameter, 180, 90);//same
  769. }
  770. else
  771. {
  772. g.DrawArc(pen, rect.X, rect.Y, diameter, diameter, 180, 90);//same
  773. }
  774. }
  775. }
  776. #endregion
  777. #region 绘制上边
  778. if ((borderStyle & BorderVisibleStyle.Top) != 0)
  779. {
  780. g.DrawLine(pen, ptEndTopLeft, ptBeginTopRight);
  781. }
  782. #endregion
  783. #region 绘制右上角
  784. if ((borderStyle & BorderVisibleStyle.Top) != 0 || (borderStyle & BorderVisibleStyle.Right) != 0)
  785. {
  786. if ((roundStyle & RoundStyle.TopRight) == 0)
  787. {
  788. g.DrawLine(pen, ptBeginTopRight, ptEndTopRight);
  789. }
  790. else
  791. {
  792. if ((cornerStyle & CornerStyle.RightIn) != 0)
  793. {
  794. if (radius > halfHeight)
  795. g.DrawArc(pen, rect.Right - radius, rect.Y, diameter, diameter, 270, -lrDegrees);
  796. else
  797. g.DrawArc(pen, rect.Right - radius, rect.Y, diameter, diameter, 270, -90);
  798. }
  799. else if ((cornerStyle & CornerStyle.RightOut) != 0)
  800. {
  801. if (radius > halfHeight)
  802. g.DrawArc(pen, rect.Right - radius - lrOffset, rect.Y, diameter, diameter, 270, lrDegrees);
  803. else
  804. g.DrawArc(pen, rect.Right - diameter, rect.Y, diameter, diameter, 270, 90);//same
  805. }
  806. else if ((cornerStyle & CornerStyle.TopIn) != 0)
  807. {
  808. if (radius > halfWidth)
  809. g.DrawArc(pen, rect.Right - diameter, rect.Y - radius, diameter, diameter, tbDegrees, -tbDegrees);
  810. else
  811. g.DrawArc(pen, rect.Right - diameter, rect.Y - radius, diameter, diameter, 90, -90);
  812. }
  813. else if ((cornerStyle & CornerStyle.TopOut) != 0)
  814. {
  815. if (radius > halfWidth)
  816. g.DrawArc(pen, rect.Right - diameter, rect.Y - (radius - tbOffset), diameter, diameter, 360 - tbDegrees, tbDegrees);
  817. else
  818. g.DrawArc(pen, rect.Right - diameter, rect.Y, diameter, diameter, 270, 90);//same
  819. }
  820. else
  821. {
  822. g.DrawArc(pen, rect.Right - diameter, rect.Y, diameter, diameter, 270, 90);//same
  823. }
  824. }
  825. }
  826. #endregion
  827. #region 绘制右边
  828. if ((borderStyle & BorderVisibleStyle.Right) != 0)
  829. {
  830. g.DrawLine(pen, ptEndTopRight, ptBeginBottomRight);
  831. }
  832. #endregion
  833. #region 绘制右下角
  834. if ((borderStyle & BorderVisibleStyle.Right) != 0 || (borderStyle & BorderVisibleStyle.Bottom) != 0)
  835. {
  836. if ((roundStyle & RoundStyle.BottomRight) == 0)
  837. {
  838. g.DrawLine(pen, ptBeginBottomRight, ptEndBottomRight);
  839. }
  840. else
  841. {
  842. if ((cornerStyle & CornerStyle.RightIn) != 0)
  843. {
  844. if (radius > halfHeight)
  845. g.DrawArc(pen, rect.Right - radius, rect.Bottom - diameter, diameter, diameter, 90 + lrDegrees, -lrDegrees);
  846. else
  847. g.DrawArc(pen, rect.Right - radius, rect.Bottom - diameter, diameter, diameter, 180, -90);
  848. }
  849. else if ((cornerStyle & CornerStyle.RightOut) != 0)
  850. {
  851. if (radius > halfHeight)
  852. g.DrawArc(pen, rect.Right - radius - lrOffset, rect.Bottom - diameter, diameter, diameter, 90 - lrDegrees, lrDegrees);
  853. else
  854. g.DrawArc(pen, rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);//same
  855. }
  856. else if ((cornerStyle & CornerStyle.BottomIn) != 0)
  857. {
  858. if (radius > halfWidth)
  859. g.DrawArc(pen, rect.Right - diameter, rect.Bottom - radius, diameter, diameter, 0, -tbDegrees);
  860. else
  861. g.DrawArc(pen, rect.Right - diameter, rect.Bottom - radius, diameter, diameter, 0, -90);
  862. }
  863. else if ((cornerStyle & CornerStyle.BottomOut) != 0)
  864. {
  865. if (radius > halfWidth)
  866. g.DrawArc(pen, rect.Right - diameter, rect.Bottom - radius - tbOffset, diameter, diameter, 0, tbDegrees);
  867. else
  868. g.DrawArc(pen, rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);//same
  869. }
  870. else
  871. {
  872. g.DrawArc(pen, rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);//same
  873. }
  874. }
  875. }
  876. #endregion
  877. #region 绘制下边
  878. if ((borderStyle & BorderVisibleStyle.Bottom) != 0)
  879. {
  880. g.DrawLine(pen, ptEndBottomRight, ptBeginBottomLeft);
  881. }
  882. #endregion
  883. #region 绘制左下角
  884. if ((borderStyle & BorderVisibleStyle.Bottom) != 0 || (borderStyle & BorderVisibleStyle.Left) != 0)
  885. {
  886. if ((roundStyle & RoundStyle.BottomLeft) == 0)
  887. {
  888. g.DrawLine(pen, ptBeginBottomLeft, ptEndBottomLeft);
  889. }
  890. else
  891. {
  892. if ((cornerStyle & CornerStyle.LeftIn) != 0)
  893. {
  894. if (radius > halfHeight)
  895. g.DrawArc(pen, rect.X - radius, rect.Bottom - diameter, diameter, diameter, 90, -lrDegrees);
  896. else
  897. g.DrawArc(pen, rect.X - radius, rect.Bottom - diameter, diameter, diameter, 90, -90);
  898. }
  899. else if ((cornerStyle & CornerStyle.LeftOut) != 0)
  900. {
  901. if (radius > halfHeight)
  902. g.DrawArc(pen, rect.X - (radius - lrOffset), rect.Bottom - diameter, diameter, diameter, 90, lrDegrees);
  903. else
  904. g.DrawArc(pen, rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90);//same
  905. }
  906. else if ((cornerStyle & CornerStyle.BottomIn) != 0)
  907. {
  908. if (radius > halfWidth)
  909. g.DrawArc(pen, rect.X, rect.Bottom - radius, diameter, diameter, 180 + tbDegrees, -tbDegrees);
  910. else
  911. g.DrawArc(pen, rect.X, rect.Bottom - radius, diameter, diameter, 270, -90);
  912. }
  913. else if ((cornerStyle & CornerStyle.BottomOut) != 0)
  914. {
  915. if (radius > halfWidth)
  916. g.DrawArc(pen, rect.X, rect.Bottom - radius - tbOffset, diameter, diameter, 180 - tbDegrees, tbDegrees);
  917. else
  918. g.DrawArc(pen, rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90);//same
  919. }
  920. else
  921. {
  922. g.DrawArc(pen, rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90);//same
  923. }
  924. }
  925. }
  926. #endregion
  927. }
  928. /// <summary>
  929. /// 绘制模糊特效,颜色需要带alpha通道
  930. /// </summary>
  931. /// <param name="g">绘图对象</param>
  932. /// <param name="rect">区域</param>
  933. /// <param name="color">颜色(带alpha通道)</param>
  934. public static void DrawAeroBlur(Graphics g, Rectangle rect, Color color)
  935. {
  936. using (Brush brush = new SolidBrush(color))
  937. {
  938. g.FillRectangle(brush, rect);
  939. }
  940. }
  941. /// <summary>
  942. /// 绘制玻璃效果,颜色需要带alpha通道
  943. /// </summary>
  944. /// <param name="g">绘图对象</param>
  945. /// <param name="rect">区域</param>
  946. /// <param name="centerColor">中心颜色(带alpha通道)</param>
  947. /// <param name="surroundColor">周围颜色(带alpha通道)</param>
  948. public static void DrawAeroGlass(Graphics g, Rectangle rect, Color centerColor, Color surroundColor)
  949. {
  950. using (GraphicsPath path = new GraphicsPath())
  951. {
  952. path.AddEllipse(rect);
  953. using (PathGradientBrush brush = new PathGradientBrush(path))
  954. {
  955. brush.CenterColor = centerColor;
  956. brush.SurroundColors = new Color[] { surroundColor };
  957. brush.CenterPoint = new PointF(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
  958. g.FillPath(brush, path);
  959. }
  960. }
  961. }
  962. /// <summary>
  963. /// 绘制对号(按比例)
  964. /// </summary>
  965. /// <param name="g">绘图对象</param>
  966. /// <param name="rect">绘图区域</param>
  967. /// <param name="color">颜色</param>
  968. public static void DrawCheck(Graphics g, Rectangle rect, Color color)
  969. {
  970. rect.Width--;
  971. rect.Height--;
  972. int width = rect.Width;
  973. int height = rect.Height;
  974. int l = rect.X;
  975. int t = rect.Y;
  976. int r = rect.Right;
  977. int b = rect.Bottom;
  978. PointF[] points = new PointF[3];
  979. points[0] = new PointF(l + width * 0.2f, t + height * 0.522f);//左
  980. points[1] = new PointF(l + width * 0.422f, b - height * 0.251f);//中
  981. points[2] = new PointF(r - width * 0.204f, t + height * 0.208f);//右
  982. using (Pen pen = new Pen(color, Math.Max(2f, Math.Min(rect.Width, rect.Height) * 0.15f)))
  983. {
  984. using (new SmoothingModeGraphics(g))
  985. {
  986. g.DrawLines(pen, points);
  987. }
  988. }
  989. }
  990. /// <summary>
  991. /// 绘制叉号(按比例)
  992. /// </summary>
  993. /// <param name="g">绘图对象</param>
  994. /// <param name="rect">绘图区域</param>
  995. /// <param name="color">颜色</param>
  996. public static void DrawCross(Graphics g, Rectangle rect, Color color)
  997. {
  998. rect.Width--;
  999. rect.Height--;
  1000. int width = rect.Width;
  1001. int height = rect.Height;
  1002. int l = rect.X;
  1003. int t = rect.Y;
  1004. int r = rect.Right;
  1005. int b = rect.Bottom;
  1006. float offset = 0.2f;
  1007. PointF[] points = new PointF[2];
  1008. points[0] = new PointF(l + offset * width, t + offset * height);
  1009. points[1] = new PointF(r - offset * width, b - offset * height);
  1010. PointF[] points1 = new PointF[2];
  1011. points1[0] = new PointF(r - offset * width, t + offset * height);
  1012. points1[1] = new PointF(l + offset * width, b - offset * height);
  1013. using (Pen pen = new Pen(color, Math.Max(2f, Math.Min(rect.Width, rect.Height) / 6f)))
  1014. {
  1015. using (new SmoothingModeGraphics(g))
  1016. {
  1017. g.DrawLines(pen, points);
  1018. g.DrawLines(pen, points1);
  1019. }
  1020. }
  1021. }
  1022. /// <summary>
  1023. /// 绘制省略号(按比例)
  1024. /// </summary>
  1025. /// <param name="g">绘图对象</param>
  1026. /// <param name="rect">绘图区域</param>
  1027. /// <param name="color">颜色</param>
  1028. public static void DrawEllipsis(Graphics g, Rectangle rect, Color color)
  1029. {
  1030. rect.Width--;
  1031. rect.Height--;
  1032. float d = Math.Max(3f, rect.Width / 6f);
  1033. float t = rect.Y + (rect.Height - d) / 2f;
  1034. float leftl = rect.X + d;
  1035. float midl = rect.X + (rect.Width - d) / 2f;
  1036. float rightl = rect.Right - d - d;
  1037. using (Brush brush = new SolidBrush(color))
  1038. {
  1039. using (new SmoothingModeGraphics(g))
  1040. {
  1041. g.FillEllipse(brush, leftl, t, d, d);
  1042. g.FillEllipse(brush, midl, t, d, d);
  1043. g.FillEllipse(brush, rightl, t, d, d);
  1044. }
  1045. }
  1046. }
  1047. /// <summary>
  1048. /// 绘制箭头(按比例)
  1049. /// </summary>
  1050. /// <param name="g">绘图对象</param>
  1051. /// <param name="rect">绘图区域</param>
  1052. /// <param name="color">颜色</param>
  1053. /// <param name="direction">方向</param>
  1054. public static void DrawArrow(Graphics g, Rectangle rect, Color color, ArrowDirection direction)
  1055. {
  1056. rect.Width--;
  1057. rect.Height--;
  1058. int width = rect.Width;
  1059. int height = rect.Height;
  1060. int l = rect.X;
  1061. int t = rect.Y;
  1062. int r = rect.Right;
  1063. int b = rect.Bottom;
  1064. //以朝下的为准定义以下变量
  1065. float offsetL = 0.24f;
  1066. float offsetT = 0.33f;
  1067. float offsetB = 0.27f;
  1068. PointF[] points = new PointF[3]; ;
  1069. switch (direction)
  1070. {
  1071. case ArrowDirection.Left:
  1072. points[0] = new PointF(l + width * offsetB, t + height * 0.5f);
  1073. points[1] = new PointF(r - width * offsetT, t + height * offsetL);
  1074. points[2] = new PointF(r - width * offsetT, b - height * offsetL);
  1075. break;
  1076. case ArrowDirection.Up:
  1077. points[0] = new PointF(l + width * 0.5f, t + height * offsetB);
  1078. points[1] = new PointF(r - width * offsetL, b - height * offsetT);
  1079. points[2] = new PointF(l + width * offsetL, b - height * offsetT);
  1080. break;
  1081. case ArrowDirection.Right:
  1082. points[0] = new PointF(l + width * offsetT, t + height * offsetL);
  1083. points[1] = new PointF(r - width * offsetB, t + height * 0.5f);
  1084. points[2] = new PointF(l + width * offsetT, b - height * offsetL);
  1085. break;
  1086. default:
  1087. points[0] = new PointF(l + width * offsetL, t + height * offsetT);
  1088. points[1] = new PointF(r - width * offsetL, t + height * offsetT);
  1089. points[2] = new PointF(l + width * 0.5f, b - height * offsetB);
  1090. break;
  1091. }
  1092. using (Brush brush = new SolidBrush(color))
  1093. {
  1094. using (new SmoothingModeGraphics(g, SmoothingMode.AntiAlias))
  1095. {
  1096. using (new PixelOffsetModeGraphics(g, PixelOffsetMode.Default))
  1097. {
  1098. g.FillPolygon(brush, points);
  1099. }
  1100. }
  1101. }
  1102. }
  1103. /// <summary>
  1104. /// 绘制箭头(可选大小)
  1105. /// </summary>
  1106. /// <param name="g">绘图对象</param>
  1107. /// <param name="rect">区域</param>
  1108. /// <param name="color">颜色</param>
  1109. /// <param name="direction">箭头方向</param>
  1110. /// <param name="style">大小样式</param>
  1111. public static void DrawArrow(Graphics g, Rectangle rect, Color color, ArrowDirection direction, SizeStyle style)
  1112. {
  1113. Point point = new Point(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2));
  1114. Point[] points = null;
  1115. switch (style)
  1116. {
  1117. case SizeStyle.Tiny:
  1118. switch (direction)
  1119. {
  1120. case ArrowDirection.Left:
  1121. points = new Point[] { new Point(point.X + 1, point.Y - 2), new Point(point.X + 1, point.Y + 2), new Point(point.X - 1, point.Y) };
  1122. break;
  1123. case ArrowDirection.Up:
  1124. points = new Point[] { new Point(point.X - 2, point.Y + 1), new Point(point.X + 2, point.Y + 1), new Point(point.X, point.Y - 2) };
  1125. break;
  1126. case ArrowDirection.Right:
  1127. points = new Point[] { new Point(point.X - 1, point.Y - 2), new Point(point.X - 1, point.Y + 2), new Point(point.X + 1, point.Y) };
  1128. break;
  1129. default:
  1130. points = new Point[] { new Point(point.X - 1, point.Y - 1), new Point(point.X + 2, point.Y - 1), new Point(point.X, point.Y + 1) };
  1131. break;
  1132. }
  1133. break;
  1134. case SizeStyle.Small:
  1135. switch (direction)
  1136. {
  1137. case ArrowDirection.Left:
  1138. points = new Point[] { new Point(point.X + 2, point.Y - 3), new Point(point.X + 2, point.Y + 3), new Point(point.X - 1, point.Y) };
  1139. break;
  1140. case ArrowDirection.Up:
  1141. points = new Point[] { new Point(point.X - 3, point.Y + 2), new Point(point.X + 3, point.Y + 2), new Point(point.X, point.Y - 2) };
  1142. break;
  1143. case ArrowDirection.Right:
  1144. points = new Point[] { new Point(point.X - 1, point.Y - 3), new Point(point.X - 1, point.Y + 3), new Point(point.X + 2, point.Y) };
  1145. break;
  1146. default:
  1147. points = new Point[] { new Point(point.X - 2, point.Y - 1), new Point(point.X + 3, point.Y - 1), new Point(point.X, point.Y + 2) };
  1148. break;
  1149. }
  1150. break;
  1151. case SizeStyle.Normal:
  1152. switch (direction)
  1153. {
  1154. case ArrowDirection.Left:
  1155. points = new Point[] { new Point(point.X + 2, point.Y - 4), new Point(point.X + 2, point.Y + 4), new Point(point.X - 2, point.Y) };
  1156. break;
  1157. case ArrowDirection.Up:
  1158. points = new Point[] { new Point(point.X - 4, point.Y + 2), new Point(point.X + 5, point.Y + 2), new Point(point.X, point.Y - 3) };
  1159. break;
  1160. case ArrowDirection.Right:
  1161. points = new Point[] { new Point(point.X - 2, point.Y - 4), new Point(point.X - 2, point.Y + 4), new Point(point.X + 2, point.Y) };
  1162. break;
  1163. default:
  1164. points = new Point[] { new Point(point.X - 3, point.Y - 2), new Point(point.X + 4, point.Y - 2), new Point(point.X, point.Y + 2) };
  1165. break;
  1166. }
  1167. break;
  1168. case SizeStyle.Large:
  1169. switch (direction)
  1170. {
  1171. case ArrowDirection.Left:
  1172. points = new Point[] { new Point(point.X + 3, point.Y - 5), new Point(point.X + 3, point.Y + 5), new Point(point.X - 2, point.Y) };
  1173. break;
  1174. case ArrowDirection.Up:
  1175. points = new Point[] { new Point(point.X - 5, point.Y + 3), new Point(point.X + 6, point.Y + 3), new Point(point.X, point.Y - 3) };
  1176. break;
  1177. case ArrowDirection.Right:
  1178. points = new Point[] { new Point(point.X - 2, point.Y - 5), new Point(point.X - 2, point.Y + 5), new Point(point.X + 3, point.Y) };
  1179. break;
  1180. default:
  1181. points = new Point[] { new Point(point.X - 4, point.Y - 2), new Point(point.X + 5, point.Y - 2), new Point(point.X, point.Y + 3) };
  1182. break;
  1183. }
  1184. break;
  1185. case SizeStyle.Huge:
  1186. switch (direction)
  1187. {
  1188. case ArrowDirection.Left:
  1189. points = new Point[] { new Point(point.X + 3, point.Y - 6), new Point(point.X + 3, point.Y + 6), new Point(point.X - 3, point.Y) };
  1190. break;
  1191. case ArrowDirection.Up:
  1192. points = new Point[] { new Point(point.X - 6, point.Y + 3), new Point(point.X + 7, point.Y + 3), new Point(point.X, point.Y - 4) };
  1193. break;
  1194. case ArrowDirection.Right:
  1195. points = new Point[] { new Point(point.X - 3, point.Y - 6), new Point(point.X - 3, point.Y + 6), new Point(point.X + 3, point.Y) };
  1196. break;
  1197. default:
  1198. points = new Point[] { new Point(point.X - 5, point.Y - 3), new Point(point.X + 6, point.Y - 3), new Point(point.X, point.Y + 3) };
  1199. break;
  1200. }
  1201. break;
  1202. default:
  1203. break;
  1204. }
  1205. using (Brush brush = new SolidBrush(color))
  1206. {
  1207. using (new SmoothingModeGraphics(g, SmoothingMode.None))
  1208. {
  1209. using (new PixelOffsetModeGraphics(g, PixelOffsetMode.Default))
  1210. {
  1211. g.FillPolygon(brush, points);
  1212. }
  1213. }
  1214. }
  1215. }
  1216. }
  1217. }