mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-18 09:00:34 +00:00
quartz: correct deficiencies in the gdk_draw_drawable() implementation
The call to scrollRect: must be accompanied by a call to redraw the newly exposed area, otherwise the scrollRect: will have no effect. Secondly, compute the newly exposed area correctly. Thirdly, also expose the lower window border or the area moved from the lower window border if applicable, to make sure rounded corners are properly drawn or don't leave garbage.
This commit is contained in:
parent
4d01c56d89
commit
e982461ad6
@ -361,15 +361,90 @@ gdk_quartz_draw_drawable (GdkDrawable *drawable,
|
||||
{
|
||||
NSRect rect = NSMakeRect (xsrc, ysrc, width, height);
|
||||
NSSize offset = NSMakeSize (xdest - xsrc, ydest - ysrc);
|
||||
GdkRectangle tmp_rect;
|
||||
GdkRegion *orig_region, *offset_region, *need_display_region;
|
||||
GdkWindow *window = GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper;
|
||||
|
||||
[window_impl->view scrollRect:rect by:offset];
|
||||
/* Origin region */
|
||||
tmp_rect.x = xsrc;
|
||||
tmp_rect.y = ysrc;
|
||||
tmp_rect.width = width;
|
||||
tmp_rect.height = height;
|
||||
orig_region = gdk_region_rectangle (&tmp_rect);
|
||||
|
||||
/* The scrollRect only "takes effect" on the next redraw, we must
|
||||
* set that the offset rectangle needs display.
|
||||
*/
|
||||
rect.origin.x += offset.width;
|
||||
rect.origin.y += offset.height;
|
||||
[window_impl->view setNeedsDisplayInRect:rect];
|
||||
/* Destination region (or the offset region) */
|
||||
offset_region = gdk_region_copy (orig_region);
|
||||
gdk_region_offset (offset_region, offset.width, offset.height);
|
||||
|
||||
need_display_region = gdk_region_copy (orig_region);
|
||||
|
||||
if (window_impl->in_paint_rect_count == 0)
|
||||
{
|
||||
GdkRegion *bottom_border_region;
|
||||
|
||||
/* If we are not in drawRect:, we can use scrollRect:.
|
||||
* We apply scrollRect on the rectangle to be moved and
|
||||
* subtract this area from the rectangle that needs display.
|
||||
*
|
||||
* Note: any area in this moved region that already needed
|
||||
* display will be handled by GDK (queue translation).
|
||||
*
|
||||
* Queuing the redraw below is important, otherwise the
|
||||
* results from scrollRect will not take effect!
|
||||
*/
|
||||
[window_impl->view scrollRect:rect by:offset];
|
||||
|
||||
gdk_region_subtract (need_display_region, offset_region);
|
||||
|
||||
/* Here we take special care with the bottom window border,
|
||||
* which extents 4 pixels and typically draws rounded corners.
|
||||
*/
|
||||
tmp_rect.x = 0;
|
||||
tmp_rect.y = gdk_window_get_height (window) - 4;
|
||||
tmp_rect.width = gdk_window_get_width (window);
|
||||
tmp_rect.height = 4;
|
||||
|
||||
if (gdk_region_rect_in (offset_region, &tmp_rect) !=
|
||||
GDK_OVERLAP_RECTANGLE_OUT)
|
||||
{
|
||||
/* We are copying pixels to the bottom border, we need
|
||||
* to submit this area for redisplay to get the rounded
|
||||
* corners drawn.
|
||||
*/
|
||||
gdk_region_union_with_rect (need_display_region,
|
||||
&tmp_rect);
|
||||
}
|
||||
|
||||
/* Compute whether the bottom border is moved elsewhere.
|
||||
* Because this part will have rounded corners, we have
|
||||
* to fill the contents of where the rounded corners used
|
||||
* to be. We post this area for redisplay.
|
||||
*/
|
||||
bottom_border_region = gdk_region_rectangle (&tmp_rect);
|
||||
gdk_region_intersect (bottom_border_region,
|
||||
orig_region);
|
||||
|
||||
gdk_region_offset (bottom_border_region,
|
||||
offset.width, offset.height);
|
||||
|
||||
gdk_region_union (need_display_region, bottom_border_region);
|
||||
|
||||
gdk_region_destroy (bottom_border_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we cannot handle things with a scroll, we must redisplay
|
||||
* the union of the source area and the destination area.
|
||||
*/
|
||||
gdk_region_union (need_display_region, offset_region);
|
||||
}
|
||||
|
||||
_gdk_quartz_window_set_needs_display_in_region (window,
|
||||
need_display_region);
|
||||
|
||||
gdk_region_destroy (orig_region);
|
||||
gdk_region_destroy (offset_region);
|
||||
gdk_region_destroy (need_display_region);
|
||||
}
|
||||
else
|
||||
g_warning ("Drawing with window source != dest is not supported");
|
||||
|
Loading…
Reference in New Issue
Block a user