Image-ButtonMaker

 view release on metacpan or  search on metacpan

lib/Image/ButtonMaker/TextContainer.pm  view on Meta::CPAN

package Image::ButtonMaker::TextContainer;

use Image::Magick;
use strict;
use utf8;


#### Create a dummy image for QueryFontMetrics calls
my $idummy = Image::Magick->new();
$idummy->Read('xc:black');



#### Prototype for TextContainer objects
my @defaults = (
                layout      => 'horizontal',
                align       => 'baseline',
                cells       => [],
                );


my @align_horiz_types  = ('baseline', 'top', 'bottom');
my @layout_types = ('vertical', 'horizontal'); 


#### Private data for TextContainer objects
my @defaults_priv = (
                     error  => 0,
                     errstr => '',
                     );


#### Error codes
use constant ERR_WRONG_CELL_TYPE  => 100;
use constant ERR_WRONG_CELL_PARAM => 101;
use constant ERR_UNSUPPORTED_FEAT => 1000;


#### Cell prototypes #####################################
my @cell_types = ('text', 'space', 'icon');
my %cell_proto = (
                  text => {
                           type      => 'text',
                           font      => '',
                           size      => 10,
                           text      => 'NO_TEXT',
                           antialias => 1,
                           fill      => 'white',
                           scale     => 1.0,
                           },

                  space => {
                            type  => 'space',
                            width => 3,
                            },

                  icon  => {
                            type => 'icon',
                            image => undef,
                            vertfix => 0,
                           }
                  );



##########################################################
## Public-ish methods 
sub new {
    my $self  = shift;

lib/Image/ButtonMaker/TextContainer.pm  view on Meta::CPAN

                             scale     => $cell->{scale},
                             text      => $cell->{text},
                             );


            my ($x_ppem, $y_ppem, $ascender, $descender, $width, $height, $max_advance) =
                $idummy->QueryFontMetrics(%text_param);


            #Height is kinda strange. Recompute:
            $height = $ascender - $descender;

            $acc_width += $width;
            $max_height = $height    if($height    > $max_height);
            $max_asc    = $ascender  if($ascender  > $max_asc);
            $min_desc   = $descender if($descender < $min_desc);
        }

        elsif($type eq 'space') {
            $acc_width += $cell->{width};
        }
        elsif($type eq 'icon') {
            my($width, $height) = $cell->{image}->Get('columns', 'rows');

            $max_height = $height if($height > $max_height);
            $max_asc    = $height if($height > $max_asc);
            $acc_width += $width;
        }
    }

    if($self->{align} eq 'baseline') {
        return ($acc_width, $max_asc-$min_desc, $max_asc, $min_desc);
    }
    return ($acc_width, $max_height, $max_asc, $min_desc);
}


#### render cells into a target image
sub render {
    my $self = shift;
    my ($image, $x_offset, $y_offset) = @_;
    $x_offset = 0 unless($x_offset);
    $y_offset = 0 unless($y_offset);

    $self->reset_error;

    my $layout = $self->{layout};
    if($layout ne 'horizontal') {
        $self->set_error(ERR_UNSUPPORTED_FEAT,
                         "Unsupported layout: $layout");
        return undef;
    }

    my $align = $self->{align};
    my $cells = $self->{cells};

    my ($img_width, $img_height, $max_asc, $min_desc) = $self->compute_size;

    #### If no target image is passed, then generate a target
    if(!$image) {
        $image = Image::Magick->new(size  => $img_width .'x'.$img_height,
                                       matte => 1,
                                       );
        $image->Read('xc:rgba(0,0,0,0)');
    }

    my $leftpoint = $x_offset;
    my $toppoint;

    foreach my $cell (@$cells) {
        my $type = $cell->{type};

        if($type eq 'text') {

            my %text_param =(font      => $cell->{font},
                             pointsize => $cell->{size},
                             text      => $cell->{text},
                             );

            my( $x_ppem, $y_ppem, $ascender, $descender, 
                $width,  $height, $max_advance ) =
                $idummy->QueryFontMetrics(%text_param);

            $height = $ascender - $descender;

            $text_param{antialias} = $cell->{antialias};
            $text_param{fill}      = $cell->{fill};
            $text_param{stroke}    = 'rgba(0,0,0,255)';
            $text_param{scale}     = $cell->{scale};

            if($align eq 'top') {
                $toppoint = $ascender + $y_offset;
            }
            elsif($align eq 'bottom') {
                $toppoint = $img_height + $descender + $y_offset;;
            }
            elsif($align eq 'baseline') {
                $toppoint = $max_asc + $y_offset;;
            }

            $text_param{x} = $leftpoint;
            $text_param{y} = $toppoint;

            my $rr = $image->Annotate(%text_param);

            $leftpoint += $width;
        }
        elsif($type eq 'icon') {

            my $icon = $cell->{image};
            my($i_width, $i_height) = $icon->Get('columns', 'rows');


            if($align eq 'top') {
                $toppoint = $y_offset;;
            }
            elsif($align eq 'bottom') {
                $toppoint = $img_height - $i_height + $y_offset;;
            }
            elsif($align eq 'baseline') {
                $toppoint = $max_asc - $i_height + $y_offset;;



( run in 1.148 second using v1.01-cache-2.11-cpan-39bf76dae61 )