added new function gimp_preview_area_fill().

2004-07-31  Sven Neumann  <sven@gimp.org>

	* libgimpwidgets/gimppreviewarea.[ch]: added new function
	gimp_preview_area_fill().

	* libgimpwidgets/test-preview-area.c: added a test for new function.

	* libgimp/gimpbrushmenu.c: ported to GimpPreviewArea.
This commit is contained in:
Sven Neumann
2004-07-31 01:03:00 +00:00
committed by Sven Neumann
parent 3069689b48
commit 96b9987210
7 changed files with 225 additions and 95 deletions

View File

@ -1,3 +1,12 @@
2004-07-31 Sven Neumann <sven@gimp.org>
* libgimpwidgets/gimppreviewarea.[ch]: added new function
gimp_preview_area_fill().
* libgimpwidgets/test-preview-area.c: added a test for new function.
* libgimp/gimpbrushmenu.c: ported to GimpPreviewArea.
2004-07-31 DindinX <david@dindinx.org>
* plug-ins/common/depthmerge.c: use a GimpPreviewArea instead of a

View File

@ -775,6 +775,7 @@ GIMP_PICK_BUTTON_GET_CLASS
GimpPreviewArea
gimp_preview_area_new
gimp_preview_area_draw
gimp_preview_area_fill
gimp_preview_area_set_cmap
<SUBSECTION Standard>
GimpPreviewAreaClass

View File

@ -45,6 +45,21 @@ GimpPreviewArea
@image_type:
<!-- ##### FUNCTION gimp_preview_area_fill ##### -->
<para>
</para>
@area:
@x:
@y:
@width:
@height:
@red:
@green:
@blue:
<!-- ##### FUNCTION gimp_preview_area_set_cmap ##### -->
<para>

View File

