获取模拟 Cairo::Context 以测试路径上的条件

Posted

技术标签:

【中文标题】获取模拟 Cairo::Context 以测试路径上的条件【英文标题】:Get a mock Cairo::Context to test conditions on the path 【发布时间】:2018-02-17 16:30:17 【问题描述】:

这是对this post 的跟进,我在其中询问了在Gtk::DrawingArea 派生小部件中检查使用 Cairomm 绘制的形状边界上的某些条件。在我的例子中,我有一个 void drawBorder(const Cairo::RefPtr<Cairo::Context>& p_context) 方法,它是虚拟的并且被覆盖以指定形状的边框。例如,如果我想要一个圆圈,我可以提供以下实现:

void drawBorder(const Cairo::RefPtr<Cairo::Context>& p_context)

    const Gtk::Allocation allocationget_allocation();

    const int widthallocation.get_width();
    const int heightallocation.get_height();
    const int smallestDimensionstd::min(width, height);

    const int xCenterwidth / 2;
    const int yCenterheight / 2;

    p_context->arc(xCenter,
                   yCenter,
                   smallestDimension / 2.5,
                   0.0,
                   2.0 * M_PI);

我想用这个方法来检查我在边界曲线上的情况,正如the answer中所建议的那样:

所以,你会以某种方式获得一个 cairo 上下文(C 中的cairo_t),在那里创建你的形状(使用line_tocurve_toarc 等)。那你就不用fillstroke了,而是cairo_copy_path_flat

到目前为止,我无法获得可用的 Cairo::Context 模拟来执行检查。我不需要绘制任何东西来执行我的检查,我只需要获取底层路径并对其进行处理。

到目前为止,我已经尝试过:

    nullptr 传递为Cairo::Surface(当然失败了); 获得与我的小部件等效的表面。

但它失败了。这个:gdk_window_create_similar_surface 看起来很有希望,但我还没有找到小部件的等价物。

如何获得一个最小的模拟上下文来执行此类检查?这对我以后的单元测试也很有帮助。


到目前为止,我得到了这个代码:

bool isTheBorderASimpleAndClosedCurve()

    const Gtk::Allocation allocationget_allocation();

    Glib::RefPtr<Gdk::Window> widgetWindowget_window();

    Cairo::RefPtr<Cairo::Surface> widgetSurfacewidgetWindow->create_similar_surface(Cairo::Content::CONTENT_COLOR_ALPHA,
                                                                                     allocation.get_width(),                                                                            allocation.get_height()) ;

    Cairo::Context nakedContextcairo_create(widgetSurface->cobj());
    const Cairo::RefPtr<Cairo::Context> context&nakedContext;

    drawBorder(context);

    // Would like to get the path and test my condition here...!

它编译并链接,但在运行时我收到一条带有此消息的段错误和一堆垃圾:

double free or corruption (out): 0x00007ffc0401c740

【问题讨论】:

【参考方案1】:

只需创建一个大小为 0x0 的 cairo 图像表面并为此创建一个上下文。

Cairo::RefPtr<Cairo::Surface> surface = Cairo::ImageSurface::create(
    Cairo::Format::FORMAT_ARGB32, 0, 0);
Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create(surface);

由于表面不用于任何用途,因此它的大小无关紧要。

(旁注:根据 Google 给我的 API 文档,Context 的构造函数需要 cairo_t* 作为参数,而不是 Cairo::Context*;这可能解释了您所看到的崩溃)

【讨论】:

但是有一个大小为 0x0 的表面是什么意思?如果我决定在其上创建一个形状(例如,arc),即使表面只是一个点,也会考虑它吗? 是的。您不使用此表面进行绘图,只是为了您可以调用cairo_copy_path_flat 注意,第一行有一个小错字:Cairo::ImageSurface 是正确的命名空间。 谢谢,我修好了

以上是关于获取模拟 Cairo::Context 以测试路径上的条件的主要内容,如果未能解决你的问题,请参考以下文章

找不到'cairo.Context'的外来struct转换器

如何在 Gtkmm DrawingArea 中绘制 cairo_surface_t

Gtk+:如何从 Cairo 上下文中设置窗口的光标?

如何从模拟路径加载模拟文件

如何在 Spring Boot 中模拟数据库连接以进行测试?

5.2 模拟测试86