PenInfo.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. using PaintDotNet.Measurement.Enum;
  2. using System;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Drawing.Drawing2D;
  6. using System.Runtime.Serialization;
  7. namespace PaintDotNet.Measurement.ObjInfo
  8. {
  9. /// <summary>
  10. /// Carries information about the subset of Pen configuration details that we support.
  11. /// Does not carry color information.
  12. /// </summary>
  13. [Serializable]
  14. public sealed class PenInfo
  15. : ICloneable,
  16. ISerializable
  17. {
  18. public const DashStyle DefaultDashStyle = DashStyle.Solid;
  19. public const LineCap2 DefaultLineCap = LineCap2.Flat;
  20. public const float DefaultCapScale = 1.0f;
  21. public const float MinCapScale = 1.0f;
  22. public const float MaxCapScale = 5.0f;
  23. private DashStyle dashStyle;
  24. public DashStyle DashStyle
  25. {
  26. get
  27. {
  28. return this.dashStyle;
  29. }
  30. set
  31. {
  32. this.dashStyle = value;
  33. }
  34. }
  35. private float width;
  36. public float Width
  37. {
  38. get
  39. {
  40. return this.width;
  41. }
  42. set
  43. {
  44. this.width = value;
  45. }
  46. }
  47. private LineCap2 startCap;
  48. public LineCap2 StartCap
  49. {
  50. get
  51. {
  52. return this.startCap;
  53. }
  54. set
  55. {
  56. this.startCap = value;
  57. }
  58. }
  59. private LineCap2 endCap;
  60. public LineCap2 EndCap
  61. {
  62. get
  63. {
  64. return this.endCap;
  65. }
  66. set
  67. {
  68. this.endCap = value;
  69. }
  70. }
  71. private float capScale;
  72. private float CapScale
  73. {
  74. get
  75. {
  76. return Utility.Clamp(this.capScale, MinCapScale, MaxCapScale);
  77. }
  78. set
  79. {
  80. this.capScale = value;
  81. }
  82. }
  83. public static bool operator ==(PenInfo lhs, PenInfo rhs)
  84. {
  85. return (
  86. lhs.dashStyle == rhs.dashStyle &&
  87. lhs.width == rhs.width &&
  88. lhs.startCap == rhs.startCap &&
  89. lhs.endCap == rhs.endCap &&
  90. lhs.capScale == rhs.capScale);
  91. }
  92. public static bool operator !=(PenInfo lhs, PenInfo rhs)
  93. {
  94. return !(lhs == rhs);
  95. }
  96. public override bool Equals(object obj)
  97. {
  98. PenInfo rhs = obj as PenInfo;
  99. if (rhs == null)
  100. {
  101. return false;
  102. }
  103. return this == rhs;
  104. }
  105. public override int GetHashCode()
  106. {
  107. return
  108. this.dashStyle.GetHashCode() ^
  109. this.width.GetHashCode() ^
  110. this.startCap.GetHashCode() ^
  111. this.endCap.GetHashCode() ^
  112. this.capScale.GetHashCode();
  113. }
  114. private void LineCapToLineCap2(LineCap2 cap2, out LineCap capResult, out CustomLineCap customCapResult)
  115. {
  116. switch (cap2)
  117. {
  118. case LineCap2.Flat:
  119. capResult = LineCap.Flat;
  120. customCapResult = null;
  121. break;
  122. case LineCap2.Arrow:
  123. capResult = LineCap.ArrowAnchor;
  124. customCapResult = new AdjustableArrowCap(5.0f * this.capScale, 5.0f * this.capScale, false);
  125. break;
  126. case LineCap2.ArrowFilled:
  127. capResult = LineCap.ArrowAnchor;
  128. customCapResult = new AdjustableArrowCap(5.0f * this.capScale, 5.0f * this.capScale, true);
  129. break;
  130. case LineCap2.Rounded:
  131. capResult = LineCap.Round;
  132. customCapResult = null;
  133. break;
  134. default:
  135. throw new InvalidEnumArgumentException();
  136. }
  137. }
  138. public Pen CreatePen(BrushInfo brushInfo, Color foreColor, Color backColor)
  139. {
  140. Pen pen;
  141. if (brushInfo.BrushType == BrushType.None)
  142. {
  143. pen = new Pen(foreColor, width);
  144. }
  145. else
  146. {
  147. pen = new Pen(brushInfo.CreateBrush(foreColor, backColor), width);
  148. }
  149. LineCap startLineCap;
  150. CustomLineCap startCustomLineCap;
  151. LineCapToLineCap2(this.startCap, out startLineCap, out startCustomLineCap);
  152. if (startCustomLineCap != null)
  153. {
  154. pen.CustomStartCap = startCustomLineCap;
  155. }
  156. else
  157. {
  158. pen.StartCap = startLineCap;
  159. }
  160. LineCap endLineCap;
  161. CustomLineCap endCustomLineCap;
  162. LineCapToLineCap2(this.endCap, out endLineCap, out endCustomLineCap);
  163. if (endCustomLineCap != null)
  164. {
  165. pen.CustomEndCap = endCustomLineCap;
  166. }
  167. else
  168. {
  169. pen.EndCap = endLineCap;
  170. }
  171. pen.DashStyle = this.dashStyle;
  172. return pen;
  173. }
  174. public PenInfo(DashStyle dashStyle, float width, LineCap2 startCap, LineCap2 endCap, float capScale)
  175. {
  176. this.dashStyle = dashStyle;
  177. this.width = width;
  178. this.capScale = capScale;
  179. this.startCap = startCap;
  180. this.endCap = endCap;
  181. }
  182. private PenInfo(SerializationInfo info, StreamingContext context)
  183. {
  184. this.dashStyle = (DashStyle)info.GetValue("dashStyle", typeof(DashStyle));
  185. this.width = info.GetSingle("width");
  186. // Save the caps as integers because we want to change the "LineCap2" name.
  187. // Just not feeling very creative right now I guess.
  188. try
  189. {
  190. this.startCap = (LineCap2)info.GetInt32("startCap");
  191. }
  192. catch (SerializationException)
  193. {
  194. this.startCap = DefaultLineCap;
  195. }
  196. try
  197. {
  198. this.endCap = (LineCap2)info.GetInt32("endCap");
  199. }
  200. catch (SerializationException)
  201. {
  202. this.endCap = DefaultLineCap;
  203. }
  204. try
  205. {
  206. float loadedCapScale = info.GetSingle("capScale");
  207. this.capScale = Utility.Clamp(loadedCapScale, MinCapScale, MaxCapScale);
  208. }
  209. catch (SerializationException)
  210. {
  211. this.capScale = DefaultCapScale;
  212. }
  213. }
  214. public PenInfo Clone()
  215. {
  216. return new PenInfo(this.dashStyle, this.width, this.startCap, this.endCap, this.capScale);
  217. }
  218. object ICloneable.Clone()
  219. {
  220. return Clone();
  221. }
  222. public void GetObjectData(SerializationInfo info, StreamingContext context)
  223. {
  224. info.AddValue("dashStyle", this.dashStyle);
  225. info.AddValue("width", this.width);
  226. info.AddValue("startCap", (int)this.startCap);
  227. info.AddValue("endCap", (int)this.endCap);
  228. info.AddValue("capScale", this.capScale);
  229. }
  230. }
  231. }