@ -24,11 +24,6 @@
#include <string.h>
#ifdef __GNUC__
#warning GTK_DISABLE_DEPRECATED
#endif
#undef GTK_DISABLE_DEPRECATED
#include "gimp.h"
#include "gimpui.h"
@ -86,6 +81,7 @@ static void gimp_brush_select_preview_update (GtkWidget *preview,
gint brush_width,
gint brush_height,
const guchar *mask_data);
static void gimp_brush_select_preview_resize (BrushSelect *brush_sel);
static void gimp_brush_select_popup_open (BrushSelect *brush_sel,
gint x,
gint y);
@ -144,16 +140,19 @@ gimp_brush_select_widget_new (const gchar *title,
gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
brush_sel->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
brush_sel->preview = gimp_preview_area_new ();
gtk_widget_set_events (brush_sel->preview,
GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_BUTTON1_MOTION_MASK);
gtk_preview_size (GTK_PREVIEW (brush_sel->preview), CELL_SIZE, CELL_SIZE);
gtk_widget_set_size_request (brush_sel->preview, CELL_SIZE, CELL_SIZE);
gtk_container_add (GTK_CONTAINER (frame), brush_sel->preview);
gtk_widget_show (brush_sel->preview);
g_signal_connect_swapped (brush_sel->preview, "size_allocate",
G_CALLBACK (gimp_brush_select_preview_resize),
brush_sel);
g_signal_connect (brush_sel->preview, "event",
G_CALLBACK (gimp_brush_select_preview_events),
brush_sel);
@ -184,11 +183,6 @@ gimp_brush_select_widget_new (const gchar *title,
brush_sel->opacity = (opacity == -1.0) ? init_opacity : opacity;
brush_sel->spacing = (spacing == -1) ? init_spacing : spacing;
brush_sel->paint_mode = (paint_mode == -1) ? init_paint_mode : paint_mode;
gimp_brush_select_preview_update (brush_sel->preview,
brush_sel->width,
brush_sel->height,
brush_sel->mask_data);
}
g_object_set_data (G_OBJECT (hbox), BRUSH_SELECT_DATA_KEY, brush_sel);
@ -365,6 +359,18 @@ gimp_brush_select_widget_destroy (GtkWidget *widget,
}
static void
gimp_brush_select_preview_resize (BrushSelect *brush_sel)
{
if (brush_sel->width > 0 && brush_sel->height > 0)
gimp_brush_select_preview_update (brush_sel->preview,
brush_sel->width,
brush_sel->height,
brush_sel->mask_data);
}
static gboolean
gimp_brush_select_preview_events (GtkWidget *widget,
GdkEvent *event,
@ -404,59 +410,65 @@ gimp_brush_select_preview_events (GtkWidget *widget,
return FALSE;
}
static void
gimp_brush_select_preview_draw (GimpPreviewArea *area,
gint x,
gint y,
gint width,
gint height,
const guchar *mask_data)
{
const guchar *src;
guchar *dest;
guchar *buf;
guint pixels = width * height;
buf = g_new (guchar, pixels);
src = mask_data;
dest = buf;
while (pixels--)
{
*dest = 255 - *src;
src++;
dest++;
}
gimp_preview_area_draw (area,
x, y, width, height,
GIMP_GRAY_IMAGE,
buf,
width);
g_free (buf);
}
static void
gimp_brush_select_preview_update (GtkWidget *preview,
gint brush_width,
gint brush_height,
const guchar *mask_data)
{
guchar *buf;
guchar *b;
const guchar *src;
const guchar *s;
gint i, y;
gint offset_x, offset_y;
gint ystart, yend;
gint width, height;
GimpPreviewArea *area = GIMP_PREVIEW_AREA (preview);
gint x, y;
gint width, height;
/* Draw the brush */
buf = g_new (guchar, CELL_SIZE);
width = MIN (brush_width, preview->allocation.width);
height = MIN (brush_height, preview->allocation.height);
/* Set buffer to white */
memset (buf, 255, CELL_SIZE);
for (i = 0; i < CELL_SIZE; i++)
gtk_preview_draw_row (GTK_PREVIEW (preview),
buf, 0, i, CELL_SIZE);
x = ((preview->allocation.width - width) / 2);
y = ((preview->allocation.height - height) / 2);
/* Limit to cell size */
width = (brush_width > CELL_SIZE) ? CELL_SIZE: brush_width;
height = (brush_height > CELL_SIZE) ? CELL_SIZE: brush_height;
if (x || y)
gimp_preview_area_fill (area,
0, 0,
preview->allocation.width,
preview->allocation.height,
0xFF, 0xFF, 0xFF);
offset_x = ((CELL_SIZE - width) / 2);
offset_y = ((CELL_SIZE - height) / 2);
ystart = CLAMP (offset_y, 0, CELL_SIZE);
yend = CLAMP (offset_y + height, 0, CELL_SIZE);
src = mask_data;
for (y = ystart; y < yend; y++)
{
gint j;
s = src;
b = buf;
for (j = 0; j < width ; j++)
*b++ = 255 - *s++;
gtk_preview_draw_row (GTK_PREVIEW (preview),
buf, offset_x, y, width);
src += brush_width;
}
g_free (buf);
gtk_widget_queue_draw (preview);
gimp_brush_select_preview_draw (area, x, y, width, height, mask_data);
}
static void
@ -466,13 +478,9 @@ gimp_brush_select_popup_open (BrushSelect *brush_sel,
{
GtkWidget *frame;
GtkWidget *preview;
const guchar *src;
const guchar *s;
guchar *buf;
guchar *b;
GdkScreen *screen;
gint x_org;
gint y_org;
GdkScreen *screen;
gint scr_w;
gint scr_h;
@ -489,9 +497,8 @@ gimp_brush_select_popup_open (BrushSelect *brush_sel,
gtk_container_add (GTK_CONTAINER (brush_sel->popup), frame);
gtk_widget_show (frame);
preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_preview_size (GTK_PREVIEW (preview),
brush_sel->width, brush_sel->height);
preview = gimp_preview_area_new ();
gtk_widget_set_size_request (preview, brush_sel->width, brush_sel->height);
gtk_container_add (GTK_CONTAINER (frame), preview);
gtk_widget_show (preview);
@ -499,6 +506,7 @@ gimp_brush_select_popup_open (BrushSelect *brush_sel,
gdk_window_get_origin (brush_sel->preview->window, &x_org, &y_org);
screen = gtk_widget_get_screen (brush_sel->popup);
scr_w = gdk_screen_get_width (screen);
scr_h = gdk_screen_get_height (screen);
@ -511,30 +519,12 @@ gimp_brush_select_popup_open (BrushSelect *brush_sel,
gtk_window_move (GTK_WINDOW (brush_sel->popup), x, y);
/* Draw the brush */
buf = g_new (guchar, brush_sel->width);
memset (buf, 255, brush_sel->width);
src = brush_sel->mask_data;
for (y = 0; y < brush_sel->height; y++)
{
int j;
s = src;
b = buf;
for (j = 0; j < brush_sel->width ; j++)
*b++ = 255 - *s++;
gtk_preview_draw_row (GTK_PREVIEW (preview), buf,
0, y, brush_sel->width);
src += brush_sel->width;
}
g_free (buf);
gtk_widget_show (brush_sel->popup);
/* Draw the brush */
gimp_brush_select_preview_draw (GIMP_PREVIEW_AREA (preview),
0, 0, brush_sel->width, brush_sel->height,
brush_sel->mask_data);
}
static void

View File

@ -159,7 +159,7 @@ gimp_preview_area_expose (GtkWidget *widget,
area = GIMP_PREVIEW_AREA (widget);
if (! area->buf || ! GTK_WIDGET_DRAWABLE (widget))
if (! area->buf)
return FALSE;
buf = area->buf + event->area.x * 3 + event->area.y * area->rowstride;
@ -200,9 +200,9 @@ gimp_preview_area_new (void)
* @y: y offset in preview
* @width: buffer width
* @height: buffer height
* @type: the #GimpImageType of the pixels to draw
* @type: the #GimpImageType of @buf
* @buf: a #guchar buffer that contains the preview pixel data.
* @rowstride: rowstride of buffer
* @rowstride: rowstride of @buf
*
* Draws @buf on @area and queues a redraw on the rectangle that
* changed.
@ -265,12 +265,6 @@ gimp_preview_area_draw (GimpPreviewArea *area,
x = 0;
}
if (! area->buf)
{
area->rowstride = ((area->width * 3) + 3) & ~3;
area->buf = g_new (guchar, area->rowstride * area->height);
}
if (x + width > area->width)
width = area->width - x;
@ -284,6 +278,12 @@ gimp_preview_area_draw (GimpPreviewArea *area,
if (y + height > area->height)
height = area->height - y;
if (! area->buf)
{
area->rowstride = ((area->width * 3) + 3) & ~3;
area->buf = g_new (guchar, area->rowstride * area->height);
}
src = buf;
dest = area->buf + x * 3 + y * area->rowstride;
@ -454,6 +454,88 @@ gimp_preview_area_draw (GimpPreviewArea *area,
gtk_widget_queue_draw_area (GTK_WIDGET (area), x, y, width, height);
}
/**
* gimp_preview_area_fill:
* @area: a #GimpPreviewArea widget.
* @x: x offset in preview
* @y: y offset in preview
* @width: buffer width
* @height: buffer height
* @red:
* @green:
* @blue:
*
* Fills the @area in the given color.
*
* Since GIMP 2.2
**/
void
gimp_preview_area_fill (GimpPreviewArea *area,
gint x,
gint y,
gint width,
gint height,
guchar red,
guchar green,
guchar blue)
{
guchar *dest;
gint row;
gint col;
g_return_if_fail (GIMP_IS_PREVIEW_AREA (area));
g_return_if_fail (width > 0 && height > 0);
if (x + width < 0 || x >= area->width)
return;
if (y + height < 0 || y >= area->height)
return;
if (x < 0)
{
width -= x;
x = 0;
}
if (x + width > area->width)
width = area->width - x;
if (y < 0)
{
height -= y;
y = 0;
}
if (y + height > area->height)
height = area->height - y;
if (! area->buf)
{
area->rowstride = ((area->width * 3) + 3) & ~3;
area->buf = g_new (guchar, area->rowstride * area->height);
}
dest = area->buf + x * 3 + y * area->rowstride;
for (row = 0; row < height; row++)
{
guchar *d = dest;
for (col = 0; col < width; col++, d+= 3)
{
d[0] = red;
d[1] = green;
d[2] = blue;
}
dest += area->rowstride;
}
gtk_widget_queue_draw_area (GTK_WIDGET (area), x, y, width, height);
}
/**
* gimp_preview_area_set_cmap:
* @area: a #GimpPreviewArea

View File

@ -65,6 +65,15 @@ void gimp_preview_area_draw (GimpPreviewArea *area,
const guchar *buf,
gint rowstride);
void gimp_preview_area_fill (GimpPreviewArea *area,
gint x,
gint y,
gint width,
gint height,
guchar red,
guchar green,
guchar blue);
void gimp_preview_area_set_cmap (GimpPreviewArea *area,
const guchar *cmap,
gint num_colors);

View File

@ -118,6 +118,30 @@ test_run (GtkWidget *area,
num_iters * (WIDTH * HEIGHT * 1e-6) / total_time);
}
start_time = g_timer_elapsed (timer, NULL);
for (i = 0; i < num_iters; i++)
{
guchar r = rand () % 0xFF;
guchar g = rand () % 0xFF;
guchar b = rand () % 0xFF;
gimp_preview_area_fill (GIMP_PREVIEW_AREA (area),
0, 0, WIDTH, HEIGHT,
r, g, b);
gdk_window_process_updates (area->window, FALSE);
}
gdk_flush ();
total_time = g_timer_elapsed (timer, NULL) - start_time;
g_print ("%-16s "
"time elapsed: %5.2fs, %8.1f fps, %8.2f megapixels/s\n",
"Color fill",
total_time,
num_iters / total_time,
num_iters * (WIDTH * HEIGHT * 1e-6) / total_time);
g_free (buf);
}