16.2.2 Drawing Area Methods

The GtkDrawingArea supports serveral methods that can be used to draw onto the drawing area 'canvas'. The drawing methods are:
 
area.draw_point(gc, x, y)

gc is the Graphics Context to be used to do the drawing.

x and y are the coordinates of the point.
 
area.draw_line(gc, x1, y1, x2, y2)

gc is the Graphics Context.

x1 and y1 are the starting point of the line. x2 and y2 are the ending point of the line.
 
area.draw_rectangle(gc, fill, x, y, width, height)

gc is the Graphics Context.

fill is a boolean indicating the rectangle should be filled with the foreground color if TRUE or not filled, if FALSE.
x and y are the top left corner of the rectangle.
width and height are the width and height of the rectangle.
 
area.draw_arc(gc, fill, x, y, width, height, angle1, angle2)

gc is the Graphics Context.

fill is a boolean indicating the arc should be filled with the foreground color if TRUE or not filled, if FALSE.
x and y are the top left corner of the bounding rectangle. width and height are the width and height of the bounding rectangle.
angle1 is  the start angle of the arc, relative to the 3 o'clock position, counter-clockwise, in 1/64ths of a degree.
angle2 is the end angle of the arc, relative to angle1, in 1/64ths of a degree counter clockwise.
 
area.draw_polygon(gc, fill, points)

gc is the Graphics Context.

fill is a boolean indicating the polygon should be filled with the foreground color if TRUE or not filled, if FALSE.
points is a list of coordinate pairs in tuples e.g. [ (0,0), (2,5), (3,7), (4,11) ] of the points to be drawn as a connected polygon.
 
area.draw_string(font, gc, x, y, string)
area.draw_text(font, gc, x, y, string)

font is the GdkFont to use to render the string.

gc is the Graphics Context.
x and y are the coordinates of the point to start rendering the string i.e the left baseline.
string is the string of characters to render.
 
area.draw_pixmap(gc, src, xsrc, ysrc, xdest, ydest, width, height)

gc is the Graphics Context.

src is the source pixmap.
xsrc and ysrc are the coordinates of the top left rectangle in the source pixmap.
xdest and ydest are the coordinates of the top left corner in the drawing area.
width and height are the width and height of the source pixmap area to be copied to the area.
 
area.draw_points(gc, points)

gc is the Graphics Context.

points is a list or tuple of coordinate pairs in tuples e.g. [ (0,0), (2,5), (3,7), (4,11) ] of the points to be drawn.
 
area.draw_segments(gc, segments)

gc is the Graphics Context.

segments is a list or tuple of start and end coordinate pairs in tuples e.g. [ (0,0, 1,5), (2,5, 1,7), (3,7, 1,11), (4,11, 1,13) ] of the line segments to be drawn.
 
area.draw_lines(gc, points)

gc is the Graphics Context.

points is a list or tuple of coordinate pairs in tuples e.g. [ (0,0), (2,5), (3,7), (4,11) ] of the points to be connected with lines.
 
area.draw_rgb_image(gc, x, y, width, height, dither, buffer, rowstride)
area.draw_rgb_32_image(gc, x, y, width, height, dither, buffer, rowstride)
area.draw_gray_image(gc, x, y, width, height, dither, buffer, rowstride)

gc is the Graphics Context.

x and y are the top left corner of the image bounding rectangle.
width and height are the width and height of the image bounding rectangle.
dither is the dither mode as described below

For the draw_rgb_image() method, buffer is the RGB Image data packed in a string as a sequence of 8-bit RGB pixel triplets. For the draw_rgb_32_image() method, buffer is the RGB Image data packed in a string as a sequence of 8-bit RGB pixel triplets with 8-bit padding (4 characters per RGB pixel). For the draw_gray_image() method, buffer is the gray image data packed in a string as 8-bit pixel data.

rowstride is the number of characters from the start of one row to the start of the next row of the image. rowstride is usuallydefaults to 3 * width for the draw_rgb_image() method; 4 * width for the draw_rgb_32_image(); and, width for the draw_gray_image() method. If rowstride is set to -1 then rowstride will be calculated as the defaults. If rowstride is 0 the line will be replicated height times.

The dither modes (defined in GDK.py) are:
 
    RGB_DITHER_NONE    # Never use dithering.

    RGB_DITHER_NORMAL  # Use dithering in 8 bits per pixel (and below) only.

    RGB_DITHER_MAX     # Use dithering in 16 bits per pixel and below.

Note: the draw_*_image() methods require that the functions:
 
push_rgb_visual()
pop_visual()

bracket the function that creates the drawing area to ensure that the RGB Image library is properly initialized.

The drawingarea.py example program demonstrates the use of most of the Drawing Area methods. Figure 16.1 shows the resulting display:

Figure 16.1 Drawing Area Example

