line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package SWF::Builder::Character::Text; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
7
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
42
|
|
4
|
1
|
|
|
1
|
|
6
|
use utf8; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
56
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION="0.04"; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
@SWF::Builder::Character::Text::ISA = qw/ SWF::Builder::Character::UsableAsMask /; |
9
|
|
|
|
|
|
|
@SWF::Builder::Character::Text::Imported::ISA = qw/ SWF::Builder::Character::Imported SWF::Builder::Character::Text /; |
10
|
|
|
|
|
|
|
@SWF::Builder::Character::StaticText::Imported::ISA = qw/ SWF::Builder::Character::Text::Imported /; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
#### |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
package SWF::Builder::Character::Text::Def; |
15
|
|
|
|
|
|
|
|
16
|
1
|
|
|
1
|
|
158
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
87
|
|
17
|
1
|
|
|
1
|
|
6
|
use SWF::Element; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
20
|
|
18
|
1
|
|
|
1
|
|
5
|
use SWF::Builder::Character; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
29
|
|
19
|
1
|
|
|
1
|
|
5
|
use SWF::Builder::Character::Font; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
23
|
|
20
|
1
|
|
|
1
|
|
6
|
use SWF::Builder::ExElement; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2285
|
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
@SWF::Builder::Character::Text::Def::ISA = qw/ SWF::Builder::Character::Text SWF::Builder::ExElement::Color::AddColor/; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub new { |
25
|
1
|
|
|
1
|
|
3
|
my ($class, $font, $text) = @_; |
26
|
1
|
|
|
|
|
1
|
my $tag; |
27
|
1
|
|
|
|
|
11
|
my $self = bless { |
28
|
|
|
|
|
|
|
_bounds => SWF::Builder::ExElement::BoundaryRect->new, |
29
|
|
|
|
|
|
|
_textrecords => SWF::Element::Array::TEXTRECORDARRAY2->new, |
30
|
|
|
|
|
|
|
_kerning => 1, |
31
|
|
|
|
|
|
|
_current_font => '', |
32
|
|
|
|
|
|
|
_current_size => 12, |
33
|
|
|
|
|
|
|
_max_ascent => 0, |
34
|
|
|
|
|
|
|
_max_descent => 0, |
35
|
|
|
|
|
|
|
_p_max_descent=> 0, |
36
|
|
|
|
|
|
|
_current_X => 0, |
37
|
|
|
|
|
|
|
_current_Y => 0, |
38
|
|
|
|
|
|
|
_leading => 0, |
39
|
|
|
|
|
|
|
_nl => undef, |
40
|
|
|
|
|
|
|
_nl_X => 0, |
41
|
|
|
|
|
|
|
_nlbounds => SWF::Builder::ExElement::BoundaryRect->new, |
42
|
|
|
|
|
|
|
}, $class; |
43
|
1
|
|
|
|
|
14
|
$self->_init_character; |
44
|
1
|
|
|
|
|
12
|
$self->_init_is_alpha; |
45
|
1
|
|
|
|
|
18
|
$self->{_nl} = $self->_get_last_record; |
46
|
1
|
50
|
|
|
|
5
|
$self->font($font) if defined $font; |
47
|
1
|
50
|
|
|
|
3
|
$self->text($text) if defined $text; |
48
|
1
|
|
|
|
|
8
|
$self; |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
sub _get_last_record { |
52
|
4
|
|
|
4
|
|
5
|
my $self = shift; |
53
|
4
|
|
|
|
|
8
|
my $records = $self->{_textrecords}; |
54
|
4
|
|
|
|
|
5
|
my $r; |
55
|
|
|
|
|
|
|
|
56
|
4
|
100
|
66
|
|
|
23
|
if (!@$records or $records->[-1]->GlyphEntries->defined) { |
57
|
1
|
|
|
|
|
16
|
$r = SWF::Element::TEXTRECORD2->new; |
58
|
1
|
|
|
|
|
18
|
push @$records, $r; |
59
|
1
|
|
|
|
|
3
|
return $r; |
60
|
|
|
|
|
|
|
} else { |
61
|
3
|
|
|
|
|
76
|
return $records->[-1]; |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub font { |
66
|
1
|
|
|
1
|
|
4
|
my ($self, $font) = @_; |
67
|
1
|
50
|
|
|
|
6
|
return if $font eq $self->{_current_font}; |
68
|
1
|
50
|
|
|
|
9
|
croak "Invalid font" unless UNIVERSAL::isa($font, 'SWF::Builder::Character::Font'); |
69
|
1
|
50
|
|
|
|
7
|
croak "The font applied to the static text needs to embed glyph data" unless $font->embed; |
70
|
1
|
|
|
|
|
5
|
my $r = $self->_get_last_record; |
71
|
1
|
|
|
|
|
3
|
my $size = $self->{_current_size}; |
72
|
1
|
|
|
|
|
7
|
$r->TextHeight($size*20); |
73
|
1
|
|
|
|
|
11
|
$r->FontID($font->{ID}); |
74
|
1
|
|
|
|
|
10
|
$self->{_current_font} = $font; |
75
|
1
|
|
|
|
|
13
|
$self->_depends($font); |
76
|
1
|
|
|
|
|
108
|
my $as = $font->{_tag}->FontAscent * $size / 1024; |
77
|
1
|
|
|
|
|
11
|
my $des = $font->{_tag}->FontDescent * $size / 1024; |
78
|
1
|
50
|
|
|
|
11
|
$self->{_max_ascent} = $as if $self->{_max_ascent} < $as; |
79
|
1
|
50
|
|
|
|
6
|
$self->{_max_descent} = $des if $self->{_max_descent} < $des; |
80
|
1
|
|
|
|
|
5
|
$self; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub size { |
84
|
1
|
|
|
1
|
|
2
|
my ($self, $size) = @_; |
85
|
1
|
|
|
|
|
4
|
my $r = $self->_get_last_record; |
86
|
1
|
|
|
|
|
5
|
$r->TextHeight($size*20); |
87
|
1
|
|
|
|
|
7
|
$r->FontID($self->{_current_font}->{ID}); |
88
|
1
|
|
|
|
|
8
|
$self->{_current_size} = $size; |
89
|
1
|
|
|
|
|
4
|
my $as = $self->{_current_font}{_tag}->FontAscent * $size / 1024; |
90
|
1
|
|
|
|
|
7
|
my $des = $self->{_current_font}{_tag}->FontDescent * $size / 1024; |
91
|
1
|
50
|
|
|
|
7
|
$self->{_max_ascent} = $as if $self->{_max_ascent} < $as; |
92
|
1
|
50
|
|
|
|
5
|
$self->{_max_descent} = $des if $self->{_max_descent} < $des; |
93
|
1
|
|
|
|
|
5
|
$self; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub kerning { |
97
|
0
|
|
|
0
|
|
0
|
my ($self, $kern) = @_; |
98
|
|
|
|
|
|
|
|
99
|
0
|
0
|
|
|
|
0
|
if (defined $kern) { |
100
|
0
|
|
|
|
|
0
|
$self->{_kerning} = $kern; |
101
|
0
|
|
|
|
|
0
|
$self; |
102
|
|
|
|
|
|
|
} else { |
103
|
0
|
|
|
|
|
0
|
$self->{_kerning}; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub leading { |
108
|
0
|
|
|
0
|
|
0
|
my ($self, $leading) = @_; |
109
|
0
|
0
|
|
|
|
0
|
if (defined $leading) { |
110
|
0
|
|
|
|
|
0
|
$self->{_leading} = $leading; |
111
|
0
|
|
|
|
|
0
|
$self; |
112
|
|
|
|
|
|
|
} else { |
113
|
0
|
|
|
|
|
0
|
$self->{_leading}; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub color { |
118
|
1
|
|
|
1
|
|
2
|
my ($self, $color) = @_; |
119
|
1
|
|
|
|
|
3
|
my $r = $self->_get_last_record; |
120
|
1
|
|
|
|
|
13
|
$color = $self->_add_color($color); |
121
|
1
|
|
|
|
|
259
|
$r->TextColor($color); |
122
|
1
|
|
|
|
|
12
|
$self; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub _bbox_adjust { |
126
|
2
|
|
|
2
|
|
6
|
my $self = $_[0]; # Don't use 'shift' |
127
|
2
|
|
|
|
|
5
|
my $nl = $self->{_nl}; |
128
|
2
|
|
|
|
|
6
|
my $nlbbox = $self->{_nlbounds}; |
129
|
2
|
100
|
|
|
|
9
|
return unless defined $nlbbox->[0]; |
130
|
|
|
|
|
|
|
|
131
|
1
|
|
|
|
|
5
|
my $s = $self->{_current_Y} + $self->{_max_ascent} + $self->{_p_max_descent}; |
132
|
|
|
|
|
|
|
|
133
|
1
|
|
|
|
|
9
|
$self->{_bounds}->set_boundary($nlbbox->[0], $nlbbox->[1]+$s*20, $nlbbox->[2], $nlbbox->[3]+$s*20); |
134
|
1
|
|
|
|
|
6
|
$self->{_nlbounds} = SWF::Builder::ExElement::BoundaryRect->new; |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub _line_adjust { |
138
|
1
|
|
|
1
|
|
3
|
my $self = $_[0]; # Don't use 'shift' |
139
|
1
|
|
|
|
|
4
|
&_bbox_adjust; |
140
|
1
|
|
|
|
|
5
|
$self->{_current_Y} += $self->{_max_ascent} + $self->{_p_max_descent}; |
141
|
1
|
|
|
|
|
9
|
$self->{_nl}->YOffset($self->{_current_Y}*20); |
142
|
1
|
|
|
|
|
7
|
my $size = $self->{_current_size}; |
143
|
1
|
|
|
|
|
5
|
my $ft = $self->{_current_font}{_tag}; |
144
|
1
|
|
|
|
|
4
|
$self->{_max_ascent} = $ft->FontAscent * $size / 1024; |
145
|
1
|
|
|
|
|
9
|
$self->{_max_descent} = $ft->FontDescent * $size / 1024; |
146
|
1
|
|
|
|
|
7
|
$self->{_nl} = undef; |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
sub position { |
150
|
0
|
|
|
0
|
|
0
|
&_line_adjust; |
151
|
0
|
|
|
|
|
0
|
goto &_position; |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
sub _position { |
155
|
0
|
|
|
0
|
|
0
|
my ($self, $x, $y) = @_; |
156
|
0
|
|
|
|
|
0
|
my $r = $self->_get_last_record; |
157
|
0
|
|
|
|
|
0
|
$r->XOffset($x*20); |
158
|
0
|
|
|
|
|
0
|
$r->YOffset($y*20); |
159
|
0
|
|
|
|
|
0
|
$self->{_bounds}->set_boundary($x*20, $y*20, $x*20, $y*20); |
160
|
0
|
|
|
|
|
0
|
$self->{_current_X} = $self->{_nl_X} = $x; |
161
|
0
|
|
|
|
|
0
|
$self->{_current_Y} = $y; |
162
|
0
|
|
|
|
|
0
|
$self->{_nl} = $r; |
163
|
0
|
|
|
|
|
0
|
$self->{_p_max_descent} = 0; |
164
|
0
|
|
|
|
|
0
|
$self; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
sub text { |
168
|
1
|
|
|
1
|
|
2
|
my ($self, $text) = @_; |
169
|
1
|
|
|
|
|
11
|
my @text = split /([\x00-\x1f]+)/, $text; |
170
|
1
|
|
|
|
|
2
|
my $font = $self->{_current_font}; |
171
|
1
|
|
|
|
|
3
|
my $scale = $self->{_current_size} / 51.2; |
172
|
1
|
|
|
|
|
2
|
my $glyph_hash = $font->{_glyph_hash}; |
173
|
|
|
|
|
|
|
|
174
|
1
|
|
|
|
|
5
|
while (my($text, $ctrl) = splice(@text, 0, 2)) { |
175
|
1
|
|
|
|
|
2
|
my $bbox = $self->{_nlbounds}; |
176
|
1
|
|
|
|
|
6
|
$font->add_glyph($text); |
177
|
1
|
|
|
|
|
7
|
my @chars = split //, $text; |
178
|
1
|
50
|
|
|
|
5
|
if (@chars) { |
179
|
1
|
|
|
|
|
10
|
my $gent = $self->{_textrecords}[-1]->GlyphEntries; |
180
|
1
|
|
|
|
|
10
|
my $c1 = shift @chars; |
181
|
1
|
|
|
|
|
4
|
push @chars, undef; |
182
|
1
|
|
|
|
|
3
|
my $x = $self->{_current_X}; |
183
|
1
|
|
|
|
|
2
|
for my $c (@chars) { |
184
|
4
|
|
|
|
|
9
|
my $ord_c1 = ord($c1); |
185
|
4
|
100
|
66
|
|
|
48
|
my $kern = ($self->{_kerning} and defined $c) ? $font->kern($ord_c1, ord($c)) : 0; |
186
|
|
|
|
|
|
|
# my $kern = 0; |
187
|
4
|
|
|
|
|
14
|
my $adv = ($glyph_hash->{$c1}[0] + $kern) * $scale; |
188
|
4
|
|
|
|
|
9
|
my $b = $glyph_hash->{$c1}[1]{_bounds}; |
189
|
4
|
50
|
|
|
|
10
|
if (defined $b->[0]) { |
190
|
4
|
|
|
|
|
65
|
$bbox->set_boundary($x*20+$b->[0]*$scale, $b->[1]*$scale, $x*20+$b->[2]*$scale, $b->[3]*$scale); |
191
|
|
|
|
|
|
|
} else { |
192
|
0
|
|
|
|
|
0
|
$bbox->set_boundary($x*20, 0, $x*20, 0); |
193
|
|
|
|
|
|
|
} |
194
|
4
|
|
|
|
|
18
|
push @$gent, SWF::Builder::Text::GLYPHENTRY->new($ord_c1, $adv, $font); |
195
|
4
|
|
|
|
|
6
|
$x += $adv; |
196
|
4
|
|
|
|
|
14
|
$c1 = $c; |
197
|
|
|
|
|
|
|
} |
198
|
1
|
|
|
|
|
4
|
$self->{_current_X} = $x; |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
1
|
50
|
33
|
|
|
11
|
if ($ctrl and (my $n = $ctrl=~tr/\n/\n/)) { |
202
|
0
|
|
|
|
|
0
|
my $md = $self->{_max_descent}; |
203
|
0
|
|
|
|
|
0
|
my $height = $self->{_max_ascent} + $md; |
204
|
0
|
|
|
|
|
0
|
$self->_line_adjust; |
205
|
|
|
|
|
|
|
# $self->_position($self->{_nl_X}, $self->{_current_Y} + $height * ($n-1) + ($font->{_tag}->FontLeading * $scale / 20 + $self->{_leading})*$n); |
206
|
0
|
|
|
|
|
0
|
$self->_position($self->{_nl_X}, $self->{_current_Y} + $height * ($n-1) + $self->{_leading} * $n); |
207
|
0
|
|
|
|
|
0
|
$self->{_p_max_descent} = $md; |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
} |
210
|
1
|
|
|
|
|
6
|
$self; |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
sub get_bbox { |
214
|
1
|
|
|
1
|
|
7
|
my $self = shift; |
215
|
1
|
|
|
|
|
5
|
$self->_bbox_adjust; |
216
|
1
|
|
|
|
|
2
|
return map{$_/20} @{$self->{_bounds}}; |
|
4
|
|
|
|
|
9
|
|
|
1
|
|
|
|
|
4
|
|
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
sub _pack { |
220
|
1
|
|
|
1
|
|
3
|
my ($self, $stream) = @_; |
221
|
|
|
|
|
|
|
|
222
|
1
|
50
|
|
|
|
10
|
$self->_line_adjust if $self->{_nl}; |
223
|
|
|
|
|
|
|
|
224
|
1
|
|
|
|
|
3
|
my $x = $self->{_current_X} = 0; |
225
|
1
|
|
|
|
|
3
|
my $y = $self->{_current_Y} = 0; |
226
|
|
|
|
|
|
|
|
227
|
1
|
|
|
|
|
2
|
my $tag; |
228
|
1
|
50
|
|
|
|
6
|
if ($self->{_is_alpha}) { |
229
|
1
|
|
|
|
|
33
|
$tag = SWF::Element::Tag::DefineText2->new; |
230
|
|
|
|
|
|
|
} else { |
231
|
0
|
|
|
|
|
0
|
$tag = SWF::Element::Tag::DefineText->new; |
232
|
|
|
|
|
|
|
} |
233
|
1
|
|
|
|
|
66
|
$tag->configure( CharacterID => $self->{ID}, |
234
|
|
|
|
|
|
|
TextBounds => $self->{_bounds}, |
235
|
|
|
|
|
|
|
TextRecords => $self->{_textrecords}, |
236
|
|
|
|
|
|
|
); |
237
|
1
|
|
|
|
|
61
|
$tag->pack($stream); |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
#### |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
{ |
245
|
|
|
|
|
|
|
package SWF::Builder::Text::GLYPHENTRY; |
246
|
|
|
|
|
|
|
@SWF::Builder::Text::GLYPHENTRY::ISA = ('SWF::Element::GLYPHENTRY'); |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
sub new { |
249
|
4
|
|
|
4
|
|
8
|
my ($class, $code, $adv, $font) = @_; |
250
|
4
|
|
|
|
|
22
|
bless [$code, $adv*20, $font->{_code_hash}], $class; |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
sub GlyphIndex { |
254
|
8
|
|
|
8
|
|
945
|
my $self = shift; |
255
|
|
|
|
|
|
|
|
256
|
8
|
|
|
|
|
38
|
return $self->[2]{$self->[0]}; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
sub GlyphAdvance { |
260
|
8
|
|
|
8
|
|
33
|
return shift->[1]; |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
1; |
265
|
|
|
|
|
|
|
__END__ |