File: CairoSample.cs

package info (click to toggle)
gtk-sharp2 2.12.40-3.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 26,632 kB
  • sloc: xml: 351,292; cs: 26,444; sh: 4,228; ansic: 2,915; makefile: 1,288; perl: 1,179
file content (151 lines) | stat: -rw-r--r-- 4,074 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
using System;
using Gtk;
using Cairo;

class Knockout : DrawingArea
{
	static void Main ()
	{
		Application.Init ();
		new Knockout ();
		Application.Run ();
	}

	Knockout ()
	{
		Window win = new Window ("Cairo with Gtk#");
		win.SetDefaultSize (400, 400);
		win.DeleteEvent += new DeleteEventHandler (OnQuit);
		win.Add (this);
		win.ShowAll ();
	}

	void OvalPath (Context cr, double xc, double yc, double xr, double yr)
	{
		Matrix m = cr.Matrix;

		cr.Translate (xc, yc);
		cr.Scale (1.0, yr / xr);
		cr.MoveTo (xr, 0.0);
		cr.Arc (0, 0, xr, 0, 2 * Math.PI);
		cr.ClosePath ();

		cr.Matrix = m;
	}

	void FillChecks (Context cr, int x, int y, int width, int height)
	{
		int CHECK_SIZE = 32;
		
		cr.Save ();
		Surface check = cr.Target.CreateSimilar (Content.Color, 2 * CHECK_SIZE, 2 * CHECK_SIZE);
		
		// draw the check
		using (Context cr2 = new Context (check)) {
			cr2.Operator = Operator.Source;
			cr2.Color = new Color (0.4, 0.4, 0.4);
			cr2.Rectangle (0, 0, 2 * CHECK_SIZE, 2 * CHECK_SIZE);
			cr2.Fill ();

			cr2.Color = new Color (0.7, 0.7, 0.7);
			cr2.Rectangle (x, y, CHECK_SIZE, CHECK_SIZE);
			cr2.Fill ();

			cr2.Rectangle (x + CHECK_SIZE, y + CHECK_SIZE, CHECK_SIZE, CHECK_SIZE);
			cr2.Fill ();
		}

		// Fill the whole surface with the check
		SurfacePattern check_pattern = new SurfacePattern (check);
		check_pattern.Extend = Extend.Repeat;
		cr.Source = check_pattern;
		cr.Rectangle (0, 0, width, height);
		cr.Fill ();

		check_pattern.Destroy ();
		check.Destroy ();
		cr.Restore ();
	}

	void Draw3Circles (Context cr, int xc, int yc, double radius, double alpha)
	{
		double subradius = radius * (2 / 3.0 - 0.1);

		cr.Color = new Color (1.0, 0.0, 0.0, alpha);
		OvalPath (cr, xc + radius / 3.0 * Math.Cos (Math.PI * 0.5), yc - radius / 3.0 * Math.Sin (Math.PI * 0.5), subradius, subradius);
		cr.Fill ();

		cr.Color = new Color (0.0, 1.0, 0.0, alpha);
		OvalPath (cr, 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);
		cr.Fill ();

		cr.Color = new Color (0.0, 0.0, 1.0, alpha);
    	OvalPath (cr, 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);
		cr.Fill ();
	}

	void Draw (Context cr, int width, int height)
	{
		double radius = 0.5 * Math.Min (width, height) - 10;
		int xc = width / 2;
		int yc = height / 2;

		Surface overlay = cr.Target.CreateSimilar (Content.ColorAlpha, width, height);
		Surface punch   = cr.Target.CreateSimilar (Content.Alpha, width, height);
		Surface circles = cr.Target.CreateSimilar (Content.ColorAlpha, width, height);

		FillChecks (cr, 0, 0, width, height);
		cr.Save ();

		// Draw a black circle on the overlay
		using (Context cr_overlay = new Context (overlay)) {
			cr_overlay.Color = new Color (0.0, 0.0, 0.0);
			OvalPath (cr_overlay, xc, yc, radius, radius);
			cr_overlay.Fill ();

			// Draw 3 circles to the punch surface, then cut
			// that out of the main circle in the overlay
			using (Context cr_tmp = new Context (punch))
				Draw3Circles (cr_tmp, xc, yc, radius, 1.0);

			cr_overlay.Operator = Operator.DestOut;
			cr_overlay.SetSourceSurface (punch, 0, 0);
			cr_overlay.Paint ();

			// Now draw the 3 circles in a subgroup again
			// at half intensity, and use OperatorAdd to join up
			// without seams.
			using (Context cr_circles = new Context (circles)) {
				cr_circles.Operator = Operator.Over;
				Draw3Circles (cr_circles, xc, yc, radius, 0.5);
			}

			cr_overlay.Operator = Operator.Add;
			cr_overlay.SetSourceSurface (circles, 0, 0);
			cr_overlay.Paint ();
		}

		cr.SetSourceSurface (overlay, 0, 0);
		cr.Paint ();

		overlay.Destroy ();
		punch.Destroy ();
		circles.Destroy ();
	}

	protected override bool OnExposeEvent (Gdk.EventExpose e)
	{
		using (Context cr = Gdk.CairoHelper.Create (e.Window)) {
			int w, h;
			e.Window.GetSize (out w, out h);
			Draw (cr, w, h);
		}
		return true;
	}

	void OnQuit (object sender, DeleteEventArgs e)
	{
		Application.Quit ();
	}
}