The drawingarea.py source code is:
 
    1   #!/usr/bin/env python
    2   
    3   # example drawingarea.py
    4   
    5   import gtk
    6   import GDK
    7   import gtkxpm
    8   import operator
    9   import time
   10   import string
   11   
   12   class DrawingAreaExample:
   13       def __init__(self):
   14           window = gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
   15           window.set_title("Drawing Area Example")
   16           window.connect("destroy", gtk.mainquit)
   17           gtk.push_rgb_visual()
   18           self.area = gtk.GtkDrawingArea()
   19           gtk.pop_visual()
   20           self.area.size(400, 300)
   21           window.add(self.area)
   22           self.area.connect("expose-event", self.area_expose_cb)
   23           self.area.show()
   24           window.show()
   25   
   26       def area_expose_cb(self, area, event):
   27           self.style = self.area.get_style()
   28           self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
   29           self.font = self.style.font
   30           self.draw_point(10,10)
   31           self.draw_points(110, 10)
   32           self.draw_line(210, 10)
   33           self.draw_lines(310, 10)
   34           self.draw_segments(10, 100)
   35           self.draw_rectangles(110, 100)
   36           self.draw_arcs(210, 100)
   37           self.draw_pixmap(310, 100)
   38           self.draw_polygon(10, 200)
   39           self.draw_rgb_image(110, 200)
   40           return gtk.TRUE
   41   
   42       def draw_point(self, x, y):
   43           self.area.draw_point(self.gc, x+300, y+300)
   44           self.area.draw_string(self.font, self.gc, x+5, y+60, "Point")
   45           return
   46   
   47       def draw_points(self, x, y):
   48           points = [(x+10,y+10), (x+10,y), (x+40,y+30),
   49                     (x+30,y+10), (x+50,y+10)]
   50           self.area.draw_points(self.gc, points)
   51           self.area.draw_string(self.font, self.gc, x+5, y+60, "Points")
   52           return
   53   
   54       def draw_line(self, x, y):
   55           self.area.draw_line(self.gc, x+10, y+10, x+20, y+30)
   56           self.area.draw_string(self.font, self.gc, x+5, y+60, "Line")
   57           return
   58   
   59       def draw_lines(self, x, y):
   60           points = [(x+10,y+10), (x+10,y), (x+40,y+30),
   61                     (x+30,y+10), (x+50,y+10)]
   62           self.area.draw_lines(self.gc, points)
   63           self.area.draw_string(self.font, self.gc, x+5, y+60, "Lines")
   64           return
   65   
   66       def draw_segments(self, x, y):
   67           segments = ((x+20,y+10, x+20,y+70), (x+60,y+10, x+60,y+70),
   68               (x+10,y+30 , x+70,y+30), (x+10, y+50 , x+70, y+50))
   69           self.area.draw_segments(self.gc, segments)
   70           self.area.draw_string(self.font, self.gc, x+5, y+90, "Segments")
   71           return
   72   
   73       def draw_rectangles(self, x, y):
   74           self.area.draw_rectangle(self.gc, gtk.FALSE, x, y, 80, 70)
   75           self.area.draw_rectangle(self.gc, gtk.TRUE, x+10, y+10, 20, 20)
   76           self.area.draw_rectangle(self.gc, gtk.TRUE, x+50, y+10, 20, 20)
   77           self.area.draw_rectangle(self.gc, gtk.TRUE, x+20, y+50, 40, 10)
   78           self.area.draw_string(self.font, self.gc, x+5, y+90, "Rectangles")
   79           return
   80   
   81       def draw_arcs(self, x, y):
   82           self.area.draw_arc(self.gc, gtk.FALSE, x+10, y, 70, 70, 0, 360*64)
   83           self.area.draw_arc(self.gc, gtk.TRUE, x+30, y+20, 10, 10, 0, 360*64)
   84           self.area.draw_arc(self.gc, gtk.TRUE, x+50, y+20, 10, 10, 0, 360*64)
   85           self.area.draw_arc(self.gc, gtk.TRUE, x+30, y+10, 30, 50, 210*64,
   86                              120*64)
   87           self.area.draw_string(self.font, self.gc, x+5, y+90, "Arcs")
   88           return
   89   
   90       def draw_pixmap(self, x, y):
   91           pixmap, mask = gtk.create_pixmap_from_xpm_d(
   92               self.area, self.style.bg[gtk.STATE_NORMAL], gtkxpm.gtk_xpm)
   93           self.area.draw_pixmap(self.gc, pixmap, 0, 0, x+15, y+25,
   94                                 pixmap.width, pixmap.height)
   95           self.area.draw_string(self.font, self.gc, x+5, y+90, "Pixmap")
   96           return
   97   
   98       def draw_polygon(self, x, y):
   99           points = [(x+10,y+60), (x+10,y+20), (x+40,y+70),
  100                     (x+30,y+30), (x+50,y+40)]
  101           self.area.draw_polygon(self.gc, gtk.TRUE, points)
  102           self.area.draw_string(self.font, self.gc, x+5, y+90, "Polygon")
  103           return
  104   
  105       def draw_rgb_image(self, x, y):
  106           b = 80*3*80*['\0']
  107           for i in range(80):
  108               for j in range(80):
  109                   b[3*80*i+3*j] = chr(255-i%80)
  110                   b[3*80*i+3*j+1] = chr(255-abs(i-j)%80)
  111                   b[3*80*i+3*j+2] = chr(255-j%80)
  112           buff = string.join(b, '')
  113           self.area.draw_rgb_image(self.gc, x, y, 80, 80,
  114                                    GDK.RGB_DITHER_NONE, buff, -1)
  115           self.area.draw_text(self.font, self.gc, x+5, y+90, "RGB Image")
  116           return
  117   
  118   def main():
  119       gtk.mainloop()
  120       return 0
  121   
  122   if __name__ == "__main__":
  123       DrawingAreaExample()
  124       main()