FastGraphicsPath.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. namespace FastReport.Fonts
  5. {
  6. #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
  7. public class FastGraphicsPath
  8. {
  9. public enum PointType : byte
  10. {
  11. /// <summary>
  12. /// Indicates that the point is the start of a figure.
  13. /// </summary>
  14. Start = 0x00,
  15. /// <summary>
  16. /// Indicates that the point is one of the two endpoints of a line.
  17. /// </summary>
  18. Connect = 0x01,
  19. /// <summary>
  20. /// Indicates that the point is an endpoint or control point of a cubic Bézier spline.
  21. /// </summary>
  22. Bezier = 0x03,
  23. /// <summary>
  24. /// Masks all bits except for the three low-order bits, which indicate the point type.
  25. /// </summary>
  26. All = 0x07,
  27. /// <summary>
  28. /// Specifies that the point is a marker.
  29. /// </summary>
  30. Marker = 0x20,
  31. /// <summary>
  32. /// Specifies that the point is the last point in a closed subpath (figure).
  33. /// </summary>
  34. Last = 0x80,
  35. }
  36. private List<PointF> points = new List<PointF>();
  37. private List<PointType> pointTypes = new List<PointType>();
  38. private bool startNewFigure = false;
  39. public byte[] PathTypes
  40. {
  41. get
  42. {
  43. byte[] result = new byte[pointTypes.Count];
  44. int i = 0;
  45. foreach (PointType type in pointTypes)
  46. {
  47. result[i] = (byte)type;
  48. i++;
  49. }
  50. return result;
  51. }
  52. }
  53. public PointF[] PathPoints
  54. {
  55. get
  56. {
  57. return points.ToArray();
  58. }
  59. }
  60. private FastFillMode fillMode;
  61. public FastFillMode FillMode
  62. {
  63. get
  64. {
  65. return fillMode;
  66. }
  67. set
  68. {
  69. fillMode = value;
  70. }
  71. }
  72. public int PointCount { get { return points.Count; } }
  73. public FastGraphicsPath(FastFillMode fastFillMode /*= FastFillMode.Alternate*/)
  74. {
  75. FillMode = fastFillMode;
  76. }
  77. public void AddPath(FastGraphicsPath fastGraphicsPath, bool connect)
  78. {
  79. if (points.Count == 0)
  80. {
  81. points.AddRange(fastGraphicsPath.points);
  82. pointTypes.AddRange(fastGraphicsPath.pointTypes);
  83. }
  84. else
  85. {
  86. int i = -1;
  87. foreach (PointF point in fastGraphicsPath.points)
  88. {
  89. i++;
  90. if (connect)
  91. {
  92. if (points[points.Count - 1] == point)
  93. {
  94. connect = false;
  95. continue;
  96. }
  97. else
  98. {
  99. points.Add(point);
  100. pointTypes.Add(PointType.Connect);
  101. }
  102. connect = false;
  103. }
  104. else
  105. {
  106. points.Add(point);
  107. pointTypes.Add(fastGraphicsPath.pointTypes[i]);
  108. }
  109. }
  110. }
  111. }
  112. public void Transform(float m00, float m01, float m10, float m11, float v1, float v2)
  113. {
  114. List<PointF> points2 = new List<PointF>(points.Capacity);
  115. foreach (PointF point in points)
  116. {
  117. points2.Add(Transform(point, m00, m01, m10, m11, v1, v2));
  118. }
  119. points = points2;
  120. }
  121. private PointF Transform(PointF point, float m00, float m01, float m10, float m11, float v1, float v2)
  122. {
  123. return new PointF(point.X * m00 + v1 + point.Y * m10, point.Y * m11 + v2 + point.X * m01);
  124. }
  125. public void StartFigure()
  126. {
  127. startNewFigure = true;
  128. }
  129. public void AddLine(PointF pntStart, PointF pntEnd)
  130. {
  131. if (startNewFigure || points.Count == 0)
  132. {
  133. points.Add(pntStart);
  134. pointTypes.Add(PointType.Start);
  135. }
  136. else if (points[points.Count - 1] != pntStart)
  137. {
  138. points.Add(pntStart);
  139. pointTypes.Add(PointType.Connect);
  140. }
  141. points.Add(pntEnd);
  142. pointTypes.Add(PointType.Connect);
  143. startNewFigure = false;
  144. }
  145. public void AddBezier(PointF pntStart, PointF pnt1, PointF pnt2, PointF pntEnd)
  146. {
  147. if (startNewFigure || points.Count == 0)
  148. {
  149. points.Add(pntStart);
  150. pointTypes.Add(PointType.Start);
  151. }
  152. else if (points[points.Count - 1] != pntStart)
  153. {
  154. points.Add(pntStart);
  155. pointTypes.Add(PointType.Connect);
  156. }
  157. points.Add(pnt1);
  158. pointTypes.Add(PointType.Bezier);
  159. points.Add(pnt2);
  160. pointTypes.Add(PointType.Bezier);
  161. points.Add(pntEnd);
  162. pointTypes.Add(PointType.Bezier);
  163. startNewFigure = false;
  164. }
  165. }
  166. }