[cairo] Cairo with GTK GUI integration, getting inverse transformation matrix

Johannes Bauer dfnsonfsduifb at gmx.de
Mon Jan 18 15:05:31 PST 2016

On 18.01.2016 22:04, Johannes Bauer wrote:

> (right now I'm neither panning nor do I handle partial redraws efficiently).

So I kindof seem to have solved my problem, now I have a different one :-(

I noticed the cairo_ctx matrix is pre-set to accomodate for the window
(i.e. already has the correct panning displacement accounted for). So
it's unwise to just overwrite it (messes up the coordinate system).

Therefore, I'm doing this now. In my constructor, I do:

initial_zoom = 1.0
origin = (0, 0)
self._zoom_pan_matrix = cairo.Matrix(xx = initial_zoom, yy =
initial_zoom, x0 = origin[0], y0 = origin[1])

Then, in the draw() handler, I do:

for obj in self._objects:

When i get screen coordinates, I convert them to logical coordinates:

self._inverse_zoom_pan_matrix = cairo.Matrix(*self._zoom_pan_matrix)
(x, y) = self._inverse_zoom_pan_matrix.transform_point(screen_x, screen_y)

This seems to work nicely. I can also do zooming around the mouse cursor
this way  (zooming works as you would "naturally" expect it to work):

def _zoom(self, screen_x, screen_y, factor):
	(x, y) = self.to_logical_coordinates(screen_x, screen_y)
	self._zoom_pan_matrix.translate(x, y)
	self._zoom_pan_matrix.scale(factor, factor)
	self._zoom_pan_matrix.translate(-x, -y)

However, once I do that, the coordinate translation is all messed up
(i.e. the inverse matrix does conversion around the "zoom point"
correctly, but it gets linearly worse with the distance to the zoom point).

This is so much more complicated than I had thought it would be. Maybe
I'm just tired, but could someone show me the light in this mess? I
haven't even started with panning and already my head is spinning :-(

Hope you guys can help me.
Best regards,

More information about the cairo mailing list