Completed
Pull Request — develop (#322)
by Thomas
08:13 queued 03:00
created

AbstractSlide::writeShapeChart()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 46
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 46
ccs 0
cts 34
cp 0
rs 8.9411
cc 1
eloc 33
nc 1
nop 3
crap 2
1
<?php
2
/**
3
 * This file is part of PHPPresentation - A pure PHP library for reading and writing
4
 * presentations documents.
5
 *
6
 * PHPPresentation is free software distributed under the terms of the GNU Lesser
7
 * General Public License version 3 as published by the Free Software Foundation.
8
 *
9
 * For the full copyright and license information, please read the LICENSE
10
 * file that was distributed with this source code. For the full list of
11
 * contributors, visit https://github.com/PHPOffice/PHPPresentation/contributors.
12
 *
13
 * @link        https://github.com/PHPOffice/PHPPresentation
14
 * @copyright   2009-2015 PHPPresentation contributors
15
 * @license     http://www.gnu.org/licenses/lgpl.txt LGPL version 3
16
 */
17
namespace PhpOffice\PhpPresentation\Writer\PowerPoint2007;
18
19
use PhpOffice\Common\Drawing as CommonDrawing;
20
use PhpOffice\Common\Text;
21
use PhpOffice\Common\XMLWriter;
22
use PhpOffice\PhpPresentation\Shape\AbstractGraphic;
23
use PhpOffice\PhpPresentation\Shape\Chart as ShapeChart;
24
use PhpOffice\PhpPresentation\Shape\Comment;
25
use PhpOffice\PhpPresentation\Shape\Drawing\Gd as ShapeDrawingGd;
26
use PhpOffice\PhpPresentation\Shape\Drawing\File as ShapeDrawingFile;
27
use PhpOffice\PhpPresentation\Shape\Group;
28
use PhpOffice\PhpPresentation\Shape\Line;
29
use PhpOffice\PhpPresentation\Shape\Media;
30
use PhpOffice\PhpPresentation\Shape\Placeholder;
31
use PhpOffice\PhpPresentation\Shape\RichText;
32
use PhpOffice\PhpPresentation\Shape\RichText\BreakElement;
33
use PhpOffice\PhpPresentation\Shape\RichText\Run;
34
use PhpOffice\PhpPresentation\Shape\RichText\TextElement;
35
use PhpOffice\PhpPresentation\Shape\Table as ShapeTable;
36
use PhpOffice\PhpPresentation\Slide;
37
use PhpOffice\PhpPresentation\Slide\Note;
38
use PhpOffice\PhpPresentation\Style\Alignment;
39
use PhpOffice\PhpPresentation\Style\Bullet;
40
use PhpOffice\PhpPresentation\Style\Border;
41
use PhpOffice\PhpPresentation\Style\Shadow;
42
use PhpOffice\PhpPresentation\Slide\AbstractSlide as AbstractSlideAlias;
43
use PhpOffice\PhpPresentation\Slide\SlideMaster;
44
use PhpOffice\PhpPresentation\Slide\Background;
45
46
abstract class AbstractSlide extends AbstractDecoratorWriter
47
{
48
    /**
49
     * @param SlideMaster $pSlideMaster
50
     * @param $objWriter
51
     * @param $relId
52
     * @throws \Exception
53
     */
54 98
    protected function writeDrawingRelations(AbstractSlideAlias $pSlideMaster, $objWriter, $relId)
55
    {
56 98
        if ($pSlideMaster->getShapeCollection()->count() > 0) {
57
            // Loop trough images and write relationships
58
            $iterator = $pSlideMaster->getShapeCollection()->getIterator();
59
            while ($iterator->valid()) {
60
                if ($iterator->current() instanceof ShapeDrawingFile || $iterator->current() instanceof ShapeDrawingGd) {
61
                    // Write relationship for image drawing
62
                    $this->writeRelationship(
63
                        $objWriter,
64
                        $relId,
65
                        'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
66
                        '../media/' . str_replace(' ', '_', $iterator->current()->getIndexedFilename())
67
                    );
68
                    $iterator->current()->relationId = 'rId' . $relId;
69
                    ++$relId;
70
                } elseif ($iterator->current() instanceof ShapeChart) {
71
                    // Write relationship for chart drawing
72
                    $this->writeRelationship(
73
                        $objWriter,
74
                        $relId,
75
                        'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
76
                        '../charts/' . $iterator->current()->getIndexedFilename()
77
                    );
78
                    $iterator->current()->relationId = 'rId' . $relId;
79
                    ++$relId;
80
                } elseif ($iterator->current() instanceof Group) {
81
                    $iterator2 = $iterator->current()->getShapeCollection()->getIterator();
82
                    while ($iterator2->valid()) {
83
                        if ($iterator2->current() instanceof ShapeDrawingFile ||
84
                            $iterator2->current() instanceof ShapeDrawingGd
85
                        ) {
86
                            // Write relationship for image drawing
87
                            $this->writeRelationship(
88
                                $objWriter,
89
                                $relId,
90
                                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
91
                                '../media/' . str_replace(' ', '_', $iterator2->current()->getIndexedFilename())
92
                            );
93
                            $iterator2->current()->relationId = 'rId' . $relId;
94
                            ++$relId;
95
                        } elseif ($iterator2->current() instanceof ShapeChart) {
96
                            // Write relationship for chart drawing
97
                            $this->writeRelationship(
98
                                $objWriter,
99
                                $relId,
100
                                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
101
                                '../charts/' . $iterator2->current()->getIndexedFilename()
102
                            );
103
                            $iterator2->current()->relationId = 'rId' . $relId;
104
                            ++$relId;
105
                        }
106
                        $iterator2->next();
107
                    }
108
                }
109
                $iterator->next();
110
            }
111
        }
112 98
    }
113
114
    /**
115
     * @param XMLWriter $objWriter
116
     * @param \ArrayObject|\PhpOffice\PhpPresentation\AbstractShape[] $shapes
117
     * @param int $shapeId
118
     * @throws \Exception
119
     */
120 98
    protected function writeShapeCollection(XMLWriter $objWriter, $shapes = array(), &$shapeId = 0)
121
    {
122 98
        if (count($shapes) == 0) {
123 98
            return;
124
        }
125 73
        foreach ($shapes as $shape) {
126
            // Increment $shapeId
127 73
            ++$shapeId;
128
            // Check type
129 73
            if ($shape instanceof RichText) {
130 24
                $this->writeShapeText($objWriter, $shape, $shapeId);
131 73
            } elseif ($shape instanceof ShapeTable) {
132 9
                $this->writeShapeTable($objWriter, $shape, $shapeId);
133 49
            } elseif ($shape instanceof Line) {
134 1
                $this->writeShapeLine($objWriter, $shape, $shapeId);
135 40
            } elseif ($shape instanceof ShapeChart) {
136 24
                $this->writeShapeChart($objWriter, $shape, $shapeId);
137 39
            } elseif ($shape instanceof AbstractGraphic) {
138 8
                $this->writeShapePic($objWriter, $shape, $shapeId);
139 15
            } elseif ($shape instanceof Group) {
140 1
                $this->writeShapeGroup($objWriter, $shape, $shapeId);
141 7
            } elseif ($shape instanceof Comment) {
142 7
            } else {
143
                throw new \Exception("Unknown Shape type: {get_class($shape)}");
144
            }
145 73
        }
146 73
    }
147
148
    /**
149
     * Write txt
150
     *
151
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
152
     * @param  \PhpOffice\PhpPresentation\Shape\RichText $shape
153
     * @param  int $shapeId
154
     * @throws \Exception
155
     */
156
    protected function writeShapeText(XMLWriter $objWriter, RichText $shape, $shapeId)
157
    {
158
        // p:sp
159
        $objWriter->startElement('p:sp');
160
        // p:sp\p:nvSpPr
161
        $objWriter->startElement('p:nvSpPr');
162
        // p:sp\p:nvSpPr\p:cNvPr
163
        $objWriter->startElement('p:cNvPr');
164
        $objWriter->writeAttribute('id', $shapeId);
165
        if ($shape->isPlaceholder()) {
166
            $objWriter->writeAttribute('name', 'Placeholder for ' . $shape->getPlaceholder()->getType());
167
        } else {
168
            $objWriter->writeAttribute('name', '');
169
        }
170
        // Hyperlink
171
        if ($shape->hasHyperlink()) {
172
            $this->writeHyperlink($objWriter, $shape);
173
        }
174
        // > p:sp\p:nvSpPr
175
        $objWriter->endElement();
176
        // p:sp\p:cNvSpPr
177
        $objWriter->startElement('p:cNvSpPr');
178
        $objWriter->writeAttribute('txBox', '1');
179
        $objWriter->endElement();
180
        // p:sp\p:cNvSpPr\p:nvPr
181
        if ($shape->isPlaceholder()) {
182
            $objWriter->startElement('p:nvPr');
183
            $objWriter->startElement('p:ph');
184
            $objWriter->writeAttribute('type', $shape->getPlaceholder()->getType());
185
            if (!is_null($shape->getPlaceholder()->getIdx())) {
186
                $objWriter->writeAttribute('idx', $shape->getPlaceholder()->getIdx());
187
            }
188
            $objWriter->endElement();
189
            $objWriter->endElement();
190
        } else {
191
            $objWriter->writeElement('p:nvPr', null);
192
        }
193
        // > p:sp\p:cNvSpPr
194
        $objWriter->endElement();
195
        // p:sp\p:spPr
196
        $objWriter->startElement('p:spPr');
197
        // p:sp\p:spPr\a:xfrm
198
        $objWriter->startElement('a:xfrm');
199
        $objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
200
        // p:sp\p:spPr\a:xfrm\a:off
201
        $objWriter->startElement('a:off');
202
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
203
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
204
        $objWriter->endElement();
205
        // p:sp\p:spPr\a:xfrm\a:ext
206
        $objWriter->startElement('a:ext');
207
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
208
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
209
        $objWriter->endElement();
210
        // > p:sp\p:spPr\a:xfrm
211
        $objWriter->endElement();
212
        // p:sp\p:spPr\a:prstGeom
213
        $objWriter->startElement('a:prstGeom');
214
        $objWriter->writeAttribute('prst', 'rect');
215
216
        // p:sp\p:spPr\a:prstGeom\a:avLst
217
        $objWriter->writeElement('a:avLst');
218
219
        $objWriter->endElement();
220
        $this->writeFill($objWriter, $shape->getFill());
221
        if ($shape->getBorder()->getLineStyle() != Border::LINE_NONE) {
222
            $this->writeBorder($objWriter, $shape->getBorder(), '');
223
        }
224
        if ($shape->getShadow()->isVisible()) {
225
            $this->writeShadow($objWriter, $shape->getShadow());
226
        }
227
        // > p:sp\p:spPr
228
        $objWriter->endElement();
229
        // p:txBody
230
        $objWriter->startElement('p:txBody');
231
        // a:bodyPr
232
        //@link :http://msdn.microsoft.com/en-us/library/documentformat.openxml.drawing.bodyproperties%28v=office.14%29.aspx
233
        $objWriter->startElement('a:bodyPr');
234
        $verticalAlign = $shape->getActiveParagraph()->getAlignment()->getVertical();
235
        if ($verticalAlign != Alignment::VERTICAL_BASE && $verticalAlign != Alignment::VERTICAL_AUTO) {
236
            $objWriter->writeAttribute('anchor', $verticalAlign);
237
        }
238
        if ($shape->getWrap() != RichText::WRAP_SQUARE) {
239
            $objWriter->writeAttribute('wrap', $shape->getWrap());
240
        }
241
        $objWriter->writeAttribute('rtlCol', '0');
242
        if ($shape->getHorizontalOverflow() != RichText::OVERFLOW_OVERFLOW) {
243
            $objWriter->writeAttribute('horzOverflow', $shape->getHorizontalOverflow());
244
        }
245
        if ($shape->getVerticalOverflow() != RichText::OVERFLOW_OVERFLOW) {
246
            $objWriter->writeAttribute('vertOverflow', $shape->getVerticalOverflow());
247
        }
248
        if ($shape->isUpright()) {
249
            $objWriter->writeAttribute('upright', '1');
250
        }
251
        if ($shape->isVertical()) {
252
            $objWriter->writeAttribute('vert', 'vert');
253
        }
254
        $objWriter->writeAttribute('bIns', CommonDrawing::pixelsToEmu($shape->getInsetBottom()));
255
        $objWriter->writeAttribute('lIns', CommonDrawing::pixelsToEmu($shape->getInsetLeft()));
256
        $objWriter->writeAttribute('rIns', CommonDrawing::pixelsToEmu($shape->getInsetRight()));
257
        $objWriter->writeAttribute('tIns', CommonDrawing::pixelsToEmu($shape->getInsetTop()));
258
        if ($shape->getColumns() <> 1) {
259
            $objWriter->writeAttribute('numCol', $shape->getColumns());
260
        }
261
        // a:spAutoFit
262
        $objWriter->startElement('a:' . $shape->getAutoFit());
263
        if ($shape->getAutoFit() == RichText::AUTOFIT_NORMAL) {
264
            if (!is_null($shape->getFontScale())) {
265
                $objWriter->writeAttribute('fontScale', (int)($shape->getFontScale() * 1000));
266
            }
267
            if (!is_null($shape->getLineSpaceReduction())) {
268
                $objWriter->writeAttribute('lnSpcReduction', (int)($shape->getLineSpaceReduction() * 1000));
269
            }
270
        }
271
        $objWriter->endElement();
272
        $objWriter->endElement();
273
        // a:lstStyle
274
        $objWriter->writeElement('a:lstStyle', null);
275
        if ($shape->isPlaceholder() &&
276
            ($shape->getPlaceholder()->getType() == Placeholder::PH_TYPE_SLIDENUM ||
277
                $shape->getPlaceholder()->getType() == Placeholder::PH_TYPE_DATETIME)
278
        ) {
279
            $objWriter->startElement('a:p');
280
            $objWriter->startElement('a:fld');
281
            $objWriter->writeAttribute('id', $this->getGUID());
282
            $objWriter->writeAttribute('type', (
283
            $shape->getPlaceholder()->getType() == Placeholder::PH_TYPE_SLIDENUM ? 'slidenum' : 'datetime'));
284
            $objWriter->writeElement('a:t', (
285
            $shape->getPlaceholder()->getType() == Placeholder::PH_TYPE_SLIDENUM ? '<nr.>' : '03-04-05'));
286
            $objWriter->endElement();
287
            $objWriter->endElement();
288
        } else {
289
            // Write paragraphs
290
            $this->writeParagraphs($objWriter, $shape->getParagraphs());
291
        }
292
        $objWriter->endElement();
293
        $objWriter->endElement();
294
    }
295
296
    /**
297
     * Write table
298
     *
299
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
300
     * @param  \PhpOffice\PhpPresentation\Shape\Table $shape
301
     * @param  int $shapeId
302
     * @throws \Exception
303
     */
304
    protected function writeShapeTable(XMLWriter $objWriter, ShapeTable $shape, $shapeId)
305
    {
306
        // p:graphicFrame
307
        $objWriter->startElement('p:graphicFrame');
308
        // p:nvGraphicFramePr
309
        $objWriter->startElement('p:nvGraphicFramePr');
310
        // p:cNvPr
311
        $objWriter->startElement('p:cNvPr');
312
        $objWriter->writeAttribute('id', $shapeId);
313
        $objWriter->writeAttribute('name', $shape->getName());
314
        $objWriter->writeAttribute('descr', $shape->getDescription());
315
        $objWriter->endElement();
316
        // p:cNvGraphicFramePr
317
        $objWriter->startElement('p:cNvGraphicFramePr');
318
        // a:graphicFrameLocks
319
        $objWriter->startElement('a:graphicFrameLocks');
320
        $objWriter->writeAttribute('noGrp', '1');
321
        $objWriter->endElement();
322
        $objWriter->endElement();
323
        // p:nvPr
324
        $objWriter->writeElement('p:nvPr', null);
325
        $objWriter->endElement();
326
        // p:xfrm
327
        $objWriter->startElement('p:xfrm');
328
        // a:off
329
        $objWriter->startElement('a:off');
330
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
331
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
332
        $objWriter->endElement();
333
        // a:ext
334
        $objWriter->startElement('a:ext');
335
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
336
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
337
        $objWriter->endElement();
338
        $objWriter->endElement();
339
        // a:graphic
340
        $objWriter->startElement('a:graphic');
341
        // a:graphicData
342
        $objWriter->startElement('a:graphicData');
343
        $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/table');
344
        // a:tbl
345
        $objWriter->startElement('a:tbl');
346
        // a:tblPr
347
        $objWriter->startElement('a:tblPr');
348
        $objWriter->writeAttribute('firstRow', '1');
349
        $objWriter->writeAttribute('bandRow', '1');
350
        $objWriter->endElement();
351
        // a:tblGrid
352
        $objWriter->startElement('a:tblGrid');
353
        // Write cell widths
354
        $countCells = count($shape->getRow(0)->getCells());
355
        for ($cell = 0; $cell < $countCells; $cell++) {
356
            // a:gridCol
357
            $objWriter->startElement('a:gridCol');
358
            // Calculate column width
359
            $width = $shape->getRow(0)->getCell($cell)->getWidth();
360
            if ($width == 0) {
361
                $colCount = count($shape->getRow(0)->getCells());
362
                $totalWidth = $shape->getWidth();
363
                $width = $totalWidth / $colCount;
364
            }
365
            $objWriter->writeAttribute('w', CommonDrawing::pixelsToEmu($width));
366
            $objWriter->endElement();
367
        }
368
        $objWriter->endElement();
369
        // Colspan / rowspan containers
370
        $colSpan = array();
371
        $rowSpan = array();
372
        // Default border style
373
        $defaultBorder = new Border();
374
        // Write rows
375
        $countRows = count($shape->getRows());
376
        for ($row = 0; $row < $countRows; $row++) {
377
            // a:tr
378
            $objWriter->startElement('a:tr');
379
            $objWriter->writeAttribute('h', CommonDrawing::pixelsToEmu($shape->getRow($row)->getHeight()));
380
            // Write cells
381
            $countCells = count($shape->getRow($row)->getCells());
382
            for ($cell = 0; $cell < $countCells; $cell++) {
383
                // Current cell
384
                $currentCell = $shape->getRow($row)->getCell($cell);
385
                // Next cell right
386
                $nextCellRight = $shape->getRow($row)->getCell($cell + 1, true);
387
                // Next cell below
388
                $nextRowBelow = $shape->getRow($row + 1, true);
389
                $nextCellBelow = null;
390
                if ($nextRowBelow != null) {
391
                    $nextCellBelow = $nextRowBelow->getCell($cell, true);
392
                }
393
                // a:tc
394
                $objWriter->startElement('a:tc');
395
                // Colspan
396
                if ($currentCell->getColSpan() > 1) {
397
                    $objWriter->writeAttribute('gridSpan', $currentCell->getColSpan());
398
                    $colSpan[$row] = $currentCell->getColSpan() - 1;
399
                } elseif (isset($colSpan[$row]) && $colSpan[$row] > 0) {
400
                    $colSpan[$row]--;
401
                    $objWriter->writeAttribute('hMerge', '1');
402
                }
403
                // Rowspan
404
                if ($currentCell->getRowSpan() > 1) {
405
                    $objWriter->writeAttribute('rowSpan', $currentCell->getRowSpan());
406
                    $rowSpan[$cell] = $currentCell->getRowSpan() - 1;
407
                } elseif (isset($rowSpan[$cell]) && $rowSpan[$cell] > 0) {
408
                    $rowSpan[$cell]--;
409
                    $objWriter->writeAttribute('vMerge', '1');
410
                }
411
                // a:txBody
412
                $objWriter->startElement('a:txBody');
413
                // a:bodyPr
414
                $objWriter->startElement('a:bodyPr');
415
                $objWriter->writeAttribute('wrap', 'square');
416
                $objWriter->writeAttribute('rtlCol', '0');
417
                // a:spAutoFit
418
                $objWriter->writeElement('a:spAutoFit', null);
419
                $objWriter->endElement();
420
                // a:lstStyle
421
                $objWriter->writeElement('a:lstStyle', null);
422
                // Write paragraphs
423
                $this->writeParagraphs($objWriter, $currentCell->getParagraphs());
424
                $objWriter->endElement();
425
                // a:tcPr
426
                $objWriter->startElement('a:tcPr');
427
                // Alignment (horizontal)
428
                $firstParagraph = $currentCell->getParagraph(0);
429
                $verticalAlign = $firstParagraph->getAlignment()->getVertical();
430
                if ($verticalAlign != Alignment::VERTICAL_BASE && $verticalAlign != Alignment::VERTICAL_AUTO) {
431
                    $objWriter->writeAttribute('anchor', $verticalAlign);
432
                }
433
                // Determine borders
434
                $borderLeft = $currentCell->getBorders()->getLeft();
435
                $borderRight = $currentCell->getBorders()->getRight();
436
                $borderTop = $currentCell->getBorders()->getTop();
437
                $borderBottom = $currentCell->getBorders()->getBottom();
438
                $borderDiagonalDown = $currentCell->getBorders()->getDiagonalDown();
439
                $borderDiagonalUp = $currentCell->getBorders()->getDiagonalUp();
440
                // Fix PowerPoint implementation
441
                if (!is_null($nextCellRight)
442
                    && $nextCellRight->getBorders()->getRight()->getHashCode() != $defaultBorder->getHashCode()
443
                ) {
444
                    $borderRight = $nextCellRight->getBorders()->getLeft();
445
                }
446
                if (!is_null($nextCellBelow)
447
                    && $nextCellBelow->getBorders()->getBottom()->getHashCode() != $defaultBorder->getHashCode()
448
                ) {
449
                    $borderBottom = $nextCellBelow->getBorders()->getTop();
450
                }
451
                // Write borders
452
                $this->writeBorder($objWriter, $borderLeft, 'L');
453
                $this->writeBorder($objWriter, $borderRight, 'R');
454
                $this->writeBorder($objWriter, $borderTop, 'T');
455
                $this->writeBorder($objWriter, $borderBottom, 'B');
456
                $this->writeBorder($objWriter, $borderDiagonalDown, 'TlToBr');
457
                $this->writeBorder($objWriter, $borderDiagonalUp, 'BlToTr');
458
                // Fill
459
                $this->writeFill($objWriter, $currentCell->getFill());
460
                $objWriter->endElement();
461
                $objWriter->endElement();
462
            }
463
            $objWriter->endElement();
464
        }
465
        $objWriter->endElement();
466
        $objWriter->endElement();
467
        $objWriter->endElement();
468
        $objWriter->endElement();
469
    }
470
471
    /**
472
     * Write paragraphs
473
     *
474
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
475
     * @param  \PhpOffice\PhpPresentation\Shape\RichText\Paragraph[] $paragraphs
476
     * @throws \Exception
477
     */
478
    protected function writeParagraphs(XMLWriter $objWriter, $paragraphs)
479
    {
480
        // Loop trough paragraphs
481
        foreach ($paragraphs as $paragraph) {
482
            // a:p
483
            $objWriter->startElement('a:p');
484
            // a:pPr
485
            $objWriter->startElement('a:pPr');
486
            $objWriter->writeAttribute('algn', $paragraph->getAlignment()->getHorizontal());
487
            $objWriter->writeAttribute('fontAlgn', $paragraph->getAlignment()->getVertical());
488
            $objWriter->writeAttribute('marL', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginLeft()));
489
            $objWriter->writeAttribute('marR', CommonDrawing::pixelsToEmu(
490
                $paragraph->getAlignment()->getMarginRight()
491
            ));
492
            $objWriter->writeAttribute('indent', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getIndent()));
493
            $objWriter->writeAttribute('lvl', $paragraph->getAlignment()->getLevel());
494
            // Bullet type specified?
495
            if ($paragraph->getBulletStyle()->getBulletType() != Bullet::TYPE_NONE) {
496
                // a:buFont
497
                $objWriter->startElement('a:buFont');
498
                $objWriter->writeAttribute('typeface', $paragraph->getBulletStyle()->getBulletFont());
499
                $objWriter->endElement();
500
                if ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_BULLET) {
501
                    // a:buChar
502
                    $objWriter->startElement('a:buChar');
503
                    $objWriter->writeAttribute('char', $paragraph->getBulletStyle()->getBulletChar());
504
                    $objWriter->endElement();
505
                } elseif ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_NUMERIC) {
506
                    // a:buAutoNum
507
                    $objWriter->startElement('a:buAutoNum');
508
                    $objWriter->writeAttribute('type', $paragraph->getBulletStyle()->getBulletNumericStyle());
509
                    if ($paragraph->getBulletStyle()->getBulletNumericStartAt() != 1) {
510
                        $objWriter->writeAttribute('startAt', $paragraph->getBulletStyle()->getBulletNumericStartAt());
511
                    }
512
                    $objWriter->endElement();
513
                }
514
            }
