app/display/gimpdisplayshell-render.c renamed overlay to mask and added a

2005-07-30  Sven Neumann  <sven@gimp.org>

	* app/display/gimpdisplayshell-render.c
	* app/display/gimpdisplayshell.[ch]: renamed overlay to mask and
	added a different overlay implementation that will be needed to
	finish the new foreground-select tool.

	* app/tools/gimpforegroundselecttool.c: changed accordingly.
This commit is contained in:
Sven Neumann 2005-07-30 22:29:02 +00:00 committed by Sven Neumann
parent 7e92212593
commit d53a10c004
5 changed files with 211 additions and 66 deletions

View File

@ -1,3 +1,12 @@
2005-07-30 Sven Neumann <sven@gimp.org>
* app/display/gimpdisplayshell-render.c
* app/display/gimpdisplayshell.[ch]: renamed overlay to mask and
added a different overlay implementation that will be needed to
finish the new foreground-select tool.
* app/tools/gimpforegroundselecttool.c: changed accordingly.
2005-07-30 Sven Neumann <sven@gimp.org> 2005-07-30 Sven Neumann <sven@gimp.org>
* app/tools/gimptoolcontrol.[ch]: transparently handle cursor * app/tools/gimptoolcontrol.[ch]: transparently handle cursor

View File

