#!perl -w
use strict;
-use Test::More tests => 121;
+use Test::More tests => 156;
use Imager ':handy';
use Imager::Fill;
use Imager::Color::Float;
+use Imager::Test qw(is_image is_color4 is_fcolor4 is_color3);
use Config;
Imager::init_log("testout/t20fill.log", 1);
cmp_ok(Imager->errstr, '=~', 'No color named', "check error message");
}
+{ # RT #35278
+ # hatch fills on a grey scale image don't adapt colors
+ for my $bits (8, 'double') {
+ my $im_g = Imager->new(xsize => 10, ysize => 10, channels => 1, bits => $bits);
+ $im_g->box(filled => 1, color => 'FFFFFF');
+ my $fill = Imager::Fill->new
+ (
+ combine => 'normal',
+ hatch => 'weave',
+ fg => '000000',
+ bg => 'FFFFFF'
+ );
+ $im_g->box(fill => $fill);
+ my $im_c = Imager->new(xsize => 10, ysize => 10, channels => 3, bits => $bits);
+ $im_c->box(filled => 1, color => 'FFFFFF');
+ $im_c->box(fill => $fill);
+ my $im_cg = $im_g->convert(preset => 'rgb');
+ is_image($im_c, $im_cg, "check hatch is the same between color and greyscale (bits $bits)");
+
+ # check the same for image fills
+ my $grey_fill = Imager::Fill->new
+ (
+ image => $im_g,
+ combine => 'normal'
+ );
+ my $im_cfg = Imager->new(xsize => 20, ysize => 20, bits => $bits);
+ $im_cfg->box(filled => 1, color => '808080');
+ $im_cfg->box(fill => $grey_fill);
+ my $rgb_fill = Imager::Fill->new
+ (
+ image => $im_cg,
+ combine => 'normal'
+ );
+ my $im_cfc = Imager->new(xsize => 20, ysize => 20, bits => $bits);
+ $im_cfc->box(filled => 1, color => '808080');
+ $im_cfc->box(fill => $rgb_fill);
+ is_image($im_cfg, $im_cfc, "check filling from grey image matches filling from rgb (bits = $bits)");
+
+ my $im_gfg = Imager->new(xsize => 20, ysize => 20, channels => 1, bits => $bits);
+ $im_gfg->box(filled => 1, color => '808080');
+ $im_gfg->box(fill => $grey_fill);
+ my $im_gfg_c = $im_gfg->convert(preset => 'rgb');
+ is_image($im_gfg_c, $im_cfg, "check grey filled with grey against base (bits = $bits)");
+
+ my $im_gfc = Imager->new(xsize => 20, ysize => 20, channels => 1, bits => $bits);
+ $im_gfc->box(filled => 1, color => '808080');
+ $im_gfc->box(fill => $rgb_fill);
+ my $im_gfc_c = $im_gfc->convert(preset => 'rgb');
+ is_image($im_gfc_c, $im_cfg, "check grey filled with color against base (bits = $bits)");
+ }
+}
+
+{ # alpha modifying fills
+ { # 8-bit/sample
+ my $base_img = Imager->new(xsize => 4, ysize => 2, channels => 4);
+ $base_img->setscanline
+ (
+ x => 0,
+ y => 0,
+ pixels =>
+ [
+ map Imager::Color->new($_),
+ qw/FF000020 00FF0080 00008040 FFFF00FF/,
+ ],
+ );
+ $base_img->setscanline
+ (
+ x => 0,
+ y => 1,
+ pixels =>
+ [
+ map Imager::Color->new($_),
+ qw/FFFF00FF FF000000 00FF0080 00008040/
+ ]
+ );
+ my $base_fill = Imager::Fill->new
+ (
+ image => $base_img,
+ combine => "normal",
+ );
+ ok($base_fill, "make the base image fill");
+ my $fill50 = Imager::Fill->new(type => "opacity", opacity => 0.5, other => $base_fill)
+ or print "# ", Imager->errstr, "\n";
+ ok($fill50, "make 50% alpha translation fill");
+
+ { # 4 channel image
+ my $out = Imager->new(xsize => 10, ysize => 10, channels => 4);
+ $out->box(fill => $fill50);
+ is_color4($out->getpixel(x => 0, y => 0),
+ 255, 0, 0, 16, "check alpha output");
+ is_color4($out->getpixel(x => 2, y => 1),
+ 0, 255, 0, 64, "check alpha output");
+ $out->box(filled => 1, color => "000000");
+ is_color4($out->getpixel(x => 0, y => 0),
+ 0, 0, 0, 255, "check after clear");
+ $out->box(fill => $fill50);
+ is_color4($out->getpixel(x => 4, y => 2),
+ 16, 0, 0, 255, "check drawn against background");
+ is_color4($out->getpixel(x => 6, y => 3),
+ 0, 64, 0, 255, "check drawn against background");
+ }
+ { # 3 channel image
+ my $out = Imager->new(xsize => 10, ysize => 10, channels => 3);
+ $out->box(fill => $fill50);
+ is_color3($out->getpixel(x => 0, y => 0),
+ 16, 0, 0, "check alpha output");
+ is_color3($out->getpixel(x => 2, y => 1),
+ 0, 64, 0, "check alpha output");
+ is_color3($out->getpixel(x => 0, y => 1),
+ 128, 128, 0, "check alpha output");
+ }
+ }
+ { # double/sample
+ use Imager::Color::Float;
+ my $base_img = Imager->new(xsize => 4, ysize => 2, channels => 4, bits => "double");
+ $base_img->setscanline
+ (
+ x => 0,
+ y => 0,
+ pixels =>
+ [
+ map Imager::Color::Float->new(@$_),
+ [ 1, 0, 0, 0.125 ],
+ [ 0, 1, 0, 0.5 ],
+ [ 0, 0, 0.5, 0.25 ],
+ [ 1, 1, 0, 1 ],
+ ],
+ );
+ $base_img->setscanline
+ (
+ x => 0,
+ y => 1,
+ pixels =>
+ [
+ map Imager::Color::Float->new(@$_),
+ [ 1, 1, 0, 1 ],
+ [ 1, 0, 0, 0 ],
+ [ 0, 1, 0, 0.5 ],
+ [ 0, 0, 0.5, 0.25 ],
+ ]
+ );
+ my $base_fill = Imager::Fill->new
+ (
+ image => $base_img,
+ combine => "normal",
+ );
+ ok($base_fill, "make the base image fill");
+ my $fill50 = Imager::Fill->new(type => "opacity", opacity => 0.5, other => $base_fill)
+ or print "# ", Imager->errstr, "\n";
+ ok($fill50, "make 50% alpha translation fill");
+ my $out = Imager->new(xsize => 10, ysize => 10, channels => 4, bits => "double");
+ $out->box(fill => $fill50);
+ is_fcolor4($out->getpixel(x => 0, y => 0, type => "float"),
+ 1, 0, 0, 0.0625, "check alpha output at 0,0");
+ is_fcolor4($out->getpixel(x => 2, y => 1, type => "float"),
+ 0, 1, 0, 0.25, "check alpha output at 2,1");
+ $out->box(filled => 1, color => "000000");
+ is_fcolor4($out->getpixel(x => 0, y => 0, type => "float"),
+ 0, 0, 0, 1, "check after clear");
+ $out->box(fill => $fill50);
+ is_fcolor4($out->getpixel(x => 4, y => 2, type => "float"),
+ 0.0625, 0, 0, 1, "check drawn against background at 4,2");
+ is_fcolor4($out->getpixel(x => 6, y => 3, type => "float"),
+ 0, 0.25, 0, 1, "check drawn against background at 6,3");
+ }
+ ok(!Imager::Fill->new(type => "opacity"),
+ "should fail to make an opacity fill with no other fill object");
+ is(Imager->errstr, "'other' parameter required to create opacity fill",
+ "check error message");
+ ok(!Imager::Fill->new(type => "opacity", other => "xx"),
+ "should fail to make an opacity fill with a bad other parameter");
+ is(Imager->errstr, "'other' parameter must be an Imager::Fill object to create an opacity fill",
+ "check error message");
+
+ # check auto conversion of hashes
+ ok(Imager::Fill->new(type => "opacity", other => { solid => "FF0000" }),
+ "check we auto-create fills")
+ or print "# ", Imager->errstr, "\n";
+
+ {
+ # fill with combine none was modifying the wrong channel for a
+ # no-alpha target image
+ my $fill = Imager::Fill->new(solid => "#FFF", combine => "none");
+ my $fill2 = Imager::Fill->new
+ (
+ type => "opacity",
+ opacity => 0.5,
+ other => $fill
+ );
+ my $im = Imager->new(xsize => 1, ysize => 1);
+ ok($im->box(fill => $fill2), "fill with replacement opacity fill");
+ is_color3($im->getpixel(x => 0, y => 0), 255, 255, 255,
+ "check for correct colour");
+ }
+
+ {
+ require Imager::Fountain;
+ my $fount = Imager::Fountain->new;
+ $fount->add(c1 => "FFFFFF"); # simple white to black
+ # base fill is a fountain
+ my $base_fill = Imager::Fill->new
+ (
+ fountain => "linear",
+ segments => $fount,
+ xa => 0,
+ ya => 0,
+ xb => 100,
+ yb => 100,
+ );
+ ok($base_fill, "made fountain fill base");
+ my $op_fill = Imager::Fill->new
+ (
+ type => "opacity",
+ other => $base_fill,
+ opacity => 0.5,
+ );
+ ok($op_fill, "made opacity fountain fill");
+ my $im = Imager->new(xsize => 100, ysize => 100);
+ ok($im->box(fill => $op_fill), "draw with it");
+ }
+}
+
sub color_close {
my ($c1, $c2) = @_;