515
            $objWriter->endElement();
516
            // Loop trough rich text elements
517
            $elements = $paragraph->getRichTextElements();
518
            foreach ($elements as $element) {
519
                if ($element instanceof BreakElement) {
520
                    // a:br
521
                    $objWriter->writeElement('a:br', null);
522
                } elseif ($element instanceof Run || $element instanceof TextElement) {
523
                    // a:r
524
                    $objWriter->startElement('a:r');
525
                    // a:rPr
526
                    if ($element instanceof Run) {
527
                        // a:rPr
528
                        $objWriter->startElement('a:rPr');
529
                        // Lang
530
                        $objWriter->writeAttribute('lang', ($element->getLanguage() ?
531
                            $element->getLanguage() : 'en-US'));
532
                        // Bold
533
                        $objWriter->writeAttribute('b', ($element->getFont()->isBold() ? '1' : '0'));
534
                        // Italic
535
                        $objWriter->writeAttribute('i', ($element->getFont()->isItalic() ? '1' : '0'));
536
                        // Strikethrough
537
                        $objWriter->writeAttribute('strike', ($element->getFont()->isStrikethrough() ?
538
                            'sngStrike' : 'noStrike'));
539
                        // Size
540
                        $objWriter->writeAttribute('sz', ($element->getFont()->getSize() * 100));
541
                        // Underline
542
                        $objWriter->writeAttribute('u', $element->getFont()->getUnderline());
543
                        // Superscript / subscript
544
                        if ($element->getFont()->isSuperScript() || $element->getFont()->isSubScript()) {
545
                            if ($element->getFont()->isSuperScript()) {
546
                                $objWriter->writeAttribute('baseline', '30000');
547
                            } elseif ($element->getFont()->isSubScript()) {
548
                                $objWriter->writeAttribute('baseline', '-25000');
549
                            }
550
                        }
551
                        // Color - a:solidFill
552
                        $objWriter->startElement('a:solidFill');
553
                        // a:srgbClr
554
                        $objWriter->startElement('a:srgbClr');
555
                        $objWriter->writeAttribute('val', $element->getFont()->getColor()->getRGB());
556
                        $objWriter->endElement();
557
                        $objWriter->endElement();
558
                        // Font - a:latin
559
                        $objWriter->startElement('a:latin');
560
                        $objWriter->writeAttribute('typeface', $element->getFont()->getName());
561
                        $objWriter->endElement();
562
                        // a:hlinkClick
563
                        if ($element->hasHyperlink()) {
564
                            $this->writeHyperlink($objWriter, $element);
565
                        }
566
                        $objWriter->endElement();
567
                    }
568
                    // t
569
                    $objWriter->startElement('a:t');
570
                    $objWriter->writeCData(Text::controlCharacterPHP2OOXML($element->getText()));
571
                    $objWriter->endElement();
572
                    $objWriter->endElement();
573
                }
574
            }
