获取模拟 Cairo::Context 以测试路径上的条件
Get a mock Cairo::Context to test conditions on the path
这是 的跟进,我在其中询问了有关检查在 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);
}
我想用这个方法检查我在边界曲线上的情况,如:
中所建议
So, you would somehow get a cairo context (cairo_t
in C), create your shape there (with line_to
, curve_to
, arc
etc). Then you do not call fill
or stroke
, but instead cairo_copy_path_flat
.
到目前为止,我无法获得可用的 Cairo::Context
模拟来执行检查。我不需要绘制任何东西来执行我的检查,我只需要获取底层路径并对其进行处理。
到目前为止,我已经尝试过:
- 将
nullptr
作为 Cairo::Surface
传递(当然失败了);
- 获得与我的小部件等效的表面。
但是失败了。这: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
只需创建大小为 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*
;这可能解释了您所看到的崩溃)
这是 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);
}
我想用这个方法检查我在边界曲线上的情况,如
So, you would somehow get a cairo context (
cairo_t
in C), create your shape there (withline_to
,curve_to
,arc
etc). Then you do not callfill
orstroke
, but insteadcairo_copy_path_flat
.
到目前为止,我无法获得可用的 Cairo::Context
模拟来执行检查。我不需要绘制任何东西来执行我的检查,我只需要获取底层路径并对其进行处理。
到目前为止,我已经尝试过:
- 将
nullptr
作为Cairo::Surface
传递(当然失败了); - 获得与我的小部件等效的表面。
但是失败了。这: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
只需创建大小为 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*
;这可能解释了您所看到的崩溃)