diff --git a/ChangeLog b/ChangeLog index 3ba4b6ca7f..5947dc2d7a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Sat Aug 21 22:32:25 MEST 1999 Sven Neumann + + * app/brush_select.c + * app/brush_scale.[ch]: implemented brush_scaling for pixmap brushes. + This commit is done only to get some working code in before I start to + move all the brush_preview crap into one central place. Sat Aug 21 20:30:48 BST 1999 Adam D. Moss diff --git a/app/base/brush-scale.c b/app/base/brush-scale.c index c7ab425f02..b1cd47fef2 100644 --- a/app/base/brush-scale.c +++ b/app/base/brush-scale.c @@ -19,6 +19,7 @@ #include #include "brush_scale.h" + MaskBuf * brush_scale_mask (MaskBuf *brush_mask, int dest_width, @@ -164,3 +165,180 @@ brush_scale_mask (MaskBuf *brush_mask, return scale_brush; } + + +#define ADD_RGB(dest, factor, src) \ + dest[0] += factor * src[0]; \ + dest[1] += factor * src[1]; \ + dest[2] += factor * src[2]; + +MaskBuf * +brush_scale_pixmap (MaskBuf *pixmap, + int dest_width, + int dest_height) +{ + MaskBuf *scale_brush; + int src_width; + int src_height; + int value[3]; + int factor; + int area; + int i, j; + int x, x0, y, y0; + int dx, dx0, dy, dy0; + int fx, fx0, fy, fy0; + unsigned char *src, *src_ptr, *dest; + + g_return_val_if_fail (pixmap != NULL && pixmap->bytes == 3 && + dest_width != 0 && dest_height != 0, NULL); + + src_width = pixmap->width; + src_height = pixmap->height; + + scale_brush = temp_buf_new (dest_width, dest_height, 3, 0, 0, NULL); + g_return_val_if_fail (scale_brush != NULL, NULL); + + /* get the data */ + dest = mask_buf_data (scale_brush); + src = mask_buf_data (pixmap); + + fx = fx0 = (256.0 * src_width) / dest_width; + fy = fy0 = (256.0 * src_height) / dest_height; + area = fx0 * fy0; + + x = x0 = 0; + y = y0 = 0; + dx = dx0 = 0; + dy = dy0 = 0; + + for (i=0; i= 256) + { + factor = 256 * dy; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + x++; + fx -= 256; + } + if (fx) + { + factor = fx * dy; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + dx = 256 - fx; + } + y++; + fy -= dy; + dy = 0; + } + + while (fy >= 256) + { + fx = fx0; + x = x0; + dx = dx0; + + if (dx) + { + factor = dx * 256; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + x++; + fx -= dx; + dx = 0; + } + while (fx >= 256) + { + factor = 256 * 256; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + x++; + fx -= 256; + } + if (fx) + { + factor = fx * 256; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + dx = 256 - fx; + } + y++; + fy -= 256; + } + + if (fy) + { + fx = fx0; + x = x0; + dx = dx0; + + if (dx) + { + factor = dx * fy; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + x++; + fx -= dx; + dx = 0; + } + while (fx >= 256) + { + factor = 256 * fy; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + x++; + fx -= 256; + } + if (fx) + { + factor = fx * fy; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + dx = 256 - fx; + } + dy = 256 - fy; + } + + *dest++ = MIN ((value[0] / area), 255); + *dest++ = MIN ((value[1] / area), 255); + *dest++ = MIN ((value[2] / area), 255); + + x0 = x; + dx0 = dx; + } + x0 = 0; + dx0 = 0; + y0 = y; + dy0 = dy; + } + + return scale_brush; +} + +#undef ADD_RGB diff --git a/app/base/brush-scale.h b/app/base/brush-scale.h index 465d8147e2..d676413e75 100644 --- a/app/base/brush-scale.h +++ b/app/base/brush-scale.h @@ -43,7 +43,8 @@ static unsigned char brush_scale_indicator_bits[7][7][3] = /* functions */ -MaskBuf * brush_scale_mask (MaskBuf *, int, int); +MaskBuf * brush_scale_mask (MaskBuf *, int, int); +MaskBuf * brush_scale_pixmap (MaskBuf *, int, int); #endif /* __BRUSH_SCALE_H__ */ diff --git a/app/brush_scale.c b/app/brush_scale.c index c7ab425f02..b1cd47fef2 100644 --- a/app/brush_scale.c +++ b/app/brush_scale.c @@ -19,6 +19,7 @@ #include #include "brush_scale.h" + MaskBuf * brush_scale_mask (MaskBuf *brush_mask, int dest_width, @@ -164,3 +165,180 @@ brush_scale_mask (MaskBuf *brush_mask, return scale_brush; } + + +#define ADD_RGB(dest, factor, src) \ + dest[0] += factor * src[0]; \ + dest[1] += factor * src[1]; \ + dest[2] += factor * src[2]; + +MaskBuf * +brush_scale_pixmap (MaskBuf *pixmap, + int dest_width, + int dest_height) +{ + MaskBuf *scale_brush; + int src_width; + int src_height; + int value[3]; + int factor; + int area; + int i, j; + int x, x0, y, y0; + int dx, dx0, dy, dy0; + int fx, fx0, fy, fy0; + unsigned char *src, *src_ptr, *dest; + + g_return_val_if_fail (pixmap != NULL && pixmap->bytes == 3 && + dest_width != 0 && dest_height != 0, NULL); + + src_width = pixmap->width; + src_height = pixmap->height; + + scale_brush = temp_buf_new (dest_width, dest_height, 3, 0, 0, NULL); + g_return_val_if_fail (scale_brush != NULL, NULL); + + /* get the data */ + dest = mask_buf_data (scale_brush); + src = mask_buf_data (pixmap); + + fx = fx0 = (256.0 * src_width) / dest_width; + fy = fy0 = (256.0 * src_height) / dest_height; + area = fx0 * fy0; + + x = x0 = 0; + y = y0 = 0; + dx = dx0 = 0; + dy = dy0 = 0; + + for (i=0; i= 256) + { + factor = 256 * dy; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + x++; + fx -= 256; + } + if (fx) + { + factor = fx * dy; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + dx = 256 - fx; + } + y++; + fy -= dy; + dy = 0; + } + + while (fy >= 256) + { + fx = fx0; + x = x0; + dx = dx0; + + if (dx) + { + factor = dx * 256; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + x++; + fx -= dx; + dx = 0; + } + while (fx >= 256) + { + factor = 256 * 256; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + x++; + fx -= 256; + } + if (fx) + { + factor = fx * 256; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + dx = 256 - fx; + } + y++; + fy -= 256; + } + + if (fy) + { + fx = fx0; + x = x0; + dx = dx0; + + if (dx) + { + factor = dx * fy; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + x++; + fx -= dx; + dx = 0; + } + while (fx >= 256) + { + factor = 256 * fy; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + x++; + fx -= 256; + } + if (fx) + { + factor = fx * fy; + src_ptr = src + 3 * (x + y * src_width); + ADD_RGB (value, factor, src_ptr); + dx = 256 - fx; + } + dy = 256 - fy; + } + + *dest++ = MIN ((value[0] / area), 255); + *dest++ = MIN ((value[1] / area), 255); + *dest++ = MIN ((value[2] / area), 255); + + x0 = x; + dx0 = dx; + } + x0 = 0; + dx0 = 0; + y0 = y; + dy0 = dy; + } + + return scale_brush; +} + +#undef ADD_RGB diff --git a/app/brush_scale.h b/app/brush_scale.h index 465d8147e2..d676413e75 100644 --- a/app/brush_scale.h +++ b/app/brush_scale.h @@ -43,7 +43,8 @@ static unsigned char brush_scale_indicator_bits[7][7][3] = /* functions */ -MaskBuf * brush_scale_mask (MaskBuf *, int, int); +MaskBuf * brush_scale_mask (MaskBuf *, int, int); +MaskBuf * brush_scale_pixmap (MaskBuf *, int, int); #endif /* __BRUSH_SCALE_H__ */ diff --git a/app/brush_select.c b/app/brush_select.c index e08e28346d..d9e7c6cf0e 100644 --- a/app/brush_select.c +++ b/app/brush_select.c @@ -817,23 +817,30 @@ display_brush (BrushSelectP bsp, int ystart; int i, j; - brush_buf = brush->mask; + brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ? GIMP_BRUSH_PIXMAP(brush)->pixmap_mask + : brush->mask; - if (!GIMP_IS_BRUSH_PIXMAP(brush) && /* can't scale color brushes yet */ - (brush_buf->width > bsp->cell_width || - brush_buf->height > bsp->cell_height)) + if (brush_buf->width > bsp->cell_width || brush_buf->height > bsp->cell_height) { double ratio_x = (double)brush_buf->width / bsp->cell_width; double ratio_y = (double)brush_buf->height / bsp->cell_height; if (ratio_x >= ratio_y) - brush_buf = brush_scale_mask (brush_buf, - (double)(brush_buf->width) / ratio_x, - (double)(brush_buf->height) / ratio_x); + brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ? + brush_scale_pixmap (brush_buf, + (double)(brush_buf->width) / ratio_x, + (double)(brush_buf->height) / ratio_x) : + brush_scale_mask (brush_buf, + (double)(brush_buf->width) / ratio_x, + (double)(brush_buf->height) / ratio_x); else - brush_buf = brush_scale_mask (brush_buf, - (double)(brush_buf->width) / ratio_y, - (double)(brush_buf->height) / ratio_y); + brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ? + brush_scale_pixmap (brush_buf, + (double)(brush_buf->width) / ratio_y, + (double)(brush_buf->height) / ratio_y) : + brush_scale_mask (brush_buf, + (double)(brush_buf->width) / ratio_y, + (double)(brush_buf->height) / ratio_y); scale = TRUE; } @@ -853,13 +860,12 @@ display_brush (BrushSelectP bsp, /* Get the pointer into the brush mask data */ if (GIMP_IS_BRUSH_PIXMAP (brush)) { - GimpBrushPixmap *pixmapbrush = GIMP_BRUSH_PIXMAP(brush); - src = (gchar *) temp_buf_data (pixmapbrush->pixmap_mask) + (ystart - offset_y) * brush->mask->width * 3; + src = mask_buf_data (brush_buf) + (ystart - offset_y) * brush_buf->width * 3; for (i = ystart; i < yend; i++) { gtk_preview_draw_row (GTK_PREVIEW (bsp->preview), src, offset_x, i, width); - src += brush->mask->width * 3; + src += brush_buf->width * 3; } } else diff --git a/app/gui/brush-select.c b/app/gui/brush-select.c index e08e28346d..d9e7c6cf0e 100644 --- a/app/gui/brush-select.c +++ b/app/gui/brush-select.c @@ -817,23 +817,30 @@ display_brush (BrushSelectP bsp, int ystart; int i, j; - brush_buf = brush->mask; + brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ? GIMP_BRUSH_PIXMAP(brush)->pixmap_mask + : brush->mask; - if (!GIMP_IS_BRUSH_PIXMAP(brush) && /* can't scale color brushes yet */ - (brush_buf->width > bsp->cell_width || - brush_buf->height > bsp->cell_height)) + if (brush_buf->width > bsp->cell_width || brush_buf->height > bsp->cell_height) { double ratio_x = (double)brush_buf->width / bsp->cell_width; double ratio_y = (double)brush_buf->height / bsp->cell_height; if (ratio_x >= ratio_y) - brush_buf = brush_scale_mask (brush_buf, - (double)(brush_buf->width) / ratio_x, - (double)(brush_buf->height) / ratio_x); + brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ? + brush_scale_pixmap (brush_buf, + (double)(brush_buf->width) / ratio_x, + (double)(brush_buf->height) / ratio_x) : + brush_scale_mask (brush_buf, + (double)(brush_buf->width) / ratio_x, + (double)(brush_buf->height) / ratio_x); else - brush_buf = brush_scale_mask (brush_buf, - (double)(brush_buf->width) / ratio_y, - (double)(brush_buf->height) / ratio_y); + brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ? + brush_scale_pixmap (brush_buf, + (double)(brush_buf->width) / ratio_y, + (double)(brush_buf->height) / ratio_y) : + brush_scale_mask (brush_buf, + (double)(brush_buf->width) / ratio_y, + (double)(brush_buf->height) / ratio_y); scale = TRUE; } @@ -853,13 +860,12 @@ display_brush (BrushSelectP bsp, /* Get the pointer into the brush mask data */ if (GIMP_IS_BRUSH_PIXMAP (brush)) { - GimpBrushPixmap *pixmapbrush = GIMP_BRUSH_PIXMAP(brush); - src = (gchar *) temp_buf_data (pixmapbrush->pixmap_mask) + (ystart - offset_y) * brush->mask->width * 3; + src = mask_buf_data (brush_buf) + (ystart - offset_y) * brush_buf->width * 3; for (i = ystart; i < yend; i++) { gtk_preview_draw_row (GTK_PREVIEW (bsp->preview), src, offset_x, i, width); - src += brush->mask->width * 3; + src += brush_buf->width * 3; } } else