575
            $objWriter->endElement();
576
        }
577
    }
578
579
    /**
580
     * Write Line Shape
581
     *
582
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
583
     * @param \PhpOffice\PhpPresentation\Shape\Line $shape
584
     * @param  int $shapeId
585
     */
586
    protected function writeShapeLine(XMLWriter $objWriter, Line $shape, $shapeId)
587
    {
588
        // p:sp
589
        $objWriter->startElement('p:cxnSp');
590
        // p:nvSpPr
591
        $objWriter->startElement('p:nvCxnSpPr');
592
        // p:cNvPr
593
        $objWriter->startElement('p:cNvPr');
594
        $objWriter->writeAttribute('id', $shapeId);
595
        $objWriter->writeAttribute('name', '');
596
        $objWriter->endElement();
597
        // p:cNvCxnSpPr
598
        $objWriter->writeElement('p:cNvCxnSpPr', null);
599
        // p:nvPr
600
        $objWriter->writeElement('p:nvPr', null);
601
        $objWriter->endElement();
602
        // p:spPr
603
        $objWriter->startElement('p:spPr');
604
        // a:xfrm
605
        $objWriter->startElement('a:xfrm');
606
        if ($shape->getWidth() >= 0 && $shape->getHeight() >= 0) {
607
            // a:off
608
            $objWriter->startElement('a:off');
609
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
610
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
611
            $objWriter->endElement();
612
            // a:ext
613
            $objWriter->startElement('a:ext');
614
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
615
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
616
            $objWriter->endElement();
617
        } elseif ($shape->getWidth() < 0 && $shape->getHeight() < 0) {
618
            // a:off
619
            $objWriter->startElement('a:off');
620
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX() + $shape->getWidth()));
621
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY() + $shape->getHeight()));
622
            $objWriter->endElement();
