Kreslení křivek

Mimo rovných čar umožňuje Cairo kreslit jednoduše i křivky (přesný technický termín je kubické Bézierovy splajny) pomocí funkcí Cairo::Context::curve_to() a Cairo::Context::rel_curve_to(). Tyto funkce přebírají souřadnice pro cílový bod a souřadnice dvou „řídících“ bodů. Nejlépe to bude vysvětlit na příkladu, tak pojďme na to.

16.3.1. Příklad

Tato jednoduchá aplikace kreslí pomocí Cairo křivku a zobrazuje řídící body pro její jednotlivé konce.

Obrázek 16-4Kreslicí oblast – čáry

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

#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("DrawingArea");
  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"
#include <cairomm/context.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)
{
  double x0=0.1, y0=0.5, // start point
         x1=0.4, y1=0.9,  // control point #1
         x2=0.6, y2=0.1,  // control point #2
         x3=0.9, y3=0.5;  // end point

  // scale to unit square (0 to 1 width and height)
  cr->scale(width, height);

  cr->set_line_width(0.05);
  // draw curve
  cr->move_to(x0, y0);
  cr->curve_to(x1, y1, x2, y2, x3, y3);
  cr->stroke();
  // show control points
  cr->set_source_rgba(1, 0.2, 0.2, 0.6);
  cr->move_to(x0, y0);
  cr->line_to (x1, y1);
  cr->move_to(x2, y2);
  cr->line_to (x3, y3);
  cr->stroke();
}

Jediný rozdíl mezi tímto příkladem a příkladem s rovnými čárami je ve funkci on_draw(), ale je zde uvedeno pár nových konceptů a funkcí, tak si je pojďme ve stručnosti vysvětlit.

Voláme metodu Cairo::Context::scale() a předáváme jí šířku a výšku kreslicí oblasti. Tím se přepočítá systém souřadnic v uživatelském prostoru, jako by tato šířka a výška widgetu byly obojí rovny 1,0 „jednotek“. K tomuto systému přepočítání není žádný konkrétní důvod, ale občas to může kreslení zjednodušit.

Volání metody Cairo::Context::curve_to() by mělo být pochopitelné na pohled. První pár souřadnic definuje řídící bod pro začátek křivky. Druhá sada souřadnic definuje řídící bod pro konec křivky a poslední sada souřadnic definuje cílový bod. Abyste si dokázali koncept řídících bodů snáze vizuálně představit, nakreslí se čára z obou řídících bodů do příslušných koncových bodů křivky. Tyto pomocné čáry jsou průsvitné, čehož se dosáhne zavoláním metody set_source_rgba(), která je jen rozšířenou variantou set_source_rgb(). Přebírá navíc čtvrtý argument určující alfakanál barvy (platné hodnoty jsou mezi 0 a 1).