mirror of https://github.com/GNOME/gimp.git
639 lines
17 KiB
C
639 lines
17 KiB
C
/* The GIMP -- an image manipulation program
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* GimpContextPreview Widget
|
|
* Copyright (C) 1999 Sven Neumann
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "brush_scale.h"
|
|
#include "gimpbrush.h"
|
|
#include "gimpbrushpipe.h"
|
|
#include "gimpbrushpipeP.h"
|
|
#include "gimpcontextpreview.h"
|
|
#include "interface.h" /* for tool_tips */
|
|
#include "patterns.h"
|
|
#include "temp_buf.h"
|
|
|
|
/* the pixmap for the scale_indicator */
|
|
#define scale_indicator_width 7
|
|
#define scale_indicator_height 7
|
|
|
|
#define WHT {255,255,255}
|
|
#define BLK { 0, 0, 0}
|
|
|
|
static unsigned char scale_indicator_bits[7][7][3] =
|
|
{
|
|
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT },
|
|
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
|
|
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
|
|
{ WHT, BLK, BLK, BLK, BLK, BLK, WHT },
|
|
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
|
|
{ WHT, WHT, WHT, BLK, WHT, WHT, WHT },
|
|
{ WHT, WHT, WHT, WHT, WHT, WHT, WHT }
|
|
};
|
|
|
|
#define CONTEXT_PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \
|
|
GDK_BUTTON_RELEASE_MASK | \
|
|
GDK_ENTER_NOTIFY_MASK | \
|
|
GDK_LEAVE_NOTIFY_MASK)
|
|
|
|
static GtkWidget *gcp_popup = NULL;
|
|
static GtkWidget *gcp_popup_preview = NULL;
|
|
|
|
enum {
|
|
CLICKED,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
static guint gimp_context_preview_signals[LAST_SIGNAL] = { 0 };
|
|
static GtkPreviewClass *parent_class = NULL;
|
|
|
|
static gint gimp_context_preview_button_press_event (GtkWidget *,
|
|
GdkEventButton *);
|
|
static gint gimp_context_preview_button_release_event (GtkWidget *,
|
|
GdkEventButton *);
|
|
static void gimp_context_preview_popup_open (GimpContextPreview *,
|
|
gint, gint);
|
|
static void gimp_context_preview_popup_close ();
|
|
static gboolean gimp_context_preview_data_matches_type (GimpContextPreview *,
|
|
gpointer);
|
|
static void gimp_context_preview_draw_brush (GimpContextPreview *);
|
|
static void gimp_context_preview_draw_brush_popup (GimpContextPreview *);
|
|
static void gimp_context_preview_draw_pattern (GimpContextPreview *);
|
|
static void gimp_context_preview_draw_pattern_popup (GimpContextPreview *);
|
|
|
|
|
|
static void
|
|
gimp_context_preview_destroy (GtkObject *object)
|
|
{
|
|
g_return_if_fail (GIMP_IS_CONTEXT_PREVIEW (object));
|
|
|
|
if (GTK_OBJECT_CLASS (parent_class)->destroy)
|
|
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
|
|
}
|
|
|
|
static void
|
|
gimp_context_preview_class_init (GimpContextPreviewClass *class)
|
|
{
|
|
GtkObjectClass *object_class;
|
|
GtkWidgetClass *widget_class;
|
|
|
|
object_class = (GtkObjectClass*) class;
|
|
widget_class = (GtkWidgetClass*) class;
|
|
|
|
parent_class = gtk_type_class (gtk_preview_get_type ());
|
|
|
|
gimp_context_preview_signals[CLICKED] =
|
|
gtk_signal_new ("clicked",
|
|
GTK_RUN_FIRST,
|
|
object_class->type,
|
|
GTK_SIGNAL_OFFSET (GimpContextPreviewClass, clicked),
|
|
gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
|
|
gtk_object_class_add_signals (object_class, gimp_context_preview_signals,
|
|
LAST_SIGNAL);
|
|
|
|
class->clicked = NULL;
|
|
|
|
widget_class->button_press_event = gimp_context_preview_button_press_event;
|
|
widget_class->button_release_event = gimp_context_preview_button_release_event;
|
|
|
|
object_class->destroy = gimp_context_preview_destroy;
|
|
}
|
|
|
|
static void
|
|
gimp_context_preview_init (GimpContextPreview *gcp)
|
|
{
|
|
gcp->data = NULL;
|
|
gcp->type = GCP_LAST;
|
|
gcp->width = 0;
|
|
gcp->height = 0;
|
|
gcp->show_tooltips = FALSE;
|
|
GTK_PREVIEW (gcp)->type = GTK_PREVIEW_COLOR;
|
|
GTK_PREVIEW (gcp)->bpp = 3;
|
|
GTK_PREVIEW (gcp)->dither = GDK_RGB_DITHER_NORMAL;
|
|
|
|
gtk_widget_set_events (GTK_WIDGET (gcp), CONTEXT_PREVIEW_EVENT_MASK);
|
|
}
|
|
|
|
GtkType
|
|
gimp_context_preview_get_type ()
|
|
{
|
|
static GtkType gcp_type = 0;
|
|
|
|
if (!gcp_type)
|
|
{
|
|
GtkTypeInfo gcp_info =
|
|
{
|
|
"GimpContextPreview",
|
|
sizeof (GimpContextPreview),
|
|
sizeof (GimpContextPreviewClass),
|
|
(GtkClassInitFunc) gimp_context_preview_class_init,
|
|
(GtkObjectInitFunc) gimp_context_preview_init,
|
|
/* reserved_1 */ NULL,
|
|
/* reserved_2 */ NULL,
|
|
(GtkClassInitFunc) NULL
|
|
};
|
|
|
|
gcp_type = gtk_type_unique (gtk_preview_get_type (), &gcp_info);
|
|
}
|
|
|
|
return gcp_type;
|
|
}
|
|
|
|
GtkWidget*
|
|
gimp_context_preview_new (GimpContextPreviewType type,
|
|
gint width,
|
|
gint height,
|
|
gboolean show_tooltips)
|
|
{
|
|
GimpContextPreview *gcp;
|
|
|
|
g_return_val_if_fail (type >= 0 && type < GCP_LAST, NULL);
|
|
g_return_val_if_fail (width > 0 && height > 0, NULL);
|
|
|
|
gcp = gtk_type_new (gimp_context_preview_get_type ());
|
|
|
|
gcp->type = type;
|
|
gcp->width = width;
|
|
gcp->height = height;
|
|
gcp->show_tooltips = show_tooltips;
|
|
|
|
gtk_preview_size (GTK_PREVIEW (gcp), width, height);
|
|
|
|
return GTK_WIDGET (gcp);
|
|
}
|
|
|
|
void
|
|
gimp_context_preview_update (GimpContextPreview *gcp,
|
|
gpointer data)
|
|
{
|
|
g_return_if_fail (GIMP_IS_CONTEXT_PREVIEW (gcp));
|
|
g_return_if_fail (gimp_context_preview_data_matches_type (gcp, data));
|
|
|
|
gcp->data = data;
|
|
if (GTK_IS_OBJECT (gcp->data))
|
|
gtk_signal_connect (GTK_OBJECT (gcp->data), "destroy",
|
|
gtk_widget_destroyed, &gcp->data);
|
|
switch (gcp->type)
|
|
{
|
|
case GCP_BRUSH:
|
|
gimp_context_preview_draw_brush (gcp);
|
|
break;
|
|
case GCP_PATTERN:
|
|
gimp_context_preview_draw_pattern (gcp);
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (gcp->show_tooltips)
|
|
{
|
|
gchar *name = NULL;
|
|
|
|
switch (gcp->type)
|
|
{
|
|
case GCP_BRUSH:
|
|
{
|
|
GimpBrush *brush = GIMP_BRUSH (gcp->data);
|
|
name = brush->name;
|
|
}
|
|
break;
|
|
case GCP_PATTERN:
|
|
{
|
|
GPattern *pattern = (GPattern *)(gcp->data);
|
|
name = pattern->name;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
gtk_tooltips_set_tip (tool_tips, GTK_WIDGET (gcp), name, NULL);
|
|
}
|
|
}
|
|
|
|
static gint
|
|
gimp_context_preview_button_press_event (GtkWidget *widget,
|
|
GdkEventButton *bevent)
|
|
{
|
|
if (bevent->button == 1)
|
|
{
|
|
gtk_signal_emit_by_name (GTK_OBJECT (widget), "clicked");
|
|
gimp_context_preview_popup_open (GIMP_CONTEXT_PREVIEW (widget),
|
|
bevent->x, bevent->y);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static gint
|
|
gimp_context_preview_button_release_event (GtkWidget *widget,
|
|
GdkEventButton *bevent)
|
|
{
|
|
if (bevent->button == 1)
|
|
gimp_context_preview_popup_close ();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
gimp_context_preview_popup_open (GimpContextPreview *gcp,
|
|
gint x,
|
|
gint y)
|
|
{
|
|
gint x_org, y_org;
|
|
gint scr_w, scr_h;
|
|
gint width, height;
|
|
|
|
g_return_if_fail (gcp != NULL);
|
|
if (!gcp->data)
|
|
return;
|
|
|
|
switch (gcp->type)
|
|
{
|
|
case GCP_BRUSH:
|
|
{
|
|
GimpBrush *brush = GIMP_BRUSH (gcp->data);
|
|
width = brush->mask->width;
|
|
height = brush->mask->height;
|
|
}
|
|
break;
|
|
case GCP_PATTERN:
|
|
{
|
|
GPattern *pattern = (GPattern*)gcp->data;
|
|
width = pattern->mask->width;
|
|
height = pattern->mask->height;
|
|
}
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
if (width <= gcp->width && height <= gcp->height)
|
|
return;
|
|
|
|
/* make sure the popup exists and is not visible */
|
|
if (gcp_popup == NULL)
|
|
{
|
|
GtkWidget *frame;
|
|
|
|
gcp_popup = gtk_window_new (GTK_WINDOW_POPUP);
|
|
gtk_window_set_policy (GTK_WINDOW (gcp_popup), FALSE, FALSE, TRUE);
|
|
gtk_signal_connect (GTK_OBJECT (gcp_popup), "destroy",
|
|
gtk_widget_destroyed, &gcp_popup);
|
|
frame = gtk_frame_new (NULL);
|
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
|
gtk_container_add (GTK_CONTAINER (gcp_popup), frame);
|
|
gtk_widget_show (frame);
|
|
gcp_popup_preview = gtk_preview_new (GTK_PREVIEW_COLOR);
|
|
gtk_signal_connect (GTK_OBJECT (gcp_popup_preview), "destroy",
|
|
gtk_widget_destroyed, &gcp_popup_preview);
|
|
gtk_container_add (GTK_CONTAINER (frame), gcp_popup_preview);
|
|
gtk_widget_show (gcp_popup_preview);
|
|
}
|
|
else
|
|
{
|
|
gtk_widget_hide (gcp_popup);
|
|
}
|
|
|
|
/* decide where to put the popup */
|
|
gdk_window_get_origin (GTK_WIDGET (gcp)->window, &x_org, &y_org);
|
|
scr_w = gdk_screen_width ();
|
|
scr_h = gdk_screen_height ();
|
|
x = x_org + x - (width >> 1);
|
|
y = y_org + y - (height >> 1);
|
|
x = (x < 0) ? 0 : x;
|
|
y = (y < 0) ? 0 : y;
|
|
x = (x + width > scr_w) ? scr_w - width : x;
|
|
y = (y + height > scr_h) ? scr_h - height : y;
|
|
gtk_preview_size (GTK_PREVIEW (gcp_popup_preview), width, height);
|
|
gtk_widget_popup (gcp_popup, x, y);
|
|
|
|
switch (gcp->type)
|
|
{
|
|
case GCP_BRUSH:
|
|
gimp_context_preview_draw_brush_popup (gcp);
|
|
break;
|
|
case GCP_PATTERN:
|
|
gimp_context_preview_draw_pattern_popup (gcp);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
gtk_widget_queue_draw (gcp_popup_preview);
|
|
}
|
|
|
|
static void
|
|
gimp_context_preview_popup_close ()
|
|
{
|
|
if (gcp_popup != NULL)
|
|
gtk_widget_hide (gcp_popup);
|
|
}
|
|
|
|
static gboolean
|
|
gimp_context_preview_data_matches_type (GimpContextPreview *gcp,
|
|
gpointer data)
|
|
{
|
|
gboolean match = FALSE;
|
|
|
|
g_return_val_if_fail (GIMP_IS_CONTEXT_PREVIEW (gcp), FALSE);
|
|
|
|
switch (gcp->type)
|
|
{
|
|
case GCP_BRUSH:
|
|
match = GIMP_IS_BRUSH (data);
|
|
break;
|
|
case GCP_PATTERN:
|
|
match = data != NULL; /* would be nice if pattern was a real gtk_object */
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return (match);
|
|
}
|
|
|
|
|
|
|
|
/* brush draw functions */
|
|
|
|
static void
|
|
gimp_context_preview_draw_brush_popup (GimpContextPreview *gcp)
|
|
{
|
|
GimpBrush *brush;
|
|
guchar *mask, *buf, *b;
|
|
guchar bg;
|
|
gint width, height;
|
|
gint x, y;
|
|
|
|
g_return_if_fail (gcp != NULL && GIMP_IS_BRUSH (gcp->data));
|
|
|
|
brush = GIMP_BRUSH (gcp->data);
|
|
width = brush->mask->width;
|
|
height = brush->mask->height;
|
|
buf = g_new (guchar, 3 * width);
|
|
mask = temp_buf_data (brush->mask);
|
|
|
|
if (GIMP_IS_BRUSH_PIXMAP (brush))
|
|
{
|
|
guchar *pixmap = temp_buf_data (GIMP_BRUSH_PIXMAP (brush)->pixmap_mask);
|
|
|
|
for (y = 0; y < height; y++)
|
|
{
|
|
b = buf;
|
|
for (x = 0; x < width ; x++)
|
|
{
|
|
bg = (255 - *mask);
|
|
*b++ = bg + (*mask * *pixmap++) / 255;
|
|
*b++ = bg + (*mask * *pixmap++) / 255;
|
|
*b++ = bg + (*mask * *pixmap++) / 255;
|
|
mask++;
|
|
}
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp_popup_preview), buf, 0, y, width);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (y = 0; y < height; y++)
|
|
{
|
|
b = buf;
|
|
/* Invert the mask for display. */
|
|
for (x = 0; x < width; x++)
|
|
{
|
|
bg = 255 - *mask++;
|
|
memset (b, bg, 3);
|
|
b += 3;
|
|
}
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp_popup_preview), buf, 0, y, width);
|
|
}
|
|
}
|
|
|
|
g_free(buf);
|
|
}
|
|
|
|
static void
|
|
gimp_context_preview_draw_brush (GimpContextPreview *gcp)
|
|
{
|
|
GimpBrush *brush;
|
|
gboolean scale = FALSE;
|
|
gint brush_width, brush_height;
|
|
gint offset_x, offset_y;
|
|
TempBuf *mask_buf, *pixmap_buf = NULL;
|
|
guchar *mask, *buf, *b;
|
|
guchar bg;
|
|
gint x, y;
|
|
|
|
g_return_if_fail (gcp != NULL && GIMP_IS_BRUSH (gcp->data));
|
|
|
|
brush = GIMP_BRUSH (gcp->data);
|
|
brush_width = brush->mask->width;
|
|
brush_height = brush->mask->height;
|
|
|
|
if (brush_width > gcp->width || brush_height > gcp->height)
|
|
{
|
|
gdouble ratio_x = (gdouble)brush_width / gcp->width;
|
|
gdouble ratio_y = (gdouble)brush_height / gcp->height;
|
|
|
|
brush_width = (gdouble)brush_width / MAX (ratio_x, ratio_y);
|
|
brush_height = (gdouble)brush_height / MAX (ratio_x, ratio_y);
|
|
|
|
mask_buf = brush_scale_mask (brush->mask, brush_width, brush_height);
|
|
if (GIMP_IS_BRUSH_PIXMAP (brush))
|
|
{
|
|
/* TODO: the scale function should scale the pixmap
|
|
and the mask in one run */
|
|
pixmap_buf = brush_scale_pixmap (GIMP_BRUSH_PIXMAP(brush)->pixmap_mask,
|
|
brush_width, brush_height);
|
|
}
|
|
scale = TRUE;
|
|
}
|
|
else
|
|
{
|
|
mask_buf = brush->mask;
|
|
if (GIMP_IS_BRUSH_PIXMAP (brush))
|
|
pixmap_buf = GIMP_BRUSH_PIXMAP(brush)->pixmap_mask;
|
|
}
|
|
|
|
offset_x = (gcp->width - brush_width) >> 1;
|
|
offset_y = (gcp->height - brush_height) >> 1;
|
|
|
|
mask = temp_buf_data (mask_buf);
|
|
buf = g_new (guchar, 3 * gcp->width);
|
|
memset (buf, 255, 3 * gcp->width);
|
|
|
|
if (GIMP_IS_BRUSH_PIXMAP (brush))
|
|
{
|
|
guchar *pixmap = temp_buf_data (pixmap_buf);
|
|
|
|
for (y = 0; y < offset_y; y++)
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
|
|
for (y = offset_y; y < brush_height + offset_y; y++)
|
|
{
|
|
b = buf + 3 * offset_x;
|
|
for (x = 0; x < brush_width ; x++)
|
|
{
|
|
bg = (255 - *mask);
|
|
*b++ = bg + (*mask * *pixmap++) / 255;
|
|
*b++ = bg + (*mask * *pixmap++) / 255;
|
|
*b++ = bg + (*mask * *pixmap++) / 255;
|
|
mask++;
|
|
}
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
|
|
}
|
|
memset (buf, 255, 3 * gcp->width);
|
|
for (y = brush_height + offset_y; y < gcp->height; y++)
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
|
|
}
|
|
else
|
|
{
|
|
for (y = 0; y < offset_y; y++)
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
|
|
for (y = offset_y; y < brush_height + offset_y; y++)
|
|
{
|
|
b = buf + 3 * offset_x;
|
|
for (x = 0; x < brush_width ; x++)
|
|
{
|
|
bg = 255 - *mask++;
|
|
memset (b, bg, 3);
|
|
b += 3;
|
|
}
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
|
|
}
|
|
memset (buf, 255, 3 * gcp->width);
|
|
for (y = brush_height + offset_y; y < gcp->height; y++)
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
|
|
}
|
|
|
|
if (scale)
|
|
{
|
|
offset_x = gcp->width - scale_indicator_width - 1;
|
|
offset_y = gcp->height - scale_indicator_height - 1;
|
|
for (y = 0; y < scale_indicator_height; y++)
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp), scale_indicator_bits[y][0],
|
|
offset_x, offset_y + y, scale_indicator_width);
|
|
temp_buf_free (mask_buf);
|
|
if (GIMP_IS_BRUSH_PIXMAP (brush))
|
|
temp_buf_free (pixmap_buf);
|
|
}
|
|
|
|
g_free (buf);
|
|
|
|
gtk_widget_queue_draw (GTK_WIDGET (gcp));
|
|
}
|
|
|
|
|
|
/* pattern draw functions */
|
|
|
|
static void
|
|
gimp_context_preview_draw_pattern_popup (GimpContextPreview *gcp)
|
|
{
|
|
GPattern *pattern;
|
|
guchar *mask;
|
|
gint width, height;
|
|
gint x, y;
|
|
|
|
g_return_if_fail (gcp != NULL && gcp->data != NULL);
|
|
|
|
pattern = (GPattern*)(gcp->data);
|
|
width = pattern->mask->width;
|
|
height = pattern->mask->height;
|
|
mask = temp_buf_data (pattern->mask);
|
|
|
|
if (pattern->mask->bytes == 1)
|
|
{
|
|
guchar *buf = g_new (guchar, 3 * width);
|
|
guchar *b;
|
|
|
|
for (y = 0; y < height; y++)
|
|
{
|
|
b = buf;
|
|
for (x = 0; x < width ; x++)
|
|
{
|
|
memset (b, *mask++, 3);
|
|
b += 3;
|
|
}
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp_popup_preview), buf, 0, y, width);
|
|
}
|
|
g_free(buf);
|
|
}
|
|
else
|
|
{
|
|
for (y = 0; y < height; y++)
|
|
{
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp_popup_preview), mask, 0, y, width);
|
|
mask += 3 * width;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
gimp_context_preview_draw_pattern (GimpContextPreview *gcp)
|
|
{
|
|
GPattern *pattern;
|
|
gint pattern_width, pattern_height;
|
|
gint width, height;
|
|
gint offset_x, offset_y;
|
|
guchar *mask, *buf, *b;
|
|
gint x, y;
|
|
|
|
g_return_if_fail (gcp != NULL && gcp->data != NULL);
|
|
|
|
pattern = (GPattern*)(gcp->data);
|
|
pattern_width = pattern->mask->width;
|
|
pattern_height = pattern->mask->height;
|
|
|
|
width = (pattern_width > gcp->width) ? gcp->width : pattern_width;
|
|
height = (pattern_height > gcp->height) ? gcp->height : pattern_height;
|
|
|
|
offset_x = (gcp->width - width) >> 1;
|
|
offset_y = (gcp->height - height) >> 1;
|
|
|
|
mask = temp_buf_data (pattern->mask);
|
|
buf = g_new (guchar, 3 * gcp->width);
|
|
|
|
memset (buf, 255, 3 * gcp->width);
|
|
for (y = 0; y < offset_y; y++)
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
|
|
|
|
if (pattern->mask->bytes == 1)
|
|
{
|
|
for (y = offset_y; y < height + offset_y; y++)
|
|
{
|
|
b = buf + 3 * offset_x;
|
|
for (x = 0; x < width ; x++)
|
|
{
|
|
memset (b, mask[x], 3);
|
|
b += 3;
|
|
}
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
|
|
mask += pattern_width;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (y = offset_y; y < height + offset_y; y++)
|
|
{
|
|
b = buf + 3 * offset_x;
|
|
memcpy (b, mask, 3 * width);
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
|
|
mask += 3 * pattern_width;
|
|
}
|
|
}
|
|
|
|
memset (buf, 255, 3 * gcp->width);
|
|
for (y = height + offset_y; y < gcp->height; y++)
|
|
gtk_preview_draw_row (GTK_PREVIEW (gcp), buf, 0, y, gcp->width);
|
|
|
|
g_free(buf);
|
|
}
|