File Coverage

blib/lib/FigAnim/Arc.pm
Criterion Covered Total %
statement 9 184 4.8
branch 0 36 0.0
condition 0 9 0.0
subroutine 3 17 17.6
pod n/a
total 12 246 4.8


line stmt bran cond sub pod time code
1             package Arc;
2              
3             =head1 NAME
4              
5             Arc - A XFig file animator class - Arc object
6              
7             =head1 DESCRIPTION
8              
9             Arc object - object code in FIG format: 5.
10             Here are all the attributes of this class:
11              
12             B
13             area_fill, style_val, cap_style, direction, forward_arrow, backward_arrow,
14             center_x, center_y, x1, y1, x2, y2, x3, y3, f_arrow_type, f_arrow_style,
15             f_arrow_thickness, f_arrow_width, f_arrow_height, b_arrow_type, b_arrow_style,
16             b_arrow_thickness, b_arrow_width, b_arrow_height, visibility>
17              
18             =head1 FIG ATTRIBUTES
19              
20             =over
21              
22             =item sub_type
23              
24             0: pie-wedge (closed)
25             1: open ended arc
26              
27             =item line_style
28              
29             -1: Default;
30             0: Solid;
31             1: Dashed;
32             2: Dotted;
33             3: Dash-dotted;
34             4: Dash-double-dotted;
35             5: Dash-triple-dotted
36              
37             =item thickness
38              
39             80-ths of an inch ("display units")
40              
41             =item pen_color
42              
43             -1..31: FIG colors;
44             32..543 (512 total): user colors
45              
46             =item fill_color
47              
48             -1..31: FIG colors;
49             32..543 (512 total): user colors
50              
51             =item depth
52              
53             0 ... 999: larger value means object is deeper than (under)
54             objects with smaller depth
55              
56             =item pen_style
57              
58             unused
59              
60             =item area_fill
61              
62             fill type
63              
64             =item style_val
65              
66             length, in 1/80 inches, of the on/off
67             dashes for dashed lines, and the distance between the dots, in 1/80 inches,
68             for dotted lines
69              
70             =item cap_style
71              
72             0: Butt (default);
73             1: Round;
74             2: Projecting
75              
76             =item direction
77              
78             0: clockwise;
79             1: counterclockwise
80              
81             =item forward_arrow
82              
83             0: no forward arrow;
84             1: on
85              
86             =item backward_arrow
87              
88             0: no backward arrow;
89             1: on
90              
91             =item center_x, center_y
92              
93             Fig units, the center of the arc
94              
95             =item x1, y1
96              
97             Fig units, the 1st point the user entered
98              
99             =item x2, y2
100              
101             Fig units, the 2nd point
102              
103             =item x3, y3
104              
105             Fig units, the last point
106              
107             =item f_arrow_type, b_arrow_type
108              
109             0: Stick-type (default);
110             1: Closed triangle;
111             2: Closed with "indented" butt;
112             3: Closed with "pointed" butt
113              
114             =item f_arrow_style, b_arrow_style
115              
116             0: Hollow (filled with white);
117             1: Filled with pen_color
118              
119             =item f_arrow_thickness, b_arrow_thickness
120              
121             1/80 inch
122              
123             =item f_arrow_width, b_arrow_width
124              
125             Fig units
126              
127             =item f_arrow_height, b_arrow_height
128              
129             Fig units
130              
131             =back
132              
133             =head1 ADDITONNAL ATTRIBUTES
134              
135             =over
136              
137             =item visibility
138              
139             0: hidden;
140             1: shown
141              
142             =back
143              
144             =cut
145              
146 1     1   4 use strict;
  1         2  
  1         27  
147 1     1   5 use warnings;
  1         1  
  1         18  
148              
149             # useful classes
150 1     1   460 use FigAnim::Utils;
  1         5  
  1         2033  
