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 license-pdn.txt for full licensing and attribution details.             //
6 //                                                                             //
7 // Ported to Pinta by: Krzysztof Marecki <marecki.krzysztof@gmail.com>         //
8 /////////////////////////////////////////////////////////////////////////////////
9 
10 using System;
11 using Cairo;
12 
13 using Pinta.Gui.Widgets;
14 using Pinta.Core;
15 using Mono.Unix;
16 
17 namespace Pinta.Effects
18 {
19 	public class EdgeDetectEffect : ColorDifferenceEffect
20 	{
21 		private double[][] weights;
22 
23 		public override string Icon {
24 			get { return "Menu.Effects.Stylize.EdgeDetect.png"; }
25 		}
26 
27 		public override string Name {
28 			get { return Catalog.GetString ("Edge Detect"); }
29 		}
30 
31 		public override bool IsConfigurable {
32 			get { return true; }
33 		}
34 
35 		public override string EffectMenuCategory {
36 			get { return Catalog.GetString ("Stylize"); }
37 		}
38 
39 		public EdgeDetectData Data { get { return EffectData as EdgeDetectData; } }
40 
EdgeDetectEffect()41 		public EdgeDetectEffect ()
42 		{
43 			EffectData = new EdgeDetectData ();
44 		}
45 
LaunchConfiguration()46 		public override bool LaunchConfiguration ()
47 		{
48 			return EffectHelper.LaunchSimpleEffectDialog (this);
49 		}
50 
Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois)51 		public unsafe override void Render (ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois)
52 		{
53 			SetWeights ();
54 			base.RenderColorDifferenceEffect (weights, src, dest, rois);
55 		}
56 
SetWeights()57 		private void SetWeights ()
58 		{
59 			weights = new double[3][];
60             for (int i = 0; i < this.weights.Length; ++i) {
61                 this.weights[i] = new double[3];
62             }
63 
64             // adjust and convert angle to radians
65             double r = (double)Data.Angle * 2.0 * Math.PI / 360.0;
66 
67             // angle delta for each weight
68             double dr = Math.PI / 4.0;
69 
70             // for r = 0 this builds an edge detect filter pointing straight left
71 
72             this.weights[0][0] = Math.Cos(r + dr);
73             this.weights[0][1] = Math.Cos(r + 2.0 * dr);
74             this.weights[0][2] = Math.Cos(r + 3.0 * dr);
75 
76             this.weights[1][0] = Math.Cos(r);
77             this.weights[1][1] = 0;
78             this.weights[1][2] = Math.Cos(r + 4.0 * dr);
79 
80             this.weights[2][0] = Math.Cos(r - dr);
81             this.weights[2][1] = Math.Cos(r - 2.0 * dr);
82             this.weights[2][2] = Math.Cos(r - 3.0 * dr);
83 		}
84 	}
85 
86 	public class EdgeDetectData : EffectData
87 	{
88 		[Caption ("Angle")]
89 		public double Angle = 45;
90 	}
91 }
92