SWF::Builder::Gradient - SWF gradient object.


SWF-Builder documentation Contained in the SWF-Builder distribution.

Index


Code Index:

NAME

Top

SWF::Builder::Gradient - SWF gradient object.

SYNOPSIS

Top

    my $gr = $mc->new_gradient;
    $gr->add_color(   0 => '000000',
		     98 => '0000ff',
		    128 => 'ff0000',
		    158 => '0000ff',
		    255 => '000000',
		   );

    my $gm = $gr->matrix;
    my $shape = $mc->new_shape
        ->fillstyle($gr, 'linear', $gm)
        ->moveto( ... )
        ->lineto( ... )-> ... ;
    $gm->fit_to_rect(longer => $shape->get_bbox);

DESCRIPTION

Top

Gradient object is a kind of fill styles of shapes. Colors are interpolated between the control points determined by ratios. Each gradient has 1-8 control points.

$gr = $mc->new_gradient

returns a new gradient object.

$gr->add_color( $ratio, $color [, $ratio, $color ...])

adds control points of the gradient. $ratio is a position of the point. 0 maps to left/center and 255 to right/outer for linear/radial gradient. $color can take a six or eight-figure hexadecimal string, an array reference of R, G, B, and optional alpha value, an array reference of named parameters such as [Red => 255], and SWF::Element::RGB/RGBA object.

$gm = $gr->matrix

returns a transformation matrix for the gradient.

$gm->fit_to_rect( $mode => @rect )

transforms the gradient matrix to fit to the rectangle. $mode can take as follows:

fit

to fit the gradient square to the rectangle. It does not keep proportion.

width

to fit the gradient square to the width of the rectangle, and scales it with keeping proportion.

height

to fit the gradient square to the height of the rectangle, and scales it with keeping proportion.

longer

to fit the gradient square to the longer side of the rectangle, and scales it with keeping proportion.

shorter

to fit the gradient square to the shorter side of the rectangle, and scales it with keeping proportion.

COPYRIGHT

Top


SWF-Builder documentation Contained in the SWF-Builder distribution.

package SWF::Builder::Gradient;

use Carp;
use SWF::Builder::ExElement;

@SWF::Builder::Gradient::ISA = ('SWF::Element::Array::GRADIENT3', 'SWF::Builder::ExElement::Color::AddColor');
our $VERSION = "0.02";

sub new {
    my ($class, $is_alpha) = @_;

    bless {
	'_is_alpha' => SWF::Element::Scalar->new($is_alpha||0),
	'_gradient' => SWF::Element::Array::GRADIENT3->new,
    }, $class;
}

sub pack {
    my ($self, $stream) = @_;
    $self->{_gradient}->pack($stream);
}

sub add_color {
    my $self = shift;
    my $g = $self->{_gradient};

    while ( my ($ratio, $color) = splice(@_,0, 2) ) {
	croak "Too many gradient records (must be 1 to 8)" if @$g >= 8;
	push @$g, $g->new_element
	    ( Color => $self->_add_color($color),
	      Ratio => $ratio
	      );
    }
    $self;
}

sub matrix {
  SWF::Builder::Gradient::MATRIX->new;
}

package SWF::Builder::Gradient::MATRIX;

@SWF::Builder::Gradient::MATRIX::ISA = ('SWF::Builder::ExElement::MATRIX');

use Carp;

sub fit_to_rect {
    my $self = shift;
    my $mode = shift;
    $mode ||= 'longer';
    my @rect = @_;
    my ($x1, $y1, $x2, $y2, $sx, $sy);

    {
	if (@rect == 1) {
	    if (ref($param[0]) eq 'ARRAY') {
		@rect = @{$rect[0]};
		redo;
	    } elsif (UNIVERSAL::isa($rect[0], 'SWF::Element::RECT')) {
		($x1, $y1, $x2, $y2) = ($rect[0]->Xmin, $rect[0]->Ymin, $rect[0]->Xmax, $rect[0]->Ymax);
	    }
	} elsif ($rect[0]=~/^[XY]m/) {
	    my %rect = @rect;
	    ($x1, $y1, $x2, $y2) = @rect{qw/Xmin Ymin Xmax Ymax/};
	} else {
	    ($x1, $y1, $x2, $y2) = @rect;
	}
    }
    croak('Invalid rectangle for fit_to_rect') unless defined $x1;

    $sx = ($x2 - $x1)*20/32768;
    $sy = ($y2 - $y1)*20/32768;
    for ($mode) {
	/^fit$/ and do {
	    $self->scale($sx,$sy);
	    last;
	};
	/^width$/ and do {
	    $self->scale($sx);
	    last;
	};
	/^height$/ and do {
	    $self->scale($sy);
	    last;
	};
	/^longer$/ and do {
	    $self->scale(($sx>=$sy)?$sx:$sy);
	    last;
	};
	/^shorter$/ and do {
	    $self->scale(($sx>=$sy)?$sy:$sx);
	    last;
	};
    }
    $self->moveto(($x1+$x2)/2, ($y1+$y2)/2);  # /2*20
    $self;
}

1;
__END__