File Coverage

blib/lib/WE_Frontend/TextLayouter.pm
Criterion Covered Total %
statement 78 82 95.1
branch 26 32 81.2
condition 7 12 58.3
subroutine 9 10 90.0
pod 1 4 25.0
total 121 140 86.4


line stmt bran cond sub pod time code
1             # -*- perl -*-
2              
3             #
4             # $Id: TextLayouter.pm,v 1.4 2003/12/16 15:21:23 eserte Exp $
5             # Author: Slaven Rezic
6             #
7             # Copyright (C) 2001 Online Office Berlin. All rights reserved.
8             # Copyright (C) 2002 Slaven Rezic.
9             # This is free software; you can redistribute it and/or modify it under the
10             # terms of the GNU General Public License, see the file COPYING.
11              
12             #
13             # Mail: slaven@rezic.de
14             # WWW: http://we-framework.sourceforge.net
15             #
16              
17             package WE_Frontend::TextLayouter;
18              
19 2     2   1461 use strict;
  2         4  
  2         76  
20 2     2   10 use vars qw($VERSION %fontinfo @EXPORT_OK);
  2         3  
  2         206  
21             $VERSION = sprintf("%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/);
22              
23 2     2   12 use base 'Exporter';
  2         4  
  2         1794  
24             @EXPORT_OK = qw(break_text continue_text_with_nl combine_fontinfo);
25              
26             sub break_text {
27 2     2 1 607 my($text, $fontinfo, $boxwidth, $boxheight, %args) = @_;
28              
29 2         4 my @out;
30 2 100       6 my $box = $args{'-box'}; $box = "" if !defined $box;
  2         13  
31 2   50     12 my $x = $args{'-x'} || 0;
32 2   100     9 my $y = $args{'-y'} || 0;
33 2   50     10 my $maxlineheight = $args{'-maxlineheight'} || 0;
34 2         4 my $lastboxref = $args{'-lastbox'};
35              
36 2         10 my $space_width = (get_bounds(" ", $fontinfo))[0];
37 2         19 my $line_height = (get_bounds("A", $fontinfo))[1]; # XXX maybe better character than "A"?
38              
39 2         12 foreach my $line (split /\n/, $text) {
40              
41 14         16 my $push_word;
42 14         20 my $word_height = 0;
43              
44             my $next_line_or_box = sub {
45 26 100   26   50 if ($y+$word_height+$maxlineheight >= $boxheight) {
46             # next box
47 3         7 push @out, $box;
48 3         6 $box = "";
49 3         3 $x = 0;
50 3         4 $y = 0;
51 3         4 $maxlineheight = 0;
52 3 100       16 $push_word->() if $push_word;
53             } else {
54             # next line
55 23         28 $box .= "\n";
56 23         28 $x = 0;
57 23         24 $y += $maxlineheight;
58 23         22 $maxlineheight = 0;
59 23 100       105 $push_word->() if $push_word;
60             }
61 14         51 };
62              
63 14         58 foreach my $word (split /\s+/, $line) {
64 106         112 my $word_width;
65 106         186 ($word_width, $word_height) = get_bounds($word, $fontinfo);
66              
67             my $is_beginning_of_line = sub {
68 212 100   212   1184 $box eq '' || $box =~ /\n\Z/s;
69 106         339 };
70              
71             $push_word = sub {
72 106 100   106   130 if (!$is_beginning_of_line->()) {
73 80         99 $box .= " ";
74 80         96 $x += $space_width;
75             }
76 106         171 $box .= $word;
77 106         100 $x += $word_width;
78 106 100       275 if ($word_height > $maxlineheight) {
79 26         65 $maxlineheight = $word_height;
80             }
81 106         335 };
82              
83 106 100       476 my $this_space_width = (!$is_beginning_of_line->() ? $space_width : 0);
84              
85 106 100 66     474 if ($x+$word_width+$this_space_width < $boxwidth &&
86             $y+$word_height < $boxheight) {
87             # fits into this line
88 94         148 $push_word->();
89             } else {
90 12         20 $next_line_or_box->();
91             }
92             }
93              
94 14         30 undef $push_word;
95 14         58 $maxlineheight = $line_height;
96 14         28 $next_line_or_box->();
97             }
98              
99 2 50       9 push @out, $box if $box ne "";
100              
101 2 100       9 if ($lastboxref) {
102 1         4 $lastboxref->{'-box'} = $box;
103 1         2 $lastboxref->{'-x'} = $x;
104 1         3 $lastboxref->{'-y'} = $y;
105 1         2 $lastboxref->{'-maxlineheight'} = $maxlineheight;
106             }
107              
108 2         23 @out;
109             }
110              
111             #XXX
112             # sub add_br {
113             # my($fontinfo, $boxwidth, $boxheight, %args) = @_;
114             # if (!$args{'-prevlastbox'}) {
115             # die "The -prevlastbox option is missing";
116             # }
117             # my $prevlastbox = delete $args{'-prevlastbox'};
118             # my %new_args = (-box => $prevlastbox->{'-box'}."
\n",
119             # -x => 0,
120             # -y => $prevlastbox->{'-maxlineheight'}+$prevlastbox->{'-y'});
121             # break_text("", $fontinfo, $boxwidth, $boxheight, %args, %new_args);
122             # }
123              
124             ###XXX hmmm...????
125             sub continue_text_with_nl {
126 1     1 0 973 my($text, $fontinfo, $boxwidth, $boxheight, %args) = @_;
127 1 50       6 if (!$args{'-prevlastbox'}) {
128 0         0 die "The -prevlastbox option is missing";
129             }
130 1         2 my $prevlastbox = delete $args{'-prevlastbox'};
131 1 50       10 my %new_args = (-box => $prevlastbox->{'-box'}.($prevlastbox->{'-box'}ne""?"\n":""),
132             -x => 0,
133             -y => $prevlastbox->{'-maxlineheight'}+$prevlastbox->{'-y'});
134 1         6 break_text($text, $fontinfo, $boxwidth, $boxheight, %args, %new_args);
135             }
136              
137             sub add_y {
138 0     0 0 0 my($prevlastbox_ref, $yadd) = @_;
139 0 0       0 $prevlastbox_ref->{'y'} = 0 if !$prevlastbox_ref->{'y'};
140 0         0 $prevlastbox_ref->{'y'} += $yadd;
141             }
142              
143             sub get_bounds {
144 110     110 0 165 my($text, $fontinfo) = @_;
145 110         125 my($x,$y) = (0,0);
146              
147 110         319 foreach my $ch (split //, $text) {
148 732         763 my $ord = ord $ch;
149 732 50 33     3010 if ($ord >= $fontinfo->{'firstchar'} &&
150             $ord <= $fontinfo->{'lastchar'}) {
151 732         949 my $inx = $ord-$fontinfo->{'firstchar'};
152 732         936 $x += $fontinfo->{'widths'}[$inx];
153 732         1003 my $chheight = $fontinfo->{'heights'}[$inx];
154 732 100       1635 if ($chheight > $y) {
155 110         196 $y = $chheight;
156             }
157             }
158             }
159              
160 110         349 ($x,$y);
161             }
162              
163             1;
164              
165             __END__