use MOONLIGHT symbol
[mono.git] / mcs / class / Mono.Cairo / Samples / png / knockout.cs
1 using System;
2 using Cairo;
3
4 class Knockout
5 {
6         void OvalPath (Context ctx, double xc, double yc, double xr, double yr)
7         {
8                 Matrix m = ctx.Matrix;
9
10                 ctx.Translate (xc, yc);
11                 ctx.Scale (1.0, yr / xr);
12                 ctx.MoveTo (xr, 0.0);
13                 ctx.Arc (0, 0, xr, 0, 2 * Math.PI);
14                 ctx.ClosePath ();
15
16                 ctx.Matrix = m;
17         }
18
19         void FillChecks (Context ctx, int x, int y, int width, int height)
20         {
21                 int CHECK_SIZE = 32;
22                 
23                 ctx.Save ();
24                 Surface check = ctx.Target.CreateSimilar (Content.Color, 2 * CHECK_SIZE, 2 * CHECK_SIZE);
25                 
26                 // draw the check
27                 Context cr2 = new Context (check);
28                 cr2.Operator = Operator.Source;
29                 cr2.Color = new Color (0.4, 0.4, 0.4);
30                 cr2.Rectangle (0, 0, 2 * CHECK_SIZE, 2 * CHECK_SIZE);
31                 cr2.Fill ();
32
33                 cr2.Color = new Color (0.7, 0.7, 0.7);
34                 cr2.Rectangle (x, y, CHECK_SIZE, CHECK_SIZE);
35                 cr2.Fill ();
36
37                 cr2.Rectangle (x + CHECK_SIZE, y + CHECK_SIZE, CHECK_SIZE, CHECK_SIZE);
38                 cr2.Fill ();
39                 //cr2.Destroy ();
40
41                 // Fill the whole surface with the check
42                 SurfacePattern check_pattern = new SurfacePattern (check);
43                 check_pattern.Extend = Extend.Repeat;
44                 ctx.Source = check_pattern;
45                 ctx.Rectangle (0, 0, width, height);
46                 ctx.Fill ();
47
48                 check_pattern.Destroy ();
49                 check.Destroy ();
50                 ctx.Restore ();
51         }
52
53         void Draw3Circles (Context ctx, int xc, int yc, double radius, double alpha)
54         {
55                 double subradius = radius * (2 / 3.0 - 0.1);
56
57                 ctx.Color = new Color (1.0, 0.0, 0.0, alpha);
58                 OvalPath (ctx, xc + radius / 3.0 * Math.Cos (Math.PI * 0.5), yc - radius / 3.0 * Math.Sin (Math.PI * 0.5), subradius, subradius);
59                 ctx.Fill ();
60
61                 ctx.Color = new Color (0.0, 1.0, 0.0, alpha);
62                 OvalPath (ctx, xc + radius / 3.0 * Math.Cos (Math.PI * (0.5 + 2 / 0.3)), yc - radius / 3.0 * Math.Sin (Math.PI * (0.5 + 2 / 0.3)), subradius, subradius);
63                 ctx.Fill ();
64
65                 ctx.Color = new Color (0.0, 0.0, 1.0, alpha);
66         OvalPath (ctx, xc + radius / 3.0 * Math.Cos (Math.PI * (0.5 + 4 / 0.3)), yc - radius / 3.0 * Math.Sin (Math.PI * (0.5 + 4 / 0.3)), subradius, subradius);
67                 ctx.Fill ();
68         }
69
70         void Draw (Context ctx, int width, int height)
71         {
72                 double radius = 0.5 * Math.Min (width, height) - 10;
73                 int xc = width / 2;
74                 int yc = height / 2;
75
76                 Surface overlay = ctx.Target.CreateSimilar (Content.ColorAlpha, width, height);
77                 Surface punch   = ctx.Target.CreateSimilar (Content.Alpha, width, height);
78                 Surface circles = ctx.Target.CreateSimilar (Content.ColorAlpha, width, height);
79
80                 FillChecks (ctx, 0, 0, width, height);
81                 ctx.Save ();
82
83                 // Draw a black circle on the overlay
84                 Context cr_overlay = new Context (overlay);
85                 cr_overlay.Color = new Color (0.0, 0.0, 0.0);
86                 OvalPath (cr_overlay, xc, yc, radius, radius);
87                 cr_overlay.Fill ();
88
89                 // Draw 3 circles to the punch surface, then cut
90                 // that out of the main circle in the overlay
91                 Context cr_tmp = new Context (punch);
92                 Draw3Circles (cr_tmp, xc, yc, radius, 1.0);
93                 //cr_tmp.Destroy ();
94
95                 cr_overlay.Operator = Operator.DestOut;
96                 cr_overlay.SetSourceSurface (punch, 0, 0);
97                 cr_overlay.Paint ();
98
99                 // Now draw the 3 circles in a subgroup again
100                 // at half intensity, and use OperatorAdd to join up
101                 // without seams.
102                 Context cr_circles = new Context (circles);
103                 cr_circles.Operator = Operator.Over;
104                 Draw3Circles (cr_circles, xc, yc, radius, 0.5);
105                 // cr_circles.Destroy ();
106
107                 cr_overlay.Operator = Operator.Add;
108                 cr_overlay.SetSourceSurface (circles, 0, 0);
109                 cr_overlay.Paint ();
110                 // cr_overlay.Destroy ();
111
112                 ctx.SetSourceSurface (overlay, 0, 0);
113                 ctx.Paint ();
114
115                 overlay.Destroy ();
116                 punch.Destroy ();
117                 circles.Destroy ();
118         }
119
120         static void Main ()
121         {
122                 new Knockout ();
123         }
124
125         Knockout ()
126         {
127                 Surface s = new ImageSurface (Format.ARGB32, 400, 400);
128                 Context ctx = new Context (s);
129                 Draw (ctx, 400, 400);
130                 s.WriteToPng ("knockout.png");
131         }
132 }
133