mirror of
https://github.com/Ryujinx/GtkSharp.git
synced 2024-09-09 08:23:19 +02:00
![John Luke](/assets/img/avatar_default.png)
* samples/CairoSample.cs: * samples/GtkCairo.cs: * samples/Makefile.am: update the cairo sample, fixes bug #76324 svn path=/trunk/gtk-sharp/; revision=54558
156 lines
4.1 KiB
C#
156 lines
4.1 KiB
C#
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
|
|
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 ();
|
|
//cr2.Destroy ();
|
|
|
|
// 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
|
|
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
|
|
Context cr_tmp = new Context (punch);
|
|
Draw3Circles (cr_tmp, xc, yc, radius, 1.0);
|
|
//cr_tmp.Destroy ();
|
|
|
|
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.
|
|
Context cr_circles = new Context (circles);
|
|
cr_circles.Operator = Operator.Over;
|
|
Draw3Circles (cr_circles, xc, yc, radius, 0.5);
|
|
// cr_circles.Destroy ();
|
|
|
|
cr_overlay.Operator = Operator.Add;
|
|
cr_overlay.SetSourceSurface (circles, 0, 0);
|
|
cr_overlay.Paint ();
|
|
// cr_overlay.Destroy ();
|
|
|
|
cr.SetSourceSurface (overlay, 0, 0);
|
|
cr.Paint ();
|
|
|
|
overlay.Destroy ();
|
|
punch.Destroy ();
|
|
circles.Destroy ();
|
|
}
|
|
|
|
protected override bool OnExposeEvent (Gdk.EventExpose e)
|
|
{
|
|
#if GTK_SHARP_2_8
|
|
Context cr = Gdk.CairoHelper.Create (e.Window);
|
|
#else
|
|
Context cr = Gdk.Graphics.CreateDrawable (e.Window);
|
|
#endif
|
|
int w, h;
|
|
e.Window.GetSize (out w, out h);
|
|
Draw (cr, w, h);
|
|
return true;
|
|
}
|
|
|
|
void OnQuit (object sender, DeleteEventArgs e)
|
|
{
|
|
Application.Quit ();
|
|
}
|
|
}
|
|
|