App-WIoZ

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

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

README.md  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 `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

ex/wioz.pl  view on Meta::CPAN

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 1.095 second using v1.01-cache-2.11-cpan-5735350b133 )