@ -62,8 +62,8 @@ struct _RenderInfo
gint w, h; gint w, h;
gdouble scalex; gdouble scalex;
gdouble scaley; gdouble scaley;
gint src_x, src_y; gint src_x;
gint src_bpp; gint src_y;
gint dest_bpp; gint dest_bpp;
gint dest_bpl; gint dest_bpl;
gint dest_width; gint dest_width;
@ -162,12 +162,18 @@ static void render_image_gray_a (RenderInfo *info);
static void render_image_indexed (RenderInfo *info); static void render_image_indexed (RenderInfo *info);
static void render_image_indexed_a (RenderInfo *info); static void render_image_indexed_a (RenderInfo *info);
static void render_image_init_info (RenderInfo *info, static void render_image_init_info_full (RenderInfo *info,
GimpDisplayShell *shell, GimpDisplayShell *shell,
gint x, gint x,
gint y, gint y,
gint w, gint w,
gint h); gint h,
GimpProjection *projection);
static void render_image_init_info (RenderInfo *info,
GimpDisplayShell *shell,
gint x,
gint y,
TileManager *tiles);
static guint * render_image_init_alpha (gint mult); static guint * render_image_init_alpha (gint mult);
static guchar * render_image_accelerate_scaling (gint width, static guchar * render_image_accelerate_scaling (gint width,
gint start, gint start,
@ -192,8 +198,11 @@ static void gimp_display_shell_render_highlight (GimpDisplayShell *shell,
gint w, gint w,
gint h, gint h,
GdkRectangle *highlight); GdkRectangle *highlight);
static void gimp_display_shell_render_overlay (GimpDisplayShell *shell, static void gimp_display_shell_render_mask (GimpDisplayShell *shell,
RenderInfo *info); RenderInfo *info);
static void gimp_display_shell_render_overlay (GimpDisplayShell *shell,
RenderInfo *info,
const guchar *color);
/*****************************************************************/ /*****************************************************************/
@ -211,16 +220,17 @@ gimp_display_shell_render (GimpDisplayShell *shell,
gint h, gint h,
GdkRectangle *highlight) GdkRectangle *highlight)
{ {
RenderInfo info; GimpProjection *projection;
GimpImageType type; RenderInfo info;
GimpImageType type;
g_return_if_fail (w > 0 && h > 0); g_return_if_fail (w > 0 && h > 0);
render_image_init_info (&info, shell, x, y, w, h); projection = shell->gdisp->gimage->projection;
type = gimp_projection_get_image_type (shell->gdisp->gimage->projection); render_image_init_info_full (&info, shell, x, y, w, h, projection);
g_return_if_fail ((info.dest_bpp >= 1) && (info.dest_bpp <= 4)); type = gimp_projection_get_image_type (projection);
/* Currently, only RGBA and GRAYA projection types are used - the rest /* Currently, only RGBA and GRAYA projection types are used - the rest
* are in case of future need. -- austin, 28th Nov 1998. * are in case of future need. -- austin, 28th Nov 1998.
@ -243,17 +253,24 @@ gimp_display_shell_render (GimpDisplayShell *shell,
{ {
gimp_display_shell_render_highlight (shell, x, y, w, h, highlight); gimp_display_shell_render_highlight (shell, x, y, w, h, highlight);
} }
else if (shell->overlay) else
{ {
info.src_tiles = gimp_drawable_data (shell->overlay); if (shell->mask)
info.src_bpp = 1; {
info.x = x + shell->offset_x; render_image_init_info (&info, shell, x, y,
info.y = y + shell->offset_y; gimp_drawable_data (shell->mask));
info.src_x = (gdouble) info.x / info.scalex;
info.src_y = (gdouble) info.y / info.scaley;
info.dest = shell->render_buf;
gimp_display_shell_render_overlay (shell, &info); gimp_display_shell_render_mask (shell, &info);
}
if (shell->overlay)
{
render_image_init_info (&info, shell, x, y,
gimp_drawable_data (shell->overlay));
gimp_display_shell_render_overlay (shell, &info,
shell->overlay_color);
}
} }
/* put it to the screen */ /* put it to the screen */
@ -336,8 +353,8 @@ gimp_display_shell_render_highlight (GimpDisplayShell *shell,
} }
static void static void
gimp_display_shell_render_overlay (GimpDisplayShell *shell, gimp_display_shell_render_mask (GimpDisplayShell *shell,
RenderInfo *info) RenderInfo *info)
{ {
gint y, ye; gint y, ye;
gint x, xe; gint x, xe;
@ -392,6 +409,64 @@ gimp_display_shell_render_overlay (GimpDisplayShell *shell,
} }
} }
static void
gimp_display_shell_render_overlay (GimpDisplayShell *shell,
RenderInfo *info,
const guchar *color)
{
gint y, ye;
gint x, xe;
gboolean initial = TRUE;
y = info->y;
ye = info->y + info->h;
xe = info->x + info->w;
info->src = render_image_tile_fault (info);
while (TRUE)
{
gint error =
RINT (floor ((y + 1) / info->scaley) - floor (y / info->scaley));
if (!initial && (error == 0))
{
memcpy (info->dest, info->dest - info->dest_bpl, info->dest_width);
}
else
{
const guchar *src = info->src;
guchar *dest = info->dest;
for (x = info->x; x < xe; x++, src++, dest += 3)
{
if (*src & 0x80)
{
dest[0] = color[0];
dest[1] = color[1];
dest[2] = color[2];
}
}
}
if (++y == ye)
break;
info->dest += info->dest_bpl;
if (error)
{
info->src_y += error;
info->src = render_image_tile_fault (info);
initial = TRUE;
}
else
{
initial = FALSE;
}
}
}
/*************************/ /*************************/
/* 8 Bit functions */ /* 8 Bit functions */
@ -463,14 +538,11 @@ static void
render_image_indexed_a (RenderInfo *info) render_image_indexed_a (RenderInfo *info)
{ {
const guint *alpha = info->alpha; const guint *alpha = info->alpha;
const guchar *cmap; const guchar *cmap = gimp_image_get_colormap (info->shell->gdisp->gimage);
gint y, ye; gint y, ye;
gint x, xe; gint x, xe;
gboolean initial = TRUE; gboolean initial = TRUE;
cmap = gimp_image_get_colormap (info->shell->gdisp->gimage);
alpha = info->alpha;
y = info->y; y = info->y;
ye = info->y + info->h; ye = info->y + info->h;
xe = info->x + info->w; xe = info->x + info->w;
@ -800,41 +872,51 @@ render_image_rgb_a (RenderInfo *info)
} }
static void static void
render_image_init_info (RenderInfo *info, render_image_init_info_full (RenderInfo *info,
GimpDisplayShell *shell, GimpDisplayShell *shell,
gint x, gint x,
gint y, gint y,
gint w, gint w,
gint h) gint h,
GimpProjection *projection)
{ {
GimpImage *gimage = shell->gdisp->gimage;
info->shell = shell; info->shell = shell;
info->src_tiles = gimp_projection_get_tiles (gimage->projection);
info->src_bpp = gimp_projection_get_bytes (gimage->projection);
info->x = x + shell->offset_x;
info->y = y + shell->offset_y;
info->w = w; info->w = w;
info->h = h; info->h = h;
info->scalex = SCALEFACTOR_X (shell); info->scalex = SCALEFACTOR_X (shell);
info->scaley = SCALEFACTOR_Y (shell); info->scaley = SCALEFACTOR_Y (shell);
info->src_x = (gdouble) info->x / info->scalex;
info->src_y = (gdouble) info->y / info->scaley;
info->dest = shell->render_buf;
info->dest_bpp = 3; info->dest_bpp = 3;
info->dest_bpl = info->dest_bpp * GIMP_RENDER_BUF_WIDTH; info->dest_bpl = info->dest_bpp * GIMP_RENDER_BUF_WIDTH;
info->dest_width = info->w * info->dest_bpp; info->dest_width = info->dest_bpp * info->w;
info->scale = render_image_accelerate_scaling (w,
info->x, info->scalex);
info->alpha = NULL;
if (GIMP_IMAGE_TYPE_HAS_ALPHA (gimp_projection_get_image_type (gimage->projection))) render_image_init_info (info, shell, x, y,
gimp_projection_get_tiles (projection));
info->scale = render_image_accelerate_scaling (w, info->x, info->scalex);
if (GIMP_IMAGE_TYPE_HAS_ALPHA (gimp_projection_get_image_type (projection)))
{ {
info->alpha = gdouble opacity = gimp_projection_get_opacity (projection);
render_image_init_alpha (gimp_projection_get_opacity (gimage->projection) * 255.999);
info->alpha = render_image_init_alpha (opacity * 255.999);
} }
} }
static void
render_image_init_info (RenderInfo *info,
GimpDisplayShell *shell,
gint x,
gint y,
TileManager *tiles)
{
info->src_tiles = tiles;
info->x = x + shell->offset_x;
info->y = y + shell->offset_y;
info->src_x = (gdouble) info->x / info->scalex;
info->src_y = (gdouble) info->y / info->scaley;
info->dest = shell->render_buf;
}
static guint * static guint *
render_image_init_alpha (gint mult) render_image_init_alpha (gint mult)
{ {
@ -887,7 +969,7 @@ render_image_tile_fault (RenderInfo *info)
gint width; gint width;
gint tilex; gint tilex;
gint step; gint step;
gint bpp = info->src_bpp; gint bpp;
gint x; gint x;
tile = tile_manager_get_tile (info->src_tiles, tile = tile_manager_get_tile (info->src_tiles,
@ -898,6 +980,8 @@ render_image_tile_fault (RenderInfo *info)
src = tile_data_pointer (tile, src = tile_data_pointer (tile,
info->src_x % TILE_WIDTH, info->src_x % TILE_WIDTH,
info->src_y % TILE_HEIGHT); info->src_y % TILE_HEIGHT);
bpp = tile_manager_bpp (info->src_tiles);
scale = info->scale; scale = info->scale;
dest = tile_buf; dest = tile_buf;

View File

@ -23,6 +23,7 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h" #include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h"
#include "libgimpconfig/gimpconfig.h" #include "libgimpconfig/gimpconfig.h"
#include "libgimpwidgets/gimpwidgets.h" #include "libgimpwidgets/gimpwidgets.h"
@ -318,6 +319,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->button_press_before_focus = FALSE; shell->button_press_before_focus = FALSE;
shell->highlight = NULL; shell->highlight = NULL;
shell->mask = NULL;
shell->overlay = NULL; shell->overlay = NULL;
gtk_window_set_role (GTK_WINDOW (shell), "gimp-image-window"); gtk_window_set_role (GTK_WINDOW (shell), "gimp-image-window");
@ -408,6 +410,12 @@ gimp_display_shell_destroy (GtkObject *object)
shell->highlight = NULL; shell->highlight = NULL;
} }
if (shell->mask)
{
g_object_unref (shell->mask);
shell->mask = NULL;
}
if (shell->overlay) if (shell->overlay)
{ {
g_object_unref (shell->overlay); g_object_unref (shell->overlay);
@ -1595,31 +1603,71 @@ gimp_display_shell_set_highlight (GimpDisplayShell *shell,
} }
/** /**
* gimp_display_shell_set_overlay: * gimp_display_shell_set_mask:
* @shell: a #GimpDisplayShell * @shell: a #GimpDisplayShell
* @mask: a #GimpDrawable (1 byte per pixel) * @mask: a #GimpDrawable (1 byte per pixel)
* *
* Allows to preview a selection (used by the foreground selection tool). * Allows to preview a selection (used by the foreground selection
* tool). Pixels that are not selected (> 127) in the mask are tinted
* with dark blue.
**/ **/
void void
gimp_display_shell_set_overlay (GimpDisplayShell *shell, gimp_display_shell_set_mask (GimpDisplayShell *shell,
GimpDrawable *mask) GimpDrawable *mask)
{ {
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (mask == NULL || GIMP_IS_DRAWABLE (mask)); g_return_if_fail (mask == NULL ||
(GIMP_IS_DRAWABLE (mask) && gimp_drawable_bytes (mask) == 1));
if (shell->overlay) if (shell->mask == mask)
{ return;
g_object_unref (shell->overlay);
shell->overlay = NULL;
}
if (mask) if (mask)
{ g_object_ref (mask);
g_return_if_fail (gimp_drawable_bytes (mask) == 1);
shell->overlay = g_object_ref (mask); if (shell->mask)
} g_object_unref (shell->mask);
shell->mask = mask;
gimp_display_shell_expose_full (shell);
}
/**
* gimp_display_shell_set_overlay:
* @shell: a #GimpDisplayShell
* @mask: a #GimpDrawable (1 byte per pixel)
* @color: the color to use for the overlay (or %NULL to not change color)
*
* Allows to mark areas in a given color (used by the foreground
* selection tool). Pixels that are selected (> 127) in the mask are
* drawn in the given color.
**/
void
gimp_display_shell_set_overlay (GimpDisplayShell *shell,
GimpDrawable *mask,
const GimpRGB *color)
{
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (mask == NULL ||
(GIMP_IS_DRAWABLE (mask) && gimp_drawable_bytes (mask) == 1));
if (shell->overlay == mask && ! color)
return;
if (color)
gimp_rgb_get_uchar (color,
shell->overlay_color + 0,
shell->overlay_color + 1,
shell->overlay_color + 2);
if (mask)
g_object_ref (mask);
if (shell->overlay)
g_object_unref (shell->overlay);
shell->overlay = mask;
gimp_display_shell_expose_full (shell); gimp_display_shell_expose_full (shell);
} }

View File

@ -166,7 +166,9 @@ struct _GimpDisplayShell
GdkRectangle *highlight; /* in image coordinates, can be NULL */ GdkRectangle *highlight; /* in image coordinates, can be NULL */
GimpDrawable *mask;
GimpDrawable *overlay; GimpDrawable *overlay;
guchar overlay_color[3];
gpointer scroll_info; gpointer scroll_info;
}; };
@ -237,8 +239,10 @@ void gimp_display_shell_selection_visibility (GimpDisplayShell *shell,
GimpSelectionControl control); GimpSelectionControl control);
void gimp_display_shell_set_highlight (GimpDisplayShell *shell, void gimp_display_shell_set_highlight (GimpDisplayShell *shell,
const GdkRectangle *highlight); const GdkRectangle *highlight);
void gimp_display_shell_set_mask (GimpDisplayShell *shell,
GimpDrawable *mask);
void gimp_display_shell_set_overlay (GimpDisplayShell *shell, void gimp_display_shell_set_overlay (GimpDisplayShell *shell,
GimpDrawable *overlay); GimpDrawable *mask,
const GimpRGB *color);
#endif /* __GIMP_DISPLAY_SHELL_H__ */ #endif /* __GIMP_DISPLAY_SHELL_H__ */

View File

@ -421,8 +421,8 @@ gimp_foreground_select_tool_set_mask (GimpForegroundSelectTool *fg_select,
if (mask) if (mask)
fg_select->mask = g_object_ref (mask); fg_select->mask = g_object_ref (mask);
gimp_display_shell_set_overlay (GIMP_DISPLAY_SHELL (gdisp->shell), gimp_display_shell_set_mask (GIMP_DISPLAY_SHELL (gdisp->shell),
GIMP_DRAWABLE (mask)); GIMP_DRAWABLE (mask));
gimp_tool_control_set_toggle (GIMP_TOOL (fg_select)->control, mask != NULL); gimp_tool_control_set_toggle (GIMP_TOOL (fg_select)->control, mask != NULL);
} }