623
            // a:ext
624
            $objWriter->startElement('a:ext');
625
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu(-$shape->getWidth()));
626
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu(-$shape->getHeight()));
627
            $objWriter->endElement();
628
        } elseif ($shape->getHeight() < 0) {
629
            $objWriter->writeAttribute('flipV', 1);
630
            // a:off
631
            $objWriter->startElement('a:off');
632
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
633
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY() + $shape->getHeight()));
634
            $objWriter->endElement();
635
            // a:ext
636
            $objWriter->startElement('a:ext');
637
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
638
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu(-$shape->getHeight()));
639
            $objWriter->endElement();
640
        } elseif ($shape->getWidth() < 0) {
641
            $objWriter->writeAttribute('flipV', 1);
642
            // a:off
643
            $objWriter->startElement('a:off');
644
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX() + $shape->getWidth()));
645
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
646
            $objWriter->endElement();
647
            // a:ext
648
            $objWriter->startElement('a:ext');
649
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu(-$shape->getWidth()));
650
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
651
            $objWriter->endElement();
652
        }
653
        $objWriter->endElement();
654
        // a:prstGeom
655
        $objWriter->startElement('a:prstGeom');
656
        $objWriter->writeAttribute('prst', 'line');
657
658
        // a:prstGeom/a:avLst
