# Copyright 2010, 2011, 2012 Kevin Ryde # This file is part of Image-Base-Other. # # Image-Base-Other is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3, or (at your option) any later # version. # # Image-Base-Other is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with Image-Base-Other. If not, see . package Image::Base::Multiplex; use 5.004; use strict; use Carp; use vars '$VERSION', '@ISA'; $VERSION = 9; use Image::Base; @ISA = ('Image::Base'); # uncomment this to run the ### lines #use Smart::Comments; sub new { my $class = shift; if (ref $class) { # clone by copying fields, don't think need to copy images array return bless { %$class }, $class; } return bless { -images => [], @_ }, $class; } sub _get { my ($self, $key) = @_; # ### Image-Base-Multiplex _get(): $key if ($key eq '-images') { return $self->SUPER::_get($key); } else { my $image = $self->{'-images'}->[0] || return undef; return $image->get($key); } } sub set { my $self = shift; # ### Image-Base-Multiplex set() my $set_file; for (my $i = 0; $i < @_; ) { my $key = $_[$i]; $set_file = ($key eq '-file'); if ($key eq '-images') { $self->{$key} = $_[$i+1]; splice @_, $i, 2; } else { $i += 2 } } my $images = $self->{'-images'}; if ($set_file && @$images > 1) { croak 'Refusing to set multiple images to same -file'; } foreach my $image (@$images) { $image->set(@_); } } sub load { my $self = shift; my $images = $self->{'-images'}; if (@_ && @$images > 1) { croak 'Refusing to load multiple images from one file'; } foreach my $image (@$images) { $image->load; } } sub save { my $self = shift; my $images = $self->{'-images'}; if (@_ && @$images > 1) { croak 'Refusing to save multiple images to one file'; } foreach my $image (@$images) { $image->save; } } sub xy { my $self = shift; ### Image-Base-Multiplex xy(): @_[1..$#_] my $images = $self->{'-images'}; if (@_ > 2) { foreach my $image (@$images) { $image->xy(@_); } } else { my ($x, $y) = @_; my $image = $images->[0] || return undef; return $image->xy($x,$y); } } sub line { foreach my $image (@{shift->{'-images'}}) { $image->line(@_); } } sub rectangle { foreach my $image (@{shift->{'-images'}}) { $image->rectangle(@_); } } sub ellipse { foreach my $image (@{shift->{'-images'}}) { $image->ellipse(@_); } } sub diamond { foreach my $image (@{shift->{'-images'}}) { $image->diamond(@_); } } sub add_colours { foreach my $image (@{shift->{'-images'}}) { if (my $coderef = $image->can('add_colours')) { $image->$coderef(@_); } } } sub Image_Base_Other_xy_points { ### Multiplex xy_points foreach my $image (@{shift->{'-images'}}) { if (my $coderef = $image->can('Image_Base_Other_xy_points')) { $image->$coderef(@_); } else { for (my $i = 1; $i < @_; $i += 2) { $image->xy ($_[$i], $_[$i+1], $_[0]); # colour } } } } sub Image_Base_Other_rectangles { ### Multiplex rectangles foreach my $image (@{shift->{'-images'}}) { if (my $coderef = $image->can('Image_Base_Other_rectangles')) { $image->$coderef(@_); } else { for (my $i = 2; $i < @_; $i += 4) { ### rect: @_[$i .. $i+3], $_[0], $_[1] $image->rectangle (@_[$i .. $i+3], $_[0], # colour $_[1]); # fill } } } } 1; __END__ =for stopwords filename Ryde arrayref multi-output =head1 NAME Image::Base::Multiplex -- draw to multiple Image::Base objects simultaneously =for test_synopsis my ($image1, $image2) =head1 SYNOPSIS use Image::Base::Multiplex; my $multiplex_image = Image::Base::Multiplex->new (-images => [$image1,$image2]); $multiplex_image->rectangle (0,0, 99,99, 'white'); $multiplex_image->line (50,50, 70,70, '#FF00FF'); =head1 CLASS HIERARCHY C is a subclass of C, Image::Base Image::Base::Multiplex =head1 DESCRIPTION C operates on multiple C objects simultaneously so that one drawing call draws to a set of images. =head1 FUNCTIONS =over 4 =item C<$image = Image::Base::Multiplex-Enew (key=Evalue,...)> Create and return a new multiplex image object. An initial list of target images can be supplied, my $image = Image::Base::Multiplex->new (-images => [ $image1, $image2 ]); Or start empty and set some C<-images> later my $image = Image::Base::Multiplex->new (); =item C<$image-Exy (...)> =item C<$image-Eline (...)> =item C<$image-Erectangle (...)> =item C<$image-Eellipse (...)> =item C<$image-Ediamond (...)> These calls are passed through to each target image. =item C<$image-Eadd_colours ($colour, $colour, ...)> Call C on each target image which supports that method, and skip those which don't. =back =head1 ATTRIBUTES =over =item C<-images> (arrayref of C objects) The target images to draw on. =back =head1 SEE ALSO L L has a similar multi-output to its devices. =head1 HOME PAGE http://user42.tuxfamily.org/image-base-other/index.html =head1 LICENSE Image-Base-Other is Copyright 2010, 2011, 2012 Kevin Ryde Image-Base-Other is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. Image-Base-Other is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Image-Base-Other. If not, see . =cut