Drawing Text

Text is drawn via Pango Layouts. The easiest way to create a Pango::Layout is to use create_pango_layout. Once created, the layout can be manipulated in various ways, including changing the text, font, etc. Finally, the layout can be rendered using the draw_layout method of Gdk::Drawable, which takes the usual Gdk::GC, an x-position, a y-position and the layout itself.

Example

Here's a sample program using all of the drawing methods shown so far:

Figure 14.2. Drawing Area - Text

Drawing Area - Text

Source Code

File: customdrawingarea.h

#ifndef GTKMM_EXAMPLE_DRAWINGAREATEXT_H
#define GTKMM_EXAMPLE_DRAWINGAREATEXT_H

#include <gtkmm.h>

class CustomDrawingArea : public Gtk::DrawingArea
{
public:
  CustomDrawingArea(int x_size = 0, int y_size = 0);
  bool on_expose_event(GdkEventExpose* event);
  
protected:
  int m_width, m_height;
};

#endif //GTKMM_EXAMPLE_DRAWINGAREATEXT_H

File: testwindow.h

#ifndef GTKMM_EXAMPLE_DATTESTWIN_H
#define GTKMM_EXAMPLE_DATTESTWIN_H

#include "customdrawingarea.h"

class TestWindow : public Gtk::Window
{
public:
  TestWindow();
private:
  CustomDrawingArea m_drawing_area;
};

#endif

File: customdrawingarea.cc

#include "customdrawingarea.h"
#include <pangomm/layout.h>

CustomDrawingArea::CustomDrawingArea(int x_size, int y_size)
  : DrawingArea(), m_width(x_size), m_height(y_size)
{
  set_size_request(m_width, m_height);

   //TODO: Why do we store m_width and m_height? murrayc
}

//Expose_event method.
bool CustomDrawingArea::on_expose_event(GdkEventExpose*)
{
  Glib::RefPtr<Gdk::Window> win = get_window();
  Glib::RefPtr<Gdk::GC> some_gc = Gdk::GC::create(win);
  Glib::RefPtr<Gdk::GC> blackgc = get_style()->get_black_gc();
  Glib::RefPtr<Gdk::GC> whitegc = get_style()->get_white_gc();
  
  Gdk::Color some_color;
  Glib::RefPtr<Gdk::Colormap> some_colormap = get_default_colormap();
  some_color.set_red(65535);
  some_color.set_green(65535);
  some_color.set_blue(0);
  some_colormap->alloc_color(some_color);
  some_gc->set_foreground(some_color);

  //Draw pac-man.
  win->draw_arc(some_gc, true, 30, 100, 50, 50, 2880, 17280); //2880==45*64, 17280==270*64

  //Draw pellets.
  win->draw_rectangle(whitegc, true, 80, 120, 15, 10);
  win->draw_rectangle(whitegc, true, 110, 120, 15, 10);
  win->draw_rectangle(whitegc, true, 140, 120, 15, 10);

  //Draw some lines.
  win->draw_line(blackgc, 5, 2, 5, 20);
  win->draw_line(blackgc, 5, 11, 10, 11);
  win->draw_line(blackgc, 10, 2, 10, 20);
  win->draw_line(blackgc, 15, 2, 21, 2);
  win->draw_line(blackgc, 18, 2, 18, 20);
  win->draw_line(blackgc, 15, 20, 21, 20);

  //Draw a diamond.
  std::vector<Gdk::Point> some_points;
  some_points.push_back(Gdk::Point(100, 10));
  some_points.push_back(Gdk::Point(50, 60));
  some_points.push_back(Gdk::Point(100, 110));
  some_points.push_back(Gdk::Point(150, 60));
  win->draw_polygon(blackgc, true, some_points);

  //Draw some text.
  Glib::RefPtr<Pango::Layout> pangolayout = create_pango_layout("Hello, World!");
  win->draw_layout(blackgc, 30, 170, pangolayout);

  // return true to stop any other event handlers being called to
  // draw this area
  return true;
}

File: main.cc

#include "testwindow.h"

int main(int argc, char *argv[])
{
  Gtk::Main main_runner(argc, argv);
  TestWindow foo;
  main_runner.run(foo);
  return 0;
}

File: testwindow.cc

#include "testwindow.h"

TestWindow::TestWindow()
  : m_drawing_area(200, 200)
{
  add(m_drawing_area);
  show_all_children();
}

The structure of the program is the same as the first one, except that this one includes examples of the drawing elements discussed up to now.