sx107
sx107

Reputation: 309

cairo_push_group analog in Qt: "clear" composition mode clears everything underneath it

I am writing an app using QPainter and I need an analog of the cairo_push_group in the QPainter class to draw, say, a rectangle with bunch of holes in it, which may intersect.

The problem is that when I draw holes with the "clear" compose mode, everything is cleared underneath the holes I draw; I want the image, that was underneath the hole before I started drawing my complex shape, to stay. In other words - everything underneath the hole is cleared, when I just want everything underneath the hole to bee seen through.

One solution seems to be using the QPainterPath with Odd fill option (the default one), but that does not suit me, as in my app the holes may intersect, and this way the two holes won't combine (the intersection of two holes is not a hole).

One more solution is to just to use the QPainterPath::subtracted method, but for some reason it reduces the quality of polygons (circles become shapes with a countable number of sides, for example).

The other solution is to save the QImage I am drawing on to a temporary QImage, clear it, draw everything that I need and then using the "destination over" mode draw it again, but that seems to be a very slow and memory-consuming solution.

Is there any other solution to this problem? Maybe there IS an analog of the cairo_push_group function in Qt?

Please don't advice me to switch to cairo.
Pictures explain the problem better: Pictures

Upvotes: 1

Views: 257

Answers (1)

sx107
sx107

Reputation: 309

I've found anwser myself. One way one can do it is to still use the QPainterPath += and -= operators (which are identical to the QPainterPath::united and QPainterPath::subtracted methods), but without any bezier curves. I've replaced all the arcs, circles, etc. with "polylines" (for example, every circle is replaced with a 100-sided polygon). You can achieve any quality you need just by changing the number of sides etc.

The other solution - with the temporary QImage - seems to be not too slow and works just okay. This is the way it is done in cairo also. Just create a QImage with the same size asthe original, a QPainter with the same settings as the original one and use the new QPainter to draw on the temporary image, and, finally, use the QPainter::drawImage method to draw everything on the original device.

Upvotes: 1

Related Questions