diff --git a/ChangeLog b/ChangeLog index f4fa8402b..abebd5723 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-12-16 John Luke + + * samples/CairoSample.cs: + * samples/GtkCairo.cs: + * samples/Makefile.am: update the cairo sample, fixes bug #76324 + 2005-12-16 Mike Kestner * gdk/PixbufLoader.custom (InitFromAssemblyResource): move stream diff --git a/sample/CairoSample.cs b/sample/CairoSample.cs index fa7ff50dd..78c037ddc 100644 --- a/sample/CairoSample.cs +++ b/sample/CairoSample.cs @@ -1,117 +1,155 @@ -// -// Sample program demostrating using Cairo with Gtk# -// -using Gtk; -using Gdk; using System; +using Gtk; using Cairo; -class X { - static DrawingArea a, b; - +class Knockout : DrawingArea +{ static void Main () { Application.Init (); - Gtk.Window w = new Gtk.Window ("Hello"); - - a = new DrawingArea (); - a.ExposeEvent += new ExposeEventHandler (LineExposeHandler); - - b = new DrawingArea (); - b.ExposeEvent += new ExposeEventHandler (CirclesExposeHandler); - b.SizeAllocated += new SizeAllocatedHandler (SizeAllocatedHandler); - - Box box = new HBox (true, 0); - //box.Add (a); - box.Add (b); - w.Add (box); - - w.ShowAll (); + new Knockout (); Application.Run (); } - static void LineExposeHandler (object obj, ExposeEventArgs args) + Knockout () { - int offx, offy; - - using (Cairo.Graphics o = GtkCairo.GraphicsFromWindow (args.Event.Window, out offx, out offy)){ - o.SetRGBColor (1, 0, 0); - o.Translate (-offx, -offy); - o.MoveTo (0, 0); - o.LineTo (100, 100); - o.Stroke (); - } + Window win = new Window ("Cairo with Gtk#"); + win.SetDefaultSize (400, 400); + win.DeleteEvent += new DeleteEventHandler (OnQuit); + win.Add (this); + win.ShowAll (); } - static Rectangle rect; + 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; - static void SizeAllocatedHandler (object obj, SizeAllocatedArgs args) - { - rect = args.Allocation; + 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 (); } - static void CirclesExposeHandler (object obj, ExposeEventArgs args) + void Draw3Circles (Context cr, int xc, int yc, double radius, double alpha) { - Rectangle area = args.Event.Area; - Gdk.Window window = args.Event.Window; - Pixmap p = new Pixmap (window, area.Width, area.Height, -1); + double subradius = radius * (2 / 3.0 - 0.1); - int x, y; - //Cairo.Object o = p.CairoGraphics (); - using (Cairo.Graphics o = GtkCairo.GraphicsFromWindow (window, out x, out y)) - { - o.Translate (-area.X, -area.Y); - DrawCircles (o, rect); - - //using (Gdk.GC gc = new Gdk.GC (window)){ - //window.DrawDrawable (gc, p, 0, 0, area.x, area.y, area.height, area.width); - //} - } - } - - static void DrawCircles (Cairo.Graphics o, Gdk.Rectangle rect) - { - FillChecks (o, rect); + 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 (); } - const int CS = 32; - - static void FillChecks (Cairo.Graphics o, Gdk.Rectangle rect) + void Draw (Context cr, int width, int height) { - Surface check; - // Draw the check - o.Save (); - using (check = Surface.CreateSimilar (o.TargetSurface, Format.RGB24, 2 * CS, 2 * CS)){ -#if true - o.Save (); - check.Repeat = 1; - - o.TargetSurface = check; - o.Operator = Operator.Src; - o.SetRGBColor (0.4, 0.4, 0.4); - - // Clear the background - o.Rectangle (0, 0, 2*CS, 2*CS); - o.Fill (); - o.SetRGBColor (0.7, 0.7, 0.7); - o.Rectangle (0, CS, CS, CS *2); - o.Fill (); - o.Rectangle (CS, 0, CS*2, CS); - o.Fill (); - o.Restore (); + double radius = 0.5 * Math.Min (width, height) - 10; + int xc = width / 2; + int yc = height / 2; - // Fill the surface with the check - //o.SetPattern (check); - o.Rectangle (0, 0, rect.Width, rect.Height); - o.Fill (); -#endif - } - o.Restore (); - o.SetRGBColor (1, 0, 0); - o.Alpha = 0.5; - Console.WriteLine (rect); - o.MoveTo (0, 0); - o.LineTo (rect.Width, rect.Height); - o.Stroke (); + 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 (); } } + diff --git a/sample/GtkCairo.cs b/sample/GtkCairo.cs index 19cd92afa..14902fbde 100644 --- a/sample/GtkCairo.cs +++ b/sample/GtkCairo.cs @@ -1,46 +1,91 @@ +// +// +// GDK-X11 interface +// + +// +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + using System; -using Cairo; +using System.Reflection; using System.Runtime.InteropServices; +using Gtk; +using Cairo; -public class GtkCairo { - -#region You can cut and paste this into your application - [DllImport("libgdk-win32-2.0-0.dll")] - static extern IntPtr gdk_x11_drawable_get_xdisplay (IntPtr raw); - - [DllImport("libgdk-win32-2.0-0.dll")] - static extern IntPtr gdk_x11_drawable_get_xid (IntPtr raw); - - [DllImport("libgdk-win32-2.0-0.dll")] - static extern void gdk_window_get_internal_paint_info(IntPtr raw, out IntPtr real_drawable, out int x_offset, out int y_offset); - - static public Cairo.Graphics GraphicsFromWindow (Gdk.Window window, out int offset_x, out int offset_y) - { - IntPtr real_drawable; - Cairo.Graphics o = new Cairo.Graphics (); - - gdk_window_get_internal_paint_info (window.Handle, out real_drawable, out offset_x, out offset_y); - IntPtr x11 = gdk_x11_drawable_get_xid (real_drawable); - IntPtr display = gdk_x11_drawable_get_xdisplay (real_drawable); - o.SetTargetDrawable (display, x11); - - return o; - } - - static public Cairo.Graphics GraphicsFromDrawable (Gdk.Drawable drawable) - { - Cairo.Graphics o = new Cairo.Graphics (); - - IntPtr display = gdk_x11_drawable_get_xdisplay (drawable.Handle); - o.SetTargetDrawable (display, gdk_x11_drawable_get_xid (drawable.Handle)); - - return o; - } - - static GtkCairo () - { +namespace Gdk +{ + public class Graphics + { + //Use [DllImport("libgdk-win32-2.0-0.dll")] for Win32 + [DllImport("libgdk-x11-2.0.so")] + internal static extern IntPtr gdk_x11_drawable_get_xdisplay (IntPtr raw); + [DllImport("libgdk-x11-2.0.so")] + internal static extern IntPtr gdk_x11_drawable_get_xid (IntPtr raw); + + [DllImport("libgdk-x11-2.0.so")] + internal static extern IntPtr gdk_drawable_get_visual (IntPtr raw); + + [DllImport("libgdk-x11-2.0.so")] + internal static extern IntPtr gdk_x11_visual_get_xvisual (IntPtr raw); + + [DllImport("libgdk-x11-2.0.so")] + internal static extern IntPtr gdk_cairo_create (IntPtr raw); + + public static Cairo.Context CreateDrawable (Gdk.Drawable drawable) + { + IntPtr x_drawable = IntPtr.Zero; + int x_off = 0, y_off = 0; + + int x, y, w, h, d; + ((Gdk.Window)drawable).GetGeometry(out x, out y, out w, out h, out d); + + bool is_gdk_window = drawable is Gdk.Window; + if (is_gdk_window) + ((Gdk.Window) drawable).GetInternalPaintInfo(out drawable, + out x_off, out y_off); + + x_drawable = drawable.Handle; + IntPtr visual = gdk_drawable_get_visual(x_drawable); + + IntPtr Xdisplay = gdk_x11_drawable_get_xdisplay(x_drawable); + IntPtr Xvisual = gdk_x11_visual_get_xvisual(visual); + IntPtr Xdrawable = gdk_x11_drawable_get_xid (x_drawable); + + Cairo.XlibSurface s = new Cairo.XlibSurface (Xdisplay, + Xdrawable, + Xvisual, + w, h); + + Cairo.Context g = new Cairo.Context (s); + + // this can be safely removed now, just keep it for a bit more + //Cairo.Context g = new Cairo.Context ( + // gdk_cairo_create (x_drawable )); + + if (is_gdk_window) + g.Translate (-(double)x_off,-(double)y_off); + return g; + } } - -#endregion } diff --git a/sample/Makefile.am b/sample/Makefile.am index 63facd88c..f5ba8421b 100755 --- a/sample/Makefile.am +++ b/sample/Makefile.am @@ -40,7 +40,7 @@ DOTNET_TARGETS= DOTNET_ASSEMBLY= endif -TARGETS = polarfixed.exe custom-widget.exe custom-cellrenderer.exe gtk-hello-world.exe button.exe calendar.exe subclass.exe menu.exe size.exe scribble.exe scribble-xinput.exe treeviewdemo.exe managedtreeviewdemo.exe nodeviewdemo.exe testdnd.exe actions.exe $(GNOMEVFS_TARGETS) $(GNOME_TARGETS) $(GLADE_TARGETS) $(VTE_TARGETS) $(DOTNET_TARGETS) +TARGETS = cairo-sample.exe polarfixed.exe custom-widget.exe custom-cellrenderer.exe gtk-hello-world.exe button.exe calendar.exe subclass.exe menu.exe size.exe scribble.exe scribble-xinput.exe treeviewdemo.exe managedtreeviewdemo.exe nodeviewdemo.exe testdnd.exe actions.exe $(GNOMEVFS_TARGETS) $(GNOME_TARGETS) $(GLADE_TARGETS) $(VTE_TARGETS) $(DOTNET_TARGETS) DEBUGS = $(addsuffix .mdb, $(TARGETS))