App-WIoZ
view release on metacpan or search on metacpan
Revision history for Perl module App::WIoZ
0.004 Fri, 30 Aug 2013 17:30:11 +0200
- manage fonts
0.003 Mon, 05 Aug 2013 09:53:49 +0200
- fix angle constraint on Moose 2.1004 by switching from Num to Str
0.002 Sun, 04 Aug 2013 17:58:05 +0200
- try to fix default value for angle to 0.0 after cpantest bug reports
with Moose 2.1004
0.001 Fri, 02 Aug 2013 13:38:30 +0200
- initial release
App::WIoZ is an acronym for "Words for Io by Zeus", look for the Correggio painting to watch the cloud.
App::WIoZ is based on `Wordle` strategy and `yawc` perl clone.
Usage:
my $File = 'words.txt';
my $wioz = App::WIoZ->new(
font_min => 18, font_max => 64,
set_font => "DejaVuSans,normal,bold",
filename => "testoutput",
basecolor => '226666'); # violet
if (-f $File) {
my @words = $wioz->read_words($File);
$wioz->do_layout(@words);
}
else {
$wioz->chg_font("LiberationSans,normal,bold");
$wioz->update_colors('testoutput.sl.txt');
}
watch `doc/freq.pl` to create a `words.txt` file.
# STATUS
App::WIoZ is actually a POC to play with Moose, Cairo or Math::PlanePath.
The use of an Hilbert curve to manage free space is for playing with Math::PlanePath modules.
Performance can be improved in free space matching, or in spiral strategy to find free space.
Max and min font sizes can certainly be computed.
Feel free to clone this project on GitHub.
# SETTINGS
## height
image height, default to 600
## width
image width, default to 800
## font_min, font_max
required min and max font size
## set_font, chg_font, font
accessors for font name, type and weight
`set_font` : set font in new WIoZ object, default is `'LiberationSans,normal,bold'`
`chg_font` : change font
`font` : read font object
Usage :
$wioz = App::WIoZ->new( font_min => 18, font_max => 64,
set_font => 'DejaVuSans,normal,bold');
$fontname = $wioz->font->{font};
$wioz->chg_font('LiberationSans,normal,bold');
## filename
file name output, extension `.png` or `.svg` will be added
## svg
produce a svg output, default value
sub usage {
say './wioz.pl [file.txt|color]';
exit;
}
my $File = $ARGV[0];
&usage if !$File ;
my $wioz = App::WIoZ->new(
font_min => 18, font_max => 64,
filename => "testoutput",
#set_font => 'DejaVuSans,normal,bold',
basecolor => '226666'); # violet
#basecolor => '084A93'); # bleu
#basecolor => '29872F'); # vert
if (-f $File) {
my @words = $wioz->read_words($File);
$wioz->do_layout(@words);
}
else {
$wioz->update_colors('testoutput.sl.txt');
lib/App/WIoZ.pm view on Meta::CPAN
App::WIoZ is an acronym for "Words for Io by Zeus", look for the Correggio painting to watch the cloud.
App::WIoZ is based on C<Wordle> strategy and C<yawc> perl clone.
Usage:
my $File = 'words.txt';
my $wioz = App::WIoZ->new(
font_min => 18, font_max => 64,
set_font => "DejaVuSans,normal,bold",
filename => "testoutput",
basecolor => '226666'); # violet
if (-f $File) {
my @words = $wioz->read_words($File);
$wioz->do_layout(@words);
}
else {
$wioz->chg_font("LiberationSans,normal,bold");
$wioz->update_colors('testoutput.sl.txt');
}
watch C<doc/freq.pl> to create a C<words.txt> file.
=head1 STATUS
App::WIoZ is actually a POC to play with Moose, Cairo or Math::PlanePath.
The use of an Hilbert curve to manage free space is for playing with Math::PlanePath modules.
Performance can be improved in free space matching, or in spiral strategy to find free space.
Max and min font sizes can certainly be computed.
Feel free to clone this project on GitHub.
=head1 SETTINGS
=head2 height
image height, default to 600
=cut
lib/App/WIoZ.pm view on Meta::CPAN
is => 'ro', isa => 'App::WIoZ::Point',
lazy => 1,
default => sub {
my $self = shift;
return App::WIoZ::Point->new(
x => int($self->width/2),
y => int($self->height/2));
}
);
=head2 font_min, font_max
required min and max font size
=cut
has ['font_min','font_max'] => (
is => 'ro', required => 1, isa => 'Int'
);
=head2 set_font, chg_font, font
accessors for font name, type and weight
C<set_font> : set font in new WIoZ object, default is C<'LiberationSans,normal,bold'>
C<chg_font> : change font
C<font> : read font object
Usage :
$wioz = App::WIoZ->new( font_min => 18, font_max => 64,
set_font => 'DejaVuSans,normal,bold');
$fontname = $wioz->font->{font};
$wioz->chg_font('LiberationSans,normal,bold');
=cut
has 'font' => (
isa => 'HashRef',
is => 'ro', lazy => 1,
writer => 'chg_font',
builder => '_set_font'
);
# for font builder
has 'set_font' => ( is => 'rw',isa => 'Str' );
sub _set_font {
my ($self,$font) = @_;
my ($fname,$ftype,$fweight) = split ',', ($self->set_font || ',,');
return ( { font => $fname || 'LiberationSans',
type => $ftype || 'normal',
weight => $fweight || 'bold' });
};
# for font change
around 'chg_font' => sub {
my ($next,$self,$font) = @_;
my ($fname,$ftype,$fweight) = split ',', $font;
$self->$next( {font => $fname, type => $ftype, weight => $fweight});
};
has 'backcolor' => (
is => 'ro', isa => 'Str',
default => 'white'
);
has 'cr' => (
is => 'rw', isa => 'Cairo::Context',
lazy => 1, builder => '_create_cr'
lib/App/WIoZ.pm view on Meta::CPAN
open $fh, '<:utf8', $filename;
my @L = <$fh>;
close $fh;
foreach my $l (@L) {
my ($t,$n) = split /;/,$l;
if ( $t && $n ) {
$t =~ s/\s*$//g; $n =~ s/\s*$//g;
#$all_weight += $n;
$weight_max = $n if ( $n >$weight_max );
$weight_min = $n if ( $n <$weight_min );
my $w = new App::WIoZ::Word(text => $t, weight => $n, font => $self->font);
push @res, $w;
} else {
warn "error line: $_";
}
}
# set initial size and color
my @color = Color::Mix->new->analogous($self->basecolor, 12, 12);
foreach my $v (@res) {
$v->size( (($v->weight - $weight_min) / ($weight_max - $weight_min)) *
($self->font_max - $self->font_min) +
$self->font_min );
$v->color($color[int(rand(12))]);
}
return @res;
}
=head2 update_colors
Read words position from file and update colors.
lib/App/WIoZ.pm view on Meta::CPAN
# reset background
$self->cr->rectangle (0, 0, $self->width, $self->height);
my $po = Graphics::ColorNames->new;
my @rgb = $po->rgb($self->backcolor);
$self->cr->set_source_rgb ($rgb[0]/255.0, $rgb[1]/255.0, $rgb[2]/255.0);
$self->cr->fill;
foreach my $l (@L) {
my ($show,$text,$size,$x,$y,$angle) = split /\t/,$l;
#say "$text - $size - $angle";
my $w = App::WIoZ::Word->new(text => $text, size => $size, angle => $angle, show => $show, color => $color[int(rand(12))], font => $self->font);
my $newc = App::WIoZ::Point->new( x => $x, y => $y);
$w->update_size($self,$size);
$w->update_c($newc);
$self->_show_word($w);
}
$self->_save_to_png if (!$self->svg);
}
=head2 do_layout
lib/App/WIoZ.pm view on Meta::CPAN
foreach my $w (@words) {
print $fh $w->show."\t".$w->text."\t".$w->size."\t".$w->c->x."\t".$w->c->y."\t".$w->angle."\n";
}
close $fh;
}
sub _show_word {
my ($self,$w) = @_;
$self->cr->select_font_face(
$w->font->{font},$w->font->{type},$w->font->{weight});
$self->cr->set_font_size($w->size);
my $po = Graphics::ColorNames->new;
my @rgb = $po->rgb($w->color);
$self->cr->set_source_rgb ($rgb[0]/255.0, $rgb[1]/255.0, $rgb[2]/255.0);
#say ' '.$w->text.' '.$w->color;
if ($w->angle < 0) {
$self->cr->save;
$self->cr->move_to($w->p->x+$w->width,$w->p->y);
$self->cr->rotate($w->angle);
$self->cr->show_text($w->text);
$self->cr->restore;
lib/App/WIoZ/Word.pm view on Meta::CPAN
#use feature 'say';
has 'text' => (
is => 'ro', required => 1, isa => 'Str'
);
has 'weight' => (
is => 'ro', required => 0, isa => 'Int'
);
has 'font' => (
is => 'rw', isa => 'HashRef',
default => sub { {font => 'LiberationSans', type => 'normal', weight => 'bold'} }
);
has 'width' => (
is => 'rw', isa => 'Int'
);
has 'height' => (
is => 'rw', isa => 'Int'
);
lib/App/WIoZ/Word.pm view on Meta::CPAN
my $center = App::WIoZ::Point->new(x=>$c->x,y=>$c->y);
my $p = App::WIoZ::Point->new(x=>$c->x-int($tl/2),y=>$c->y+int($th/2));
my $p2 = App::WIoZ::Point->new(x=>$c->x+int($tl/2),y=>$c->y-int($th/2));
$self->c($center);
$self->p($p);
$self->p2($p2);
}
sub update_size {
my ($self,$ya,$size) = @_;
$ya->cr->select_font_face($self->font->{font},$self->font->{type},$self->font->{weight});
$ya->cr->set_font_size($size);
#$ya->cr->rotate($self->angle);
my $te = $ya->cr->text_extents ($self->text);
my $fe = $ya->cr->font_extents;
#my $th = $fe->{"height"};#-4*$fe->{"descent"};
my $th = $fe->{"height"}-2*$fe->{"descent"};
my $tl = $te->{"width"};#+2*$te->{"x_bearing"};
$self->size($size);
if ($self->angle < 0) {
$self->height(int($tl+2*$te->{"x_bearing"}));
$self->width(int($th));
}
else {
$self->height(int($th));
t/00-wioz.t view on Meta::CPAN
=cut
use Test::More tests => 14;
use_ok('App::WIoZ');
my $dirname = (-f 't/test-words.txt')?'t/':'';
my $wioz = App::WIoZ->new( height => 300, font_min => 18, font_max => 64 );
is($wioz->center->x,400,'x center is 400 (def 800)');
is($wioz->center->y,150,'y center is 150');
is($wioz->font->{font},'LiberationSans','default font LiberationSans');
# a new smallest svg image for tests
$wioz = App::WIoZ->new( height => 200, width => 200, font_min => 18, font_max => 64, filename => $dirname.'test');
my @words = $wioz->read_words($dirname.'test-words.txt');
isa_ok($words[0],'App::WIoZ::Word');
$wioz->do_layout(@words); # compute image
is(-f $dirname.'test.svg',1,"create image ".$dirname.'test.svg');
is(-f $dirname.'test.sl.txt',1,"save layout ".$dirname.'test.sl.txt');
# a new smallest png image for tests
$wioz = App::WIoZ->new( height => 200, width => 200, font_min => 18, font_max => 64,
filename => $dirname.'test' , svg => 0,
set_font => 'DejaVuSans,italic,normal');
is($wioz->font->{font},'DejaVuSans','set_font to DejaVuSans');
@words = $wioz->read_words($dirname.'test-words.txt');
is ($words[0]->font->{font},'DejaVuSans','word with DejaVuSans font');
$wioz->do_layout(@words); # compute image
is(-f $dirname.'test.png',1,"create image ".$dirname.'test.png');
is(-f $dirname.'test.sl.txt',1,"save layout ".$dirname.'test.sl.txt');
# update colorsa nd font
#$wioz->chg_font('strenuous,normal,normal');
$wioz->chg_font('LiberationSans,normal,bold');
is($wioz->font->{font},'LiberationSans','chg_font to LiberationSans');
$wioz->filename($dirname.'test2');
$wioz->update_colors($dirname.'test.sl.txt');
is(-f $dirname.'test2.png',1,"create image with new color ".$dirname.'test2.png');
# update colors
$wioz->filename($dirname.'test3');
$wioz->update_colors($dirname.'test.sl.txt');
is(-f $dirname.'test3.png',1,"create image with new color ".$dirname.'test3.png');
# test directory clean up
unlink $dirname.'test.sl.txt';
unlink $dirname.'test.svg';
unlink $dirname.'test.png';
unlink $dirname.'test2.png';
unlink $dirname.'test3.png';
$wioz = App::WIoZ->new( height => 300, font_min => 18, font_max => 64, set_font => 'DejaVuSans,normal,bold');
t/00-word.t view on Meta::CPAN
=cut
use Test::More tests => 13;
use_ok('App::WIoZ::Word');
my $w = App::WIoZ::Word->new( text => 'test', weight => 4 );
is($w->text,'test','text is test');
is($w->weight,4,'weight set to 4');
is($w->font->{font},'LiberationSans','default font to LiberationSans');
#is($w->angle,0,'most of the time angle is set to 0');
$w->height(10);
$w->width(40);
is($w->height,10,'basic test: real word height will be compute in graphic context');
is($w->width,40,'basic test: real word width will be compute in graphic context');
use_ok('App::WIoZ::Point');
( run in 2.325 seconds using v1.01-cache-2.11-cpan-5735350b133 )