659
        $objWriter->writeElement('a:avLst');
660
661
        $objWriter->endElement();
662
        if ($shape->getBorder()->getLineStyle() != Border::LINE_NONE) {
663
            $this->writeBorder($objWriter, $shape->getBorder(), '');
664
        }
665
        $objWriter->endElement();
666
        $objWriter->endElement();
667
    }
668
669
    /**
670
     * Write Shadow
671
     * @param XMLWriter $objWriter
672
     * @param Shadow $oShadow
673
     */
674 25
    protected function writeShadow(XMLWriter $objWriter, $oShadow)
675
    {
676 25
        if (!($oShadow instanceof Shadow)) {
677
            return;
678
        }
679
680 25
        if (!$oShadow->isVisible()) {
681 23
            return;
682
        }
683
684
        // a:effectLst
685 2
        $objWriter->startElement('a:effectLst');
686
687
        // a:outerShdw
688 2
        $objWriter->startElement('a:outerShdw');
689 2
        $objWriter->writeAttribute('blurRad', CommonDrawing::pixelsToEmu($oShadow->getBlurRadius()));
690 2
        $objWriter->writeAttribute('dist', CommonDrawing::pixelsToEmu($oShadow->getDistance()));
691 2
        $objWriter->writeAttribute('dir', CommonDrawing::degreesToAngle($oShadow->getDirection()));
692 2
        $objWriter->writeAttribute('algn', $oShadow->getAlignment());
693 2
        $objWriter->writeAttribute('rotWithShape', '0');
694
695 2
        $this->writeColor($objWriter, $oShadow->getColor(), $oShadow->getAlpha());
696
697 2
        $objWriter->endElement();
698
699 2
        $objWriter->endElement();
700 2
    }
