File Coverage

blib/lib/Khonsu/Text.pm
Criterion Covered Total %
statement 72 72 100.0
branch 33 36 91.6
condition 16 19 84.2
subroutine 6 6 100.0
pod 0 2 0.0
total 127 135 94.0


line stmt bran cond sub pod time code
1             package Khonsu::Text;
2              
3 5     5   32 use parent 'Khonsu::Ra';
  5         11  
  5         42  
4              
5             sub attributes {
6 608     608 0 1379 my $a = shift;
7             return (
8             text => {$a->RW, $a->STR},
9             overflow => {$a->RW, $a->BOOL},
10 608     608   2166 indent => {$a->RW, $a->NUM, default => sub { 0 }},
11             pad => {$a->RW, $a->STR},
12             pad_end => {$a->RW, $a->STR},
13 608     608   2361 align => {$a->RW, $a->STR, default => sub { 'left' }},
14             end_w => {$a->RW, $a->NUM},
15 608     608   1948 margin => {$a->RW, $a->NUM, default => sub { 5 }},
16 608         52456 $a->FONT,
17             $a->POINTS
18             );
19             }
20              
21             sub add {
22 1660     1660 0 12861 my ($self, $file, %attributes) = @_;
23            
24 1660 100       11763 my $font = $self->font->load($file, %{ delete $attributes{font} || {} });
  1660         18387  
25              
26 1660 100 100     26905 if (!$attributes{x} && !$attributes{align}) {
27 34         214 $attributes{x} = $file->page->x;
28 34   33     258 $attributes{y} = $attributes{y} || $file->page->y;
29 34         220 $attributes{h} = $file->page->remaining_height();
30 34         253 $attributes{w} = $file->page->width();
31             }
32            
33 1660         13396 $self->set_attributes(%attributes);
34              
35 1660         15018 my $size = $self->font->size;
36            
37 1660         22556 my $text = $file->page->current->text;
38            
39 1660         783930 $text->font($font, $size);
40            
41 1660         461652 $text->fillcolor($self->font->colour);
42              
43 1660         322307 my (%pos) = (
44             l => $self->font->line_height,
45             $self->get_points()
46             );
47              
48 1660         13136 my $ypos = $file->page->h - ($pos{y} + $pos{l});
49            
50 1660         5619 my $max_height = $ypos - $pos{h};
51            
52 1660         3771 my $xpos = $pos{x};
53              
54 1660         10999 my $indent = $self->indent;
55            
56 1660         12273 my @paragraphs = split /\n/, $self->text;
57 1660         8964 my $space = $text->advancewidth(" ");
58              
59 1660         210541 my @words;
60 1660   100     12794 while ($ypos - $pos{l} >= $max_height && (scalar @paragraphs || scalar @words)) {
      100        
61 2995 100       8192 unless (scalar @words) {
62 1660         4868 my $next_line = shift @paragraphs;
63 1660         20944 @words = split(/ /, $next_line);
64 1660 100 66     32201 push @words, $1 if $next_line !~ m/^\s+$/ && $next_line =~ m/(\s+)$/;
65 1660 50       4674 push @words, $next_line unless scalar @words;
66 1660 100       4918 if ($indent) {
67 464         2138 unshift @words, map { "" } 0 .. $indent;
  3236         7698  
68             }
69             }
70 2995         7216 my $word = shift @words;
71 2995         9078 $word =~ s/\t/ /g;
72 2995         9543 my ($width, @line) = ($text->advancewidth($word), ());
73 2995   100     418296 while ($width <= $pos{w} && defined $word) {
74 42469         4170142 push @line, $word;
75 42469         70839 $word = shift @words;
76 42469 100       109602 if (defined $word) {
77 40828 100       130939 $width += $space unless $word =~ m/^(\s+)$/;
78 40828         69553 $word =~ s/\t/ /g;
79 40828         89471 $width += $text->advancewidth($word);
80             }
81             }
82 2995         181875 $self->end_w($xpos + $width);
83 2995 100       16812 if ($word) {
    100          
84 1354 50       4576 unshift @words, $word if (scalar @words);
85             } elsif ($self->pad) {
86 558         2602 my $pad_width = $text->advancewidth($self->pad);
87 558 100       49765 my $pad_end_width = $self->pad_end ? $text->advancewidth($self->pad_end) : 0;
88 558         56393 my $left = int(($pos{w} - ($width + $pad_end_width)) / $pad_width);
89 558 50       4252 push @line, $self->pad x $left if $left;
90 558 100       2719 push @line, $self->pad_end if $self->pad_end;
91 558         1743 $width = $pos{w};
92             }
93              
94 2995         14786 my $align = $self->align;
95 2995 100       12593 if ($align eq 'center') {
    100          
96 250         1049 $xpos = $xpos + (($pos{w} - $width) / 2);
97             } elsif ($align eq 'right') {
98 125         433 $xpos = $xpos + ($pos{w} - $width);
99 125         695 $self->end_w($xpos + $pos{w});
100             }
101 2995         14636 $text->translate($xpos, $ypos);
102 2995         1837173 $text->text(join(" ", @line));
103 2995         2244693 $ypos -= $pos{l};
104             }
105              
106 1660         15398 $file->page->y($file->page->h - (($ypos + $pos{l}) - $self->margin));
107              
108 1660 100       8587 if (scalar @words) {
109 19         2859 push @paragraphs, join " ", @words;
110             }
111              
112 1660 100 100     11354 if (!$self->overflow && scalar @paragraphs) {
113 17         148 $file->page->next($file);
114 17         455 return $self->add($file, text => join "\n", @paragraphs);
115             }
116              
117 1643         19311 return $file;
118             }
119              
120             1;