Drawing Text
| Chapter 16. The DrawingArea Widget |

## Drawing Text

### Drawing Text with Pango

Text is drawn via Pango Layouts. The easiest way to create a `Pango::Layout` is to use `Gtk::Widget::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 `Pango::Layout::show_in_cairo_context()` method.

### Example

Here is an example of a program that draws some text, some of it upside-down. The Printing chapter contains another example of drawing text.

Figure 16.6. Drawing Area - Text

Source Code

File: `myarea.h` (For use with gtkmm 4)

    #ifndef GTKMM_EXAMPLE_MYAREA_H
    #define GTKMM_EXAMPLE_MYAREA_H

    #include <gtkmm/drawingarea.h>

    class MyArea : public Gtk::DrawingArea
    {
    public:
      MyArea();
      virtual ~MyArea();

    protected:
      void on_draw(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height);

    private:
      void draw_rectangle(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height);
      void draw_text(const Cairo::RefPtr<Cairo::Context>& cr, int rectangle_width, int rectangle_height);

    };

    #endif // GTKMM_EXAMPLE_MYAREA_H

File: `main.cc` (For use with gtkmm 4)

    #include "myarea.h"
    #include <gtkmm/application.h>
    #include <gtkmm/window.h>

    class ExampleWindow : public Gtk::Window
    {
    public:
      ExampleWindow();

    protected:
      MyArea m_area;
    };

    ExampleWindow::ExampleWindow()
    {
      set_title("Drawing text example");
      set_child(m_area);
    }

    int main(int argc, char* argv[])
    {
      auto app = Gtk::Application::create("org.gtkmm.example");

      return app->make_window_and_run<ExampleWindow>(argc, argv);
    }

File: `myarea.cc` (For use with gtkmm 4)

    #include "myarea.h"

    MyArea::MyArea()
    {
      set_draw_func(sigc::mem_fun(*this, &MyArea::on_draw));
    }

    MyArea::~MyArea()
    {
    }

    void MyArea::on_draw(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height)
    {
      const int rectangle_width = width;
      const int rectangle_height = height / 2;

      // Draw a black rectangle
      cr->set_source_rgb(0.0, 0.0, 0.0);
      draw_rectangle(cr, rectangle_width, rectangle_height);

      // and some white text
      cr->set_source_rgb(1.0, 1.0, 1.0);
      draw_text(cr, rectangle_width, rectangle_height);

      // flip the image vertically
      // see http://www.cairographics.org/documentation/cairomm/reference/classCairo_1_1Matrix.html
      // the -1 corresponds to the yy part (the flipping part)
      // the height part is a translation (we could have just called cr->translate(0, height) instead)
      // it's height and not height / 2, since we want this to be on the second part of our drawing
      // (otherwise, it would draw over the previous part)
      Cairo::Matrix matrix(1.0, 0.0, 0.0, -1.0, 0.0, height);

      // apply the matrix
      cr->transform(matrix);

      // white rectangle
      cr->set_source_rgb(1.0, 1.0, 1.0);
      draw_rectangle(cr, rectangle_width, rectangle_height);

      // black text
      cr->set_source_rgb(0.0, 0.0, 0.0);
      draw_text(cr, rectangle_width, rectangle_height);
    }

    void MyArea::draw_rectangle(const Cairo::RefPtr<Cairo::Context>& cr,
                                int width, int height)
    {
      cr->rectangle(0, 0, width, height);
      cr->fill();
    }

    void MyArea::draw_text(const Cairo::RefPtr<Cairo::Context>& cr,
                           int rectangle_width, int rectangle_height)
    {
      // http://developer.gnome.org/pangomm/unstable/classPango_1_1FontDescription.html
      Pango::FontDescription font;

      font.set_family("Monospace");
      font.set_weight(Pango::Weight::BOLD);

      // http://developer.gnome.org/pangomm/unstable/classPango_1_1Layout.html
      auto layout = create_pango_layout("Hi there!");

      layout->set_font_description(font);

      int text_width;
      int text_height;

      //get the text dimensions (it updates the variables -- by reference)
      layout->get_pixel_size(text_width, text_height);

      // Position the text in the middle
      cr->move_to((rectangle_width-text_width)/2, (rectangle_height-text_height)/2);

      layout->show_in_cairo_context(cr);
    }

Drawing Arcs and Circles |  | Drawing Images