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   45 use parent 'Khonsu::Ra';
  5         10  
  5         29  
4              
5             sub attributes {
6 398     398 0 608 my $a = shift;
7             return (
8             text => {$a->RW, $a->STR},
9             overflow => {$a->RW, $a->BOOL},
10 398     398   908 indent => {$a->RW, $a->NUM, default => sub { 0 }},
11             pad => {$a->RW, $a->STR},
12             pad_end => {$a->RW, $a->STR},
13 398     398   1105 align => {$a->RW, $a->STR, default => sub { 'left' }},
14             end_w => {$a->RW, $a->NUM},
15 398     398   1061 margin => {$a->RW, $a->NUM, default => sub { 5 }},
16 398         17974 $a->FONT,
17             $a->POINTS
18             );
19             }
20              
21             sub add {
22 1084     1084 0 5822 my ($self, $file, %attributes) = @_;
23            
24 1084 100       4586 my $font = $self->font->load($file, %{ delete $attributes{font} || {} });
  1084         7708  
25              
26 1084 100 100     5217 if (!$attributes{x} && !$attributes{align}) {
27 34         168 $attributes{x} = $file->page->x;
28 34   33     257 $attributes{y} = $attributes{y} || $file->page->y;
29 34         188 $attributes{h} = $file->page->remaining_height();
30 34         183 $attributes{w} = $file->page->width();
31             }
32            
33 1084         5394 $self->set_attributes(%attributes);
34              
35 1084         5062 my $size = $self->font->size;
36            
37 1084         5070 my $text = $file->page->current->text;
38            
39 1084         339898 $text->font($font, $size);
40            
41 1084         206507 $text->fillcolor($self->font->colour);
42              
43 1084         158786 my (%pos) = (
44             l => $self->font->line_height,
45             $self->get_points()
46             );
47              
48 1084         5234 my $ypos = $file->page->h - ($pos{y} + $pos{l});
49            
50 1084         2648 my $max_height = $ypos - $pos{h};
51            
52 1084         1835 my $xpos = $pos{x};
53              
54 1084         4651 my $indent = $self->indent;
55            
56 1084         4674 my @paragraphs = split /\n/, $self->text;
57 1084         3987 my $space = $text->advancewidth(" ");
58              
59 1084         86527 my @words;
60 1084   100     4980 while ($ypos - $pos{l} >= $max_height && (scalar @paragraphs || scalar @words)) {
      100        
61 2419 100       5561 unless (scalar @words) {
62 1084         1849 my $next_line = shift @paragraphs;
63 1084         15126 @words = split(/ /, $next_line);
64 1084 100 66     20031 push @words, $1 if $next_line !~ m/^\s+$/ && $next_line =~ m/(\s+)$/;
65 1084 50       2297 push @words, $next_line unless scalar @words;
66 1084 100       2256 if ($indent) {
67 289         852 unshift @words, map { "" } 0 .. $indent;
  2011         3821  
68             }
69             }
70 2419         4154 my $word = shift @words;
71 2419         4639 $word =~ s/\t/ /g;
72 2419         5764 my ($width, @line) = ($text->advancewidth($word), ());
73 2419   100     258212 while ($width <= $pos{w} && defined $word) {
74 39334         3433918 push @line, $word;
75 39334         58783 $word = shift @words;
76 39334 100       68628 if (defined $word) {
77 38269 100       83164 $width += $space unless $word =~ m/^(\s+)$/;
78 38269         53206 $word =~ s/\t/ /g;
79 38269         72961 $width += $text->advancewidth($word);
80             }
81             }
82 2419         151322 $self->end_w($xpos + $width);
83 2419 100       7882 if ($word) {
    100          
84 1354 50       3860 unshift @words, $word if (scalar @words);
85             } elsif ($self->pad) {
86 348         1412 my $pad_width = $text->advancewidth($self->pad);
87 348 100       25429 my $pad_end_width = $self->pad_end ? $text->advancewidth($self->pad_end) : 0;
88 348         28971 my $left = int(($pos{w} - ($width + $pad_end_width)) / $pad_width);
89 348 50       1853 push @line, $self->pad x $left if $left;
90 348 100       1336 push @line, $self->pad_end if $self->pad_end;
91 348         850 $width = $pos{w};
92             }
93              
94 2419         9747 my $align = $self->align;
95 2419 100       7135 if ($align eq 'center') {
    100          
96 172         480 $xpos = $xpos + (($pos{w} - $width) / 2);
97             } elsif ($align eq 'right') {
98 86         272 $xpos = $xpos + ($pos{w} - $width);
99 86         523 $self->end_w($xpos + $pos{w});
100             }
101 2419         7884 $text->translate($xpos, $ypos);
102 2419         1131947 $text->text(join(" ", @line));
103 2419         1536664 $ypos -= $pos{l};
104             }
105              
106 1084         6364 $file->page->y($file->page->h - (($ypos + $pos{l}) - $self->margin));
107              
108 1084 100       3840 if (scalar @words) {
109 19         2620 push @paragraphs, join " ", @words;
110             }
111              
112 1084 100 100     5104 if (!$self->overflow && scalar @paragraphs) {
113 17         98 $file->page->next($file);
114 17         397 return $self->add($file, text => join "\n", @paragraphs);
115             }
116              
117 1067         8572 return $file;
118             }
119              
120             1;