701
702
    /**
703
     * Write hyperlink
704
     *
705
     * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer
706
     * @param \PhpOffice\PhpPresentation\AbstractShape|\PhpOffice\PhpPresentation\Shape\RichText\TextElement $shape
707
     */
708
    protected function writeHyperlink(XMLWriter $objWriter, $shape)
709
    {
710
        // a:hlinkClick
711
        $objWriter->startElement('a:hlinkClick');
712
        $objWriter->writeAttribute('r:id', $shape->getHyperlink()->relationId);
713
        $objWriter->writeAttribute('tooltip', $shape->getHyperlink()->getTooltip());
714
        if ($shape->getHyperlink()->isInternal()) {
715
            $objWriter->writeAttribute('action', $shape->getHyperlink()->getUrl());
716
        }
717
        $objWriter->endElement();
718
    }
719
720
    /**
721
     * Write Note Slide
722
     * @param Note $pNote
723
     * @throws \Exception
724
     * @return  string
725
     */
726
    protected function writeNote(Note $pNote)
727
    {
728
        // Create XML writer
729
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
730
        // XML header
731
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
732
        // p:notes
733
        $objWriter->startElement('p:notes');
734
        $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
735
        $objWriter->writeAttribute('xmlns:p', 'http://schemas.openxmlformats.org/presentationml/2006/main');
736
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
737
        // p:cSld
738
        $objWriter->startElement('p:cSld');
739
        // p:spTree
740
        $objWriter->startElement('p:spTree');
741
        // p:nvGrpSpPr
742
        $objWriter->startElement('p:nvGrpSpPr');
743
        // p:cNvPr
744
        $objWriter->startElement('p:cNvPr');
745
        $objWriter->writeAttribute('id', '1');
746
        $objWriter->writeAttribute('name', '');
747
        $objWriter->endElement();
748
        // p:cNvGrpSpPr
749
        $objWriter->writeElement('p:cNvGrpSpPr', null);
750
        // p:nvPr
751
        $objWriter->writeElement('p:nvPr', null);
752
        // ## p:nvGrpSpPr
753
        $objWriter->endElement();
754
        // p:grpSpPr
755
        $objWriter->startElement('p:grpSpPr');
756
        // a:xfrm
757
        $objWriter->startElement('a:xfrm');
758
        // a:off
759
        $objWriter->startElement('a:off');
760
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pNote->getOffsetX()));
761
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pNote->getOffsetY()));
762
        $objWriter->endElement(); // a:off
763
        // a:ext
764
        $objWriter->startElement('a:ext');
765
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pNote->getExtentX()));
766
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pNote->getExtentY()));
767
        $objWriter->endElement(); // a:ext
768
        // a:chOff
769
        $objWriter->startElement('a:chOff');
770
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pNote->getOffsetX()));
771
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pNote->getOffsetY()));
772
        $objWriter->endElement(); // a:chOff
773
        // a:chExt
774
        $objWriter->startElement('a:chExt');
775
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pNote->getExtentX()));
776
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pNote->getExtentY()));
777
        $objWriter->endElement(); // a:chExt
778
        // ## a:xfrm
779
        $objWriter->endElement();
780
        // ## p:grpSpPr
781
        $objWriter->endElement();
782
        // p:sp
783
        $objWriter->startElement('p:sp');
784
        // p:nvSpPr
785
        $objWriter->startElement('p:nvSpPr');
786
        $objWriter->startElement('p:cNvPr');
787
        $objWriter->writeAttribute('id', '1');
788
        $objWriter->writeAttribute('name', 'Notes Placeholder');
789
        $objWriter->endElement();
790
        // p:cNvSpPr
791
        $objWriter->startElement('p:cNvSpPr');
792
        //a:spLocks
793
        $objWriter->startElement('a:spLocks');
794
        $objWriter->writeAttribute('noGrp', '1');
795
        $objWriter->endElement();
796
        // ## p:cNvSpPr
797
        $objWriter->endElement();
798
        // p:nvPr
799
        $objWriter->startElement('p:nvPr');
800
        $objWriter->startElement('p:ph');
801
        $objWriter->writeAttribute('type', 'body');
802
        $objWriter->writeAttribute('idx', '1');
803
        $objWriter->endElement();
804
        // ## p:nvPr
805
        $objWriter->endElement();
806
        // ## p:nvSpPr
807
        $objWriter->endElement();
808
        $objWriter->writeElement('p:spPr', null);
809
        // p:txBody
810
        $objWriter->startElement('p:txBody');
811
        $objWriter->writeElement('a:bodyPr', null);
812
        $objWriter->writeElement('a:lstStyle', null);
813
        // Loop shapes
814
        $shapes = $pNote->getShapeCollection();
815
        foreach ($shapes as $shape) {
816
            // Check type
817
            if ($shape instanceof RichText) {
818
                $paragraphs = $shape->getParagraphs();
819
                $this->writeParagraphs($objWriter, $paragraphs);
820
            }
821
        }
822
        // ## p:txBody
823
        $objWriter->endElement();
824
        // ## p:sp
825
        $objWriter->endElement();
826
        // ## p:spTree
827
        $objWriter->endElement();
828
        // ## p:cSld
829
        $objWriter->endElement();
830
        // ## p:notes
831
        $objWriter->endElement();
832
        // Return
833
        return $objWriter->getData();
834
    }
