implemented unionall and unionall_ip
[sdlgit/SDL_perl.git] / lib / SDL / Game / Rect.pm
index 274c4b8..b3070d7 100644 (file)
@@ -411,6 +411,108 @@ sub clip_ip {
     return;
 }
 
+
+sub _test_union {
+    my ($self, $rect) = (@_);
+    my ($x, $y, $w, $h);
+
+    $x = $self->x < $rect->x ? $self->x : $rect->x;  # MIN
+    $y = $self->y < $rect->y ? $self->y : $rect->y;  # MIN
+    
+    $w = ($self->x + $self->w) > ($rect->x + $rect->w)
+       ? ($self->x + $self->w) - $x
+       : ($rect->x + $rect->w) - $x
+       ;  # MAX
+       
+    $h = ($self->y + $self->h) > ($rect->y + $rect->h)
+       ? ($self->y + $self->h) - $y
+       : ($rect->y + $rect->h) - $y
+       ;  # MAX
+
+    return ($x, $y, $w, $h);
+}
+
+sub union {
+    my ($self, $rect) = (@_);
+    
+    unless ($rect->isa('SDL::Rect')) {
+        croak "must receive an SDL::Rect-based object";
+    }
+    
+    my ($x, $y, $w, $h) = _test_union($self, $rect);
+    return $self->new($x, $y, $w, $h);
+}
+
+sub union_ip {
+    my ($self, $rect) = (@_);
+    
+    unless ($rect->isa('SDL::Rect')) {
+        croak "must receive an SDL::Rect-based object";
+    }
+    
+    my ($x, $y, $w, $h) = _test_union($self, $rect);
+    
+    $self->x($x);
+    $self->y($y);
+    $self->w($w);
+    $self->y($h);
+    
+    return;
+}
+
+sub _test_unionall {
+    my ($self, $rects) = (@_);
+    
+    # initial values for union rect
+    my $left   = $self->x;
+    my $top    = $self->y;
+    my $right  = $self->x + $self->w;
+    my $bottom = $self->y + $self->h;
+    
+    foreach my $rect (@{$rects}) {
+        unless ($rect->isa('SDL::Rect')) {
+            # TODO: better error message, maybe saying which item 
+            # is the bad one (by list position)
+            croak "must receive an array reference of SDL::Rect-based objects";
+        }
+
+        $left   = $rect->x if $rect->x < $left; # MIN
+        $top    = $rect->y if $rect->y < $top; # MIN
+        $right  = ($rect->x + $rect->w) if ($rect->x + $rect->w) > $right;  # MAX
+        $bottom = ($rect->y + $rect->h) if ($rect->y + $rect->h) > $bottom; # MAX 
+    }
+    
+    return ($left, $top, $right - $left, $bottom - $top);
+}
+
+sub unionall {
+    my ($self, $rects) = (@_);
+    
+    croak "must receive an array reference of SDL::Rect-based objects"
+        unless defined $rects and ref $rects eq 'ARRAY';
+
+    my ($x, $y, $w, $h) = _test_unionall($self, $rects);
+    
+    return $self->new($x, $y, $w, $h);
+}
+
+sub unionall_ip {
+    my ($self, $rects) = (@_);
+    
+    croak "must receive an array reference of SDL::Rect-based objects"
+        unless defined $rects and ref $rects eq 'ARRAY';
+
+    my ($x, $y, $w, $h) = _test_unionall($self, $rects);
+    
+    $self->x($x);
+    $self->y($y);
+    $self->w($w);
+    $self->h($h);
+    
+    return;
+}
+
+
 42;
 __END__