151              
152             # constructor
153             sub new {
154 0     0     my $proto = shift;
155 0   0       my $class = ref($proto) || $proto;
156 0           my $self = {};
157            
158 0           $self->{name} = shift; # object's name in comment
159            
160             #$self->{object_code} = 5;
161 0           $self->{sub_type} = shift;
162 0           $self->{line_style} = shift;
163 0           $self->{thickness} = shift;
164 0           $self->{pen_color} = shift;
165 0           $self->{fill_color} = shift;
166 0           $self->{depth} = shift;
167 0           $self->{pen_style} = shift;
168 0           $self->{area_fill} = shift;
169 0           $self->{style_val} = shift;
170 0           $self->{cap_style} = shift;
171 0           $self->{direction} = shift;
172 0           $self->{forward_arrow} = shift;
173 0           $self->{backward_arrow} = shift;
174 0           $self->{center_x} = shift;
175 0           $self->{center_y} = shift;
176 0           $self->{x1} = shift;
177 0           $self->{y1} = shift;
178 0           $self->{x2} = shift;
179 0           $self->{y2} = shift;
180 0           $self->{x3} = shift;
181 0           $self->{y3} = shift;
182            
183             # forward arrow
184 0           $self->{f_arrow_type} = shift;
185 0           $self->{f_arrow_style} = shift;
186 0           $self->{f_arrow_thickness} = shift;
187 0           $self->{f_arrow_width} = shift;
188 0           $self->{f_arrow_height} = shift;
189            
190             # backward arrow
191 0           $self->{b_arrow_type} = shift;
192 0           $self->{b_arrow_style} = shift;
193 0           $self->{b_arrow_thickness} = shift;
194 0           $self->{b_arrow_width} = shift;
195 0           $self->{b_arrow_height} = shift;
196            
197             # reference to the FigFile
198 0           $self->{fig_file} = shift;
199            
200             # object's visibility : 0=hidden 1=shown
201 0           $self->{visibility} = 1;
202              
203             # animations
204 0           $self->{animations} = [];
205              
206 0           bless ($self, $class);
207 0           return $self;
208             }
209              
210              
211             # methods
212             sub clone {
213 0     0     my $self = shift;
214 0           my $obj = new Arc;
215 0           $obj->{$_} = $self->{$_} foreach (keys %{$self});
  0            
216 0           return $obj;
217             }
218              
219             sub output {
220 0     0     my $self = shift;
221 0 0         return if ($self->{visibility} == 0);
222            
223 0           my $fh = shift;
224            
225 0           foreach (split(/\n/, $self->{name})) {
226 0           printf $fh "# $_\n";
227             }
228            
229 0           printf $fh
230             "5 %d %d %d %d %d %d %d %d %.3f %d %d %d %d %.3f %.3f %d %d %d %d %d %d\n",
231             @$self{'sub_type','line_style','thickness','pen_color',
232             'fill_color','depth','pen_style','area_fill','style_val',
233             'cap_style','direction','forward_arrow','backward_arrow',
234             'center_x','center_y','x1','y1','x2','y2','x3','y3'};
235            
236 0 0         if ($self->{forward_arrow}) {
237 0           printf $fh "\t%d %d %.2f %.2f %.2f\n",
238             @$self{'f_arrow_type','f_arrow_style','f_arrow_thickness',
239             'f_arrow_width','f_arrow_height'};
240             }
241            
242 0 0         if ($self->{backward_arrow}) {
243 0           printf $fh "\t%d %d %.2f %.2f %.2f\n",
244             @$self{'b_arrow_type','b_arrow_style','b_arrow_thickness',
245             'b_arrow_width','b_arrow_height'};
246             }
247             }
248              
249              
250             # animation methods
251             sub setAttributeValue {
252 0     0     my $self = shift;
253 0           my @anim = (0, $self->{name}, shift, 0, shift, shift);
254 0           push @{$self->{fig_file}->{animations}}, \@anim;
  0            
255             }
256              
257             sub setPenColor {
258 0     0     my $self = shift;
259 0           my $time = shift;
260 0           my $color = $FigAnim::Utils::colors_codes{shift};
261 0 0         if (defined $color) {
262 0           my @anim = (0, $self->{name}, $time, 0, 'pen_color', $color);
263 0           push @{$self->{fig_file}->{animations}}, \@anim;
  0            
264             }
265             }
266              
267             sub setFillColor {
268 0     0     my $self = shift;
269 0           my $time = shift;
270 0           my $color = $FigAnim::Utils::colors_codes{shift};
271 0 0         if (defined $color) {
272 0           my @anim = (0, $self->{name}, $time, 0, 'fill_color', $color);
273 0           push @{$self->{fig_file}->{animations}}, \@anim;
  0            
274             }
275             }
276              
277             sub hide {
278 0     0     my $self = shift;
279 0           my @anim = (0, $self->{name}, shift, 0, 'visibility', 0);
280 0           push @{$self->{fig_file}->{animations}}, \@anim;
  0            
281             }
282              
283             sub show {
284 0     0     my $self = shift;
285 0           my @anim = (0, $self->{name}, shift, 0, 'visibility', 1);
286 0           push @{$self->{fig_file}->{animations}}, \@anim;
  0            
287             }
288              
289             sub changeThickness {
290 0     0     my $self = shift;
291 0           my @anim = (1, $self->{name}, shift, shift, int shift);
292 0           push @{$self->{fig_file}->{animations}}, \@anim;
  0            
293             }
294              
295             sub changeFillIntensity {
296 0     0     my $self = shift;
297 0           my @anim = (2, $self->{name}, shift, shift, int shift);
298 0 0         $anim[4] = 0 if ($anim[4] < 0);
299 0 0         $anim[4] = 20 if ($anim[4] > 20);
300 0           push @{$self->{fig_file}->{animations}}, \@anim;
  0            
301             }
302              
303             sub translate {
304 0     0     my $self = shift;
305 0           my @anim = (15, $self->{name}, shift, shift, shift, shift, shift);
306 0 0         $anim[6] = '' if (!(defined $anim[6]));
307 0           push @{$self->{fig_file}->{animations}}, \@anim;
  0            
308             }
309              
310             sub rotate {
311 0     0     my $self = shift;
312 0           my @anim = (25, $self->{name}, shift, shift, shift, shift, shift, shift);
313 0 0 0       if (!((defined $anim[5]) && (defined $anim[6]))) {
314 0           $anim[5] = $self->{center_x};
315 0           $anim[6] = $self->{center_y};
316             }
317 0 0         $anim[7] = '' if (!(defined $anim[7]));
318 0           push @{$self->{fig_file}->{animations}}, \@anim;
  0            
319             }
320              
321             sub scale {
322 0     0     my $self = shift;
323 0           my @anim = (35, $self->{name}, shift, shift, shift, shift, shift);
324 0 0 0       if (!((defined $anim[5]) && (defined $anim[6]))) {
325 0           $anim[5] = $self->{center_x};
326 0           $anim[6] = $self->{center_y};
327             }
328 0           push @{$self->{fig_file}->{animations}}, \@anim;
  0            
329             }
330              
331              
332             # outputs a SVG element
333             sub outputSVG {
334 0     0     my $self = shift;
335 0           my $fh = shift;
336              
337 0           my ($colors) = @_;
338              
339 0           foreach (split(/\n/, $self->{name})) {
340 0           print $fh "\n";
341             }
342              
343             # converts values into SVG-CSS
344              
345 0           my $direction = $self->{direction};
346              
347 0           my $center_x = $self->{center_x};
348 0           my $center_y = $self->{center_y};
349              
350 0           my $x1 = $self->{x1};
351 0           my $y1 = $self->{y1};
352              
353 0           my $x2 = $self->{x2};
354 0           my $y2 = $self->{y2};
355              
356 0           my $x3 = $self->{x3};
357 0           my $y3 = $self->{y3};
358              
359             # radius_x, radius_y
360 0           my $rx = int(sqrt(($x1-$self->{center_x})*($x1-$self->{center_x}) +
361             ($y1-$self->{center_y})*($y1-$self->{center_y})));
362 0           my $ry = $rx;
363              
364 0           my $sweep_flag;
365             my $large_arc_flag;
366              
367 0 0         if ($self->{direction} == 0) {
368 0           $sweep_flag = 1;
369 0 0         if (($x3 - $center_x) * ($y1 - $center_y) -
370             ($y3 - $center_y) * ($x1 - $center_x) >= 0) {
371 0           $large_arc_flag = 1;
372             } else {
373 0           $large_arc_flag = 0;
374             }
375             } else {
376 0           $sweep_flag = 0;
377 0 0         if (($x1 - $center_x) * ($y3 - $center_y) -
378             ($y1 - $center_y) * ($x3 - $center_x) >= 0) {
379 0           $large_arc_flag = 1;
380             } else {
381 0           $large_arc_flag = 0;
382             }
383             }
384              
385 0           my $style = "style=\"";
386              
387             # converts arrows into SVG paths
388              
389 0           my $f_arrow_name = "";
390 0           my $b_arrow_name = "";
391              
392 0 0         if ($self->{forward_arrow} == 1) {
393 0           $_ = $self->{name};
394 0           s/\W//g;
395 0           $f_arrow_name = $_ . "_f_arrow";
396              
397 0           my $f_arrow =
398             ConvertSVG::arrows_to_markers($f_arrow_name,
399             1,
400             "auto",
401             $self->{f_arrow_type},
402             $self->{f_arrow_style},
403             $self->{f_arrow_thickness},
404             $self->{f_arrow_width},
405             $self->{f_arrow_height},
406             $self->{pen_color},
407             $colors);
408 0           print $fh $f_arrow;
409 0           $style .=
410             "marker-end: url(#" . $f_arrow_name . "); ";
411             }
412              
413 0 0         if ($self->{backward_arrow} == 1) {
414 0           $_ = $self->{name};
415 0           s/\W//g;
416 0           $b_arrow_name = $_ . "_b_arrow";
417              
418 0           my $b_arrow =
419             ConvertSVG::arrows_to_markers($b_arrow_name,
420             0,
421             "auto",
422             $self->{b_arrow_type},
423             $self->{b_arrow_style},
424             $self->{b_arrow_thickness},
425             $self->{b_arrow_width},
426             $self->{b_arrow_height},
427             $self->{pen_color},
428             $colors);
429 0           print $fh $b_arrow;
430 0           $style .=
431             "marker-start: url(#" . $b_arrow_name . "); ";
432             }
433              
434             # line_style, style_val, pen_color
435 0           $style .= ConvertSVG::line_style_to_stroke($self->{line_style},
436             $self->{style_val},
437             $self->{pen_color},
438             $colors) . "; ";
439             # thickness
440 0           $style .= ConvertSVG::thickness_to_stroke($self->{thickness}) . "; ";
441              
442             # fill_color, area_fill
443 0           $style .= ConvertSVG::area_fill_to_fill($self->{area_fill},
444             $self->{fill_color},
445             $colors) . "; ";
446              
447             # cap_style
448 0           $style .= ConvertSVG::cap_style_to_linecap($self->{cap_style});
449              
450             # end of style
451 0           $style .= "\"";
452              
453 0           my $d = "d=\"" .
454             "M $x1 $y1, " .
455             "A $rx $ry, " .
456             "0, " .
457             "$large_arc_flag, " .
458             "$sweep_flag, " .
459             "$x3 $y3";
460              
461 0 0         if ($self->{sub_type} == 2) { # pie-wedge (closed)
462 0           $d .= "L $center_x $center_y, L $x1 $y1\"";
463             } else { # open ended arc
464 0           $d .= "\"";
465             }
466              
467 0           print $fh "
468              
469 0 0         if ($#{$self->{animations}} >= 0) { # SVG + SMIL
  0            
470 0           print $fh ">\n";
471 0           for (my $i = 0; $i <= $#{$self->{animations}}; $i++) {
  0            
472 0           print $fh "\t";
473 0           my $smil = ConvertSMIL::smil($self->{animations}[$i]);
474 0           print $fh $smil;
475 0           print $fh "\n";
476             }
477 0           print $fh "\n\n";
478             } else { # SVG only
479 0           print $fh " />\n\n";
480             }
481             }
482              
483              
484             1;