X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/52f2b10a2d0eb84f8c300146d57f6643b91619b3..f7675b46b77133b516c407fdd9f63abcca50fd45:/fills.c diff --git a/fills.c b/fills.c index e386d8a4..ea586476 100644 --- a/fills.c +++ b/fills.c @@ -1,3 +1,4 @@ +#define IMAGER_NO_CONTEXT #include "imager.h" #include "imageri.h" @@ -163,10 +164,10 @@ typedef struct i_fcolor fc; } i_fill_solid_t; -static void fill_solid(i_fill_t *, int x, int y, int width, int channels, - i_color *); -static void fill_solidf(i_fill_t *, int x, int y, int width, int channels, - i_fcolor *); +static void fill_solid(i_fill_t *, i_img_dim x, i_img_dim y, i_img_dim width, + int channels, i_color *); +static void fill_solidf(i_fill_t *, i_img_dim x, i_img_dim y, i_img_dim width, + int channels, i_fcolor *); static i_fill_solid_t base_solid_fill = { @@ -398,79 +399,83 @@ typedef struct i_color fg, bg; i_fcolor ffg, fbg; unsigned char hatch[8]; - int dx, dy; + i_img_dim dx, dy; } i_fill_hatch_t; -static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels, - i_color *data); -static void fill_hatchf(i_fill_t *fill, int x, int y, int width, int channels, - i_fcolor *data); +static void fill_hatch(i_fill_t *fill, i_img_dim x, i_img_dim y, + i_img_dim width, int channels, i_color *data); +static void fill_hatchf(i_fill_t *fill, i_img_dim x, i_img_dim y, + i_img_dim width, int channels, i_fcolor *data); static i_fill_t * i_new_hatch_low(const i_color *fg, const i_color *bg, const i_fcolor *ffg, const i_fcolor *fbg, int combine, int hatch, const unsigned char *cust_hatch, - int dx, int dy); + i_img_dim dx, i_img_dim dy); /* -=item i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy) +=item i_new_fill_hatch(C, C, C, C, C, C, C) =category Fills =synopsis i_fill_t *fill = i_new_fill_hatch(&fg_color, &bg_color, combine, hatch, custom_hatch, dx, dy); -Creates a new hatched fill with the fg color used for the 1 bits in -the hatch and bg for the 0 bits. If combine is non-zero alpha values -will be combined. +Creates a new hatched fill with the C color used for the 1 bits in +the hatch and C for the 0 bits. If C is non-zero alpha +values will be combined. -If cust_hatch is non-NULL it should be a pointer to 8 bytes of the +If C is non-NULL it should be a pointer to 8 bytes of the hash definition, with the high-bits to the left. -If cust_hatch is NULL then one of the standard hatches is used. +If C is NULL then one of the standard hatches is used. -(dx, dy) are an offset into the hatch which can be used to unalign adjoining areas, or to align the origin of a hatch with the the side of a filled area. +(C, C) are an offset into the hatch which can be used to hatch +adjoining areas out of alignment, or to align the origin of a hatch +with the side of a filled area. =cut */ i_fill_t * i_new_fill_hatch(const i_color *fg, const i_color *bg, int combine, int hatch, - const unsigned char *cust_hatch, int dx, int dy) { + const unsigned char *cust_hatch, i_img_dim dx, i_img_dim dy) { return i_new_hatch_low(fg, bg, NULL, NULL, combine, hatch, cust_hatch, dx, dy); } /* -=item i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy) +=item i_new_fill_hatchf(C, C, C, C, C, C, C) =category Fills =synopsis i_fill_t *fill = i_new_fill_hatchf(&fg_fcolor, &bg_fcolor, combine, hatch, custom_hatch, dx, dy); -Creates a new hatched fill with the fg color used for the 1 bits in -the hatch and bg for the 0 bits. If combine is non-zero alpha values -will be combined. +Creates a new hatched fill with the C color used for the 1 bits in +the hatch and C for the 0 bits. If C is non-zero alpha +values will be combined. -If cust_hatch is non-NULL it should be a pointer to 8 bytes of the +If C is non-NULL it should be a pointer to 8 bytes of the hash definition, with the high-bits to the left. -If cust_hatch is NULL then one of the standard hatches is used. +If C is NULL then one of the standard hatches is used. -(dx, dy) are an offset into the hatch which can be used to unalign adjoining areas, or to align the origin of a hatch with the the side of a filled area. +(C, C) are an offset into the hatch which can be used to hatch +adjoining areas out of alignment, or to align the origin of a hatch +with the side of a filled area. =cut */ i_fill_t * i_new_fill_hatchf(const i_fcolor *fg, const i_fcolor *bg, int combine, int hatch, - const unsigned char *cust_hatch, int dx, int dy) { + const unsigned char *cust_hatch, i_img_dim dx, i_img_dim dy) { return i_new_hatch_low(NULL, NULL, fg, bg, combine, hatch, cust_hatch, dx, dy); } -static void fill_image(i_fill_t *fill, int x, int y, int width, int channels, - i_color *data); -static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels, - i_fcolor *data); +static void fill_image(i_fill_t *fill, i_img_dim x, i_img_dim y, + i_img_dim width, int channels, i_color *data); +static void fill_imagef(i_fill_t *fill, i_img_dim x, i_img_dim y, + i_img_dim width, int channels, i_fcolor *data); struct i_fill_image_t { i_fill_t base; i_img *src; - int xoff, yoff; + i_img_dim xoff, yoff; int has_matrix; double matrix[9]; }; @@ -486,7 +491,7 @@ image_fill_proto = }; /* -=item i_new_fill_image(im, matrix, xoff, yoff, combine) +=item i_new_fill_image(C, C, C, C, C) =category Fills =synopsis i_fill_t *fill = i_new_fill_image(src_img, matrix, x_offset, y_offset, combine); @@ -495,12 +500,12 @@ Create an image based fill. matrix is an array of 9 doubles representing a transformation matrix. -xoff and yoff are the offset into the image to start filling from. +C and C are the offset into the image to start filling from. =cut */ i_fill_t * -i_new_fill_image(i_img *im, const double *matrix, int xoff, int yoff, int combine) { +i_new_fill_image(i_img *im, const double *matrix, i_img_dim xoff, i_img_dim yoff, int combine) { struct i_fill_image_t *fill = mymalloc(sizeof(*fill)); /* checked 14jul05 tonyc */ *fill = image_fill_proto; @@ -529,10 +534,10 @@ i_new_fill_image(i_img *im, const double *matrix, int xoff, int yoff, int combin return &fill->base; } -static void fill_opacity(i_fill_t *fill, int x, int y, int width, int channels, - i_color *data); -static void fill_opacityf(i_fill_t *fill, int x, int y, int width, int channels, - i_fcolor *data); +static void fill_opacity(i_fill_t *fill, i_img_dim x, i_img_dim y, + i_img_dim width, int channels, i_color *data); +static void fill_opacityf(i_fill_t *fill, i_img_dim x, i_img_dim y, + i_img_dim width, int channels, i_fcolor *data); struct i_fill_opacity_t { i_fill_t base; @@ -543,9 +548,11 @@ struct i_fill_opacity_t { static struct i_fill_opacity_t opacity_fill_proto = { - fill_opacity, - fill_opacityf, - NULL + { + fill_opacity, + fill_opacityf, + NULL + } }; i_fill_t * @@ -559,6 +566,11 @@ i_new_fill_opacity(i_fill_t *base_fill, double alpha_mult) { fill->other_fill = base_fill; fill->alpha_mult = alpha_mult; + if (!base_fill->f_fill_with_color) { + /* base fill only does floating, so we only do that too */ + fill->base.f_fill_with_color = NULL; + } + return &fill->base; } @@ -578,8 +590,8 @@ The 8-bit sample fill function for non-combining solid fills. =cut */ static void -fill_solid(i_fill_t *fill, int x, int y, int width, int channels, - i_color *data) { +fill_solid(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width, + int channels, i_color *data) { i_color c = T_SOLID_FILL(fill)->c; i_adapt_colors(channels > 2 ? 4 : 2, 4, &c, 1); while (width-- > 0) { @@ -595,8 +607,8 @@ The floating sample fill function for non-combining solid fills. =cut */ static void -fill_solidf(i_fill_t *fill, int x, int y, int width, int channels, - i_fcolor *data) { +fill_solidf(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width, + int channels, i_fcolor *data) { i_fcolor c = T_SOLID_FILL(fill)->fc; i_adapt_fcolors(channels > 2 ? 4 : 2, 4, &c, 1); while (width-- > 0) { @@ -626,7 +638,7 @@ i_fill_t * i_new_hatch_low(const i_color *fg, const i_color *bg, const i_fcolor *ffg, const i_fcolor *fbg, int combine, int hatch, const unsigned char *cust_hatch, - int dx, int dy) { + i_img_dim dx, i_img_dim dy) { i_fill_hatch_t *fill = mymalloc(sizeof(i_fill_hatch_t)); /* checked 14jul05 tonyc */ *fill = hatch_fill_proto; @@ -677,15 +689,15 @@ The 8-bit sample fill function for hatched fills. =cut */ -static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels, - i_color *data) { +static void +fill_hatch(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width, + int channels, i_color *data) { i_fill_hatch_t *f = (i_fill_hatch_t *)fill; int byte = f->hatch[(y + f->dy) & 7]; int xpos = (x + f->dx) & 7; int mask = 128 >> xpos; i_color fg = f->fg; i_color bg = f->bg; - int want_channels = channels > 2 ? 4 : 2; if (channels < 3) { i_adapt_colors(2, 4, &fg, 1); @@ -708,10 +720,11 @@ static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels, The floating sample fill function for hatched fills. -=back +=cut */ -static void fill_hatchf(i_fill_t *fill, int x, int y, int width, int channels, - i_fcolor *data) { +static void +fill_hatchf(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width, + int channels, i_fcolor *data) { i_fill_hatch_t *f = (i_fill_hatch_t *)fill; int byte = f->hatch[(y + f->dy) & 7]; int xpos = (x + f->dx) & 7; @@ -784,10 +797,11 @@ static i_fcolor interp_i_fcolor(i_fcolor before, i_fcolor after, double pos, =cut */ -static void fill_image(i_fill_t *fill, int x, int y, int width, int channels, - i_color *data) { +static void +fill_image(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width, + int channels, i_color *data) { struct i_fill_image_t *f = (struct i_fill_image_t *)fill; - int i = 0; + i_img_dim i = 0; i_color *out = data; int want_channels = channels > 2 ? 4 : 2; @@ -800,7 +814,7 @@ static void fill_image(i_fill_t *fill, int x, int y, int width, int channels, double iy = floor(ry / f->src->ysize); i_color c[2][2]; i_color c2[2]; - int dy; + i_img_dim dy; if (f->xoff) { rx += iy * f->xoff; @@ -814,12 +828,12 @@ static void fill_image(i_fill_t *fill, int x, int y, int width, int channels, ry -= iy * f->src->ysize; for (dy = 0; dy < 2; ++dy) { - if ((int)rx == f->src->xsize-1) { - i_gpix(f->src, f->src->xsize-1, ((int)ry+dy) % f->src->ysize, &c[dy][0]); - i_gpix(f->src, 0, ((int)ry+dy) % f->src->xsize, &c[dy][1]); + if ((i_img_dim)rx == f->src->xsize-1) { + i_gpix(f->src, f->src->xsize-1, ((i_img_dim)ry+dy) % f->src->ysize, &c[dy][0]); + i_gpix(f->src, 0, ((i_img_dim)ry+dy) % f->src->xsize, &c[dy][1]); } else { - i_glin(f->src, (int)rx, (int)rx+2, ((int)ry+dy) % f->src->ysize, + i_glin(f->src, (i_img_dim)rx, (i_img_dim)rx+2, ((i_img_dim)ry+dy) % f->src->ysize, c[dy]); } c2[dy] = interp_i_color(c[dy][0], c[dy][1], rx, f->src->channels); @@ -832,10 +846,10 @@ static void fill_image(i_fill_t *fill, int x, int y, int width, int channels, /* the easy way */ /* this should be possible to optimize to use i_glin() */ while (i < width) { - int rx = x+i; - int ry = y; - int ix = rx / f->src->xsize; - int iy = ry / f->src->ysize; + i_img_dim rx = x+i; + i_img_dim ry = y; + i_img_dim ix = rx / f->src->xsize; + i_img_dim iy = ry / f->src->ysize; if (f->xoff) { rx += iy * f->xoff; @@ -843,7 +857,7 @@ static void fill_image(i_fill_t *fill, int x, int y, int width, int channels, } else if (f->yoff) { ry += ix * f->yoff; - iy = ry / f->src->xsize; + iy = ry / f->src->ysize; } rx -= ix * f->src->xsize; ry -= iy * f->src->ysize; @@ -861,10 +875,11 @@ static void fill_image(i_fill_t *fill, int x, int y, int width, int channels, =cut */ -static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels, - i_fcolor *data) { +static void +fill_imagef(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width, + int channels, i_fcolor *data) { struct i_fill_image_t *f = (struct i_fill_image_t *)fill; - int i = 0; + i_img_dim i = 0; int want_channels = channels > 2 ? 4 : 2; if (f->has_matrix) { @@ -877,7 +892,7 @@ static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels, double iy = floor(ry / f->src->ysize); i_fcolor c[2][2]; i_fcolor c2[2]; - int dy; + i_img_dim dy; if (f->xoff) { rx += iy * f->xoff; @@ -891,12 +906,12 @@ static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels, ry -= iy * f->src->ysize; for (dy = 0; dy < 2; ++dy) { - if ((int)rx == f->src->xsize-1) { - i_gpixf(f->src, f->src->xsize-1, ((int)ry+dy) % f->src->ysize, &c[dy][0]); - i_gpixf(f->src, 0, ((int)ry+dy) % f->src->xsize, &c[dy][1]); + if ((i_img_dim)rx == f->src->xsize-1) { + i_gpixf(f->src, f->src->xsize-1, ((i_img_dim)ry+dy) % f->src->ysize, &c[dy][0]); + i_gpixf(f->src, 0, ((i_img_dim)ry+dy) % f->src->xsize, &c[dy][1]); } else { - i_glinf(f->src, (int)rx, (int)rx+2, ((int)ry+dy) % f->src->ysize, + i_glinf(f->src, (i_img_dim)rx, (i_img_dim)rx+2, ((i_img_dim)ry+dy) % f->src->ysize, c[dy]); } c2[dy] = interp_i_fcolor(c[dy][0], c[dy][1], rx, f->src->channels); @@ -910,10 +925,10 @@ static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels, /* the easy way */ /* this should be possible to optimize to use i_glin() */ while (i < width) { - int rx = x+i; - int ry = y; - int ix = rx / f->src->xsize; - int iy = ry / f->src->ysize; + i_img_dim rx = x+i; + i_img_dim ry = y; + i_img_dim ix = rx / f->src->xsize; + i_img_dim iy = ry / f->src->ysize; if (f->xoff) { rx += iy * f->xoff; @@ -935,10 +950,10 @@ static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels, } static void -fill_opacity(i_fill_t *fill, int x, int y, int width, int channels, - i_color *data) { +fill_opacity(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width, + int channels, i_color *data) { struct i_fill_opacity_t *f = (struct i_fill_opacity_t *)fill; - int alpha_chan = channels-1; /* channels is always 2 or 4 */ + int alpha_chan = channels > 2 ? 3 : 1; i_color *datap = data; (f->other_fill->f_fill_with_color)(f->other_fill, x, y, width, channels, data); @@ -954,10 +969,10 @@ fill_opacity(i_fill_t *fill, int x, int y, int width, int channels, } } static void -fill_opacityf(i_fill_t *fill, int x, int y, int width, int channels, - i_fcolor *data) { - struct i_fill_opacity_t *f = (struct i_fill_alpha_t *)fill; - int alpha_chan = channels-1; /* channels is always 2 or 4 */ +fill_opacityf(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width, + int channels, i_fcolor *data) { + struct i_fill_opacity_t *f = (struct i_fill_opacity_t *)fill; + int alpha_chan = channels > 2 ? 3 : 1; i_fcolor *datap = data; (f->other_fill->f_fill_with_fcolor)(f->other_fill, x, y, width, channels, data);