GNOME Bugzilla – Bug 155317
"point" method for canvas text items is totally broken
Last modified: 2006-11-22 12:24:52 UTC
The code for gnome_canvas_text_point() in gnome-canvas-text.c is totally broken. It "works" only be accident, since in most environments (i.e. unless your canvas is big) a bogus large rectangle is checked for point. Consider the code in the pango_layout_get_iter loop. First the case where text->clip is true: x1 = PANGO_PIXELS (log_rect.x); y1 = PANGO_PIXELS (log_rect.y); x2 = PANGO_PIXELS (log_rect.x+log_rect.width); y2 = PANGO_PIXELS (log_rect.y+log_rect.height); It then proceeds to intersect this rectangle with the clip rectangle (text->clip_cx etc). But the latter are absolute canvas coordinates, but the pango coordinates are relative to the text item's reference point so the above should probably read: x1 = text->cx + PANGO_PIXELS (log_rect.x); y1 = text->cy + PANGO_PIXELS (log_rect.y); ... The non-clip case is even more broken: x1 = text->x; y1 = text->y; x2 = log_rect.width; y2 = log_rect.height; It then proceeds to compare this values with cx and cy, resp., which are absolute canvas coordinates. Now text->x is in world coordinates, and also relative to the containing item group's reference point. On the other hand, log_rect.width is in pango units (which are several orders of magnitude large than canvas, i.e. pixel, units). I think a correct computation should look like this: do { PangoRectangle log_rect; pango_layout_iter_get_line_extents (iter, NULL, &log_rect); x1 = text->cx + PANGO_PIXELS (log_rect.x); y1 = text->cy + PANGO_PIXELS (log_rect.y); x2 = text->cx + PANGO_PIXELS (log_rect.x+log_rect.width); y2 = text->cy + PANGO_PIXELS (log_rect.y+log_rect.height); if (text->clip) { if (x1 < text->clip_cx) x1 = text->clip_cx; if (y1 < text->clip_cy) y1 = text->clip_cy; if (x2 > (text->clip_cx + text->clip_width)) x2 = text->clip_cx + text->clip_width; if (y2 > (text->clip_cy + text->clip_height)) y2 = text->clip_cy + text->clip_height; if ((x1 >= x2) || (y1 >= y2)) continue; } /* Calculate distance from point to rectangle */ ...
Created attachment 32638 [details] test program (uses gtk/gnome Perl binding) Start program in terminal so that you can watch its stdout; scoll to the bottom of the canvas (using scrollbar); move mouse into "bot" item while watching terminal, see the enter/motion/leave events reported that are generated for this item; try the same with the "foo" item: no events are reported.
Roderich, do you have an idea to implement your proposed behaviour?
What do you mean: how to reproduce the bug or how to fix it? For the latter, see attached patch.
Created attachment 76451 [details] [review] suggested patch
2006-11-22 Sven Herzberg <herzi@gnome-de.org> * libgnomecanvas/gnome-canvas-text.c: improved the calculation of the bounding box. Fixes bug #155317 (Based on a patch from Roderich Schupp)