tags:

views:

178

answers:

3

Using Cairo, I'm placing some text at random positions, and I need to know if they overlap some previously drawn arbitrary shapes. I could clip the path to the previous drawings, and if any clipping occurs it means that there is overlap. However, Cairo doesn't seem to have any functions to tell if clipping did occur or not.

Is there any way to easily accomplish what I want? I guess I just basically want to see if two shapes intersect or not.

+2  A: 

I don't see anything - at least, nothing simple - and I wouldn't be surprised if there weren't anything. Cairo is aimed at rasterizing vector drawing operations, not intersection testing.

However, if I were going to see if two pieces of text overlapped, here's what I would do:

  1. Pick a Cairo backend suitable to my test environment - e.g. Xlib, etc. - and use an offscreen surface that I can use to do a pixel-by-pixel analysis.
  2. Draw the first piece of text in solid blue with 100% alpha.
  3. Draw the second piece of text in solid red with 50% alpha.
  4. Scan the surface for pixels where both red and blue are non-zero.

It's rather brute force, but it will even cope with anti-aliasing. I've done something like that before (for a different purpose) with GTK on X, which indirectly uses Cairo.

If you don't want to do it that way, and Cairo doesn't provide an API, you might be able to add one. That would probably be difficult; you might want to talk with Carl Worth before doing that.

Bob Murphy
Well, there is a lot of intersection checking code in Cairo, that's what clipping is all about, right? The code is definitely there, it's just not exposed to users. I'm going to go with a raster-based work-around like you suggest, but it does still seem a bit silly.Oh, and Cairo is not just aimed at rasterization, it outputs vector formats just fine too. I'd say Cairo is a vector-based drawing library, and having to go via raster-images to accomplish some simple things seems a bit silly.
pafcu
pafcu, I agree that the raster image route is inelegant. But depending on requirements, sometimes a workable-but-inelegant solution is preferable, if it's faster to implement. I occasionally need to dispose of hard drives and need to make sure that sensitive data they've contained cannot be read. The elegant-but-time consuming approach is a 7x or 35x rewrite with random data. Instead, I just take them to my concrete patio and hit them a few times with a sledge hammer or pickaxe.
Bob Murphy
+1  A: 

I solved the problem by using Qt for the rendering instead. It seems to have quite extensive support for different path operations and supports both PDF and SVG output.

pafcu
+4  A: 

Depending on the quality you want to get, you can use cairo_stroke_extents, cairo_fill_extents and cairo_text_extents and work on the boundary boxes.

A better approach would be to compute only the boundary box of the text and check the four corners against the last path with cairo_in_fill or cairo_in_stroke. The maximum error would be the distance from the shape of a single glyph to its bounding box but maybe this is enough for your purpose.

The last option would be to flatten the text and check any single point as in the previous step.

ntd