Le modèle de tracé Cairo

Le concept de base du tracé dans Cairo consiste à définir des chemins « invisibles », puis à les tracer ou les remplir pour les rendre visibles.

Pour effectuer un tracé dans gtkmm avec Cairo, vous devez au préalable créer un objet Cairo::Context. Cette classe contient tous les paramètres d'état graphiques décrivant comment le tracé doit être fait. Ces informations comprennent entre autres l'épaisseur du trait, la couleur, le contour à tracer et de nombreuses autres choses. Cela permet aux fonctions effectives de tracé de ne comporter qu'un minimum de paramètres pour simplifier l'interface. Dans gtkmm, un Cairo::Context est créé en appelant la fonction Gdk::Window::create_cairo_context(). Étant donné que les contextes Cairo sont des objets à décompte de référencement, cette fonction renvoie un objet Cairo::RefPtr<Cairo::Context>.

L'exemple ci-après montre comment définir un contexte Cairo avec une couleur de premier plan rouge et une épaisseur de trait de 2. Toute fonction de tracé se servant de ce contexte utilisera ces réglages.

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);

Chaque Cairo::Context est associé à une fenêtre Gdk::Window donnée ; ainsi, la première ligne de l'exemple ci-dessus crée un élément graphique Gtk::DrawingArea et la deuxième ligne utilise son objet Gdk::Window associé pour créer un objet Cairo::Context. Les deux dernières lignes modifient les caractéristiques graphiques du contexte.

De nombreuses variables d'état graphique peuvent être définies pour un contexte Cairo. Les attributs les plus courants sont la couleur (avec set_source_rgb() ou set_source_rgba() pour des couleurs transparentes), l'épaisseur du trait (avec set_line_width()), le type de pointillé (avec set_dash()), les bouts de lignes (avec set_line_cap()), les jonctions de lignes (avec set_line_join()) et les styles de polices de caractères (avec set_font_size(), set_font_face() et autres). Il existe beaucoup d'autres réglages : les matrices de transformation, les règles de remplissage, les types d'anti-crénelage, etc. Pour plus d'informations, consultez la documentation de l'API cairomm.

L'état présent d'un Cairo::Context peut être enregistré dans une pile interne de contextes enregistrés et ultérieurement rétablis dans leur état antérieur. Pour réaliser cette opération, utilisez les fonctions membres save() et restore(). Ce processus est utile si vous avez besoin de modifier temporairement l'épaisseur de trait ou la couleur (ou toute autre caractéristique graphique) pour tracer un élément puis revenir aux réglages antérieurs. Dans ce cas, appelez Cairo::Context::save(), modifiez les caractéristiques graphiques, effectuez le tracé, puis appelez Cairo::Context::restore() pour rétablir l'état graphique initial. Des appels multiples à save() et restore() peuvent être imbriqués ; chaque appel à restore() rétablit l'état correspondant à celui qui prévalait lors de l'appel de save().

Il est de bonne pratique de placer toute modification de l'état graphique entre des appels aux fonctions save()/restore(). Par exemple, si vous avez une fonction qui prend en paramètre une référence à un Cairo::Context, vous pouvez l'implémenter comme suit :

void doSomething(Cairo::RefPtr<Cairo::Context> context, int x)
{
    context->save();
    // modifier l'état graphique
    // réaliser les opérations de tracé
    context->restore();
}