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

问题描述 投票:1回答:1

这是关于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. 获得与我的小部件等效的表面。

但它失败了。这个: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
c++ gtk cairo gtkmm
1个回答
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);

由于表面不用于任何东西,因此它的尺寸无关紧要。

(附注:根据谷歌给我的API文档,Context的构造函数想要一个cairo_t*作为参数,而不是Cairo::Context*;这可能解释你所看到的崩溃)

© www.soinside.com 2019 - 2024. All rights reserved.