[Cairo] mouse pointer and cairo
Bill Spitzak
spitzak at d2.com
Sun Oct 12 18:47:07 PDT 2003
On Saturday 11 October 2003 11:31 am, Carl Worth wrote:
> We'll have to decide our own semantics for these operations.
> PostScript returns true if the pixel containing the given point would
> be painted by stroke or fill. But that may or may not be the
> definition we want when doing anti-aliased graphics. The other obvious
> choice would be to compute geometrically correct containment without
> reference to the device pixel grid.
> I'd be glad for some guidance from those with relevant user-interface
> design experience.
=== Hit area device ===
OpenGL does hit detection by a different mechanism. In Cairo terms it would
be a special drawing surface, which is a 1x1 pixel that stores a number. The
program selects this special drawing surface, and then scales and transforms
so the "hit area" (a small square around the mouse cursor) is projected to
fill this 1x1 area. There is also a call that is pretty much "set the number
to put in there", this number acts a lot like the current color. When you
draw anything to this surface it does normal drawing, but if the pixel would
change, it instead records the current number in a list. You can get all the
numbers back with another call. You can make the detection area a shape other
than a rectangle by setting a clipping path to that shape before drawing.
The main advantage of this is that you get hit detection with little or no
extra work once you have code that can draw objects.
The big disadvantage of this is that it does not detect which object was
closest to the mouse. For opaque objects that are thicker than 1 pixel it
works great. For points and lines my program has to iterate through all the
objects and do it's own calculation to figure out which one is closest to the
mouse.
Perhaps though this can be used in Cairo, with these extra changes:
1. Make the "number" reliably hold a void* pointer, not just an integer.
2. Return how opaque the object is. Programs can use this to decide if the
user was clicking through an almost-transparent window on the foreground
object. More importantly, transparent areas of images and letters can return
but the program can skip them if it wants.
3. Somehow return a distance value. This should be the distance between the
center of the pixel from the nearest line or vertex (squared to avoid the
need for sqrt). Make it negative if the pixel is inside the a filled shape.
=== the "in_fill" call ===
If you do this, I would definately use the geometrically correct solution
where it returns whether an inifintely small point at x,y is in the region.
Actually I would return a distance value, like above. This is the distance
squared to the nearest line or point, negated if the point is inside the
shape. It is ok if curves are decomposed into straight lines before the
calculation is done.
Is x and y transformed by the current transformation? Probably it should be,
but then we must be able to push the transform, draw a path, pop the
transform back, and then do the test. Alternatively there could be a call
that is "remember the x,y now", this may be good for testing against many
objects, and starts to look like the hit area desgn.
Does this return false if x and y are inside the path but outside the clip
region? I'm not sure.
> The PostScript versions of these operators also allow the user to test
> for intersection with an arbitrary region instead of a point, (the
> region is specified as a userpath). This might be another reason to
> expose a cairo_path_t object.
This could be done by clipping to one path, then building another, and then
having a call that returns true if the resulting path is non-empty.
--
,~,~,~,~ ~ ~ ~ ~
/\_ _|_========___ Bill Spitzak
~~~/\/\\~~~~~~\____________/~~~~~~~~ spitzak at d2.com
More information about the cairo
mailing list