Drawing with Cairo
In this part of the Visual Basic GTK# tutorial, we will do some painting with the Cairo library.
Cairo is a library for creating 2D vector graphics. We can use it to draw our own widgets, charts or various effects or animations.
Colors
In the first example, we will work with colors. A color is an object representing a combination of Red, Green, and Blue (RGB) intensity values. Cairo valid RGB values are in the range 0 to 1.
' ZetCode Mono Visual Basic GTK# tutorial
'
' This program draws three rectangles.
' The interiors are filled with
' different colors.
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com
Imports Gtk
Public Class GtkVBApp
Inherits Window
Public Sub New
MyBase.New("Colors")
Me.InitUI
Me.SetDefaultSize(360, 100)
Me.SetPosition(WindowPosition.Center)
AddHandler Me.DeleteEvent, AddressOf Me.OnDelete
Me.ShowAll
End Sub
Private Sub InitUI
Dim darea As New DrawingArea
AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
Me.Add(darea)
End Sub
Private Sub OnExpose(ByVal sender As Object, ByVal args As ExposeEventArgs)
Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
Me.DrawColors(cc)
Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable)
disposeTarget.Dispose
Dim disposeContext As IDisposable = CType(cc, IDisposable)
disposeContext.Dispose
End Sub
Private Sub DrawColors(ByVal cc As Cairo.Context)
cc.SetSourceRGB(0.2, 0.23, 0.9)
cc.Rectangle(10, 15, 90, 60)
cc.Fill
cc.SetSourceRGB(0.9, 0.1, 0.1)
cc.Rectangle(130, 15, 90, 60)
cc.Fill
cc.SetSourceRGB(0.4, 0.9, 0.4)
cc.Rectangle(250, 15, 90, 60)
cc.Fill
End Sub
Private Sub OnDelete(ByVal sender As Object, _
ByVal args As DeleteEventArgs)
Application.Quit
End Sub
Public Shared Sub Main
Application.Init
Dim app As New GtkVBApp
Application.Run
End Sub
End Class
In our example, we will draw three rectangles and fill them with three different colors.
vbnc -r:/usr/lib/mono/gtk-sharp-2.0/gtk-sharp.dll -r:/usr/lib/mono/gtk-sharp-2.0/gdk-sharp.dll -r:/usr/lib/mono/2.0/Mono.Cairo.dll colors.vb
Here is how we compile the example.
Dim darea As New DrawingArea
We will be doing our drawing operations on the DrawingArea widget.
AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
All drawing is done in a method, that we plug into the ExposeEvent.
Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
We create the Cairo.Context object from the GdkWindow of the drawing area. The context is an object onto which we do all our drawings.
Me.DrawColors(cc)
The actual drawing is delegated to the DrawColors method.
Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable) disposeTarget.Dispose Dim disposeContext As IDisposable = CType(cc, IDisposable) disposeContext.Dispose
Here we dispose the resources, that were used during the drawing process.
cc.SetSourceRGB(0.2, 0.23, 0.9)
The SetSourceRGB method sets a color for the cairo context. The three parameters of the method are the color intensity values.
cc.Rectangle(10, 15, 90, 60)
We draw a rectangle. The first two parameters are the x, y coordinates of the top left corner of the rectangle. The last two parameters are the width and height of the rectangle.
cc.Fill
We fill the inside of the rectangle with the current color.
Basic shapes
The next example draws some basic shapes onto the window.
' ZetCode Mono Visual Basic GTK# tutorial
'
' This program draws basic shapes
' available in Cairo
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com
Imports Gtk
Public Class GtkVBApp
Inherits Window
Public Sub New
MyBase.New("Basic Shapes")
Me.InitUI
Me.SetDefaultSize(400, 250)
Me.SetPosition(WindowPosition.Center)
AddHandler Me.DeleteEvent, AddressOf Me.OnDelete
Me.ShowAll
End Sub
Private Sub InitUI
Dim darea As New DrawingArea
AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
Me.Add(darea)
End Sub
Private Sub OnExpose(ByVal sender As Object, ByVal args As ExposeEventArgs)
Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
Me.DrawShapes(cc)
Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable)
disposeTarget.Dispose
Dim disposeContext As IDisposable = CType(cc, IDisposable)
disposeContext.Dispose
End Sub
Private Sub DrawShapes(ByVal cc As Cairo.Context)
cc.SetSourceRGB(0.5, 0.5, 0.5)
cc.Rectangle(20, 20, 120, 80)
cc.Rectangle(180, 20, 80, 80)
cc.Fill
cc.Arc(330, 60, 40, 0, 2*Math.PI)
cc.Fill
cc.Arc(90, 160, 40, Math.PI/4, Math.PI)
cc.ClosePath
cc.Fill
cc.Translate(220, 180)
cc.Scale(1, 0.7)
cc.Arc(0, 0, 50, 0, 2*Math.PI)
cc.Fill
End Sub
Private Sub OnDelete(ByVal sender As Object, _
ByVal args As DeleteEventArgs)
Application.Quit
End Sub
Public Shared Sub Main
Application.Init
Dim app As New GtkVBApp
Application.Run
End Sub
End Class
In this example, we will create a rectangle, a square, a circle, an arc and an ellipse.
cc.Rectangle(20, 20, 120, 80) cc.Rectangle(180, 20, 80, 80) cc.Fill
These lines draw a rectangle and a square.
cc.Arc(330, 60, 40, 0, 2*Math.PI) cc.Fill
Here the Arc method draws a full circle.
cc.Translate(220, 180) cc.Scale(1, 0.7) cc.Arc(0, 0, 50, 0, 2*Math.PI) cc.Fill
The Translate method moves the object to a specific point. If we want to draw an oval, we do some scaling first. Here the Scale method shrinks the y axis.
Transparent rectangles
Transparency is the quality of being able to see through a material. The easiest way to understand transparency is to imagine a piece of glass or water. Technically, the rays of light can go through the glass and this way we can see objects behind the glass.
In computer graphics, we can achieve transparency effects using alpha compositing. Alpha compositing is the process of combining an image with a background to create the appearance of partial transparency. The composition process uses an alpha channel. (wikipedia.org, answers.com)
' ZetCode Mono Visual Basic GTK# tutorial
'
' This program draws ten
' rectangles with different
' levels of transparency
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com
Imports Gtk
Public Class GtkVBApp
Inherits Window
Public Sub New
MyBase.New("Transparent rectangles")
Me.InitUI
Me.SetDefaultSize(590, 90)
Me.SetPosition(WindowPosition.Center)
AddHandler Me.DeleteEvent, AddressOf Me.OnDelete
Me.ShowAll
End Sub
Private Sub InitUI
Dim darea As New DrawingArea
AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
Me.Add(darea)
End Sub
Private Sub OnExpose(ByVal sender As Object, ByVal args As ExposeEventArgs)
Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
Me.DrawRectangles(cc)
Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable)
disposeTarget.Dispose()
Dim disposeContext As IDisposable = CType(cc, IDisposable)
disposeContext.Dispose()
End Sub
Private Sub DrawRectangles(ByVal cc As Cairo.Context)
For i As Integer = 1 To 10
cc.SetSourceRGBA(0, 0, 1, i*0.1)
cc.Rectangle(50*i, 20, 40, 40)
cc.Fill
Next
End Sub
Private Sub OnDelete(ByVal sender As Object, _
ByVal args As DeleteEventArgs)
Application.Quit
End Sub
Public Shared Sub Main
Application.Init
Dim app As New GtkVBApp
Application.Run
End Sub
End Class
In the example we will draw ten rectangles with different levels of transparency.
cc.SetSourceRGBA(0, 0, 1, i*0.1)
The last parameter of the SetSourceRGBA method is the alpha transparency.
Donut
In the following example we create n complex shape by rotating a bunch of ellipses.
' ZetCode Mono Visual Basic GTK# tutorial
'
' This program draws basic shapes
' available in Cairo
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com
Imports Gtk
Public Class GtkVBApp
Inherits Window
Public Sub New
MyBase.New("Donut")
Me.InitUI
Me.SetDefaultSize(400, 250)
Me.SetPosition(WindowPosition.Center)
AddHandler Me.DeleteEvent, AddressOf Me.OnDelete
Me.ShowAll
End Sub
Private Sub InitUI
Dim darea As New DrawingArea
AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
Me.Add(darea)
End Sub
Private Sub OnExpose(ByVal sender As Object, ByVal args As ExposeEventArgs)
Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
Me.DrawDonut(cc)
Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable)
disposeTarget.Dispose
Dim disposeContext As IDisposable = CType(cc, IDisposable)
disposeContext.Dispose
End Sub
Private Sub DrawDonut(ByVal cc As Cairo.Context)
cc.LineWidth = 0.5
Dim width, height As Integer
width = Allocation.Width
height = Allocation.Height
cc.Translate(width/2, height/2)
cc.Arc(0, 0, 120, 0, 2*Math.PI)
cc.Stroke
cc.Save
For i As Integer = 0 To 35
cc.Rotate( i*Math.PI/36)
cc.Scale(0.3, 1)
cc.Arc(0, 0, 120, 0, 2*Math.PI)
cc.Restore
cc.Stroke
cc.Save
Next
End Sub
Private Sub OnDelete(ByVal sender As Object, _
ByVal args As DeleteEventArgs)
Application.Quit
End Sub
Public Shared Sub Main
Application.Init
Dim app As New GtkVBApp
Application.Run
End Sub
End Class
In this example, we create a donut. The shape resembles a cookie, hence the name donut.
cc.Translate(width/2, height/2) cc.Arc(0, 0, 120, 0, 2*Math.PI) cc.Stroke
In the beginning there is an ellipse.
For i As Integer = 0 To 35
cc.Rotate( i*Math.PI/36)
cc.Scale(0.3, 1)
cc.Arc(0, 0, 120, 0, 2*Math.PI)
cc.Restore
cc.Stroke
cc.Save
Next
After several rotations, there is a donut.
Drawing text
In the next example, we draw some text on the window.
' ZetCode Mono Visual Basic GTK# tutorial
'
' This program draws text
' on the window
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com
Imports Gtk
Public Class GtkVBApp
Inherits Window
Public Sub New
MyBase.New("Soulmate")
Me.InitUI
Me.SetDefaultSize(400, 250)
Me.SetPosition(WindowPosition.Center)
AddHandler Me.DeleteEvent, AddressOf Me.OnDelete
Me.ShowAll
End Sub
Private Sub InitUI
Dim darea As New DrawingArea
AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
Me.Add(darea)
End Sub
Private Sub OnExpose(ByVal sender As Object, ByVal args As ExposeEventArgs)
Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
Me.DrawLyrics(cc)
Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable)
disposeTarget.Dispose
Dim disposeContext As IDisposable = CType(cc, IDisposable)
disposeContext.Dispose
End Sub
Private Sub DrawLyrics(ByVal cc As Cairo.Context)
cc.SetSourceRGB(0.1, 0.1, 0.1)
cc.SelectFontFace("Purisa", Cairo.FontSlant.Normal, Cairo.FontWeight.Bold)
cc.SetFontSize(13)
cc.MoveTo(20, 30)
cc.ShowText("Most relationships seem so transitory")
cc.MoveTo(20, 60)
cc.ShowText("They're all good but not the permanent one")
cc.MoveTo(20, 120)
cc.ShowText("Who doesn't long for someone to hold")
cc.MoveTo(20, 150)
cc.ShowText("Who knows how to love without being told")
cc.MoveTo(20, 180)
cc.ShowText("Somebody tell me why I'm on my own")
cc.MoveTo(20, 210)
cc.ShowText("If there's a soulmate for everyone")
End Sub
Private Sub OnDelete(ByVal sender As Object, _
ByVal args As DeleteEventArgs)
Application.Quit
End Sub
Public Shared Sub Main
Application.Init
Dim app As New GtkVBApp
Application.Run
End Sub
End Class
We display part of the lyrics from the Natasha Bedingfields Soulmate song.
cc.SelectFontFace("Purisa", Cairo.FontSlant.Normal, Cairo.FontWeight.Bold)
Here we specify the font, that we use. Purisa bold.
cc.SetFontSize(13)
We specify the size of the font.
cc.MoveTo(20, 30)
We move to the point, where we will draw the text.
cc.ShowText("Most relationships seem so transitory")
The ShowText method draws text onto the window.
In this chapter of the Visual Basic GTK# tutorial, we were painting with Cairo library.