+sub polypolygon {
+ my ($self, %opts) = @_;
+
+ $self->_valid_image("polypolygon")
+ or return;
+
+ my $points = $opts{points};
+ $points
+ or return $self->_set_error("polypolygon: missing required points");
+
+ my $mode = _first($opts{mode}, "evenodd");
+
+ if ($opts{filled}) {
+ my $color = _color(_first($opts{color}, [ 0, 0, 0, 0 ]))
+ or return $self->_set_error($Imager::ERRSTR);
+
+ i_poly_poly_aa($self->{IMG}, $points, $mode, $color)
+ or return $self->_set_error($self->_error_as_msg);
+ }
+ elsif ($opts{fill}) {
+ my $fill = $opts{fill};
+ $self->_valid_fill($fill, "polypolygon")
+ or return;
+
+ i_poly_poly_aa_cfill($self->{IMG}, $points, $mode, $fill->{fill})
+ or return $self->_set_error($self->_error_as_msg);
+ }
+ else {
+ my $color = _color(_first($opts{color}, [ 0, 0, 0, 255 ]))
+ or return $self->_set_error($Imager::ERRSTR);
+
+ my $rimg = $self->{IMG};
+
+ if (_first($opts{aa}, 1)) {
+ for my $poly (@$points) {
+ my $xp = $poly->[0];
+ my $yp = $poly->[1];
+ for my $i (0 .. $#$xp - 1) {
+ i_line_aa($rimg, $xp->[$i], $yp->[$i], $xp->[$i+1], $yp->[$i+1],
+ $color, 0);
+ }
+ i_line_aa($rimg, $xp->[$#$xp], $yp->[$#$yp], $xp->[0], $yp->[0],
+ $color, 0);
+ }
+ }
+ else {
+ for my $poly (@$points) {
+ my $xp = $poly->[0];
+ my $yp = $poly->[1];
+ for my $i (0 .. $#$xp - 1) {
+ i_line($rimg, $xp->[$i], $yp->[$i], $xp->[$i+1], $yp->[$i+1],
+ $color, 0);
+ }
+ i_line($rimg, $xp->[$#$xp], $yp->[$#$yp], $xp->[0], $yp->[0],
+ $color, 0);
+ }
+ }
+ }
+
+ return $self;
+}