File Coverage

blib/lib/Excel/Writer/XLSX/Package/VML.pm
Criterion Covered Total %
statement 344 344 100.0
branch 14 14 100.0
condition 8 9 88.8
subroutine 47 47 100.0
pod 0 1 0.0
total 413 415 99.5


line stmt bran cond sub pod time code
1              
2             ###############################################################################
3             #
4             # VML - A class for writing the Excel XLSX VML files.
5             #
6             # Used in conjunction with Excel::Writer::XLSX
7             #
8             # Copyright 2000-2021, John McNamara, jmcnamara@cpan.org
9             #
10             # Documentation after __END__
11             #
12              
13             # perltidy with the following options: -mbl=2 -pt=0 -nola
14              
15             use 5.008002;
16 1124     1124   18046 use strict;
  1124         3228  
17 1124     1124   5091 use warnings;
  1124         1992  
  1124         19147  
18 1124     1124   4434 use Carp;
  1124         1878  
  1124         21733  
19 1124     1124   4534 use Excel::Writer::XLSX::Package::XMLwriter;
  1124         1865  
  1124         46463  
20 1124     1124   5344  
  1124         1837  
  1124         2679225  
21             our @ISA = qw(Excel::Writer::XLSX::Package::XMLwriter);
22             our $VERSION = '1.09';
23              
24              
25             ###############################################################################
26             #
27             # Public and private API methods.
28             #
29             ###############################################################################
30              
31              
32             ###############################################################################
33             #
34             # new()
35             #
36             # Constructor.
37             #
38              
39             my $class = shift;
40             my $fh = shift;
41 104     104 0 15112 my $self = Excel::Writer::XLSX::Package::XMLwriter->new( $fh );
42 104         185  
43 104         419 bless $self, $class;
44              
45 104         202 return $self;
46             }
47 104         237  
48              
49             ###############################################################################
50             #
51             # _assemble_xml_file()
52             #
53             # Assemble and write the XML file.
54             #
55              
56             my $self = shift;
57             my $data_id = shift;
58             my $vml_shape_id = shift;
59 85     85   212 my $comments_data = shift;
60 85         150 my $buttons_data = shift;
61 85         137 my $header_images_data = shift;
62 85         144 my $z_index = 1;
63 85         136  
64 85         163  
65 85         168 $self->_write_xml_namespace;
66              
67             # Write the o:shapelayout element.
68 85         325 $self->_write_shapelayout( $data_id );
69              
70             if ( defined $buttons_data && @$buttons_data ) {
71 85         422  
72             # Write the v:shapetype element.
73 85 100 100     493 $self->_write_button_shapetype();
74              
75             for my $button ( @$buttons_data ) {
76 22         176  
77             # Write the v:shape element.
78 22         59 $self->_write_button_shape( ++$vml_shape_id, $z_index++, $button );
79             }
80             }
81 29         123  
82             if ( defined $comments_data && @$comments_data ) {
83              
84             # Write the v:shapetype element.
85 85 100 100     545 $self->_write_comment_shapetype();
86              
87             for my $comment ( @$comments_data ) {
88 45         302  
89             # Write the v:shape element.
90 45         233 $self->_write_comment_shape( ++$vml_shape_id, $z_index++,
91             $comment );
92             }
93 4163         7643 }
94              
95             if ( defined $header_images_data && @$header_images_data ) {
96              
97             # Write the v:shapetype element.
98 85 100 66     418 $self->_write_image_shapetype();
99              
100             my $index = 1;
101 25         117 for my $image ( @$header_images_data ) {
102              
103 25         50 # Write the v:shape element.
104 25         69 $self->_write_image_shape( ++$vml_shape_id, $index++, $image );
105             }
106             }
107 47         159  
108              
109             $self->xml_end_tag( 'xml' );
110              
111             # Close the XML writer filehandle.
112 85         294 $self->xml_get_fh()->close();
113             }
114              
115 85         464  
116             ###############################################################################
117             #
118             # Internal methods.
119             #
120             ###############################################################################
121              
122              
123             ###############################################################################
124             #
125             # _pixels_to_points()
126             #
127             # Convert comment vertices from pixels to points.
128             #
129              
130             my $self = shift;
131             my $vertices = shift;
132              
133             my (
134 4192     4192   4771 $col_start, $row_start, $x1, $y1,
135 4192         4430 $col_end, $row_end, $x2, $y2,
136             $left, $top, $width, $height
137             ) = @$vertices;
138 4192         9893  
139             for my $pixels ( $left, $top, $width, $height ) {
140             $pixels *= 0.75;
141             }
142              
143 4192         5741 return ( $left, $top, $width, $height );
144 16768         19564 }
145              
146              
147 4192         7949 ###############################################################################
148             #
149             # XML writing methods.
150             #
151             ###############################################################################
152              
153              
154             ###############################################################################
155             #
156             # _write_xml_namespace()
157             #
158             # Write the <xml> element. This is the root element of VML.
159             #
160              
161             my $self = shift;
162             my $schema = 'urn:schemas-microsoft-com:';
163             my $xmlns = $schema . 'vml';
164             my $xmlns_o = $schema . 'office:office';
165             my $xmlns_x = $schema . 'office:excel';
166 85     85   188  
167 85         179 my @attributes = (
168 85         284 'xmlns:v' => $xmlns,
169 85         228 'xmlns:o' => $xmlns_o,
170 85         199 'xmlns:x' => $xmlns_x,
171             );
172 85         392  
173             $self->xml_start_tag( 'xml', @attributes );
174             }
175              
176              
177             ##############################################################################
178 85         463 #
179             # _write_shapelayout()
180             #
181             # Write the <o:shapelayout> element.
182             #
183              
184             my $self = shift;
185             my $data_id = shift;
186             my $ext = 'edit';
187              
188             my @attributes = ( 'v:ext' => $ext );
189              
190 86     86   178 $self->xml_start_tag( 'o:shapelayout', @attributes );
191 86         141  
192 86         162 # Write the o:idmap element.
193             $self->_write_idmap( $data_id );
194 86         251  
195             $self->xml_end_tag( 'o:shapelayout' );
196 86         297 }
197              
198              
199 86         322 ##############################################################################
200             #
201 86         346 # _write_idmap()
202             #
203             # Write the <o:idmap> element.
204             #
205              
206             my $self = shift;
207             my $ext = 'edit';
208             my $data_id = shift;
209              
210             my @attributes = (
211             'v:ext' => $ext,
212             'data' => $data_id,
213 87     87   168 );
214 87         191  
215 87         160 $self->xml_empty_tag( 'o:idmap', @attributes );
216             }
217 87         266  
218              
219             ##############################################################################
220             #
221             # _write_comment_shapetype()
222 87         495 #
223             # Write the <v:shapetype> element.
224             #
225              
226             my $self = shift;
227             my $id = '_x0000_t202';
228             my $coordsize = '21600,21600';
229             my $spt = 202;
230             my $path = 'm,l,21600r21600,l21600,xe';
231              
232             my @attributes = (
233             'id' => $id,
234 46     46   98 'coordsize' => $coordsize,
235 46         198 'o:spt' => $spt,
236 46         83 'path' => $path,
237 46         90 );
238 46         90  
239             $self->xml_start_tag( 'v:shapetype', @attributes );
240 46         171  
241             # Write the v:stroke element.
242             $self->_write_stroke();
243              
244             # Write the v:path element.
245             $self->_write_comment_path( 't', 'rect' );
246              
247 46         179 $self->xml_end_tag( 'v:shapetype' );
248             }
249              
250 46         161  
251             ##############################################################################
252             #
253 46         169 # _write_button_shapetype()
254             #
255 46         129 # Write the <v:shapetype> element.
256             #
257              
258             my $self = shift;
259             my $id = '_x0000_t201';
260             my $coordsize = '21600,21600';
261             my $spt = 201;
262             my $path = 'm,l,21600r21600,l21600,xe';
263              
264             my @attributes = (
265             'id' => $id,
266             'coordsize' => $coordsize,
267 23     23   89 'o:spt' => $spt,
268 23         187 'path' => $path,
269 23         43 );
270 23         39  
271 23         43 $self->xml_start_tag( 'v:shapetype', @attributes );
272              
273 23         78 # Write the v:stroke element.
274             $self->_write_stroke();
275              
276             # Write the v:path element.
277             $self->_write_button_path( 't', 'rect' );
278              
279             # Write the o:lock element.
280 23         114 $self->_write_shapetype_lock();
281              
282             $self->xml_end_tag( 'v:shapetype' );
283 23         84 }
284              
285              
286 23         91 ##############################################################################
287             #
288             # _write_image_shapetype()
289 23         97 #
290             # Write the <v:shapetype> element.
291 23         64 #
292              
293             my $self = shift;
294             my $id = '_x0000_t75';
295             my $coordsize = '21600,21600';
296             my $spt = 75;
297             my $o_preferrelative = 't';
298             my $path = 'm@4@5l@4@11@9@11@9@5xe';
299             my $filled = 'f';
300             my $stroked = 'f';
301              
302             my @attributes = (
303 25     25   62 'id' => $id,
304 25         63 'coordsize' => $coordsize,
305 25         53 'o:spt' => $spt,
306 25         40 'o:preferrelative' => $o_preferrelative,
307 25         49 'path' => $path,
308 25         40 'filled' => $filled,
309 25         46 'stroked' => $stroked,
310 25         44 );
311              
312 25         119 $self->xml_start_tag( 'v:shapetype', @attributes );
313              
314             # Write the v:stroke element.
315             $self->_write_stroke();
316              
317             # Write the v:formulas element.
318             $self->_write_formulas();
319              
320             # Write the v:path element.
321             $self->_write_image_path();
322 25         102  
323             # Write the o:lock element.
324             $self->_write_aspect_ratio_lock();
325 25         94  
326             $self->xml_end_tag( 'v:shapetype' );
327             }
328 25         97  
329              
330             ##############################################################################
331 25         96 #
332             # _write_stroke()
333             #
334 25         105 # Write the <v:stroke> element.
335             #
336 25         101  
337             my $self = shift;
338             my $joinstyle = 'miter';
339              
340             my @attributes = ( 'joinstyle' => $joinstyle );
341              
342             $self->xml_empty_tag( 'v:stroke', @attributes );
343             }
344              
345              
346             ##############################################################################
347             #
348 95     95   173 # _write_comment_path()
349 95         276 #
350             # Write the <v:path> element.
351 95         259 #
352              
353 95         404 my $self = shift;
354             my $gradientshapeok = shift;
355             my $connecttype = shift;
356             my @attributes = ();
357              
358             push @attributes, ( 'gradientshapeok' => 't' ) if $gradientshapeok;
359             push @attributes, ( 'o:connecttype' => $connecttype );
360              
361             $self->xml_empty_tag( 'v:path', @attributes );
362             }
363              
364              
365 4211     4211   5153 ##############################################################################
366 4211         4458 #
367 4211         4831 # _write_button_path()
368 4211         4796 #
369             # Write the <v:path> element.
370 4211 100       6268 #
371 4211         5972  
372             my $self = shift;
373 4211         6814 my $shadowok = 'f';
374             my $extrusionok = 'f';
375             my $strokeok = 'f';
376             my $fillok = 'f';
377             my $connecttype = 'rect';
378              
379             my @attributes = (
380             'shadowok' => $shadowok,
381             'o:extrusionok' => $extrusionok,
382             'strokeok' => $strokeok,
383             'fillok' => $fillok,
384             'o:connecttype' => $connecttype,
385 24     24   51 );
386 24         41  
387 24         133 $self->xml_empty_tag( 'v:path', @attributes );
388 24         43 }
389 24         159  
390 24         50  
391             ##############################################################################
392 24         114 #
393             # _write_image_path()
394             #
395             # Write the <v:path> element.
396             #
397              
398             my $self = shift;
399             my $extrusionok = 'f';
400 24         71 my $gradientshapeok = 't';
401             my $connecttype = 'rect';
402              
403             my @attributes = (
404             'o:extrusionok' => $extrusionok,
405             'gradientshapeok' => $gradientshapeok,
406             'o:connecttype' => $connecttype,
407             );
408              
409             $self->xml_empty_tag( 'v:path', @attributes );
410             }
411              
412 25     25   47  
413 25         55 ##############################################################################
414 25         49 #
415 25         57 # _write_shapetype_lock()
416             #
417 25         85 # Write the <o:lock> element.
418             #
419              
420             my $self = shift;
421             my $ext = 'edit';
422             my $shapetype = 't';
423 25         82  
424             my @attributes = (
425             'v:ext' => $ext,
426             'shapetype' => $shapetype,
427             );
428              
429             $self->xml_empty_tag( 'o:lock', @attributes );
430             }
431              
432              
433             ##############################################################################
434             #
435 23     23   49 # _write_rotation_lock()
436 23         73 #
437 23         39 # Write the <o:lock> element.
438             #
439 23         61  
440             my $self = shift;
441             my $ext = 'edit';
442             my $rotation = 't';
443              
444 23         80 my @attributes = (
445             'v:ext' => $ext,
446             'rotation' => $rotation,
447             );
448              
449             $self->xml_empty_tag( 'o:lock', @attributes );
450             }
451              
452              
453             ##############################################################################
454             #
455             # _write_aspect_ratio_lock()
456 76     76   132 #
457 76         145 # Write the <o:lock> element.
458 76         234 #
459              
460 76         208 my $self = shift;
461             my $ext = 'edit';
462             my $aspectratio = 't';
463              
464             my @attributes = (
465 76         209 'v:ext' => $ext,
466             'aspectratio' => $aspectratio,
467             );
468              
469             $self->xml_empty_tag( 'o:lock', @attributes );
470             }
471              
472             ##############################################################################
473             #
474             # _write_comment_shape()
475             #
476             # Write the <v:shape> element.
477 25     25   55 #
478 25         66  
479 25         49 my $self = shift;
480             my $id = shift;
481 25         94 my $z_index = shift;
482             my $comment = shift;
483             my $type = '#_x0000_t202';
484             my $insetmode = 'auto';
485             my $visibility = 'hidden';
486 25         95  
487             # Set the shape index.
488             $id = '_x0000_s' . $id;
489              
490             # Get the comment parameters
491             my $row = $comment->[0];
492             my $col = $comment->[1];
493             my $string = $comment->[2];
494             my $author = $comment->[3];
495             my $visible = $comment->[4];
496             my $fillcolor = $comment->[5];
497 4163     4163   5041 my $vertices = $comment->[9];
498 4163         4617  
499 4163         4410 my ( $left, $top, $width, $height ) = $self->_pixels_to_points( $vertices );
500 4163         4842  
501 4163         4813 # Set the visibility.
502 4163         4291 $visibility = 'visible' if $visible;
503 4163         4520  
504             my $style =
505             'position:absolute;'
506 4163         5709 . 'margin-left:'
507             . $left . 'pt;'
508             . 'margin-top:'
509 4163         7580 . $top . 'pt;'
510 4163         4893 . 'width:'
511 4163         5699 . $width . 'pt;'
512 4163         5314 . 'height:'
513 4163         4848 . $height . 'pt;'
514 4163         5068 . 'z-index:'
515 4163         5143 . $z_index . ';'
516             . 'visibility:'
517 4163         6049 . $visibility;
518              
519              
520 4163 100       6587 my @attributes = (
521             'id' => $id,
522 4163         22760 'type' => $type,
523             'style' => $style,
524             'fillcolor' => $fillcolor,
525             'o:insetmode' => $insetmode,
526             );
527              
528             $self->xml_start_tag( 'v:shape', @attributes );
529              
530             # Write the v:fill element.
531             $self->_write_comment_fill();
532              
533             # Write the v:shadow element.
534             $self->_write_shadow();
535              
536             # Write the v:path element.
537             $self->_write_comment_path( undef, 'none' );
538 4163         9444  
539             # Write the v:textbox element.
540             $self->_write_comment_textbox();
541              
542             # Write the x:ClientData element.
543             $self->_write_comment_client_data( $row, $col, $visible, $vertices );
544              
545             $self->xml_end_tag( 'v:shape' );
546 4163         9164 }
547              
548              
549 4163         8922 ##############################################################################
550             #
551             # _write_button_shape()
552 4163         8526 #
553             # Write the <v:shape> element.
554             #
555 4163         9096  
556             my $self = shift;
557             my $id = shift;
558 4163         8394 my $z_index = shift;
559             my $button = shift;
560             my $type = '#_x0000_t201';
561 4163         8519  
562             # Set the shape index.
563 4163         6903 $id = '_x0000_s' . $id;
564              
565             # Get the button parameters
566             my $row = $button->{_row};
567             my $col = $button->{_col};
568             my $vertices = $button->{_vertices};
569              
570             my ( $left, $top, $width, $height ) = $self->_pixels_to_points( $vertices );
571              
572             my $style =
573             'position:absolute;'
574             . 'margin-left:'
575 29     29   59 . $left . 'pt;'
576 29         47 . 'margin-top:'
577 29         47 . $top . 'pt;'
578 29         40 . 'width:'
579 29         55 . $width . 'pt;'
580             . 'height:'
581             . $height . 'pt;'
582 29         137 . 'z-index:'
583             . $z_index . ';'
584             . 'mso-wrap-style:tight';
585 29         82  
586 29         52  
587 29         69 my @attributes = (
588             'id' => $id,
589 29         82 'type' => $type,
590             'style' => $style,
591 29         504 'o:button' => 't',
592             'fillcolor' => 'buttonFace [67]',
593             'strokecolor' => 'windowText [64]',
594             'o:insetmode' => 'auto',
595             );
596              
597             $self->xml_start_tag( 'v:shape', @attributes );
598              
599             # Write the v:fill element.
600             $self->_write_button_fill();
601              
602             # Write the o:lock element.
603             $self->_write_rotation_lock();
604              
605             # Write the v:textbox element.
606 29         141 $self->_write_button_textbox( $button->{_font} );
607              
608             # Write the x:ClientData element.
609             $self->_write_button_client_data( $button );
610              
611             $self->xml_end_tag( 'v:shape' );
612             }
613              
614              
615             ##############################################################################
616 29         105 #
617             # _write_image_shape()
618             #
619 29         100 # Write the <v:shape> element.
620             #
621              
622 29         102 my $self = shift;
623             my $id = shift;
624             my $index = shift;
625 29         109 my $image_data = shift;
626             my $type = '#_x0000_t75';
627              
628 29         93 # Set the shape index.
629             $id = '_x0000_s' . $id;
630 29         69  
631             # Get the image parameters
632             my $width = $image_data->[0];
633             my $height = $image_data->[1];
634             my $name = $image_data->[2];
635             my $position = $image_data->[3];
636             my $x_dpi = $image_data->[4];
637             my $y_dpi = $image_data->[5];
638             my $ref_id = $image_data->[6];
639              
640             # Scale the height/width by the resolution, relative to 72dpi.
641             $width = $width * 72 / $x_dpi;
642 47     47   84 $height = $height * 72 / $y_dpi;
643 47         73  
644 47         70 # Excel uses a rounding based around 72 and 96 dpi.
645 47         75 $width = 72/96 * int($width * 96/72 + 0.25);
646 47         69 $height = 72/96 * int($height * 96/72 + 0.25);
647              
648             my $style =
649 47         105 'position:absolute;'
650             . 'margin-left:0;'
651             . 'margin-top:0;'
652 47         92 . 'width:'
653 47         77 . $width . 'pt;'
654 47         85 . 'height:'
655 47         75 . $height . 'pt;'
656 47         73 . 'z-index:'
657 47         81 . $index;
658 47         77  
659             my @attributes = (
660             'id' => $position,
661 47         116 'o:spid' => $id,
662 47         125 'type' => $type,
663             'style' => $style,
664             );
665 47         146  
666 47         115 $self->xml_start_tag( 'v:shape', @attributes );
667              
668 47         343 # Write the v:imagedata element.
669             $self->_write_imagedata( $ref_id, $name );
670              
671             # Write the o:lock element.
672             $self->_write_rotation_lock();
673              
674             $self->xml_end_tag( 'v:shape' );
675             }
676              
677             ##############################################################################
678             #
679 47         170 # _write_comment_fill()
680             #
681             # Write the <v:fill> element.
682             #
683              
684             my $self = shift;
685             my $color_2 = '#ffffe1';
686 47         168  
687             my @attributes = ( 'color2' => $color_2 );
688              
689 47         162 $self->xml_empty_tag( 'v:fill', @attributes );
690             }
691              
692 47         149  
693             ##############################################################################
694 47         127 #
695             # _write_button_fill()
696             #
697             # Write the <v:fill> element.
698             #
699              
700             my $self = shift;
701             my $color_2 = 'buttonFace [67]';
702             my $detectmouseclick = 't';
703              
704             my @attributes = (
705 4164     4164   4977 'color2' => $color_2,
706 4164         4804 'o:detectmouseclick' => $detectmouseclick,
707             );
708 4164         5939  
709             $self->xml_empty_tag( 'v:fill', @attributes );
710 4164         7223 }
711              
712              
713             ##############################################################################
714             #
715             # _write_shadow()
716             #
717             # Write the <v:shadow> element.
718             #
719              
720             my $self = shift;
721             my $on = 't';
722 30     30   60 my $color = 'black';
723 30         63 my $obscured = 't';
724 30         184  
725             my @attributes = (
726 30         90 'on' => $on,
727             'color' => $color,
728             'obscured' => $obscured,
729             );
730              
731 30         193 $self->xml_empty_tag( 'v:shadow', @attributes );
732             }
733              
734              
735             ##############################################################################
736             #
737             # _write_comment_textbox()
738             #
739             # Write the <v:textbox> element.
740             #
741              
742             my $self = shift;
743 4164     4164   4885 my $style = 'mso-direction-alt:auto';
744 4164         4773  
745 4164         4537 my @attributes = ( 'style' => $style );
746 4164         4267  
747             $self->xml_start_tag( 'v:textbox', @attributes );
748 4164         6882  
749             # Write the div element.
750             $self->_write_div( 'left' );
751              
752             $self->xml_end_tag( 'v:textbox' );
753             }
754 4164         6762  
755              
756             ##############################################################################
757             #
758             # _write_button_textbox()
759             #
760             # Write the <v:textbox> element.
761             #
762              
763             my $self = shift;
764             my $font = shift;
765             my $style = 'mso-direction-alt:auto';
766 4164     4164   5110  
767 4164         5062 my @attributes = ( 'style' => $style, 'o:singleclick' => 'f' );
768              
769 4164         5911 $self->xml_start_tag( 'v:textbox', @attributes );
770              
771 4164         8529 # Write the div element.
772             $self->_write_div( 'center', $font );
773              
774 4164         8240 $self->xml_end_tag( 'v:textbox' );
775             }
776 4164         7255  
777              
778             ##############################################################################
779             #
780             # _write_div()
781             #
782             # Write the <div> element.
783             #
784              
785             my $self = shift;
786             my $align = shift;
787             my $font = shift;
788 29     29   66 my $style = 'text-align:' . $align;
789 29         48  
790 29         52 my @attributes = ( 'style' => $style );
791              
792 29         69 $self->xml_start_tag( 'div', @attributes );
793              
794 29         92  
795             if ( $font ) {
796              
797 29         91 # Write the font element.
798             $self->_write_font( $font );
799 29         68 }
800              
801             $self->xml_end_tag( 'div' );
802             }
803              
804             ##############################################################################
805             #
806             # _write_font()
807             #
808             # Write the <font> element.
809             #
810              
811 4194     4194   4909 my $self = shift;
812 4194         4886 my $font = shift;
813 4194         4567 my $caption = $font->{_caption};
814 4194         5727 my $face = 'Calibri';
815             my $size = 220;
816 4194         6049 my $color = '#000000';
817              
818 4194         8003 my @attributes = (
819             'face' => $face,
820             'size' => $size,
821 4194 100       7045 'color' => $color,
822             );
823              
824 29         109 $self->xml_data_element( 'font', $caption, @attributes );
825             }
826              
827 4194         7458  
828             ##############################################################################
829             #
830             # _write_comment_client_data()
831             #
832             # Write the <x:ClientData> element.
833             #
834              
835             my $self = shift;
836             my $row = shift;
837             my $col = shift;
838 29     29   48 my $visible = shift;
839 29         43 my $vertices = shift;
840 29         60 my $object_type = 'Note';
841 29         46  
842 29         43 my @attributes = ( 'ObjectType' => $object_type );
843 29         49  
844             $self->xml_start_tag( 'x:ClientData', @attributes );
845 29         75  
846             # Write the x:MoveWithCells element.
847             $self->_write_move_with_cells();
848              
849             # Write the x:SizeWithCells element.
850             $self->_write_size_with_cells();
851 29         173  
852             # Write the x:Anchor element.
853             $self->_write_anchor( $vertices );
854              
855             # Write the x:AutoFill element.
856             $self->_write_auto_fill();
857              
858             # Write the x:Row element.
859             $self->_write_row( $row );
860              
861             # Write the x:Column element.
862             $self->_write_column( $col );
863 4163     4163   5262  
864 4163         4899 # Write the x:Visible element.
865 4163         4652 $self->_write_visible() if $visible;
866 4163         4617  
867 4163         4648 $self->xml_end_tag( 'x:ClientData' );
868 4163         4495 }
869              
870 4163         5773  
871             ##############################################################################
872 4163         8283 #
873             # _write_button_client_data()
874             #
875 4163         8195 # Write the <x:ClientData> element.
876             #
877              
878 4163         7915 my $self = shift;
879             my $button = shift;
880             my $row = $button->{_row};
881 4163         8123 my $col = $button->{_col};
882             my $macro = $button->{_macro};
883             my $vertices = $button->{_vertices};
884 4163         8313  
885              
886             my $object_type = 'Button';
887 4163         8514  
888             my @attributes = ( 'ObjectType' => $object_type );
889              
890 4163         8285 $self->xml_start_tag( 'x:ClientData', @attributes );
891              
892             # Write the x:Anchor element.
893 4163 100       6895 $self->_write_anchor( $vertices );
894              
895 4163         7184 # Write the x:PrintObject element.
896             $self->_write_print_object();
897              
898             # Write the x:AutoFill element.
899             $self->_write_auto_fill();
900              
901             # Write the x:FmlaMacro element.
902             $self->_write_fmla_macro( $macro );
903              
904             # Write the x:TextHAlign element.
905             $self->_write_text_halign();
906              
907 29     29   47 # Write the x:TextVAlign element.
908 29         60 $self->_write_text_valign();
909 29         55  
910 29         51 $self->xml_end_tag( 'x:ClientData' );
911 29         49 }
912 29         52  
913              
914             ##############################################################################
915 29         43 #
916             # _write_move_with_cells()
917 29         102 #
918             # Write the <x:MoveWithCells> element.
919 29         88 #
920              
921             my $self = shift;
922 29         92  
923             $self->xml_empty_tag( 'x:MoveWithCells' );
924             }
925 29         104  
926              
927             ##############################################################################
928 29         87 #
929             # _write_size_with_cells()
930             #
931 29         99 # Write the <x:SizeWithCells> element.
932             #
933              
934 29         84 my $self = shift;
935              
936             $self->xml_empty_tag( 'x:SizeWithCells' );
937 29         94 }
938              
939 29         72  
940             ##############################################################################
941             #
942             # _write_visible()
943             #
944             # Write the <x:Visible> element.
945             #
946              
947             my $self = shift;
948              
949             $self->xml_empty_tag( 'x:Visible' );
950             }
951 4164     4164   5010  
952              
953 4164         6903 ##############################################################################
954             #
955             # _write_anchor()
956             #
957             # Write the <x:Anchor> element.
958             #
959              
960             my $self = shift;
961             my $vertices = shift;
962              
963             my ( $col_start, $row_start, $x1, $y1, $col_end, $row_end, $x2, $y2 ) =
964             @$vertices;
965 4164     4164   4881  
966             my $data = join ", ",
967 4164         6248 ( $col_start, $x1, $row_start, $y1, $col_end, $x2, $row_end, $y2 );
968              
969             $self->xml_data_element( 'x:Anchor', $data );
970             }
971              
972              
973             ##############################################################################
974             #
975             # _write_auto_fill()
976             #
977             # Write the <x:AutoFill> element.
978             #
979 10     10   14  
980             my $self = shift;
981 10         21 my $data = 'False';
982              
983             $self->xml_data_element( 'x:AutoFill', $data );
984             }
985              
986              
987             ##############################################################################
988             #
989             # _write_row()
990             #
991             # Write the <x:Row> element.
992             #
993 4193     4193   4952  
994 4193         4815 my $self = shift;
995             my $data = shift;
996 4193         7426  
997             $self->xml_data_element( 'x:Row', $data );
998             }
999 4193         8383  
1000              
1001             ##############################################################################
1002 4193         7831 #
1003             # _write_column()
1004             #
1005             # Write the <x:Column> element.
1006             #
1007              
1008             my $self = shift;
1009             my $data = shift;
1010              
1011             $self->xml_data_element( 'x:Column', $data );
1012             }
1013              
1014 4193     4193   5118  
1015 4193         5103 ##############################################################################
1016             #
1017 4193         6595 # _write_print_object()
1018             #
1019             # Write the <x:PrintObject> element.
1020             #
1021              
1022             my $self = shift;
1023             my $data = 'False';
1024              
1025             $self->xml_data_element( 'x:PrintObject', $data );
1026             }
1027              
1028              
1029 4164     4164   4824 ##############################################################################
1030 4164         4848 #
1031             # _write_text_halign()
1032 4164         6532 #
1033             # Write the <x:TextHAlign> element.
1034             #
1035              
1036             my $self = shift;
1037             my $data = 'Center';
1038              
1039             $self->xml_data_element( 'x:TextHAlign', $data );
1040             }
1041              
1042              
1043             ##############################################################################
1044 4164     4164   4772 #
1045 4164         4717 # _write_text_valign()
1046             #
1047 4164         6596 # Write the <x:TextVAlign> element.
1048             #
1049              
1050             my $self = shift;
1051             my $data = 'Center';
1052              
1053             $self->xml_data_element( 'x:TextVAlign', $data );
1054             }
1055              
1056              
1057             ##############################################################################
1058             #
1059 29     29   81 # _write_fmla_macro()
1060 29         48 #
1061             # Write the <x:FmlaMacro> element.
1062 29         84 #
1063              
1064             my $self = shift;
1065             my $data = shift;
1066              
1067             $self->xml_data_element( 'x:FmlaMacro', $data );
1068             }
1069              
1070             ##############################################################################
1071             #
1072             # _write_imagedata()
1073             #
1074 29     29   220 # Write the <v:imagedata> element.
1075 29         55 #
1076              
1077 29         241 my $self = shift;
1078             my $index = shift;
1079             my $o_title = shift;
1080              
1081             my @attributes = (
1082             'o:relid' => 'rId' . $index,
1083             'o:title' => $o_title,
1084             );
1085              
1086             $self->xml_empty_tag( 'v:imagedata', @attributes );
1087             }
1088              
1089 29     29   141  
1090 29         48  
1091             ##############################################################################
1092 29         63 #
1093             # _write_formulas()
1094             #
1095             # Write the <v:formulas> element.
1096             #
1097              
1098             my $self = shift;
1099              
1100             $self->xml_start_tag( 'v:formulas' );
1101              
1102             # Write the v:f elements.
1103             $self->_write_f('if lineDrawn pixelLineWidth 0');
1104 29     29   56 $self->_write_f('sum @0 1 0');
1105 29         60 $self->_write_f('sum 0 0 @1');
1106             $self->_write_f('prod @2 1 2');
1107 29         77 $self->_write_f('prod @3 21600 pixelWidth');
1108             $self->_write_f('prod @3 21600 pixelHeight');
1109             $self->_write_f('sum @0 0 1');
1110             $self->_write_f('prod @6 1 2');
1111             $self->_write_f('prod @7 21600 pixelWidth');
1112             $self->_write_f('sum @8 21600 0');
1113             $self->_write_f('prod @7 21600 pixelHeight');
1114             $self->_write_f('sum @10 21600 0');
1115              
1116             $self->xml_end_tag( 'v:formulas' );
1117             }
1118 47     47   90  
1119 47         73  
1120 47         71 ##############################################################################
1121             #
1122 47         150 # _write_f()
1123             #
1124             # Write the <v:f> element.
1125             #
1126              
1127 47         126 my $self = shift;
1128             my $eqn = shift;
1129              
1130             my @attributes = ( 'eqn' => $eqn );
1131              
1132             $self->xml_empty_tag( 'v:f', @attributes );
1133             }
1134              
1135             1;
1136              
1137              
1138              
1139             =pod
1140 25     25   49  
1141             =head1 NAME
1142 25         114  
1143             VML - A class for writing the Excel XLSX VML files.
1144              
1145 25         111 =head1 SYNOPSIS
1146 25         86  
1147 25         82 See the documentation for L<Excel::Writer::XLSX>.
1148 25         81  
1149 25         79 =head1 DESCRIPTION
1150 25         76  
1151 25         92 This module is used in conjunction with L<Excel::Writer::XLSX>.
1152 25         88  
1153 25         73 =head1 AUTHOR
1154 25         82  
1155 25         83 John McNamara jmcnamara@cpan.org
1156 25         79  
1157             =head1 COPYRIGHT
1158 25         86  
1159             (c) MM-MMXXI, John McNamara.
1160              
1161             All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.
1162              
1163             =head1 LICENSE
1164              
1165             Either the Perl Artistic Licence L<http://dev.perl.org/licenses/artistic.html> or the GPL L<http://www.opensource.org/licenses/gpl-license.php>.
1166              
1167             =head1 DISCLAIMER OF WARRANTY
1168              
1169             See the documentation for L<Excel::Writer::XLSX>.
1170 300     300   384  
1171 300         376 =cut