this is a follow up on this post, in which I asked about checking some condition on the border of a shape drawn using Cairomm in a Gtk::DrawingArea
derived widget. In my case, I have a void drawBorder(const Cairo::RefPtr<Cairo::Context>& p_context)
method which is virtual and is overriden to specify the shape's border. For example, if I wanted a circle, I could provide the following implementation:
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);
}
I would like to use this method to check my condition on the border curve, as suggested in the answer:
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
.
So far, I am unable to get a usable Cairo::Context
mock to perform the check. I don't need to draw anything to perform my check, I only need to get the underlying path and work on it.
So far, I have tried:
nullptr
as the Cairo::Surface
(which of course failed);But it failed. This: gdk_window_create_similar_surface
looked promising, but I have not found an equivalent for widgets.
How could one go about getting a minimal mock context to perform such checks? This would also help me very much in my unit testing, later on.
So far I got this code:
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...!
}
It compiles and links, but at runtime I get a segfault with this message and a bunch of garbage:
double free or corruption (out): 0x00007ffc0401c740
Just create a cairo image surface with size 0x0 and create a context for that.
Cairo::RefPtr<Cairo::Surface> surface = Cairo::ImageSurface::create(
Cairo::Format::FORMAT_ARGB32, 0, 0);
Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create(surface);
Since the surface is not used for anything, it does not matter which size it has.
(Side note: According to the API docs that Google gave me, the constructor of Context
wants a cairo_t*
as argument, not a Cairo::Context*
; this might explain the crash that you are seeing)