Passed
Push — master ( b504ba...c2a964 )
by
unknown
21:09 queued 09:01
created

Drawing::writeVMLHeaderFooterImages()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 138
Code Lines 81

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 80
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 81
nc 4
nop 1
dl 0
loc 138
ccs 80
cts 81
cp 0.9877
crap 3
rs 8.4145
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
4
5
use Composer\Pcre\Preg;
6
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
7
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Namespaces;
8
use PhpOffice\PhpSpreadsheet\Shared\Drawing as SharedDrawing;
9
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
10
use PhpOffice\PhpSpreadsheet\Spreadsheet;
11
use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing;
12
use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing;
13
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
14
15
class Drawing extends WriterPart
16
{
17
    /**
18
     * Write drawings to XML format.
19
     *
20
     * @param bool $includeCharts Flag indicating if we should include drawing details for charts
21
     *
22
     * @return string XML Output
23
     */
24 122
    public function writeDrawings(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet, bool $includeCharts = false): string
25
    {
26
        // Create XML writer
27 122
        $objWriter = null;
28 122
        if ($this->getParentWriter()->getUseDiskCaching()) {
29
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
30
        } else {
31 122
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
32
        }
33
34
        // XML header
35 122
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
36
37
        // xdr:wsDr
38 122
        $objWriter->startElement('xdr:wsDr');
39 122
        $objWriter->writeAttribute('xmlns:xdr', Namespaces::SPREADSHEET_DRAWING);
40 122
        $objWriter->writeAttribute('xmlns:a', Namespaces::DRAWINGML);
41
42
        // Loop through images and write drawings
43 122
        $i = 1;
44 122
        $iterator = $worksheet->getDrawingCollection()->getIterator();
45 122
        while ($iterator->valid()) {
46
            /** @var BaseDrawing $pDrawing */
47 53
            $pDrawing = $iterator->current();
48 53
            $pRelationId = $i;
49 53
            $hlinkClickId = $pDrawing->getHyperlink() === null ? null : ++$i;
50
51 53
            $this->writeDrawing($objWriter, $pDrawing, $pRelationId, $hlinkClickId);
52
53 53
            $iterator->next();
54 53
            ++$i;
55
        }
56
57 122
        if ($includeCharts) {
58 78
            $chartCount = $worksheet->getChartCount();
59
            // Loop through charts and write the chart position
60 78
            if ($chartCount > 0) {
61 78
                for ($c = 0; $c < $chartCount; ++$c) {
62 78
                    $chart = $worksheet->getChartByIndex((string) $c);
63 78
                    if ($chart !== false) {
64 78
                        $this->writeChart($objWriter, $chart, $c + $i);
65
                    }
66
                }
67
            }
68
        }
69
70
        // unparsed AlternateContent
71
        /** @var string[][][][] */
72 122
        $unparsedLoadedData = $worksheet->getParentOrThrow()->getUnparsedLoadedData();
73 122
        if (isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingAlternateContents'])) {
74 4
            foreach ($unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingAlternateContents'] as $drawingAlternateContent) {
75 4
                $objWriter->writeRaw($drawingAlternateContent);
76
            }
77
        }
78
79 122
        $objWriter->endElement();
80
81
        // Return
82 122
        return $objWriter->getData();
83
    }
84
85
    /**
86
     * Write drawings to XML format.
87
     */
88 78
    public function writeChart(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Chart\Chart $chart, int $relationId = -1): void
89
    {
90 78
        $tl = $chart->getTopLeftPosition();
91 78
        $tlColRow = Coordinate::indexesFromString($tl['cell']);
92 78
        $br = $chart->getBottomRightPosition();
93
94 78
        $isTwoCellAnchor = $br['cell'] !== '';
95 78
        if ($isTwoCellAnchor) {
96 76
            $brColRow = Coordinate::indexesFromString($br['cell']);
97
98 76
            $objWriter->startElement('xdr:twoCellAnchor');
99
100 76
            $objWriter->startElement('xdr:from');
101 76
            $objWriter->writeElement('xdr:col', (string) ($tlColRow[0] - 1));
102 76
            $objWriter->writeElement('xdr:colOff', self::stringEmu($tl['xOffset']));
103 76
            $objWriter->writeElement('xdr:row', (string) ($tlColRow[1] - 1));
104 76
            $objWriter->writeElement('xdr:rowOff', self::stringEmu($tl['yOffset']));
105 76
            $objWriter->endElement();
106 76
            $objWriter->startElement('xdr:to');
107 76
            $objWriter->writeElement('xdr:col', (string) ($brColRow[0] - 1));
108 76
            $objWriter->writeElement('xdr:colOff', self::stringEmu($br['xOffset']));
109 76
            $objWriter->writeElement('xdr:row', (string) ($brColRow[1] - 1));
110 76
            $objWriter->writeElement('xdr:rowOff', self::stringEmu($br['yOffset']));
111 76
            $objWriter->endElement();
112 3
        } elseif ($chart->getOneCellAnchor()) {
113 1
            $objWriter->startElement('xdr:oneCellAnchor');
114
115 1
            $objWriter->startElement('xdr:from');
116 1
            $objWriter->writeElement('xdr:col', (string) ($tlColRow[0] - 1));
117 1
            $objWriter->writeElement('xdr:colOff', self::stringEmu($tl['xOffset']));
118 1
            $objWriter->writeElement('xdr:row', (string) ($tlColRow[1] - 1));
119 1
            $objWriter->writeElement('xdr:rowOff', self::stringEmu($tl['yOffset']));
120 1
            $objWriter->endElement();
121 1
            $objWriter->startElement('xdr:ext');
122 1
            $objWriter->writeAttribute('cx', self::stringEmu($br['xOffset']));
123 1
            $objWriter->writeAttribute('cy', self::stringEmu($br['yOffset']));
124 1
            $objWriter->endElement();
125
        } else {
126 2
            $objWriter->startElement('xdr:absoluteAnchor');
127 2
            $objWriter->startElement('xdr:pos');
128 2
            $objWriter->writeAttribute('x', '0');
129 2
            $objWriter->writeAttribute('y', '0');
130 2
            $objWriter->endElement();
131 2
            $objWriter->startElement('xdr:ext');
132 2
            $objWriter->writeAttribute('cx', self::stringEmu($br['xOffset']));
133 2
            $objWriter->writeAttribute('cy', self::stringEmu($br['yOffset']));
134 2
            $objWriter->endElement();
135
        }
136
137 78
        $objWriter->startElement('xdr:graphicFrame');
138 78
        $objWriter->writeAttribute('macro', '');
139 78
        $objWriter->startElement('xdr:nvGraphicFramePr');
140 78
        $objWriter->startElement('xdr:cNvPr');
141 78
        $objWriter->writeAttribute('name', 'Chart ' . $relationId);
142 78
        $objWriter->writeAttribute('id', (string) (1025 * $relationId));
143 78
        $objWriter->endElement();
144 78
        $objWriter->startElement('xdr:cNvGraphicFramePr');
145 78
        $objWriter->startElement('a:graphicFrameLocks');
146 78
        $objWriter->endElement();
147 78
        $objWriter->endElement();
148 78
        $objWriter->endElement();
149
150 78
        $objWriter->startElement('xdr:xfrm');
151 78
        $objWriter->startElement('a:off');
152 78
        $objWriter->writeAttribute('x', '0');
153 78
        $objWriter->writeAttribute('y', '0');
154 78
        $objWriter->endElement();
155 78
        $objWriter->startElement('a:ext');
156 78
        $objWriter->writeAttribute('cx', '0');
157 78
        $objWriter->writeAttribute('cy', '0');
158 78
        $objWriter->endElement();
159 78
        $objWriter->endElement();
160
161 78
        $objWriter->startElement('a:graphic');
162 78
        $objWriter->startElement('a:graphicData');
163 78
        $objWriter->writeAttribute('uri', Namespaces::CHART);
164 78
        $objWriter->startElement('c:chart');
165 78
        $objWriter->writeAttribute('xmlns:c', Namespaces::CHART);
166 78
        $objWriter->writeAttribute('xmlns:r', Namespaces::SCHEMA_OFFICE_DOCUMENT);
167 78
        $objWriter->writeAttribute('r:id', 'rId' . $relationId);
168 78
        $objWriter->endElement();
169 78
        $objWriter->endElement();
170 78
        $objWriter->endElement();
171 78
        $objWriter->endElement();
172
173 78
        $objWriter->startElement('xdr:clientData');
174 78
        $objWriter->endElement();
175
176 78
        $objWriter->endElement();
177
    }
178
179
    /**
180
     * Write drawings to XML format.
181
     */
182 53
    public function writeDrawing(XMLWriter $objWriter, BaseDrawing $drawing, int $relationId = -1, ?int $hlinkClickId = null): void
183
    {
184 53
        if ($relationId >= 0) {
185 53
            $isTwoCellAnchor = $drawing->getCoordinates2() !== '';
186 53
            if ($isTwoCellAnchor) {
187
                // xdr:twoCellAnchor
188 31
                $objWriter->startElement('xdr:twoCellAnchor');
189 31
                if ($drawing->validEditAs()) {
190 26
                    $objWriter->writeAttribute('editAs', $drawing->getEditAs());
191
                }
192
                // Image location
193 31
                $aCoordinates = Coordinate::indexesFromString($drawing->getCoordinates());
194 31
                $aCoordinates2 = Coordinate::indexesFromString($drawing->getCoordinates2());
195
196
                // xdr:from
197 31
                $objWriter->startElement('xdr:from');
198 31
                $objWriter->writeElement('xdr:col', (string) ($aCoordinates[0] - 1));
199 31
                $objWriter->writeElement('xdr:colOff', self::stringEmu($drawing->getOffsetX()));
200 31
                $objWriter->writeElement('xdr:row', (string) ($aCoordinates[1] - 1));
201 31
                $objWriter->writeElement('xdr:rowOff', self::stringEmu($drawing->getOffsetY()));
202 31
                $objWriter->endElement();
203
204
                // xdr:to
205 31
                $objWriter->startElement('xdr:to');
206 31
                $objWriter->writeElement('xdr:col', (string) ($aCoordinates2[0] - 1));
207 31
                $objWriter->writeElement('xdr:colOff', self::stringEmu($drawing->getOffsetX2()));
208 31
                $objWriter->writeElement('xdr:row', (string) ($aCoordinates2[1] - 1));
209 31
                $objWriter->writeElement('xdr:rowOff', self::stringEmu($drawing->getOffsetY2()));
210 31
                $objWriter->endElement();
211
            } else {
212
                // xdr:oneCellAnchor
213 24
                $objWriter->startElement('xdr:oneCellAnchor');
214
                // Image location
215 24
                $aCoordinates = Coordinate::indexesFromString($drawing->getCoordinates());
216
217
                // xdr:from
218 24
                $objWriter->startElement('xdr:from');
219 24
                $objWriter->writeElement('xdr:col', (string) ($aCoordinates[0] - 1));
220 24
                $objWriter->writeElement('xdr:colOff', self::stringEmu($drawing->getOffsetX()));
221 24
                $objWriter->writeElement('xdr:row', (string) ($aCoordinates[1] - 1));
222 24
                $objWriter->writeElement('xdr:rowOff', self::stringEmu($drawing->getOffsetY()));
223 24
                $objWriter->endElement();
224
225
                // xdr:ext
226 24
                $objWriter->startElement('xdr:ext');
227 24
                $objWriter->writeAttribute('cx', self::stringEmu($drawing->getWidth()));
228 24
                $objWriter->writeAttribute('cy', self::stringEmu($drawing->getHeight()));
229 24
                $objWriter->endElement();
230
            }
231
232
            // xdr:pic
233 53
            $objWriter->startElement('xdr:pic');
234
235
            // xdr:nvPicPr
236 53
            $objWriter->startElement('xdr:nvPicPr');
237
238
            // xdr:cNvPr
239 53
            $objWriter->startElement('xdr:cNvPr');
240 53
            $objWriter->writeAttribute('id', (string) $relationId);
241 53
            $objWriter->writeAttribute('name', $drawing->getName());
242 53
            $objWriter->writeAttribute('descr', $drawing->getDescription());
243
244
            //a:hlinkClick
245 53
            $this->writeHyperLinkDrawing($objWriter, $hlinkClickId);
246
247 53
            $objWriter->endElement();
248
249
            // xdr:cNvPicPr
250 53
            $objWriter->startElement('xdr:cNvPicPr');
251
252
            // a:picLocks
253 53
            $objWriter->startElement('a:picLocks');
254 53
            $objWriter->writeAttribute('noChangeAspect', '1');
255 53
            $objWriter->endElement();
256
257 53
            $objWriter->endElement();
258
259 53
            $objWriter->endElement();
260
261
            // xdr:blipFill
262 53
            $objWriter->startElement('xdr:blipFill');
263
264
            // a:blip
265 53
            $objWriter->startElement('a:blip');
266 53
            $objWriter->writeAttribute('xmlns:r', Namespaces::SCHEMA_OFFICE_DOCUMENT);
267 53
            $objWriter->writeAttribute('r:embed', 'rId' . $relationId);
268 53
            $temp = $drawing->getOpacity();
269 53
            if (is_int($temp) && $temp >= 0 && $temp <= 100000) {
270 4
                $objWriter->startElement('a:alphaModFix');
271 4
                $objWriter->writeAttribute('amt', "$temp");
272 4
                $objWriter->endElement(); // a:alphaModFix
273
            }
274 53
            $objWriter->endElement(); // a:blip
275
276 53
            $srcRect = $drawing->getSrcRect();
277 53
            if (!empty($srcRect)) {
278 2
                $objWriter->startElement('a:srcRect');
279 2
                foreach ($srcRect as $key => $value) {
280 2
                    $objWriter->writeAttribute($key, (string) $value);
281
                }
282 2
                $objWriter->endElement(); // a:srcRect
283 2
                $objWriter->startElement('a:stretch');
284 2
                $objWriter->endElement(); // a:stretch
285
            } else {
286
                // a:stretch
287 51
                $objWriter->startElement('a:stretch');
288 51
                $objWriter->writeElement('a:fillRect', null);
289 51
                $objWriter->endElement();
290
            }
291
292 53
            $objWriter->endElement();
293
294
            // xdr:spPr
295 53
            $objWriter->startElement('xdr:spPr');
296
297
            // a:xfrm
298 53
            $objWriter->startElement('a:xfrm');
299 53
            $objWriter->writeAttribute('rot', (string) SharedDrawing::degreesToAngle($drawing->getRotation()));
300 53
            self::writeAttributeIf($objWriter, $drawing->getFlipVertical(), 'flipV', '1');
301 53
            self::writeAttributeIf($objWriter, $drawing->getFlipHorizontal(), 'flipH', '1');
302 53
            if ($isTwoCellAnchor) {
303 31
                $objWriter->startElement('a:ext');
304 31
                $objWriter->writeAttribute('cx', self::stringEmu($drawing->getWidth()));
305 31
                $objWriter->writeAttribute('cy', self::stringEmu($drawing->getHeight()));
306 31
                $objWriter->endElement();
307
            }
308 53
            $objWriter->endElement();
309
310
            // a:prstGeom
311 53
            $objWriter->startElement('a:prstGeom');
312 53
            $objWriter->writeAttribute('prst', 'rect');
313
314
            // a:avLst
315 53
            $objWriter->writeElement('a:avLst', null);
316
317 53
            $objWriter->endElement();
318
319 53
            if ($drawing->getShadow()->getVisible()) {
320
                // a:effectLst
321 6
                $objWriter->startElement('a:effectLst');
322
323
                // a:outerShdw
324 6
                $objWriter->startElement('a:outerShdw');
325 6
                $objWriter->writeAttribute('blurRad', self::stringEmu($drawing->getShadow()->getBlurRadius()));
326 6
                $objWriter->writeAttribute('dist', self::stringEmu($drawing->getShadow()->getDistance()));
327 6
                $objWriter->writeAttribute('dir', (string) SharedDrawing::degreesToAngle($drawing->getShadow()->getDirection()));
328 6
                $objWriter->writeAttribute('algn', $drawing->getShadow()->getAlignment());
329 6
                $objWriter->writeAttribute('rotWithShape', '0');
330
331
                // a:srgbClr
332 6
                $objWriter->startElement('a:srgbClr');
333 6
                $objWriter->writeAttribute('val', $drawing->getShadow()->getColor()->getRGB());
334
335
                // a:alpha
336 6
                $objWriter->startElement('a:alpha');
337 6
                $objWriter->writeAttribute('val', (string) ($drawing->getShadow()->getAlpha() * 1000));
338 6
                $objWriter->endElement();
339
340 6
                $objWriter->endElement();
341
342 6
                $objWriter->endElement();
343
344 6
                $objWriter->endElement();
345
            }
346 53
            $objWriter->endElement();
347
348 53
            $objWriter->endElement();
349
350
            // xdr:clientData
351 53
            $objWriter->writeElement('xdr:clientData', null);
352
353 53
            $objWriter->endElement();
354
        } else {
355
            throw new WriterException('Invalid parameters passed.');
356
        }
357
    }
358
359
    /**
360
     * Write VML header/footer images to XML format.
361
     *
362
     * @return string XML Output
363
     */
364 3
    public function writeVMLHeaderFooterImages(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet): string
365
    {
366
        // Create XML writer
367 3
        $objWriter = null;
368 3
        if ($this->getParentWriter()->getUseDiskCaching()) {
369
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
370
        } else {
371 3
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
372
        }
373
374
        // XML header
375 3
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
376
377
        // Header/footer images
378 3
        $images = $worksheet->getHeaderFooter()->getImages();
379
380
        // xml
381 3
        $objWriter->startElement('xml');
382 3
        $objWriter->writeAttribute('xmlns:v', Namespaces::URN_VML);
383 3
        $objWriter->writeAttribute('xmlns:o', Namespaces::URN_MSOFFICE);
384 3
        $objWriter->writeAttribute('xmlns:x', Namespaces::URN_EXCEL);
385
386
        // o:shapelayout
387 3
        $objWriter->startElement('o:shapelayout');
388 3
        $objWriter->writeAttribute('v:ext', 'edit');
389
390
        // o:idmap
391 3
        $objWriter->startElement('o:idmap');
392 3
        $objWriter->writeAttribute('v:ext', 'edit');
393 3
        $objWriter->writeAttribute('data', '1');
394 3
        $objWriter->endElement();
395
396 3
        $objWriter->endElement();
397
398
        // v:shapetype
399 3
        $objWriter->startElement('v:shapetype');
400 3
        $objWriter->writeAttribute('id', '_x0000_t75');
401 3
        $objWriter->writeAttribute('coordsize', '21600,21600');
402 3
        $objWriter->writeAttribute('o:spt', '75');
403 3
        $objWriter->writeAttribute('o:preferrelative', 't');
404 3
        $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe');
405 3
        $objWriter->writeAttribute('filled', 'f');
406 3
        $objWriter->writeAttribute('stroked', 'f');
407
408
        // v:stroke
409 3
        $objWriter->startElement('v:stroke');
410 3
        $objWriter->writeAttribute('joinstyle', 'miter');
411 3
        $objWriter->endElement();
412
413
        // v:formulas
414 3
        $objWriter->startElement('v:formulas');
415
416
        // v:f
417 3
        $objWriter->startElement('v:f');
418 3
        $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0');
419 3
        $objWriter->endElement();
420
421
        // v:f
422 3
        $objWriter->startElement('v:f');
423 3
        $objWriter->writeAttribute('eqn', 'sum @0 1 0');
424 3
        $objWriter->endElement();
425
426
        // v:f
427 3
        $objWriter->startElement('v:f');
428 3
        $objWriter->writeAttribute('eqn', 'sum 0 0 @1');
429 3
        $objWriter->endElement();
430
431
        // v:f
432 3
        $objWriter->startElement('v:f');
433 3
        $objWriter->writeAttribute('eqn', 'prod @2 1 2');
434 3
        $objWriter->endElement();
435
436
        // v:f
437 3
        $objWriter->startElement('v:f');
438 3
        $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth');
439 3
        $objWriter->endElement();
440
441
        // v:f
442 3
        $objWriter->startElement('v:f');
443 3
        $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight');
444 3
        $objWriter->endElement();
445
446
        // v:f
447 3
        $objWriter->startElement('v:f');
448 3
        $objWriter->writeAttribute('eqn', 'sum @0 0 1');
449 3
        $objWriter->endElement();
450
451
        // v:f
452 3
        $objWriter->startElement('v:f');
453 3
        $objWriter->writeAttribute('eqn', 'prod @6 1 2');
454 3
        $objWriter->endElement();
455
456
        // v:f
457 3
        $objWriter->startElement('v:f');
458 3
        $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth');
459 3
        $objWriter->endElement();
460
461
        // v:f
462 3
        $objWriter->startElement('v:f');
463 3
        $objWriter->writeAttribute('eqn', 'sum @8 21600 0');
464 3
        $objWriter->endElement();
465
466
        // v:f
467 3
        $objWriter->startElement('v:f');
468 3
        $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight');
469 3
        $objWriter->endElement();
470
471
        // v:f
472 3
        $objWriter->startElement('v:f');
473 3
        $objWriter->writeAttribute('eqn', 'sum @10 21600 0');
474 3
        $objWriter->endElement();
475
476 3
        $objWriter->endElement();
477
478
        // v:path
479 3
        $objWriter->startElement('v:path');
480 3
        $objWriter->writeAttribute('o:extrusionok', 'f');
481 3
        $objWriter->writeAttribute('gradientshapeok', 't');
482 3
        $objWriter->writeAttribute('o:connecttype', 'rect');
483 3
        $objWriter->endElement();
484
485
        // o:lock
486 3
        $objWriter->startElement('o:lock');
487 3
        $objWriter->writeAttribute('v:ext', 'edit');
488 3
        $objWriter->writeAttribute('aspectratio', 't');
489 3
        $objWriter->endElement();
490
491 3
        $objWriter->endElement();
492
493
        // Loop through images
494 3
        foreach ($images as $key => $value) {
495 3
            $this->writeVMLHeaderFooterImage($objWriter, $key, $value);
496
        }
497
498 3
        $objWriter->endElement();
499
500
        // Return
501 3
        return $objWriter->getData();
502
    }
503
504
    /**
505
     * Write VML comment to XML format.
506
     *
507
     * @param string $reference Reference
508
     */
509 3
    private function writeVMLHeaderFooterImage(XMLWriter $objWriter, string $reference, HeaderFooterDrawing $image): void
510
    {
511
        // Calculate object id
512 3
        if (!Preg::isMatch('{(\d+)}', md5($reference), $m)) {
513
            // @codeCoverageIgnoreStart
514
            throw new WriterException('Regexp failure in writeVMLHeaderFooterImage');
515
            // @codeCoverageIgnoreEnd
516
        }
517 3
        $id = 1500 + ((int) substr($m[1], 0, 2) * 1);
518
519
        // Calculate offset
520 3
        $width = $image->getWidth();
521 3
        $height = $image->getHeight();
522 3
        $marginLeft = $image->getOffsetX();
523 3
        $marginTop = $image->getOffsetY();
524
525
        // v:shape
526 3
        $objWriter->startElement('v:shape');
527 3
        $objWriter->writeAttribute('id', $reference);
528 3
        $objWriter->writeAttribute('o:spid', '_x0000_s' . $id);
529 3
        $objWriter->writeAttribute('type', '#_x0000_t75');
530 3
        $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1");
531
532
        // v:imagedata
533 3
        $objWriter->startElement('v:imagedata');
534 3
        $objWriter->writeAttribute('o:relid', 'rId' . $reference);
535 3
        $objWriter->writeAttribute('o:title', $image->getName());
536 3
        $objWriter->endElement();
537
538
        // o:lock
539 3
        $objWriter->startElement('o:lock');
540 3
        $objWriter->writeAttribute('v:ext', 'edit');
541 3
        $objWriter->writeAttribute('textRotation', 't');
542 3
        $objWriter->endElement();
543
544 3
        $objWriter->endElement();
545
    }
546
547
    /**
548
     * Get an array of all drawings.
549
     *
550
     * @return BaseDrawing[] All drawings in PhpSpreadsheet
551
     */
552 375
    public function allDrawings(Spreadsheet $spreadsheet): array
553
    {
554
        // Get an array of all drawings
555 375
        $aDrawings = [];
556
557
        // Loop through PhpSpreadsheet
558 375
        $sheetCount = $spreadsheet->getSheetCount();
559 375
        for ($i = 0; $i < $sheetCount; ++$i) {
560
            // Loop through images and add to array
561 375
            $iterator = $spreadsheet->getSheet($i)->getDrawingCollection()->getIterator();
562 375
            while ($iterator->valid()) {
563 53
                $aDrawings[] = $iterator->current();
564
565 53
                $iterator->next();
566
            }
567
        }
568
569 375
        return $aDrawings;
570
    }
571
572 53
    private function writeHyperLinkDrawing(XMLWriter $objWriter, ?int $hlinkClickId): void
573
    {
574 53
        if ($hlinkClickId === null) {
575 51
            return;
576
        }
577
578 2
        $objWriter->startElement('a:hlinkClick');
579 2
        $objWriter->writeAttribute('xmlns:r', Namespaces::SCHEMA_OFFICE_DOCUMENT);
580 2
        $objWriter->writeAttribute('r:id', 'rId' . $hlinkClickId);
581 2
        $objWriter->endElement();
582
    }
583
584 120
    private static function stringEmu(int $pixelValue): string
585
    {
586 120
        return (string) SharedDrawing::pixelsToEMU($pixelValue);
587
    }
588
589 53
    private static function writeAttributeIf(XMLWriter $objWriter, ?bool $condition, string $attr, string $val): void
590
    {
591 53
        if ($condition) {
592 1
            $objWriter->writeAttribute($attr, $val);
593
        }
594
    }
595
}
596