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

时间:2018-02-17 16:30:18

标签: c++ gtk cairo gtkmm

这是对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 allocation{get_allocation()};

    const int width{allocation.get_width()};
    const int height{allocation.get_height()};
    const int smallestDimension{std::min(width, height)};

    const int xCenter{width / 2};
    const int yCenter{height / 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模拟来执行检查。我不需要绘制任何东西来执行我的检查,我只需要获得基础路径并对其进行处理。

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

  1. nullptr作为Cairo::Surface传递(当然失败了);
  2. 获得与我的小部件相同的表面。
  3. 但它失败了。这个:gdk_window_create_similar_surface看起来很有希望,但我找不到小部件的等价物。

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

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

    bool isTheBorderASimpleAndClosedCurve()
    {
        const Gtk::Allocation allocation{get_allocation()};
    
        Glib::RefPtr<Gdk::Window> widgetWindow{get_window()};
    
        Cairo::RefPtr<Cairo::Surface> widgetSurface{widgetWindow->create_similar_surface(Cairo::Content::CONTENT_COLOR_ALPHA,
                                                                                         allocation.get_width(),                                                                            allocation.get_height()) };
    
        Cairo::Context nakedContext{cairo_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 个答案:

答案 0 :(得分: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*;这可能解释了您的崩溃正在看见)