开罗绘制模型

开罗的基本概念包括定义'不可见'路径然后描绘(stroking)或者填充(filling)它们使其可见。

要在gtkmm中使用开罗进行绘制,必须先获取Cairo::Context对象。这个类保存了所有描述如何进行绘制的图形状态参数。状态参数包含了诸如线宽、颜色、要绘制的表面和许多其他内容的信息。这允许实际上的绘图函数只需要使用较少的参数从而简化接口。通常你使用set_draw_func()设置的绘图函数将Cairo::Context作为输入数据。也可以通过调用Gdk::Surface::create_cairo_context()Gdk::CairoContext::cairo_create()函数创建一个Cairo::Context。由于Cairo::Context是一个使用引用计数的对象,因此cairo_create()返回Cairo::RefPtr<Cairo::Context>对象(请注意区分Gdk::CairoContextCairo::Context。)。

以下示例显示如何设置一个开罗上下文(Cairo Context)的前景色为红色且宽度为2。任何使用该上下文的绘图函数都将使用这些设置。

Gtk::DrawingArea myArea;
auto gdkCairoContext = myArea.get_surface()->create_cairo_context();
auto myContext = gdkCairoContext->cairo_create();
myContext->set_source_rgb(1.0, 0.0, 0.0);
myContext->set_line_width(2.0);
    

每一个Cairo::Context都有一个特定的Gdk::Surface与之相关联,因此上面示例的第一行创建了一个Gtk::DrawingArea部件,接下来两行使用与其相关联的Gdk::Surface创建一个Cairo::Context对象。最后两行更改上下文的图形状态。

可以为开罗上下文设置许多的图形状态。最常见的上下文属性是颜色(使用set_source_rgb()或需要半透明颜色的时候用set_source_rgba())、线宽(使用set_line_width())、虚线模式(使用set_dash())、线帽样式(使用set_line_cap())、线条连接样式(使用set_line_join())以及字体样式(使用set_font_size())。还有许多其他设置,例如变换矩阵、填充规则、是否执行抗锯齿规则等。更多详情请参阅cairommAPI文档。

可以将Cairo::Context当前的状态保存到其内部用于保存状态的栈中,并在之后将状态还原为保存时的状态。要做到这个请调用save()restore()方法。当你需要临时更改某些图形设置(例如线宽和颜色)以绘制某些内容然后又退回到之前的状态时这将很有用。在这种情况下,你可以先调用Cairo::Context::save(),然后修改图形设置并绘制图形,再调用Cairo::Context::restore()恢复之前的图形状态。你可以多次嵌套调用save()restore();每次restore()调用都会将恢复状态到与之相对应的save()所保存的状态。

好的做法是在一组save()/restore()调用之间进行所有对图形状态的更改。例如,如果你有一个将Cairo::Context的引用作为参数的函数,你可以这样实现它:

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

你通过调用set_draw_func()所设置的绘图函数是由你要绘制的Gtk::DrawingArea部件用开罗上下文调用的。所以你不需要在绘图函数中对此开罗上下文进行保存和恢复(部件会在调用绘图函数时做保存与恢复)。