El modelo de dibujo de Cairo

El concepto básico de dibujar con Cairo implica definir caminos «invisibles» y luego tacharlos o rellenarlos para hacerlos visibles.

Para hacer cualquier dibujo en Gtkmm con Cairo, primero debe crear un objeto Cairo::Context. Esta clase contiene a todos los parámetros del estado de gráficos que describen cómo se dibujará. Esto incluye información como el ancho de línea, color, la superficie a la que dibujar, y muchas otras cosas. Esto permite a las funciones de dibujo en si tomar menos argumentos para simplificar la interfaz. En gtkmm, un Cairo::Context se crea llamando a la función Gdk::Window::create_cairo_context(). Dado que los contextos de Cairo son objetos contados por referencia, esta función devuelve un objeto Cairo::RefPtr<Cairo::Context>

El siguiente ejemplo muestra cómo crear un contexto Cairo con un color de frente rojo y un ancho de 2. Cualquier función de dibujo que use este contexto usará esta configuración

Gtk::DrawingArea myArea;
Cairo::RefPtr<Cairo::Context> myContext = myArea.get_window()->create_cairo_context();
myContext->set_source_rgb(1.0, 0.0, 0.0);
myContext->set_line_width(2.0);

Cada Cairo::Context se asocia a una Gdk::Window particular, por lo que la primera línea del ejemplo de abajo crea un widget Gtk::DrawingArea y la segunda línea usa su Gdk::Window asociada para crear un objeto Cairo::Context. Las dos últimas líneas cambian el estado gráfico del contexto.

Hay varias variables del estado de gráficos que pueden establecerse para un contexto Cairo. Los atributos de contexto más comunes son color (usando set_source_rgb() o set_source_rgba() para colores traslúcidos), anchura de línea (usando set_line_width()), patrón de línea de puntos (usando set_dash), estilo de terminación de línea (usando set_line_cap()), estilo de unión de línea (usando set_line_join()), y estilos de fuente (usando set_font_size(), set_font_face() y otros). Hay muchas otras opciones también, como matrices de transformación, reglas de rellenado, realización de «antialiasing», y otros. Para obtener más información, consulte la documentación de la API de cairomm.

El estado actual de un Cairo::Context puede guardarse en una pila interna de estados guardados y restaurarse más tarde como estaba cuando lo guardó. Para hacer esto, use los métodos save() y restore(). Esto puede ser útil si necesita cambiar la anchura y color de línea temporalmente (o cualquier otra configuración de gráficos) para dibujar algo y luego volver a la configuración anterior. En esta situación, puede llamar a Cairo::Context::save(), cambiar las opciones gráficas, dibujar las líneas, y luego llamar a Cairo::Context::restore() para restaurar el estado de gráficos original. Múltiples llamadas a save() y restore() pueden anidarse; cada llamada a restore() restaura el estado de su par save() correspondiente.

Es una buena práctica poner todas las modificaciones al estado de gráficos entre llamadas a función save()/restore(). Por ejemplo, si tiene una función que toma una referencia a Cairo::Context como argumento, puede implementarlo como sigue:

void doSomething(const Cairo::RefPtr<Cairo::Context>& context, int x)
{
    context->save();
    // change graphics state
    // perform drawing operations
    context->restore();
}

El método virtual on_draw() proporciona un contexto Cairo que deberá usar para dibujar en el widget Gtk::DrawingArea. No es necesario guardar y restaurar este contexto Cairo en on_draw().