File Coverage

blib/lib/SWF/Builder/Character/Shape.pm
Criterion Covered Total %
statement 135 190 71.0
branch 33 68 48.5
condition 11 27 40.7
subroutine 18 20 90.0
pod n/a
total 197 305 64.5


line stmt bran cond sub pod time code
1             package SWF::Builder::Character::Shape;
2              
3 1     1   7 use strict;
  1         1  
  1         39  
4 1     1   6 use Carp;
  1         2  
  1         58  
5 1     1   5 use SWF::Element;
  1         3  
  1         19  
6 1     1   5 use SWF::Builder::Character;
  1         2  
  1         27  
7 1     1   6 use SWF::Builder::ExElement;
  1         2  
  1         58  
8 1     1   6 use SWF::Builder::Gradient;
  1         2  
  1         30  
9 1     1   5 use SWF::Builder::Shape;
  1         2  
  1         88  
10              
11             our $VERSION="0.05";
12              
13             @SWF::Builder::Character::Shape::ISA = qw/ SWF::Builder::Character::UsableAsMask /;
14             @SWF::Builder::Character::Shape::Imported::ISA = qw/ SWF::Builder::Character::Imported SWF::Builder::Character::Shape /;
15              
16             {
17             package SWF::Builder::Character::Shape::Def;
18              
19 1     1   6 use SWF::Builder::ExElement;
  1         3  
  1         2356  
20              
21             @SWF::Builder::Character::Shape::Def::ISA = qw/ SWF::Builder::Shape SWF::Builder::Character::Shape SWF::Builder::ExElement::Color::AddColor /;
22              
23             sub new {
24 1     1   9 my $self = shift->SUPER::new;
25             }
26              
27             sub _init {
28 1     1   3 my $self = shift;
29 1         15 $self->_init_character;
30 1         14 $self->_init_is_alpha;
31              
32 1         23 $self->{_edges} = SWF::Element::SHAPEWITHSTYLE3->ShapeRecords->new;
33 1         63 $self->{_current_line_width} = -1;
34 1         5 $self->{_current_line_color} = '';
35 1         2 $self->{_current_FillStyle0} = '';
36 1         2 $self->{_current_FillStyle1} = '';
37 1         6 $self->{_line_styles} = $self->{_shape_line_styles} = SWF::Element::SHAPEWITHSTYLE3->LineStyles->new;
38 1         53 $self->{_line_style_hash} = {};
39 1         6 $self->{_fill_styles} = $self->{_shape_fill_styles} = SWF::Element::SHAPEWITHSTYLE3->FillStyles->new;
40 1         53 $self->{_fill_style_hash} = {};
41 1         2 $self->{_links} = [];
42              
43 1         3 $self;
44             }
45              
46             sub _add_gradient {
47 1     1   2 my ($self, $gradient) = @_;
48              
49 1         6 $self->{_is_alpha}->configure($self->{_is_alpha}->value | $gradient->{_is_alpha}->value);
50 1         20 return bless {
51             _is_alpha => $self->{_is_alpha},
52             _gradient => $gradient,
53             }, 'SWF::Builder::Shape::Gradient';
54             }
55              
56             sub linestyle {
57 1     1   2 my $self = shift;
58 1         13 my ($index, $width, $color);
59              
60 1 50 33     23 if ($_[0] eq 'none' or $_[0] eq 0) {
61 0         0 $index = 0;
62 0         0 $width = -1;
63 0         0 $color = '';
64             } else {
65 1         4 my %param;
66 1 50 33     8 if ($_[0] eq 'Width' or $_[0] eq 'Color') {
67 0         0 %param = @_;
68             } else {
69 1         6 %param = (Width => $_[0], Color => $_[1]);
70             }
71 1         3 $width = $param{Width};
72 1 50       4 $width = $self->{_current_line_width} unless defined $width;
73 1 50       4 if (defined $param{Color}) {
74 1         18 $color = $self->_add_color($param{Color});
75             } else {
76 0         0 $color = $self->{_current_line_color};
77             }
78 1 50 33     61 return $self if ($width == $self->{_current_line_width} and $color eq $self->{_current_line_color});
79            
80 1 50       7 if (exists $self->{_line_style_hash}{"$width:$color"}) {
81 0         0 $index = $self->{_line_style_hash}{"$width:$color"};
82             } else {
83 1 50       23 if (@{$self->{_line_styles}} >= 65534) {
  1         5  
84 0         0 my $r = $self->_get_stylerecord;
85 0         0 $self->{_line_styles} = $r->LineStyles;
86 0         0 $self->{_line_style_hash} = {};
87 0         0 $self->{_fill_styles} = $r->FillStyles;
88 0         0 $self->{_fill_style_hash} = {};
89             }
90 1         3 my $ls = $self->{_line_styles};
91 1         6 push @$ls, $ls->new_element(Width => $width*20, Color => $color);
92 1         73 $index = $self->{_line_style_hash}{"$width:$color"} = @$ls;
93             }
94             }
95 1         21 $self->_set_style(LineStyle => $index);
96 1         2 $self->{_current_line_width} = $width;
97 1         3 $self->{_current_line_color} = $color;
98 1         12 $self;
99             }
100              
101             sub _fillstyle {
102 1     1   3 my $self = shift;
103 1         1 my $setstyle = shift;
104 1         2 my ($index, $fillkey);
105              
106 1 50 33     11 if ($_[0] eq 'none' or $_[0] eq 0) {
107 0         0 $index = 0;
108 0         0 $fillkey = '';
109             } else {
110 1         3 my %param;
111 1 50 33     13 if ($_[0] eq 'Color' or $_[0] eq 'Gradient' or $_[0] eq 'Bitmap') {
      33        
112 0         0 %param = @_;
113             } else {
114 1         4 for (ref($_[0])) {
115 1 50       6 /Gradient/ and do {
116 1         14 %param = (Gradient => $_[0], Type => $_[1], Matrix => $_[2]);
117 1         2 last;
118             };
119 0 0       0 /Bitmap/ and do {
120 0         0 %param = (Bitmap => $_[0], Type => $_[1], Matrix => $_[2]);
121 0         0 last;
122             };
123 0         0 %param = (Color => $_[0]);
124             }
125             }
126 1         2 my @param2;
127              
128 1         6 $fillkey = join(',', %param);
129 1 50       5 if (exists $param{Gradient}) {
    0          
130 1 50       6 unless (UNIVERSAL::isa($param{Matrix}, 'SWF::Builder::ExElement::MATRIX')) {
131 0         0 $param{Matrix} = SWF::Builder::ExElement::MATRIX->new->init($param{Matrix});
132             }
133 1 50       4 push @param2, Gradient => $self->_add_gradient($param{Gradient}),
134             FillStyleType =>
135             (lc($param{Type}) eq 'radial' ? 0x12 : 0x10),
136             GradientMatrix => $param{Matrix};
137            
138             } elsif (exists $param{Bitmap}) {
139 0 0       0 unless (UNIVERSAL::isa($param{Matrix}, 'SWF::Builder::ExElement::MATRIX')) {
140 0         0 my $m = $param{Bitmap}->matrix;
141 0 0       0 $m->init($param{Matrix}) if defined $param{Matrix};
142 0         0 $param{Matrix} = $m;
143             }
144 0 0       0 push @param2, BitmapID => $param{Bitmap}->{ID},
145             FillStyleType =>
146             (lc($param{Type}) =~ /^clip(ped)?$/ ? 0x41 : 0x40),
147             BitmapMatrix => $param{Matrix};
148 0         0 $self->{_is_alpha}->configure($self->{_is_alpha} | $param{Bitmap}{_is_alpha});
149 0         0 $self->_depends($param{Bitmap});
150             } else {
151 0         0 push @param2, Color => $self->_add_color($param{Color}),
152             FillStyleType => 0x00;
153             }
154              
155 1 50       11 return $self if $self->{"_current_$setstyle"} eq $fillkey;
156              
157 1 50       4 if (exists $self->{_fill_style_hash}{$fillkey}) {
158 0         0 $index = $self->{_fill_style_hash}{$fillkey};
159             } else {
160 1 50       2 if (@{$self->{_fill_styles}} >= 65534) {
  1         5  
161 0         0 my $r = $self->_get_stylerecord;
162 0         0 $self->{_line_styles} = $r->LineStyles;
163 0         0 $self->{_line_style_hash} = {};
164 0         0 $self->{_fill_styles} = $r->FillStyles;
165 0         0 $self->{_fill_style_hash} = {};
166             }
167 1         3 my $fs = $self->{_fill_styles};
168 1         5 push @$fs, $fs->new_element(@param2);
169 1         102 $index = $self->{_fill_style_hash}{$fillkey} = @$fs;
170             }
171             }
172 1         3 $self->_set_style($setstyle => $index);
173 1         2 $self->{"_current_$setstyle"} = $fillkey;
174 1         6 $self;
175             }
176              
177             sub fillstyle {
178 1     1   3 my $self = shift;
179 1         4 _fillstyle($self, 'FillStyle0', @_);
180             }
181              
182             *fillstyle0 = \&fillstyle;
183              
184             sub fillstyle1 {
185 0     0   0 my $self = shift;
186 0         0 _fillstyle($self, 'FillStyle1', @_);
187             }
188              
189             sub anchor {
190 0     0   0 my ($self, $anchor) = @_;
191              
192 0         0 $self->{_anchors}{$anchor} = [$#{$self->{_edges}}, $self->{_current_X}, $self->{_current_Y}, $#{$self->{_links}}];
  0         0  
  0         0  
193 0         0 $self->{_last_anchor} = $anchor;
194 0         0 $self;
195             }
196              
197             sub _set_bounds {
198 6     6   12 my ($self, $x, $y, $f) = @_;
199 6         23 $self->SUPER::_set_bounds($x, $y);
200 6 50       18 return if $f;
201              
202 6 50       15 if (defined $self->{_links}[-1]) {
203             # my $cw = $self->{_current_line_width} * 10;
204 6         11 my $m = $self->{_links}[-1];
205             # $m->[6]->set_boundary($x-$cw, $y-$cw, $x+$cw, $y+$cw);
206 6         9 my (undef, $tlx, $tly) = @{$m->[5]};
  6         13  
207 6 50       38 if ($x*$x+$y*$y < $tlx*$tlx+$tly*$tly) {
208 0         0 $m->[5] = [$#{$self->{_edges}}, $x, $y];
  0         0  
209             }
210             }
211             }
212              
213             sub _set_style {
214 4     4   14 my ($self, %param) = @_;
215              
216 4 100 100     23 if (exists $param{MoveDeltaX} and defined $self->{_links}[-1]) {
217 1         3 my $m = $self->{_links}[-1];
218 1         2 $m->[1] = $#{$self->{_edges}};
  1         3  
219 1         3 $m->[3] = $self->{_current_X};
220 1         3 $m->[4] = $self->{_current_Y};
221             }
222              
223 4         21 my $r = $self->SUPER::_set_style(%param);
224              
225 4 100       12 if (exists $param{MoveDeltaX}) {
226 2         6 my ($x, $y) = ($param{MoveDeltaX}, $param{MoveDeltaY});
227 2         12 my @linkinfo =
228 2         5 ($#{$self->{_edges}}, # start edge index
229             undef, # last continuous edge index
230 2         7 [$#{$self->{_edges}}], # STYLECHANGERECORD indice
231             undef, # last X
232             undef, # last Y
233 2         2 [$#{$self->{_edges}}, $x, $y], # top left
234             # SWF::Builder::ExElement::BoundaryRect->new, # boundary
235             );
236 2 100 66     15 if (exists $self->{_links}[-1] and $self->{_links}[-1][0] == $linkinfo[0]) {
237 1         4 $self->{_links}[-1] = \ @linkinfo;
238             } else {
239 1         2 push @{$self->{_links}}, \ @linkinfo;
  1         2  
240             }
241 2 50       9 if (defined $self->{_last_anchor}) {
242 0         0 my $last_anchor = $self->{_anchors}{$self->{_last_anchor}};
243 0 0 0     0 if ($last_anchor->[0] == $#{$self->{_edges}} or $last_anchor->[0] == $#{$self->{_edges}}-1) {
  0         0  
  0         0  
244 0         0 $last_anchor->[0] = $#{$self->{_edges}};
  0         0  
245 0         0 $last_anchor->[1] = $x;
246 0         0 $last_anchor->[2] = $y;
247 0         0 $last_anchor->[3] = $#{$self->{_links}};
  0         0  
248             }
249             }
250 2 100       7 $r->LineStyle($self->{_line_style_hash}{$self->{_current_line_width}.':'.$self->{_current_line_color}}) unless defined $r->LineStyle;
251 2 100       28 $r->FillStyle0($self->{_fill_style_hash}{$self->{_current_FillStyle0}}) unless defined $r->FillStyle0;
252 2 50       26 $r->FillStyle1($self->{_fill_style_hash}{$self->{_current_FillStyle1}}) unless defined $r->FillStyle1;
253             } else {
254 2 50       5 push @{$self->{_links}[-1][2]}, $#{$self->{_edges}} if $self->{_links}[-1][2][-1] != $#{$self->{_edges}};
  0         0  
  0         0  
  2         9  
255             }
256 4         46 $r;
257             }
258              
259             sub _pack {
260 1     1   2 my ($self, $stream) = @_;
261              
262 1 50       11 my $tag = ($self->{_is_alpha} ? SWF::Element::Tag::DefineShape3->new : SWF::Element::Tag::DefineShape2->new);
263 1         87 $tag->ShapeID($self->{ID});
264 1         15 $tag->ShapeBounds($self->{_bounds});
265 1         15 $tag->Shapes
266             (
267             FillStyles => $self->{_shape_fill_styles},
268             LineStyles => $self->{_shape_line_styles},
269             ShapeRecords =>$self->{_edges},
270             );
271 1         102 $tag->pack($stream);
272             }
273             }
274              
275             #####
276              
277             {
278             package SWF::Builder::Shape::Gradient;
279              
280             @SWF::Builder::Shape::Gradient::ISA = ('SWF::Element::Array::GRADIENT3');
281              
282             sub pack {
283 1     1   901 my ($self, $stream) = @_;
284              
285 1         16 my $g = $self->{_gradient};
286 1         5 my $a = $g->{_is_alpha}->value;
287 1         9 $g->{_is_alpha}->configure($self->{_is_alpha});
288 1         21 $g->pack($stream);
289 1         138 $g->{_is_alpha}->configure($a);
290             }
291             }
292              
293             1;
294             __END__