如何使用cairo确定Gtk + 3中的非矩形绘图区域?

时间:2012-12-29 00:04:19

标签: c gtk cairo gtk3 inkscape

Gtk+ 3 migration guide显示了如何使用GdkEventExpose.region字段为重新呈现小部件提供细粒度区域。我们已经在Inkscape中做了类似的事情,以避免在绘图画布上渲染过多的复杂内容。

但是,指南中的示例显示了如何为旧的Gtk + 2 expose_event处理程序执行此操作。

如何在新的Gtk + 3绘制处理程序中执行等效操作,该处理程序接收“预先剪切”的Cairo上下文作为参数,而不是GdkEventExpose

我猜一种可能性是在“预先剪切”的cairo上下文中使用cairo_copy_clip_rectangle_list来获取构成要绘制区域的矩形列表。有没有人有使用它的经验?这似乎是一种明智的做法吗?

2 个答案:

答案 0 :(得分:1)

是的,你应该在你的widget的:: draw()信号处理程序中使用的cairo_t上使用cairo_copy_clip_rectangle_list()。请参阅此提交以获取示例: http://git.gnome.org/browse/vte/commit/?id=21a064ac8b5925108b0ab9bd6516664c8cd3e268

答案 1 :(得分:0)

由于我没有太多线索,我决定检查源代码。 GDK在窗口上发出GDK_EXPOSE事件,并为此创建GdkEventExpose实例。

然后通过gtk_widget_send_expose()

在gtk / gtkmain.c中处理此事件

http://git.gnome.org/browse/gtk+/tree/gtk/gtkwidget.c?id=eecb9607a5c0ee38eadb446545beccd0922cb0b8#n6104

此功能会将cairo_t剪切为GdkEventExpose.region,就像您在文档中学到的一样。

然后调用发出实际绘制信号的_gtk_widget_draw_internal()

http://git.gnome.org/browse/gtk+/tree/gtk/gtkwidget.c?id=eecb9607a5c0ee38eadb446545beccd0922cb0b8#n5726

据我所知,这里没有任何东西让你直接访问剪辑区域。在gtk_widget_send_expose()中,GdkEvent作为用户数据添加到cairo上下文中。但是,这是不可访问的,因为所有涉及的函数和变量都是静态的。因此,您必须使用cairo_copy_clip_rectangle_list()

然而,这听起来非常无穷无尽。首先gdk_cairo_region将区域转换为对cairo_rectangle的多个调用,然后cairo将其从内部表示转换为cairo_rectangle_list_t(如果剪辑由于某种原因,可能会失败一个地区)。如果你看到这个很慢,那么直接添加到gtk就可以有一些快捷方式。