835
836
    /**
837
     * Write chart
838
     *
839
     * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer
840
     * @param \PhpOffice\PhpPresentation\Shape\Chart $shape
841
     * @param  int $shapeId
842
     */
843
    protected function writeShapeChart(XMLWriter $objWriter, ShapeChart $shape, $shapeId)
844
    {
845
        // p:graphicFrame
846
        $objWriter->startElement('p:graphicFrame');
847
        // p:nvGraphicFramePr
848
        $objWriter->startElement('p:nvGraphicFramePr');
849
        // p:cNvPr
850
        $objWriter->startElement('p:cNvPr');
851
        $objWriter->writeAttribute('id', $shapeId);
852
        $objWriter->writeAttribute('name', $shape->getName());
853
        $objWriter->writeAttribute('descr', $shape->getDescription());
854
        $objWriter->endElement();
855
        // p:cNvGraphicFramePr
856
        $objWriter->writeElement('p:cNvGraphicFramePr', null);
857
        // p:nvPr
858
        $objWriter->writeElement('p:nvPr', null);
859
        $objWriter->endElement();
860
        // p:xfrm
861
        $objWriter->startElement('p:xfrm');
862
        $objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
863
        // a:off
864
        $objWriter->startElement('a:off');
865
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
866
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
867
        $objWriter->endElement();
868
        // a:ext
869
        $objWriter->startElement('a:ext');
870
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
871
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
872
        $objWriter->endElement();
873
        $objWriter->endElement();
874
        // a:graphic
875
        $objWriter->startElement('a:graphic');
876
        // a:graphicData
877
        $objWriter->startElement('a:graphicData');
878
        $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
879
        // c:chart
880
        $objWriter->startElement('c:chart');
881
        $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
882
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
883
        $objWriter->writeAttribute('r:id', $shape->relationId);
884
        $objWriter->endElement();
885
        $objWriter->endElement();
886
        $objWriter->endElement();
887
        $objWriter->endElement();
888
    }
889
890
    /**
891
     * Write pic
892
     *
893
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
894
     * @param  \PhpOffice\PhpPresentation\Shape\AbstractGraphic $shape
895
     * @param  int $shapeId
896
     * @throws \Exception
897
     */
898 8
    protected function writeShapePic(XMLWriter $objWriter, AbstractGraphic $shape, $shapeId)
899
    {
900
        // p:pic
901 8
        $objWriter->startElement('p:pic');
902
        // p:nvPicPr
903 8
        $objWriter->startElement('p:nvPicPr');
904
        // p:cNvPr
905 8
        $objWriter->startElement('p:cNvPr');
906 8
        $objWriter->writeAttribute('id', $shapeId);
907 8
        $objWriter->writeAttribute('name', $shape->getName());
908 8
        $objWriter->writeAttribute('descr', $shape->getDescription());
909
        // a:hlinkClick
910 8
        if ($shape->hasHyperlink()) {
911 1
            $this->writeHyperlink($objWriter, $shape);
912 1
        }
913 8
        $objWriter->endElement();
914
        // p:cNvPicPr
915 8
        $objWriter->startElement('p:cNvPicPr');
916
        // a:picLocks
917 8
        $objWriter->startElement('a:picLocks');
918 8
        $objWriter->writeAttribute('noChangeAspect', '1');
919 8
        $objWriter->endElement();
920 8
        $objWriter->endElement();
921
        // p:nvPr
922 8
        $objWriter->startElement('p:nvPr');
923
        /**
924
         * @link : https://github.com/stefslon/exportToPPTX/blob/master/exportToPPTX.m#L2128
925
         */
926 8
        if ($shape instanceof Media) {
927
            // p:nvPr > a:videoFile
928 1
            $objWriter->startElement('a:videoFile');
929 1
            $objWriter->writeAttribute('r:link', $shape->relationId);
930 1
            $objWriter->endElement();
931
            // p:nvPr > p:extLst
932 1
            $objWriter->startElement('p:extLst');
933
            // p:nvPr > p:extLst > p:ext
934 1
            $objWriter->startElement('p:ext');
935 1
            $objWriter->writeAttribute('uri', '{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}');
936
            // p:nvPr > p:extLst > p:ext > p14:media
937 1
            $objWriter->startElement('p14:media');
938 1
            $objWriter->writeAttribute('r:embed', $shape->relationId);
939 1
            $objWriter->writeAttribute('xmlns:p14', 'http://schemas.microsoft.com/office/powerpoint/2010/main');
940
            // p:nvPr > p:extLst > p:ext > ##p14:media
941 1
            $objWriter->endElement();
942
            // p:nvPr > p:extLst > ##p:ext
943 1
            $objWriter->endElement();
944
            // p:nvPr > ##p:extLst
945 1
            $objWriter->endElement();
946 1
        }
947
        // ##p:nvPr
948 8
        $objWriter->endElement();
949 8
        $objWriter->endElement();
950
        // p:blipFill
951 8
        $objWriter->startElement('p:blipFill');
952
        // a:blip
953 8
        $objWriter->startElement('a:blip');
954 8
        $objWriter->writeAttribute('r:embed', $shape->relationId);
955 8
        $objWriter->endElement();
956
        // a:stretch
957 8
        $objWriter->startElement('a:stretch');
958 8
        $objWriter->writeElement('a:fillRect', null);
959 8
        $objWriter->endElement();
960 8
        $objWriter->endElement();
961
        // p:spPr
962 8
        $objWriter->startElement('p:spPr');
963
        // a:xfrm
964 8
        $objWriter->startElement('a:xfrm');
965 8
        $objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
966
        // a:off
967 8
        $objWriter->startElement('a:off');
968 8
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
969 8
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
970 8
        $objWriter->endElement();
971
        // a:ext
972 8
        $objWriter->startElement('a:ext');
973 8
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
974 8
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
975 8
        $objWriter->endElement();
976 8
        $objWriter->endElement();
977
        // a:prstGeom
978 8
        $objWriter->startElement('a:prstGeom');
979 8
        $objWriter->writeAttribute('prst', 'rect');
980
        // a:avLst
981 8
        $objWriter->writeElement('a:avLst', null);
982 8
        $objWriter->endElement();
983 8
        if ($shape->getBorder()->getLineStyle() != Border::LINE_NONE) {
984 1
            $this->writeBorder($objWriter, $shape->getBorder(), '');
985 1
        }
986 8
        if ($shape->getShadow()->isVisible()) {
987 1
            $this->writeShadow($objWriter, $shape->getShadow());
988 1
        }
989 8
        $objWriter->endElement();
990 8
        $objWriter->endElement();
991 8
    }
