Created
November 23, 2008 17:20
-
-
Save pzurek/28157 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#light | |
open System | |
open Cairo | |
open Gtk | |
Gtk.Application.Init() | |
let window = new Gtk.Window("F# Cairo") | |
let vBox = new Gtk.VBox() | |
let drawingArea = new Gtk.DrawingArea() | |
let buttonHBox = new Gtk.HBox() | |
let closeButton = new Gtk.Button() | |
let SketchCircle (cc:Cairo.Context, xc, yc, xr, yr) = | |
cc.Save() | |
let m = cc.Matrix | |
cc.Translate(xc, yc) | |
cc.Scale(1., yr/xr) | |
cc.MoveTo(xr, 0.) | |
cc.Arc(0., 0., xr, 0., 2.*Math.PI) | |
cc.ClosePath() | |
cc.Matrix <- m | |
cc.Restore() | |
let FillChecks (cc:Cairo.Context, x, y, w, h) = | |
let checkSize = 32 | |
cc.Save() | |
use check = cc.Target.CreateSimilar(Cairo.Content.Color, 2*checkSize, 2*checkSize) | |
use cr2 = new Cairo.Context(check) | |
cr2.Operator <- Cairo.Operator.Source | |
cr2.Color <- new Cairo.Color(0.4, 0.4, 0.4) | |
cr2.Rectangle(0., 0., 2.*(float)checkSize, 2.*(float)checkSize) | |
cr2.Fill() | |
cr2.Color <- new Cairo.Color(0.7, 0.7, 0.7) | |
cr2.Rectangle(x, y, (float)checkSize, (float)checkSize) | |
cr2.Fill() | |
cr2.Rectangle(x + (float)checkSize, y + (float)checkSize, (float)checkSize, (float)checkSize) | |
cr2.Fill() | |
use checkPattern = new Cairo.SurfacePattern(check) | |
checkPattern.Extend <- Cairo.Extend.Repeat | |
cc.Source <- checkPattern | |
cc.Rectangle(0., 0., w, h) | |
cc.Fill() | |
cc.Restore() | |
let Draw3Circles (cc:Cairo.Context, xc, yc, radius, alfa) = | |
cc.Save() | |
let subradius = radius * (2./3. - 0.1) | |
cc.Color <- new Cairo.Color(1., 0., 0., alfa) | |
SketchCircle(cc, xc + radius / 3. * Math.Cos(Math.PI * 0.5), yc - radius / 3. * Math.Sin (Math.PI * 0.5), subradius, subradius) | |
cc.Fill() | |
cc.Color <- new Cairo.Color(0., 1., 0., alfa) | |
SketchCircle(cc, xc + radius / 3. * Math.Cos(Math.PI * (0.5 + 2. / 0.3)), yc - radius / 3. * Math.Sin (Math.PI * (0.5 + 2. / 0.3)), subradius, subradius) | |
cc.Fill() | |
cc.Color <- new Cairo.Color(0., 0., 1., alfa) | |
SketchCircle(cc, xc + radius / 3. * Math.Cos(Math.PI * (0.5 + 4. / 0.3)), yc - radius / 3. * Math.Sin (Math.PI * (0.5 + 4. / 0.3)), subradius, subradius) | |
cc.Fill() | |
cc.Restore() | |
let Draw (cc:Cairo.Context, w, h) = | |
let radius = 0.5 * Math.Min(w, h) - 10. | |
let xc = w / 2. | |
let yc = h / 2. | |
use overlay = cc.Target.CreateSimilar (Cairo.Content.ColorAlpha, (int)w , (int)h) | |
use punch = cc.Target.CreateSimilar (Cairo.Content.Alpha, (int)w , (int)h) | |
use circles = cc.Target.CreateSimilar (Cairo.Content.ColorAlpha, (int)w , (int)h) | |
FillChecks(cc, 0., 0., w, h) | |
cc.Save() | |
use cr_overlay = new Cairo.Context(overlay) | |
cr_overlay.Color <- new Cairo.Color(0., 0., 0.) | |
SketchCircle(cr_overlay, xc, yc, radius, radius) | |
cr_overlay.Fill() | |
use cr_temp = new Cairo.Context(punch) | |
Draw3Circles(cr_temp, xc, yc, radius, 1.) | |
cr_overlay.Operator <- Cairo.Operator.DestOut | |
cr_overlay.SetSourceSurface (punch, 0, 0) | |
cr_overlay.Paint() | |
use cr_circles = new Cairo.Context(circles) | |
cr_circles.Operator <- Cairo.Operator.Over | |
Draw3Circles(cr_circles, xc, yc, radius, 0.5) | |
cr_overlay.Operator <- Cairo.Operator.Add | |
cr_overlay.SetSourceSurface(circles, 0, 0) | |
cr_overlay.Paint() | |
cc.SetSourceSurface(overlay, 0, 0) | |
cc.Paint() | |
cc.Restore() | |
let Knockout(da:Gtk.DrawingArea) = | |
use drawable = da.GdkWindow | |
let w,h = da.Allocation.Width, da.Allocation.Height | |
use cairoContext = Gdk.CairoHelper.Create (drawable) | |
Draw(cairoContext, (float)w, (float)h) | |
window.WindowPosition <- Gtk.WindowPosition.Center | |
window.SetDefaultSize(400, 400) | |
window.Destroyed.Add(fun _ -> Application.Quit() ) | |
drawingArea.ExposeEvent.Add(fun _ -> Knockout(drawingArea)) | |
drawingArea.ButtonReleaseEvent.Add(fun _ -> () ) | |
closeButton.Label <- " Close " | |
closeButton.Clicked.Add(fun _ -> Application.Quit() ) | |
vBox.BorderWidth <- (uint32) 12 | |
vBox.Spacing <- 12 | |
vBox.PackStart(drawingArea, true, true, (uint32) 0) | |
buttonHBox.PackEnd(closeButton, false, false, (uint32) 0) | |
vBox.PackStart(buttonHBox, false, false, (uint32) 0) | |
window.Add(vBox) | |
window.ShowAll() | |
Gtk.Application.Run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment