app: preserve projection priority rect across structure/bounds changes
In GimpProjection, store the priority rect in image coordinates, and only convert it to projectable coordinates when initializing the chunk-iterator's priority rect. This allows us to preserve the priority rect across projectable structure/bounds changes.
This commit is contained in:
@ -135,6 +135,7 @@ static void gimp_projection_add_update_area (GimpProjection *proj,
|
|||||||
static void gimp_projection_flush_whenever (GimpProjection *proj,
|
static void gimp_projection_flush_whenever (GimpProjection *proj,
|
||||||
gboolean now,
|
gboolean now,
|
||||||
gboolean direct);
|
gboolean direct);
|
||||||
|
static void gimp_projection_update_priority_rect (GimpProjection *proj);
|
||||||
static void gimp_projection_chunk_render_start (GimpProjection *proj);
|
static void gimp_projection_chunk_render_start (GimpProjection *proj);
|
||||||
static void gimp_projection_chunk_render_stop (GimpProjection *proj,
|
static void gimp_projection_chunk_render_stop (GimpProjection *proj,
|
||||||
gboolean merge);
|
gboolean merge);
|
||||||
@ -505,30 +506,11 @@ gimp_projection_set_priority_rect (GimpProjection *proj,
|
|||||||
gint w,
|
gint w,
|
||||||
gint h)
|
gint h)
|
||||||
{
|
{
|
||||||
gint off_x, off_y;
|
|
||||||
gint width, height;
|
|
||||||
|
|
||||||
g_return_if_fail (GIMP_IS_PROJECTION (proj));
|
g_return_if_fail (GIMP_IS_PROJECTION (proj));
|
||||||
|
|
||||||
gimp_projectable_get_offset (proj->priv->projectable, &off_x, &off_y);
|
proj->priv->priority_rect = *GEGL_RECTANGLE (x, y, w, h);
|
||||||
gimp_projectable_get_size (proj->priv->projectable, &width, &height);
|
|
||||||
|
|
||||||
/* subtract the projectable's offsets because the list of update
|
gimp_projection_update_priority_rect (proj);
|
||||||
* areas is in tile-pyramid coordinates, but our external API is
|
|
||||||
* always in terms of image coordinates.
|
|
||||||
*/
|
|
||||||
x -= off_x;
|
|
||||||
y -= off_y;
|
|
||||||
|
|
||||||
gegl_rectangle_intersect (&proj->priv->priority_rect,
|
|
||||||
GEGL_RECTANGLE (x, y, w, h),
|
|
||||||
GEGL_RECTANGLE (0, 0, width, height));
|
|
||||||
|
|
||||||
if (proj->priv->iter)
|
|
||||||
{
|
|
||||||
gimp_chunk_iterator_set_priority_rect (proj->priv->iter,
|
|
||||||
&proj->priv->priority_rect);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -707,6 +689,35 @@ gimp_projection_flush_whenever (GimpProjection *proj,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_projection_update_priority_rect (GimpProjection *proj)
|
||||||
|
{
|
||||||
|
if (proj->priv->iter)
|
||||||
|
{
|
||||||
|
GeglRectangle rect;
|
||||||
|
gint off_x, off_y;
|
||||||
|
gint width, height;
|
||||||
|
|
||||||
|
rect = proj->priv->priority_rect;
|
||||||
|
|
||||||
|
gimp_projectable_get_offset (proj->priv->projectable, &off_x, &off_y);
|
||||||
|
gimp_projectable_get_size (proj->priv->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.
|
||||||
|
*/
|
||||||
|
rect.x -= off_x;
|
||||||
|
rect.y -= off_y;
|
||||||
|
|
||||||
|
gegl_rectangle_intersect (&rect,
|
||||||
|
&rect,
|
||||||
|
GEGL_RECTANGLE (0, 0, width, height));
|
||||||
|
|
||||||
|
gimp_chunk_iterator_set_priority_rect (proj->priv->iter, &rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_projection_chunk_render_start (GimpProjection *proj)
|
gimp_projection_chunk_render_start (GimpProjection *proj)
|
||||||
{
|
{
|
||||||
@ -736,8 +747,7 @@ gimp_projection_chunk_render_start (GimpProjection *proj)
|
|||||||
{
|
{
|
||||||
proj->priv->iter = gimp_chunk_iterator_new (region);
|
proj->priv->iter = gimp_chunk_iterator_new (region);
|
||||||
|
|
||||||
gimp_chunk_iterator_set_priority_rect (proj->priv->iter,
|
gimp_projection_update_priority_rect (proj);
|
||||||
&proj->priv->priority_rect);
|
|
||||||
|
|
||||||
if (! proj->priv->idle_id)
|
if (! proj->priv->idle_id)
|
||||||
{
|
{
|
||||||
@ -955,11 +965,6 @@ gimp_projection_projectable_structure_changed (GimpProjectable *projectable,
|
|||||||
gimp_projectable_get_size (projectable, &width, &height);
|
gimp_projectable_get_size (projectable, &width, &height);
|
||||||
|
|
||||||
gimp_projection_add_update_area (proj, 0, 0, width, height);
|
gimp_projection_add_update_area (proj, 0, 0, width, height);
|
||||||
|
|
||||||
proj->priv->priority_rect.x = 0;
|
|
||||||
proj->priv->priority_rect.y = 0;
|
|
||||||
proj->priv->priority_rect.width = width;
|
|
||||||
proj->priv->priority_rect.height = height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1054,25 +1059,6 @@ gimp_projection_projectable_bounds_changed (GimpProjectable *projectable,
|
|||||||
cairo_region_intersect_rectangle (proj->priv->update_region, &bounds);
|
cairo_region_intersect_rectangle (proj->priv->update_region, &bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proj->priv->priority_rect.width > 0 &&
|
|
||||||
proj->priv->priority_rect.height > 0)
|
|
||||||
{
|
|
||||||
proj->priv->priority_rect.x += dx;
|
|
||||||
proj->priv->priority_rect.y += dy;
|
|
||||||
|
|
||||||
gimp_rectangle_intersect (proj->priv->priority_rect.x,
|
|
||||||
proj->priv->priority_rect.y,
|
|
||||||
proj->priv->priority_rect.width,
|
|
||||||
proj->priv->priority_rect.height,
|
|
||||||
|
|
||||||
0, 0, w, h,
|
|
||||||
|
|
||||||
&proj->priv->priority_rect.x,
|
|
||||||
&proj->priv->priority_rect.y,
|
|
||||||
&proj->priv->priority_rect.width,
|
|
||||||
&proj->priv->priority_rect.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dx > 0)
|
if (dx > 0)
|
||||||
gimp_projection_add_update_area (proj, 0, 0, dx, h);
|
gimp_projection_add_update_area (proj, 0, 0, dx, h);
|
||||||
if (dy > 0)
|
if (dy > 0)
|
||||||
|
Reference in New Issue
Block a user