gist: 28157 Download_button fork
public
Public Clone URL: git://gist.github.com/28157.git
FsCairo.fs
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
#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()

Owner

pzurek

Revisions