fill = i_new_fill_hatchf(&fc1, &fc2, combine, hatch, cust_hash, dx, dy);
fill = i_new_fill_hatch(&c1, &c2, combine, hatch, cust_hash, dx, dy);
fill = i_new_fill_image(im, matrix, xoff, yoff, combine);
+ fill = i_new_fill_opacity(fill, alpha_mult);
i_fill_destroy(fill);
=head1 DESCRIPTION
/*
=item i_fill_destroy(fill)
-
+=order 90
=category Fills
=synopsis i_fill_destroy(fill);
int dx, int dy);
/*
-=item i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
+=item i_new_fill_hatch(C<fg>, C<bg>, C<combine>, C<hatch>, C<cust_hatch>, C<dx>, C<dy>)
=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<fg> color used for the 1 bits in
+the hatch and C<bg> for the 0 bits. If C<combine> 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<cust_hatch> 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<cust_hatch> 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<dx>, C<dy>) 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 the side of a filled area.
=cut
*/
}
/*
-=item i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
+=item i_new_fill_hatchf(C<fg>, C<bg>, C<combine>, C<hatch>, C<cust_hatch>, C<dx>, C<dy>)
=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<fg> color used for the 1 bits in
+the hatch and C<bg> for the 0 bits. If C<combine> 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<cust_hatch> 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<cust_hatch> 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<dx>, C<dy>) 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 the side of a filled area.
=cut
*/
};
/*
-=item i_new_fill_image(im, matrix, xoff, yoff, combine)
+=item i_new_fill_image(C<im>, C<matrix>, C<xoff>, C<yoff>, C<combine>)
=category Fills
=synopsis i_fill_t *fill = i_new_fill_image(src_img, matrix, x_offset, y_offset, combine);
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<xoff> and C<yoff> are the offset into the image to start filling from.
=cut
*/
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);
+
+struct i_fill_opacity_t {
+ i_fill_t base;
+ i_fill_t *other_fill;
+ double alpha_mult;
+};
+
+static struct i_fill_opacity_t
+opacity_fill_proto =
+ {
+ fill_opacity,
+ fill_opacityf,
+ NULL
+ };
+
+i_fill_t *
+i_new_fill_opacity(i_fill_t *base_fill, double alpha_mult) {
+ struct i_fill_opacity_t *fill = mymalloc(sizeof(*fill));
+ *fill = opacity_fill_proto;
+
+ fill->base.combine = base_fill->combine;
+ fill->base.combinef = base_fill->combinef;
+
+ 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;
+}
#define T_SOLID_FILL(fill) ((i_fill_solid_t *)(fill))
i_adapt_fcolors(want_channels, f->src->channels, data, width);
}
+static void
+fill_opacity(i_fill_t *fill, int x, int y, int width, int channels,
+ i_color *data) {
+ struct i_fill_opacity_t *f = (struct i_fill_opacity_t *)fill;
+ 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);
+ while (width--) {
+ double new_alpha = datap->channel[alpha_chan] * f->alpha_mult;
+ if (new_alpha < 0)
+ datap->channel[alpha_chan] = 0;
+ else if (new_alpha > 255)
+ datap->channel[alpha_chan] = 255;
+ else datap->channel[alpha_chan] = (int)(new_alpha + 0.5);
+
+ ++datap;
+ }
+}
+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_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);
+
+ while (width--) {
+ double new_alpha = datap->channel[alpha_chan] * f->alpha_mult;
+ if (new_alpha < 0)
+ datap->channel[alpha_chan] = 0;
+ else if (new_alpha > 1.0)
+ datap->channel[alpha_chan] = 1.0;
+ else datap->channel[alpha_chan] = new_alpha;
+
+ ++datap;
+ }
+}
/*
=back