static void gimp_projection_idle_render_init (GimpProjection *proj) { GSList *list; /* We need to merge the IdleRender's and the GimpProjection's update_areas * list to keep track of which of the updates have been flushed and hence * need to be drawn. */ for (list = proj->update_areas; list; list = g_slist_next (list)) { GimpArea *area = list->data; proj->idle_render.update_areas = gimp_area_list_process (proj->idle_render.update_areas, gimp_area_new (area->x1, area->y1, area->x2, area->y2)); } /* If an idlerender was already running, merge the remainder of its * unrendered area with the update_areas list, and make it start work * on the next unrendered area in the list. */ if (proj->idle_render.idle_id) { GimpArea *area = gimp_area_new (proj->idle_render.base_x, proj->idle_render.y, proj->idle_render.base_x + proj->idle_render.width, proj->idle_render.y + (proj->idle_render.height - (proj->idle_render.y - proj->idle_render.base_y))); proj->idle_render.update_areas = gimp_area_list_process (proj->idle_render.update_areas, area); gimp_projection_idle_render_next_area (proj); } else { if (proj->idle_render.update_areas == NULL) { g_warning ("%s: wanted to start idle render with no update_areas", G_STRFUNC); return; } gimp_projection_idle_render_next_area (proj); proj->idle_render.idle_id = g_idle_add_full (GIMP_PROJECTION_IDLE_PRIORITY, gimp_projection_idle_render_callback, proj, NULL); } }
static void gimp_projection_add_update_area (GimpProjection *proj, gint x, gint y, gint w, gint h) { GimpArea *area; gint off_x, off_y; gint width, height; gimp_projectable_get_offset (proj->projectable, &off_x, &off_y); gimp_projectable_get_size (proj->projectable, &width, &height); /* subtract the projectable's offsets because the list of update * areas is in tile-pyramid coordinates, but our external API is * always in terms of image coordinates. */ x -= off_x; y -= off_y; area = gimp_area_new (CLAMP (x, 0, width), CLAMP (y, 0, height), CLAMP (x + w, 0, width), CLAMP (y + h, 0, height)); proj->update_areas = gimp_area_list_process (proj->update_areas, area); }
void gimp_display_update_area (GimpDisplay *display, gboolean now, gint x, gint y, gint w, gint h) { g_return_if_fail (GIMP_IS_DISPLAY (display)); if (now) { gimp_display_paint_area (display, x, y, w, h); } else { GimpArea *area = gimp_area_new (CLAMP (x, 0, display->image->width), CLAMP (y, 0, display->image->height), CLAMP (x + w, 0, display->image->width), CLAMP (y + h, 0, display->image->height)); display->update_areas = gimp_area_list_process (display->update_areas, area); } }