[cairo] in_fill hit test and matrix transforms
Donn
donn.ingle at gmail.com
Wed Nov 21 08:46:29 PST 2007
Hi again, been a while. I'm still hacking away on my wee project and have
stumbled onto something that I'm not sure is expected behaviour. Sample code
at end.
Some context:
1. Kubuntu Gutsy (7.10)
2. Standard python-gnome install, I have not built cairo or anything from
source.
3. libcairo2 Version: 1.4.10-1ubuntu4
4. python-cairo Version: 1.4.0-2ubuntu1
5. Python 2.5
Okay, basically when stuff is drawn and not filled (in order to copy the path)
under the influence of a transform, it seems to ignore the transform and draw
at absolute coordinates.
I want to test mouse x,y over a shape drawn by cairo and I have moved that
shape to 50,50. I draw the shape at 0,0 but transform it to 50,50. After that
I draw the same shape, under the same transform, but sans fill and copy the
path so I can do a in_fill ( ) test but it "draws" the shape at 0,0.
The sample code should run. If you click around the top-left corner you'll
see True hits (printed on console). If you click where the red shape is, they
are all False.
So, I dunno if this is expected or (most likely) I am missing the point, but
it's something I'll have to code around somehow.
Any ideas?
/d
import pygtk
import gtk, gobject, cairo
from gtk import gdk
class Screen(gtk.DrawingArea):
__gsignals__ = { "expose-event": "override" }
def __init__(self):
super(Screen,self).__init__()
self.connect("button_press_event", self.button_press)
self.add_events(gdk.BUTTON_PRESS_MASK |
gdk.BUTTON_RELEASE_MASK |
gdk.POINTER_MOTION_MASK)
def do_expose_event(self, event):
cr = self.window.cairo_create()
self.cr = cr
self.draw(cr, *self.window.get_size())
def run(Widget):
window = gtk.Window()
window.connect("delete-event", gtk.main_quit)
widget = Widget()
widget.show()
window.add(widget)
window.present()
gtk.main()
class Shapes(Screen):
def matrixstart ( self, cr ):
cr.save()
matrix = cairo.Matrix(1,0,0,1, 150,150)
cairo.Matrix.rotate( matrix, 3 )
cr.transform ( matrix )
def matrixend ( self, cr ):
cr.restore ( )
def cairocommands ( self, cr ):
x = y = 10
sx = sy = 50
cr.move_to(x,y)
cr.line_to(x+sx,y)
cr.line_to(x+sx,y+sy)
cr.line_to(x+(sx/2),y+sy)
cr.line_to(x+(sx/2),y+(sy/2))
cr.line_to(x,y+(sy/2))
cr.line_to(x,y+sy)
cr.line_to(x-sx,y+sy)
cr.close_path()
cr.set_source_rgb(1,0,0)
def draw(self, cr, width, height):
#Use a matrix to change the shape's position and rotation.
self.matrixstart ( cr )
self.cairocommands ( cr )
cr.fill()
self.matrixend ( cr )
def button_press(self,widget,event):
cr = self.cr
#Exact same matrix, no effect
self.matrixstart ( cr )
self.cairocommands ( cr )
result = cr.in_fill( event.x, event.y )
print result
self.matrixend ( cr )
run(Shapes)
More information about the cairo
mailing list