Painting with Cairo
In this part of the Ruby 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.#!/usr/bin/rubyIn our example, we will draw three rectangles and fill them with three different colors.
# ZetCode Ruby GTK tutorial
#
# This program shows how to work
# with colors in Cairo
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'gtk2'
class RubyApp < Gtk::Window
def initialize
super
set_title "Colors"
signal_connect "destroy" do
Gtk.main_quit
end
init_ui
set_default_size 360, 100
set_window_position Gtk::Window::POS_CENTER
show_all
end
def init_ui
@darea = Gtk::DrawingArea.new
@darea.signal_connect "expose-event" do
on_expose
end
add(@darea)
end
def on_expose
cr = @darea.window.create_cairo_context
draw_colors cr
end
def draw_colors cr
cr.set_source_rgb 0.2, 0.23, 0.9
cr.rectangle 10, 15, 90, 60
cr.fill
cr.set_source_rgb 0.9, 0.1, 0.1
cr.rectangle 130, 15, 90, 60
cr.fill
cr.set_source_rgb 0.4, 0.9, 0.4
cr.rectangle 250, 15, 90, 60
cr.fill
end
end
Gtk.init
window = RubyApp.new
Gtk.main
@darea = Gtk::DrawingArea.newWe will be doing our drawing operations on the
DrawingArea
widget. @darea.signal_connect "expose-event" doWhen the window needs to be redrawn, the the
on_expose
end
expose-event
is triggered. In response to this event, we call the on_expose
method. cr = @darea.window.create_cairo_contextWe create the cairo context object from the
GdkWindow
of the drawing area. The context is an object onto which we do all our drawings. draw_colors crThe actual drawing is delegated to the
draw_colors
method. cr.set_source_rgb 0.2, 0.23, 0.9The
set_source_rgb
method sets a color for the cairo context. The three parameters of the method are the color intensity values. cr.rectangle 10, 15, 90, 60We 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.
cr.fillWe fill the inside of the rectangle with the current color.
Figure: Colors
Basic shapes
The next example draws some basic shapes onto the window.#!/usr/bin/rubyIn this example, we will create a rectangle, a square, a circle, an arc and an ellipse. We draw outlines in blue color, insides in white.
# ZetCode Ruby GTK tutorial
#
# This code example draws basic shapes
# with the Cairo library
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'gtk2'
class RubyApp < Gtk::Window
def initialize
super
set_title "Basic shapes"
signal_connect "destroy" do
Gtk.main_quit
end
init_ui
set_default_size 390, 240
set_window_position Gtk::Window::POS_CENTER
show_all
end
def init_ui
@darea = Gtk::DrawingArea.new
@darea.signal_connect "expose-event" do
on_expose
end
add(@darea)
end
def on_expose
cr = @darea.window.create_cairo_context
draw_shapes cr
end
def draw_shapes cr
cr.set_source_rgb 0.6, 0.6, 0.6
cr.rectangle 20, 20, 120, 80
cr.rectangle 180, 20, 80, 80
cr.fill
cr.arc 330, 60, 40, 0, 2*Math::PI
cr.fill
cr.arc 90, 160, 40, Math::PI/4, Math::PI
cr.fill
cr.translate 220, 180
cr.scale 1, 0.7
cr.arc 0, 0, 50, 0, 2*Math::PI
cr.fill
end
end
Gtk.init
window = RubyApp.new
Gtk.main
cr.rectangle 20, 20, 120, 80These lines draw a rectangle and a square.
cr.rectangle 180, 20, 80, 80
cr.fill
cr.arc 330, 60, 40, 0, 2*Math::PIHere the
cr.fill
arc
method draws a full circle. cr.translate 220, 180The
cr.scale 1, 0.7
cr.arc 0, 0, 50, 0, 2*Math::PI
cr.fill
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. Figure: Basic shapes
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)
#!/usr/bin/rubyIn the example we will draw ten rectangles with different levels of transparency.
# ZetCode Ruby GTK tutorial
#
# This program shows transparent
# rectangles using Cairo
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'gtk2'
class RubyApp < Gtk::Window
def initialize
super
set_title "Transparent rectangles"
signal_connect "destroy" do
Gtk.main_quit
end
init_ui
set_default_size 590, 90
set_window_position Gtk::Window::POS_CENTER
show_all
end
def init_ui
@darea = Gtk::DrawingArea.new
@darea.signal_connect "expose-event" do
on_expose
end
add(@darea)
end
def on_expose
cr = @darea.window.create_cairo_context
for i in (1..10)
cr.set_source_rgba 0, 0, 1, i*0.1
cr.rectangle 50*i, 20, 40, 40
cr.fill
end
end
end
Gtk.init
window = RubyApp.new
Gtk.main
cr.set_source_rgba 0, 0, 1, i*0.1The last parameter of the
set_source_rgba
method is the alpha transparency. Figure: Transparent rectangles
Donut
In the following example we create a complex shape by rotating a bunch of ellipses.#!/usr/bin/rubyIn this example, we create a donut. The shape resembles a cookie, hence the name donut.
# ZetCode Ruby GTK tutorial
#
# This program creates a donut
# with Cairo library
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'gtk2'
class RubyApp < Gtk::Window
def initialize
super
set_title "Donut"
signal_connect "destroy" do
Gtk.main_quit
end
init_ui
set_default_size 350, 250
set_window_position Gtk::Window::POS_CENTER
show_all
end
def init_ui
@darea = Gtk::DrawingArea.new
@darea.signal_connect "expose-event" do
on_expose
end
add(@darea)
end
def on_expose
cr = @darea.window.create_cairo_context
cr.set_line_width 0.5
w = allocation.width
h = allocation.height
cr.translate w/2, h/2
cr.arc 0, 0, 120, 0, 2*Math::PI
cr.stroke
for i in (1..36)
cr.save
cr.rotate i*Math::PI/36
cr.scale 0.3, 1
cr.arc 0, 0, 120, 0, 2*Math::PI
cr.restore
cr.stroke
end
end
end
Gtk.init
window = RubyApp.new
Gtk.main
cr.translate w/2, h/2In the beginning there is an ellipse.
cr.arc 0, 0, 120, 0, 2*Math::PI
cr.stroke
for i in (1..36)After several rotations, there is a donut.
cr.save
cr.rotate i*Math::PI/36
cr.scale 0.3, 1
cr.arc 0, 0, 120, 0, 2*Math::PI
cr.restore
cr.stroke
end
Figure: Donut
Drawing text
In the next example, we draw some text on the window.#!/usr/bin/rubyWe display part of the lyrics from the Natasha Bedingfields Soulmate song.
# ZetCode Ruby GTK tutorial
#
# This program draws text
# using Cairo
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'gtk2'
class RubyApp < Gtk::Window
def initialize
super
set_title "Soulmate"
signal_connect "destroy" do
Gtk.main_quit
end
init_ui
set_default_size 370, 240
set_window_position Gtk::Window::POS_CENTER
show_all
end
def init_ui
@darea = Gtk::DrawingArea.new
@darea.signal_connect "expose-event" do
on_expose
end
add(@darea)
end
def on_expose
cr = @darea.window.create_cairo_context
cr.set_source_rgb 0.1, 0.1, 0.1
cr.select_font_face "Purisa", Cairo::FONT_SLANT_NORMAL,
Cairo::FONT_WEIGHT_NORMAL
cr.set_font_size 13
cr.move_to 20, 30
cr.show_text "Most relationships seem so transitory"
cr.move_to 20, 60
cr.show_text "They're all good but not the permanent one"
cr.move_to 20, 120
cr.show_text "Who doesn't long for someone to hold"
cr.move_to 20, 150
cr.show_text "Who knows how to love without being told"
cr.move_to 20, 180
cr.show_text "Somebody tell me why I'm on my own"
cr.move_to 20, 210
cr.show_text "If there's a soulmate for everyone"
end
end
Gtk.init
window = RubyApp.new
Gtk.main
cr.select_font_face "Purisa", Cairo::FONT_SLANT_NORMAL,Here we specify the font, that we use. Purisa normal.
Cairo::FONT_WEIGHT_NORMAL
cr.set_font_size 13We specify the size of the font.
cr.move_to 20, 30We move to the point, where we will draw the text.
cr.show_text "Most relationships seem so transitory"The
show_text
method draws text onto the window. Figure: Soulmate
In this chapter of the Ruby GTK tutorial, we were painting with Cairo library.
No comments:
Post a Comment