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:

committed by
Sven Neumann

parent
3069689b48
commit
96b9987210
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user