app/display: draw the crop highlight using cairo

Instead of dimming the actual pixels, apply a translucent fill to
the area outside the highlight rectangle.
This commit is contained in:
Sven Neumann
2010-09-28 22:04:07 +02:00
parent ccee0ec41a
commit eb5bb6363e
5 changed files with 70 additions and 123 deletions

View File

@ -2293,9 +2293,9 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
image_rect.height); image_rect.height);
cairo_restore (cr); cairo_restore (cr);
gdk_region_get_rectangles (image_region, &rects, &n_rects);
cairo_save (cr); cairo_save (cr);
gdk_region_get_rectangles (image_region, &rects, &n_rects);
for (i = 0; i < n_rects; i++) for (i = 0; i < n_rects; i++)
gimp_display_shell_draw_area (shell, cr, gimp_display_shell_draw_area (shell, cr,
@ -2304,9 +2304,19 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
rects[i].width, rects[i].width,
rects[i].height); rects[i].height);
g_free (rects);
cairo_restore (cr); cairo_restore (cr);
g_free (rects); if (shell->highlight)
{
cairo_save (cr);
gimp_display_shell_draw_highlight (shell, cr,
image_rect.x,
image_rect.y,
image_rect.width,
image_rect.height);
cairo_restore (cr);
}
} }
gdk_region_destroy (image_region); gdk_region_destroy (image_region);

View File

@ -707,7 +707,6 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
gint w, gint w,
gint h) gint h)
{ {
GdkRectangle rect;
gint x2, y2; gint x2, y2;
gint i, j; gint i, j;
@ -718,14 +717,6 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
x2 = x + w; x2 = x + w;
y2 = y + h; y2 = y + h;
if (shell->highlight)
{
rect.x = ceil (shell->scale_x * shell->highlight->x);
rect.y = ceil (shell->scale_y * shell->highlight->y);
rect.width = floor (shell->scale_x * shell->highlight->width);
rect.height = floor (shell->scale_y * shell->highlight->height);
}
/* display the image in RENDER_BUF_WIDTH x RENDER_BUF_HEIGHT /* display the image in RENDER_BUF_WIDTH x RENDER_BUF_HEIGHT
* sized chunks * sized chunks
*/ */
@ -746,8 +737,7 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
gimp_display_shell_render (shell, cr, gimp_display_shell_render (shell, cr,
j - disp_xoffset, j - disp_xoffset,
i - disp_yoffset, i - disp_yoffset,
dx, dy, dx, dy);
shell->highlight ? &rect : NULL);
} }
} }
} }
@ -792,7 +782,36 @@ gimp_display_shell_draw_checkerboard (GimpDisplayShell *shell,
cairo_rectangle (cr, x, y, w, h); cairo_rectangle (cr, x, y, w, h);
cairo_clip (cr); cairo_clip (cr);
cairo_translate (cr, - shell->offset_x, - shell->offset_y); cairo_translate (cr, - shell->offset_x, - shell->offset_y);
cairo_set_source (cr, shell->checkerboard); cairo_set_source (cr, shell->checkerboard);
cairo_paint (cr); cairo_paint (cr);
} }
void
gimp_display_shell_draw_highlight (GimpDisplayShell *shell,
cairo_t *cr,
gint x,
gint y,
gint w,
gint h)
{
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (shell->highlight != NULL);
g_return_if_fail (cr != NULL);
cairo_rectangle (cr, x, y, w, h);
cairo_translate (cr, - shell->offset_x, - shell->offset_y);
cairo_scale (cr, shell->scale_x, shell->scale_y);
cairo_rectangle (cr,
shell->highlight->x, shell->highlight->y,
shell->highlight->width, shell->highlight->height);
cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
cairo_clip (cr);
/* FIXME: make this configurable or at least use gimpdisplayshell-style.c */
cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
cairo_paint (cr);
}

View File

@ -77,6 +77,12 @@ void gimp_display_shell_draw_checkerboard (GimpDisplayShell *shell,
gint y, gint y,
gint w, gint w,
gint h); gint h);
void gimp_display_shell_draw_highlight (GimpDisplayShell *shell,
cairo_t *cr,
gint x,
gint y,
gint w,
gint h);
#endif /* __GIMP_DISPLAY_SHELL_DRAW_H__ */ #endif /* __GIMP_DISPLAY_SHELL_DRAW_H__ */

