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 )