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__ |