992
993
    /**
994
     * Write group
995
     *
996
     * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer
997
     * @param \PhpOffice\PhpPresentation\Shape\Group $group
998
     * @param  int $shapeId
999
     */
1000
    protected function writeShapeGroup(XMLWriter $objWriter, Group $group, &$shapeId)
1001
    {
1002
        // p:grpSp
1003
        $objWriter->startElement('p:grpSp');
1004
        // p:nvGrpSpPr
1005
        $objWriter->startElement('p:nvGrpSpPr');
1006
        // p:cNvPr
1007
        $objWriter->startElement('p:cNvPr');
1008
        $objWriter->writeAttribute('name', 'Group ' . $shapeId++);
1009
        $objWriter->writeAttribute('id', $shapeId);
1010
        $objWriter->endElement(); // p:cNvPr
1011
        // NOTE: Re: $shapeId This seems to be how PowerPoint 2010 does business.
1012
        // p:cNvGrpSpPr
1013
        $objWriter->writeElement('p:cNvGrpSpPr', null);
1014
        // p:nvPr
1015
        $objWriter->writeElement('p:nvPr', null);
1016
        $objWriter->endElement(); // p:nvGrpSpPr
1017
        // p:grpSpPr
1018
        $objWriter->startElement('p:grpSpPr');
1019
        // a:xfrm
1020
        $objWriter->startElement('a:xfrm');
1021
        // a:off
1022
        $objWriter->startElement('a:off');
1023
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($group->getOffsetX()));
1024
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($group->getOffsetY()));
1025
        $objWriter->endElement(); // a:off
1026
        // a:ext
1027
        $objWriter->startElement('a:ext');
1028
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($group->getExtentX()));
1029
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($group->getExtentY()));
1030
        $objWriter->endElement(); // a:ext
1031
        // a:chOff
1032
        $objWriter->startElement('a:chOff');
1033
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($group->getOffsetX()));
1034
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($group->getOffsetY()));
1035
        $objWriter->endElement(); // a:chOff
1036
        // a:chExt
1037
        $objWriter->startElement('a:chExt');
1038
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($group->getExtentX()));
1039
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($group->getExtentY()));
1040
        $objWriter->endElement(); // a:chExt
1041
        $objWriter->endElement(); // a:xfrm
1042
        $objWriter->endElement(); // p:grpSpPr
1043
1044
        $this->writeShapeCollection($objWriter, $group->getShapeCollection(), $shapeId);
1045
1046
        $objWriter->endElement(); // p:grpSp
1047
    }
1048
1049
    /**
1050
     * @param \PhpOffice\PhpPresentation\Slide\AbstractSlide $pSlide
1051
     * @param $objWriter
1052
     */
1053 98
    protected function writeSlideBackground(AbstractSlideAlias $pSlide, XMLWriter $objWriter)
1054
    {
1055 98
        if (!($pSlide->getBackground() instanceof Slide\AbstractBackground)) {
1056 98
            return;
1057
        }
1058 98
        $oBackground = $pSlide->getBackground();
1059
        // p:bg
1060 98
        $objWriter->startElement('p:bg');
1061 98
        if ($oBackground instanceof Slide\Background\Color) {
1062
            // p:bgPr
1063 98
            $objWriter->startElement('p:bgPr');
1064
            // a:solidFill
1065 98
            $objWriter->startElement('a:solidFill');
1066
            // a:srgbClr
1067 98
            $objWriter->startElement('a:srgbClr');
1068 98
            $objWriter->writeAttribute('val', $oBackground->getColor()->getRGB());
1069 98
            $objWriter->endElement();
1070
            // > a:solidFill
1071 98
            $objWriter->endElement();
1072
1073
            // p:bgPr/a:effectLst
1074 98
            $objWriter->writeElement('a:effectLst');
1075
1076
            // > p:bgPr
1077 98
            $objWriter->endElement();
1078 98
        }
1079 98
        if ($oBackground instanceof Slide\Background\Image) {
1080
            // p:bgPr
1081
            $objWriter->startElement('p:bgPr');
1082
            // a:blipFill
1083
            $objWriter->startElement('a:blipFill');
1084
            // a:blip
1085
            $objWriter->startElement('a:blip');
1086
            $objWriter->writeAttribute('r:embed', $oBackground->relationId);
1087
            // > a:blipFill
1088
            $objWriter->endElement();
1089
            // a:stretch
1090
            $objWriter->startElement('a:stretch');
1091
            // a:fillRect
1092
            $objWriter->writeElement('a:fillRect');
1093
            // > a:stretch
1094
            $objWriter->endElement();
1095
            // > a:blipFill
1096
            $objWriter->endElement();
1097
            // > p:bgPr
1098
            $objWriter->endElement();
1099
        }
1100
        /**
1101
         * @link : http://www.officeopenxml.com/prSlide-background.php
1102
         */
1103 98
        if ($oBackground instanceof Slide\Background\SchemeColor) {
1104
            // p:bgRef
1105
            $objWriter->startElement('p:bgRef');
1106
            $objWriter->writeAttribute('idx', '1001');
1107
            // a:schemeClr
1108
            $objWriter->startElement('a:schemeClr');
1109
            $objWriter->writeAttribute('val', $oBackground->getSchemeColor()->getValue());
1110
            $objWriter->endElement();
1111
            // > p:bgRef
1112
            $objWriter->endElement();
1113
        }
1114
        // > p:bg
1115 98
        $objWriter->endElement();
1116 98
    }
1117
1118
    private function getGUID()
1119
    {
1120
        if (function_exists('com_create_guid')) {
1121
            return com_create_guid();
1122
        } else {
1123
            mt_srand((double)microtime() * 10000);//optional for php 4.2.0 and up.
1124
            $charid = strtoupper(md5(uniqid(rand(), true)));
1125
            $hyphen = chr(45);// "-"
1126
            $uuid = chr(123)// "{"
1127
                . substr($charid, 0, 8) . $hyphen
1128
                . substr($charid, 8, 4) . $hyphen
1129
                . substr($charid, 12, 4) . $hyphen
1130
                . substr($charid, 16, 4) . $hyphen
1131
                . substr($charid, 20, 12)
1132
                . chr(125);// "}"
1133
            return $uuid;
1134
        }
1135
    }
1136
}
1137