PageRenderTime 101ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Effects/Effect.cs

https://bitbucket.org/tuldok89/openpdn
C# | 281 lines | 199 code | 37 blank | 45 comment | 6 complexity | 2d661ad66af9c2a0f88abce4b372d820 MD5 | raw file
  1. /////////////////////////////////////////////////////////////////////////////////
  2. // Paint.NET //
  3. // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
  4. // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
  5. // See src/Resources/Files/License.txt for full licensing and attribution //
  6. // details. //
  7. // . //
  8. /////////////////////////////////////////////////////////////////////////////////
  9. using System;
  10. using System.Drawing;
  11. using System.Linq;
  12. using System.Windows.Forms;
  13. namespace PaintDotNet.Effects
  14. {
  15. public abstract class Effect
  16. {
  17. private const string ShortcutKeysObsoleteString =
  18. "Effects may not specify their own ShortcutKeys. Use one of the constructor overloads that does not take a ShortcutKeys parameter.";
  19. private readonly string _name;
  20. private readonly Image _image;
  21. private readonly string _subMenuName;
  22. private readonly EffectFlags _effectFlags;
  23. protected internal bool SetRenderInfoCalled { get; private set; }
  24. /// <summary>
  25. /// Returns the category of the effect. If there is no EffectCategoryAttribute
  26. /// applied to the runtime type, then the default category, EffectCategory.Effect,
  27. /// will be returned.
  28. /// </summary>
  29. /// <remarks>
  30. /// This controls which menu in the user interface the effect is placed in to.
  31. /// </remarks>
  32. public EffectCategory Category
  33. {
  34. get
  35. {
  36. object[] attributes = GetType().GetCustomAttributes(true);
  37. return attributes.OfType<EffectCategoryAttribute>().Select(attribute => (attribute).Category).FirstOrDefault();
  38. }
  39. }
  40. public EffectEnvironmentParameters EnvironmentParameters { get; set; }
  41. [Obsolete]
  42. public EffectDirectives EffectDirectives
  43. {
  44. get {
  45. return (_effectFlags & EffectFlags.SingleThreaded) == EffectFlags.SingleThreaded ? EffectDirectives.SingleThreaded : EffectDirectives.None;
  46. }
  47. }
  48. public EffectFlags EffectFlags
  49. {
  50. get
  51. {
  52. return _effectFlags;
  53. }
  54. }
  55. public bool CheckForEffectFlags(EffectFlags flags)
  56. {
  57. return (EffectFlags & flags) == flags;
  58. }
  59. public string SubMenuName
  60. {
  61. get
  62. {
  63. return _subMenuName;
  64. }
  65. }
  66. public string Name
  67. {
  68. get
  69. {
  70. return _name;
  71. }
  72. }
  73. public Image Image
  74. {
  75. get
  76. {
  77. return _image;
  78. }
  79. }
  80. [Obsolete("This property is obsolete. There is no replacement.")]
  81. public Keys ShortcutKeys
  82. {
  83. get
  84. {
  85. return Keys.None;
  86. }
  87. }
  88. [Obsolete("Use CheckForEffectFlags() instead")]
  89. public bool IsConfigurable
  90. {
  91. get
  92. {
  93. return (EffectFlags & EffectFlags.Configurable) == EffectFlags.Configurable;
  94. }
  95. }
  96. public void SetRenderInfo(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs)
  97. {
  98. SetRenderInfoCalled = true;
  99. OnSetRenderInfo(parameters, dstArgs, srcArgs);
  100. }
  101. protected virtual void OnSetRenderInfo(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs)
  102. {
  103. }
  104. /// <summary>
  105. /// Performs the effect's rendering. The source is to be treated as read-only,
  106. /// and only the destination pixels within the given rectangle-of-interest are
  107. /// to be written to. However, in order to compute the destination pixels,
  108. /// any pixels from the source may be utilized.
  109. /// </summary>
  110. /// <param name="parameters">The parameters to the effect. If IsConfigurable is true, then this must not be null.</param>
  111. /// <param name="dstArgs">Describes the destination surface.</param>
  112. /// <param name="srcArgs">Describes the source surface.</param>
  113. /// <param name="rois">The list of rectangles that describes the region of interest.</param>
  114. /// <param name="startIndex">The index within roi to start enumerating from.</param>
  115. /// <param name="length">The number of rectangles to enumerate from roi.</param>
  116. public abstract void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length);
  117. public void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois)
  118. {
  119. Render(parameters, dstArgs, srcArgs, rois, 0, rois.Length);
  120. }
  121. public void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, PdnRegion roi)
  122. {
  123. Rectangle[] scans = roi.GetRegionScansReadOnlyInt();
  124. Render(parameters, dstArgs, srcArgs, scans, 0, scans.Length);
  125. }
  126. public virtual EffectConfigDialog CreateConfigDialog()
  127. {
  128. if (CheckForEffectFlags(EffectFlags.Configurable))
  129. {
  130. throw new NotImplementedException("If IsConfigurable is true, then CreateConfigDialog() must be implemented");
  131. }
  132. return null;
  133. }
  134. /// <summary>
  135. /// This is a helper function. It allows you to render an effect "in place."
  136. /// That is, you don't need both a destination and a source Surface.
  137. /// </summary>
  138. public void RenderInPlace(RenderArgs srcAndDstArgs, PdnRegion roi)
  139. {
  140. using (var renderSurface = new Surface(srcAndDstArgs.Surface.Size))
  141. {
  142. using (var renderArgs = new RenderArgs(renderSurface))
  143. {
  144. Rectangle[] scans = roi.GetRegionScansReadOnlyInt();
  145. Render(null, renderArgs, srcAndDstArgs, scans);
  146. srcAndDstArgs.Surface.CopySurface(renderSurface, roi);
  147. }
  148. }
  149. }
  150. public void RenderInPlace(RenderArgs srcAndDstArgs, Rectangle roi)
  151. {
  152. using (var region = new PdnRegion(roi))
  153. {
  154. RenderInPlace(srcAndDstArgs, region);
  155. }
  156. }
  157. protected Effect(string name, Image image)
  158. : this(name, image, EffectFlags.None)
  159. {
  160. }
  161. protected Effect(string name, Image image, EffectFlags flags)
  162. : this(name, image, null, flags)
  163. {
  164. }
  165. [Obsolete]
  166. protected Effect(string name, Image image, bool isConfigurable)
  167. : this(name, image, null, isConfigurable ? EffectFlags.Configurable : EffectFlags.None)
  168. {
  169. }
  170. [Obsolete(ShortcutKeysObsoleteString, true)]
  171. protected Effect(string name, Image image, Keys shortcutKeys)
  172. : this(name, image, null)
  173. {
  174. }
  175. [Obsolete(ShortcutKeysObsoleteString, true)]
  176. protected Effect(string name, Image image, Keys shortcutKeys, bool isConfigurable)
  177. : this(name, image, null, isConfigurable)
  178. {
  179. }
  180. [Obsolete(ShortcutKeysObsoleteString, true)]
  181. protected Effect(string name, Image image, Keys shortcutKeys, string subMenuName)
  182. : this(name, image, subMenuName, EffectDirectives.None)
  183. {
  184. }
  185. protected Effect(string name, Image image, string subMenuName)
  186. : this(name, image, subMenuName, EffectFlags.None)
  187. {
  188. }
  189. [Obsolete(ShortcutKeysObsoleteString, true)]
  190. protected Effect(string name, Image image, Keys shortcutKeys, string subMenuName, bool isConfigurable)
  191. : this(name, image, subMenuName, EffectDirectives.None, isConfigurable)
  192. {
  193. }
  194. [Obsolete]
  195. protected Effect(string name, Image image, string subMenuName, EffectDirectives effectDirectives)
  196. : this(name, image, subMenuName, effectDirectives == EffectDirectives.SingleThreaded ? EffectFlags.SingleThreaded : EffectFlags.None)
  197. {
  198. }
  199. [Obsolete]
  200. protected Effect(string name, Image image, string subMenuName, bool isConfigurable)
  201. : this(name, image, subMenuName, isConfigurable ? EffectFlags.Configurable : EffectFlags.None)
  202. {
  203. }
  204. [Obsolete(ShortcutKeysObsoleteString, true)]
  205. protected Effect(string name, Image image, Keys shortcutKeys, string subMenuName, EffectDirectives effectDirectives)
  206. : this(name, image, subMenuName, effectDirectives, false)
  207. {
  208. }
  209. [Obsolete(ShortcutKeysObsoleteString, true)]
  210. protected Effect(string name, Image image, Keys shortcutKeys, string subMenuName, EffectDirectives effectDirectives, bool isConfigurable)
  211. : this(name, image, subMenuName, effectDirectives, isConfigurable)
  212. {
  213. }
  214. /// <summary>
  215. /// Base constructor for the Effect class.
  216. /// </summary>
  217. /// <param name="name">A unique name for the effect.</param>
  218. /// <param name="image">A 16x16 icon for the effect that will show up in the menu.</param>
  219. /// <param name="subMenuName">The name of a sub-menu to place the effect into. Pass null for no sub-menu.</param>
  220. /// <param name="effectDirectives">A set of flags indicating important information about the effect.</param>
  221. /// <param name="isConfigurable">A flag indicating whether the effect is configurable. If this is true, then CreateConfigDialog must be implemented.</param>
  222. /// <remarks>
  223. /// Do not include the word 'effect' in the name parameter.
  224. /// The shortcut key is only honored for effects with the [EffectCategory(EffectCategory.Adjustment)] attribute.
  225. /// The sub-menu parameter can be used to group effects. The name parameter must still be unique.
  226. /// </remarks>
  227. [Obsolete]
  228. protected Effect(string name, Image image, string subMenuName, EffectDirectives effectDirectives, bool isConfigurable)
  229. : this(name, image, subMenuName,
  230. (effectDirectives == EffectDirectives.SingleThreaded ? EffectFlags.SingleThreaded : EffectFlags.None) |
  231. (isConfigurable ? EffectFlags.Configurable : EffectFlags.None))
  232. {
  233. }
  234. protected Effect(string name, Image image, string subMenuName, EffectFlags effectFlags)
  235. {
  236. SetRenderInfoCalled = false;
  237. _name = name;
  238. _image = image;
  239. _subMenuName = subMenuName;
  240. _effectFlags = effectFlags;
  241. EnvironmentParameters = EffectEnvironmentParameters.DefaultParameters;
  242. }
  243. }
  244. }