View File

@ -135,13 +135,6 @@ static void render_image_gray_a (RenderInfo *info);
static const guchar * render_image_tile_fault (RenderInfo *info); static const guchar * render_image_tile_fault (RenderInfo *info);
static void gimp_display_shell_render_highlight (GimpDisplayShell *shell,
RenderInfo *info,
gint x,
gint y,
gint w,
gint h,
const GdkRectangle *highlight);
static void gimp_display_shell_render_mask (GimpDisplayShell *shell, static void gimp_display_shell_render_mask (GimpDisplayShell *shell,
RenderInfo *info); RenderInfo *info);
@ -159,8 +152,7 @@ gimp_display_shell_render (GimpDisplayShell *shell,
gint x, gint x,
gint y, gint y,
gint w, gint w,
gint h, gint h)
const GdkRectangle *highlight)
{ {
GimpProjection *projection; GimpProjection *projection;
GimpImage *image; GimpImage *image;
@ -245,12 +237,7 @@ gimp_display_shell_render (GimpDisplayShell *shell,
#endif #endif
#if 0 #if 0
/* dim pixels outside the highlighted rectangle */ if (shell->mask)
if (highlight)
{
gimp_display_shell_render_highlight (shell, &info, x, y, w, h, highlight);
}
else if (shell->mask)
{ {
TileManager *tiles = gimp_drawable_get_tiles (shell->mask); TileManager *tiles = gimp_drawable_get_tiles (shell->mask);
@ -288,80 +275,6 @@ gimp_display_shell_render (GimpDisplayShell *shell,
#define CAIRO_RGB24_BLUE_PIXEL 3 #define CAIRO_RGB24_BLUE_PIXEL 3
#endif #endif
#define GIMP_DISPLAY_SHELL_DIM_PIXEL(buf,x) \
{ \
buf[4 * (x) + CAIRO_RGB24_RED_PIXEL] >>= 1; \
buf[4 * (x) + CAIRO_RGB24_GREEN_PIXEL] >>= 1; \
buf[4 * (x) + CAIRO_RGB24_BLUE_PIXEL] >>= 1; \
}
/* This function highlights the given area by dimming all pixels outside. */
static void
gimp_display_shell_render_highlight (GimpDisplayShell *shell,
RenderInfo *info,
gint x,
gint y,
gint w,
gint h,
const GdkRectangle *highlight)
{
guchar *buf = cairo_image_surface_get_data (shell->render_surface);
GdkRectangle rect;
gint offset_x;
gint offset_y;
gimp_display_shell_scroll_get_render_start_offset (shell,
&offset_x, &offset_y);
rect.x = x + offset_x;
rect.y = y + offset_y;
rect.width = w;
rect.height = h;
if (gdk_rectangle_intersect (highlight, &rect, &rect))
{
rect.x -= x + offset_x;
rect.y -= y + offset_y;
for (y = 0; y < rect.y; y++)
{
for (x = 0; x < w; x++)
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
buf += info->dest_bpl;
}
for ( ; y < rect.y + rect.height; y++)
{
for (x = 0; x < rect.x; x++)
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
for (x += rect.width; x < w; x++)
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
buf += info->dest_bpl;
}
for ( ; y < h; y++)
{
for (x = 0; x < w; x++)
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
buf += info->dest_bpl;
}
}
else
{
for (y = 0; y < h; y++)
{
for (x = 0; x < w; x++)
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
buf += info->dest_bpl;
}
}
}
static void static void
gimp_display_shell_render_mask (GimpDisplayShell *shell, gimp_display_shell_render_mask (GimpDisplayShell *shell,

View File

@ -31,8 +31,7 @@ void gimp_display_shell_render (GimpDisplayShell *shell,
gint x, gint x,
gint y, gint y,
gint w, gint w,
gint h, gint h);
const GdkRectangle *highlight);
#endif /* __GIMP_DISPLAY_SHELL_RENDER_H__ */ #endif /* __GIMP_DISPLAY_SHELL_RENDER_H__ */