Drawing With Cairo
#!/usr/bin/env python
#
# [SNIPPET_NAME: Drawing With Cairo]
# [SNIPPET_CATEGORIES: PyGTK, Cairo]
# [SNIPPET_DESCRIPTION: Create a drawing with cairo]
# [SNIPPET_AUTHOR: Jurjen Stellingwerff <[email protected]>]
# [SNIPPET_LICENSE: GPL]
# example cairo_demo.py
import pygtk
pygtk.require('2.0')
import gtk
import math
import cairo
class DrawingAreaExample:
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title("Drawing With Cairo")
window.connect("destroy", lambda w: gtk.main_quit())
self.area = gtk.DrawingArea()
self.area.set_size_request(380, 300)
window.add(self.area)
self.area.connect("expose-event", self.expose)
self.area.show()
window.show()
def expose(self, area, event):
self.context = area.window.cairo_create()
self.context.rectangle(event.area.x, event.area.y, event.area.width,
event.area.height)
self.context.clip()
self.context.scale(event.area.width/380.0, event.area.height/300.0)
self.draw_point(10,10)
self.draw_points(110, 10)
self.draw_line(210, 10)
self.draw_lines(310, 10)
self.draw_segments(10, 100)
self.draw_rectangles(110, 100)
self.draw_arcs(210, 100)
self.draw_pixmap(310, 100)
self.draw_polygon(10, 200)
self.draw_rgb_image(110, 200)
self.context.move_to(210, 290)
self.context.show_text("Try to resize the window")
return False
def point(self, x, y):
self.context.arc(x, y, 1, 0.0, 2.0 * math.pi)
self.context.fill()
def draw_point(self, x, y):
self.point(x+30, y+30)
self.context.move_to(x+5, y+50)
self.context.show_text("Point")
return
def draw_points(self, x, y):
points = [(x+10,y+10), (x+10,y), (x+40,y+30),
(x+30,y+10), (x+50,y+10)]
for px,py in points:
self.point(px,py)
self.context.move_to(x+5, y+50)
self.context.show_text("Points")
return
def draw_line(self, x, y):
self.context.move_to(x+10, y+10)
self.context.line_to(x+20, y+30)
self.context.stroke()
self.context.move_to(x+5, y+50)
self.context.show_text("Line")
return
def draw_lines(self, x, y):
points = [(x+10,y), (x+40,y+30),
(x+30,y+10), (x+50,y+10)]
self.context.move_to(x+10, y+10)
for px,py in points:
self.context.line_to(px, py)
self.context.set_line_width(4.5)
self.context.stroke()
self.context.save()
self.context.set_source_rgb(1, 1, 0.7)
self.context.translate(1.5, 1)
self.context.move_to(x+10, y+10)
for px,py in points:
self.context.line_to(px, py)
self.context.set_line_width(1.5)
self.context.stroke()
self.context.restore()
self.context.set_line_width(2)
self.context.move_to(x+5, y+50)
self.context.show_text("Lines")
return
def draw_segments(self, x, y):
segments = ((x+20,y+10, x+20,y+70), (x+60,y+10, x+60,y+70),
(x+10,y+30 , x+70,y+30), (x+10, y+50 , x+70, y+50))
for fx, fy, tx, ty in segments:
self.context.move_to(fx, fy)
self.context.line_to(tx, ty)
self.context.stroke()
self.context.move_to(x+5, y+90)
self.context.show_text("Segments")
return
def draw_rectangles(self, x, y):
self.context.save()
self.context.set_source_rgb(.6, 0, 0)
self.context.rectangle(x, y, 80, 70)
self.context.stroke()
self.context.restore()
rectangles = ((x+10, y+10, 20, 20), (x+50, y+10, 20, 20), (x+20, y+50, 40, 10))
for px, py, h, w in rectangles:
self.context.rectangle(px, py, h, w)
self.context.fill()
self.context.move_to(x+5, y+90)
self.context.show_text("Rectangles")
return
def draw_arcs(self, x, y):
self.context.set_line_width(1)
arcs = [(False, x+45, y+35, 35),
(True, x+35, y+25, 5),
(True, x+55, y+25, 5)]
for fill, px, py, r in arcs:
self.context.move_to(px+r, py)
self.context.arc(px, py, r, 0, 2*math.pi)
if fill:
self.context.fill()
else:
self.context.set_source_rgb(1, 1, 0.5)
self.context.fill_preserve()
self.context.set_source_rgb(0, 0, 0)
self.context.stroke()
self.context.move_to(x+45, y+35)
s = 1.66
self.context.save()
self.context.scale(1, s)
self.context.arc(x+45, (y+35)/s, 15, 30*math.pi/180, 150*math.pi/180)
self.context.restore()
self.context.save()
self.context.move_to(x+5, y+90)
self.context.select_font_face("serif", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
self.context.show_text("Arcs")
self.context.restore()
return
def draw_pixmap(self, x, y):
try:
img = cairo.ImageSurface.create_from_png("gtk.png")
except Exception, e:
print e
exit(1)
self.context.save()
self.context.set_source_surface(img, x+5, y+15)
self.context.paint()
self.context.restore()
self.context.move_to(x+5, y+90)
self.context.show_text("Pixmap")
return
def draw_polygon(self, x, y):
points = [(x+10,y+20), (x+40,y+70),
(x+30,y+30), (x+50,y+40)]
self.context.move_to(x+10, y+60)
for px,py in points:
self.context.line_to(px, py)
self.context.fill()
self.context.move_to(x+5, y+90)
self.context.show_text("Polygon")
return
def draw_rgb_image(self, x, y):
s = 80
h = 40
self.context.save()
linpat = cairo.LinearGradient(x, y, x+s, y+s)
linpat.add_color_stop_rgb(0.0, 1, 1, 1)
linpat.add_color_stop_rgb(1.0, 0, 1, 0)
self.context.set_source(linpat)
self.context.move_to(x,y)
self.context.line_to(x,y+s)
self.context.line_to(x+s,y+s)
self.context.line_to(x+s,y)
self.context.fill()
linpat = cairo.LinearGradient(x, y+s, x+s, y)
linpat.add_color_stop_rgba(0.0, 0, 0, 1, 1)
linpat.add_color_stop_rgba(0.5, 1, 0, 1, 0)
linpat.add_color_stop_rgba(1.0, 1, 0, 0, 1)
self.context.set_source(linpat)
self.context.move_to(x,y)
self.context.line_to(x,y+s)
self.context.line_to(x+s,y+s)
self.context.line_to(x+s,y)
self.context.fill()
self.context.restore()
self.context.save()
self.context.move_to(x+5, y+92)
self.context.set_font_size(11.5)
self.context.show_text("RGB Image")
self.context.restore()
return
def main():
gtk.main()
return 0
if __name__ == "__main__":
DrawingAreaExample()
main()