开罗:抓取整幅画作图案

Cairo: grabbing the whole drawing as a pattern

我可能遗漏了一些关于 cairo 的概念性内容。我使用以下助手 class:

进行绘制
struct GroupLock {
    GroupLock(Graphics &g) : g_(g) {
        cairo_push_group(g_.cr);
    }

    ~GroupLock() {
        cairo_pop_group_to_source(g_.cr);
        cairo_paint(g_.cr);
        cairo_surface_flush(g_.surface);
        XFlush(g_.display);
    }
private:
    Graphics &g_;
};

我所有的绘图函数都是以下形式:

void drawSomething(Graphics &g) {
    GroupLock lock{g}; (void)lock;
    ... // some drawing
}

每次调用这样的绘图函数都会设置 source(通过使用 GroupLock)并使之前的 source 无法到达。如何将此代码修改为 "concatenate" 而不是 sources?我希望能够通过以下方式将整个绘图作为一个模式来抓取:

cairo_pattern_t *p_ = cairo_get_source(g_.cr);
cairo_pattern_reference(p_);

经过几个小时的努力,终于到了!所有需要做的就是将构造函数修改为如下所示:

p_ = cairo_get_source(g_.cr);
cairo_pattern_reference(p_);

cairo_push_group(g_.cr);
cairo_set_source (g_.cr, p_);
cairo_paint(g_.cr);
cairo_pattern_destroy(p_);

对于未来想知道的人,我认为 "correct" 方法的函数是 cairo_push_group and cairo_pop_group which will create a new group and allow one to draw to it, and then subsequently get the drawing result as a pattern, which can then be set as a source. Cairo provides a convenience function for the latter in the form of cairo_pop_group_to_source,它弹出组并将其设置为源,以及执行内存为您管理。